life, php

Rank Your Book Collection

I love books. It is due to my parents, that put in me from the age of 4 or 5 this passion to the written word. It might be (also), my literature teacher from high school, that took the only subject I really didn’t like (yep… I enjoyed math, physics and computers but hated literature) and made his course a pure adventure full of joy. I remember lots of moments when you finish a book but keep thinking on the subjects/point of views/heroes years and years after the 4th time you reading it. In a way, my kindle is a wonderful device but I still really like to hold a ‘real’ book.

Last weekend, I’ve decided to ‘sort’ my mobile (=kindle) books. Since I’ve had them (all 1,073) on one big folder, I wrote this little script that build a list of their names and then use amazon to get their rating. From here, the path to a spreadsheet with the data is very short. Now, I know what are the best ones, by harnessing the ‘wisdom of the crowds’.
Happy reading!

Here is the code (or if you like a better version try it on github)


 * Description: read a list of books (from a collection on your hard drive)
 * and use amazon review to rank them. This is helpful if you have lots of books.
 * It's good to put the best one on your kindle for the next vacation/conf etc'.
 * @author Ido Green
 * @date 4/24/2011
 * @see
 * - to handle regex IF you want to get ranking from the html
class scanAmazon {

    private $books = array();
    private $newRankList = array();

     * Ctor
     * @param type $dir - the path to your directory of books
    function __construct($dir) {

     * Run on all the books and get the rating, then, save them to a CSV file.
    public function run() {
        $this->saveToFile("booksRanking.csv", implode("\n", $this->newRankList));

     * build a list of books' name from the file names
     * @param type $dir - the path to your directory of books
    private function buildList($dir) {
        if ($handle = opendir($dir)) {
            while (false !== ($file = readdir($handle))) {
                //echo "$file\n";
                $name = substr($file, 0, strlen($file) - 5);
                if (strlen($name) > 2) {
                    array_push($this->books, $name);

     * Get the rating of the books
     * we are looking for this pattern: Rated 4.7 out of 5.0
     * 1. Use google results:
     * 2. Use amazon directly:
    private function getRating() {
        echo "Working on " . count($this->books) . " books\n";
        $i = 1;
        foreach ($this->books as $book) {  
            $searchUrl = '' . urlencode($book);
           // this is the pattern "alt="4.3 out of 5 stars"
            $resPage = file_get_contents($searchUrl);
            $matches = array();
            $ind2 = strpos($resPage, "out of 5 stars");
            $ind1 = $ind2 - 4;//strripos($resPage, '"',$ind2);
            //google: $ind1 = strpos($resPage, "Rated") + 5;
            //google: $ind2 = strpos($resPage, "out of", $ind1);
            if ($ind2 > $ind1 && ($ind2-$ind1) newRankList, $rank . "," . str_replace(",", " ", $book) . ",".
                echo "{$i}) {$book} - Ranking: {$rank} out of 5.0\n";
            else {
                echo "{$i} ERR - {$book} got no rating url: {$searchUrl}\n";
            sleep(5); // let not overload amazon server :)
            // $found = preg_match('/Rated (\d\.\d) out of 5.0/gi', $resPage, $matches);
            //if ($found && count($matches) > 0) { $rank = $matches[0]; }

     * simple saver of data/string to file
     * @param  $fileName
     * @param  $data
     * @return  false when we could not save the data
    function saveToFile($fileName, $data) {
        try {
            $fh = fopen($fileName, 'w');
            fwrite($fh, $data);
        } catch (Exception $exc) {
            error_log("Err: Could not write to file: {$fileName
                    } Trace:" . $exc->getTraceAsString());
            return false;
        return true;


// start the party
$scanner = new scanAmazon("PATH TO YOUR BOOKS");


Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s