Friday, January 4, 2013

PHP code for listing Facebook scores

On my website I have a directory of about 800 html files, and I wanted to create a list of the most popular ones according to Facebook "like" and "share" counts. Below is my pseudo php code for this. The steps are the following:

1. List all files in the directory.
2. Call the Facebook API and find out the score for each file. (I couldn't find a way to do this for a whole directory at once.) You don't need an API key for this so it's very straight forward.
3. Sort according to score.
4. Print a table with the title of the html file (with a link to the proper URL) and the corresponding score.

Since I have 800 files, this take about one minute to complete. Therefore I don't run it in real time on my website. Instead I run it in cron once every day and writes the output to a file that is included using SSI into my page.

Example of usage can be seen at http://www.karinboye.se/index.shtml (in Swedish).

 # Name of your website as in example.com  
 $site  = 'example.com';  
 # Name of the subdiretory as in /directory/directory  
 $dir   = '/dir/dir';  
   
 # Define some variables  
 $baseurl = 'http://api.facebook.com/restserver.php?
method=links.getStats&format=json&urls=';  
 $i    = 0;  
   
 # Loop through all files in the directory  
 if ($handle = opendir('.'.$dir)) {  
   while (false !== ($entry = readdir($handle))) {  
     if ($entry != "." && $entry != "..") {  
               
 #      Call the Facebook API to get the data  
       $url = $baseurl.$site.$dir.'/'.$entry;  
       $ch = curl_init();  
       curl_setopt($ch, CURLOPT_URL,$url);  
       curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);  
       curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);  
       curl_setopt($ch, CURLOPT_TIMEOUT, 5);  
       curl_setopt($ch, CURLOPT_NOSIGNAL, 1);  
       $string = curl_exec($ch);  
       curl_close($ch);  
   
       $result = json_decode($string, TRUE);  
   
 #      Of all the data returned I only need the total count here  
       $count = $result[0]['total_count'];  
   
 #      Store the filename and score into two arrays      
       $file[$i] = $entry;  
       $score[$i] = $count;  
       $i++;  
         
     }  
   }  
   closedir($handle);  
 }  
   
 # Sort the arrays according to highest score  
 array_multisort($score, SORT_DESC, $file);  
   
 # Open a file to store the result in  
 $f = fopen('fb.shtml', 'w');  
   
 # Write the header  
 fwrite($f, "<!-- Created at: ".date("F j, Y, G:i")." -->\n");  
 fwrite($f, "<table border=\"0\" cellspacing=\"5\">\n");  
   
 # Loop through the top 10 scores  
 for ($i=0; $i<=9; $i++) {  
   
 #  Get the title from the file  
   $url = '.'.$dir.'/'.$file[$i];  
   preg_match('/<title>(.+)<\/title>/iU',file_get_contents($url),
$matches);  
   $title = $matches[1];  
   
 #  Write the data    
   fwrite($f, "<tr><td class=\"normaltext\"><a href=\"$url\">");  
   fwrite($f, "$title</a></td>");  
   fwrite($f, "<td class=\"normaltext\" align=\"right\">$score[$i]</td>
</tr>\n");  
   
 }  
   
 fwrite($f, "</table>\n");  
 fclose($f);  

Wednesday, January 2, 2013

PHP code for Google Analytics API

I wanted to list the most popular documents during the last month within a specific directory on my website, using PHP calls to the Google Analytics API. There are several write-ups about this on the web, but here is my version.

First visit the Google API console and create a new project. You may choose any name. Enable Analytics API. Goto ”API access”. Click the button to ”Create an Oauth 2.0 client ID”. Choose any product ID. Click on “next”. Now comes the first important thing to remember: do not choose to create a webapp, instead choose to create a ”service account”. This will allow your app to login into your Google Analytics on it's own. Click create ”Client ID”. Click on ”Download private key”. You will get a .p12 file that you should put together with your php file you create later. Note the Client ID and the Email address you obtain now.

Now goto your Google Analytics pages and create a new user for the email address you just obtained. Give it administrator rights. Using this email as user, your php application will now have access to your Google Analytics data. Also note the profile ID number for your profile.

Download the google-api-php-client library from Google.

Time to code. Below are some pseudo code. There are 5 places you need to put your own data from the API console and your Google Analytics. Also change the filter if you want to narrow down the statistics to a specific directory. If you want to use the whole site, simple remove that line. The sample program will list the 5 most popular documents in the specified directory the last 30 days.

Example of usage can be seen at http://www.karinboye.se/index.shtml (in Swedish).

   
 // api dependencies  
   
 require_once('google-api-php-client/src/Google_Client.php');  
 require_once('google-api-php-client/src/contrib/
Google_AnalyticsService.php');  
   
 // create client object and set app name  
 $client = new Google_Client();  
 $client->setApplicationName('myapp'); // name of your app  
   
 // set assertion credentials  
 $client->setAssertionCredentials(  
   new Google_AssertionCredentials(  
     '000000000000@developer.gserviceaccount.com', // email to GA  
     array('https://www.googleapis.com/auth/analytics.readonly'),  
     file_get_contents('xxx-privatekey.p12') // keyfile   
   )  
 );  
   
 // other settings  
 $client->setClientId('000000000000.apps.googleusercontent.com'); 
// from API console  
 $client->setAccessType('offline_access'); 
   
 // create service and get data  
 $service = new Google_AnalyticsService($client);  
   
 $yesterday = date("Y-m-d", time() - (60*60*24) );  
 $monthago = date("Y-m-d", time() - (60*60*24*30) );  
   
 $response = $service->data_ga->get(  
     'ga:00000000', // profile id  
     $monthago, // start date  
     $yesterday, // end date  
     'ga:visitors',  
     array(  
       'dimensions' => 'ga:pagePath,ga:pageTitle',  
       'sort' => '-ga:visitors',  
       'filters' => 'ga:pagePath=~^/path/path/.*', // example url filter  
       'max-results' => '10'));  
   
 for ($i=0; $i<=9; $i++) {  
   
   $url = $response['rows'][$i][0];  
   $title = utf8_decode($response['rows'][$i][1]);  
   $visitors = $response['rows'][$i][2];  
   
   print "<a href=\"$url\">$title</a><br>";  
   
 }  
   

Tuesday, January 1, 2013

Display latest Disqus entries

I recently added disqus to a website and wanted to promote it by listing the latest entries on the home page. Unfortunately, Disqus no longer offer ready made widgets for this. There is an API that can be used, but it's even simpler to use the RSS feed. Below are some pseudo PHP code that use magpie to fetch the RSS stream and get the corresponding variables.

Example of usage can be seen at http://www.karinboye.se/index.shtml (in Swedish).

require_once 'magpierss/rss_fetch.inc';
$url = 'http://your_disqus_id.disqus.com/latest.rss';

$rss = fetch_rss($url);

echo "Site: ", $rss->channel['title'], "<br>";

foreach ($rss->items as $item ) {     

     $title   = $item['title'];
     $text    = $item['description'];
     $creator = $item['dc']['creator'];
     $date    = $item['dc']['pubdate'];
     $url     = $item[link];
     echo "<a href=$url>$title</a><br>";
     echo "$text<br>";
     echo "$creator<br>";
     echo "$date<br>";

}


Wednesday, July 13, 2011

Light Field Camera


While a normal digital camera captures 2D images on the sensor, Lytro is creating a light field camera with a new type of sensor that also captures the vector direction of the rays of light that hits the sensor. The result is images with 3D information. The examples they show are very interesting and the technology have a potential to change the way we take photographs in the future.

Wednesday, May 25, 2011

Animations at a new level

GIF animations is something that has been available for a long time. Most web developers have been working with them. But the cinemagraphs at “From me to you” (http://fromme-toyou.tumblr.com/tagged/gif) takes them to a new level. The rest of us have to put our trust in Adobe making this as easy as “content aware fill” in the next release of Photoshop or Aftereffects.

Sunday, May 22, 2011

Creativity + Memory -

Last Friday I listened to a very good talk by James Latham, Chief Marketing Officer at Open Text. One of his slides summarized a thing I have been thinking about, in a nice short way:

Creativity +

Memory -

In the information society we live in today, we have a lot of information available to us, literally at our fingertips. Using our computer or mobile phone we can easily look up the information we need at any time. This reduce the need to remember things (a very good thing for us with a bad memory). Moreover, the skills of being able to remember and collect large amounts of information become less important, while the skills of being creative and to evaluate and use the information, becomes more important. This can already be seen in the behavior of the younger generation, and it will continue.

When will education (and the selection for higher education) embrace this fully?


Wednesday, May 18, 2011

Reducing bandwidth – Results by putting static content in the cloud

Its time for step two: to reduce internal bandwidth usage of our website by putting static content in the cloud.

I think I can do this fastest by using cloud servers, replicating our internal servers. I can do it better later using CDN.

I started a Red Hat Linux server on Rackspace in US. I installed Apache, MySQL and PHP. I configured the system like our own servers. After verifying that it worked as it should, I cloned it and started a second copy of it. Now I have two new web servers just like my internal ones, situated in the cloud in US. This was done in less than an hour.

I then started a Rackspace redundant load balancer for my two web servers. This is the first time I use such a load balancer, but it turned out to be very easy and done in less than 15 minutes.

The website had already been separated so that the more frequent images and some static content are referred by a different domain name compared to the dynamic website. Now its easy for me to change my DNS so that the static content is fetched from the cloud servers while the rest of the website remain on our own local servers. This needs some time to take effect.

After a couple of days I could once again look at the full page render times in our Apica monitoring system. This time I got 30% less download time from US, 30% worse download time from Sweden and no difference from Asia.

Once again, this result is rather expected since I have moved a lot of content from Sweden to US. But since 50% of our visitors are from US and only 4% from Sweden, this is far better for our visitors. This should however be improved by using a CDN.

Now I can also look at the internal bandwidth usage. It appears as if I have cut the usage of our local network with about 30%.

This means that with a few hours of work I have reduced the local bandwidth with 30% and at the same time made the website 20-30% faster for the majority of our visitors.