Dienstag, 22. Mai 2012

Show a preview of your latest blogspot post on your external domain homepage

Hello readers!


During my internship I was given the task to find out on how to realize a small preview of the newest post from a blog here on blogspot. The problem was, that the previews should be integrated into a website owned by our client which was hosted by a different provider on a different domain, and that they should always keep up to date without any modifications. Additionally, my boss preferred to have the preview generated on client side, because it means less traffic and probably less trouble when integrating it into the rest of the framework-based project. In plain words, I was supposed to use Javascript.

So I searched the internet for multiple keyword combinations but did not find any solutions of someone who did that before. So I had to come up with a solution myself.

I believe there are three possible approaches for that:
The worst should be to go via the blog homepage, because then the desired information would either be mixed up with all sort of additional markup or completely hidden in other js-scripts.

The second approach is probably the most elegant one, but not completely simple to realize: If I tried to receive the data by pulling it from the blog's atom/rss feed I would have my information in a relatively good structure and Google would probably not set a limit to the number of accesses per day. Unfortunately though, plain javascript does not provide tools to parse the xml-alike feed output and I did not want to mess with an external library or parse the feed myself, which is probably still relatively easy with regular expression matches.

But I went the third way, which is probably the first one that came to your mind: Via the blogger api.
The api is currently under construction (heading for version 2) and the registration process takes some time to complete. You have to register/create a new api-Project on https://code.google.com/apis/console/ and apply for the permission to use the blogger api in it. The response e-mail took about twelve hours during the two times I tried it, which is the reason why I even think that there is only one Google employee who manually admits the usage of the api for your project.

Afterwards you simply do what the blogger-team wrote in their answer and you get access to the API-key, which is used by Google to keep track of your usage. I believe, the standard daily quota is about 1000 and I hope, it is counted by IPs and not by API-calls. Otherwise the permitted accesses would be exhausted quite rapidly.

Here is the code of my blogger.js file that generates the preview:
 /**  
  * Version: 2012/05/23 rev.1  
  *   
  * This script obtains information from the first post of a blogger-blog   
  * (in particular title + first image) and injects it into a specific  
  * place in the webpage.  
  *   
  * Currently, the information is written into an element (<div>) with the  
  * ID "blogger_output"  
  *   
  * To be able to style the information via css, the following classes are given to it:  
  * post title (p-tag): blogger_title  
  * post image (img-tag): blogger_image  
  */  
   
 function Blogger() {  
    Blogger.init();  
 }  
   
 Blogger.htmlOut = "blogger_output"; //The html-element, in which the blog-preview is to be written  
 Blogger.gAPI_URL = "https://www.googleapis.com/blogger/v2/blogs/"; //the blogger api base-url  
 Blogger.blogID = "9034413279324519603"; //The id of the blog whose latest post we want to generate a preview from  
 Blogger.apiKey = "AIzaSyCYuAlcd4NzcvTB2Igp7b2Tuuak_mLfcfk"; //The api-key to access the blogger-api  
   
 /**  
  * Writes a new line of (html-) text into the output element specified above  
  * @param text Some text to be written into the htmlOut element  
  */  
 Blogger.echo = function(text, writeInID) {  
    document.getElementById(writeInID).innerHTML += text;  
 };  
   
 /**  
  * Dynamically injects a script to the end of the body of the page  
  * @param jsname the url or name of the script to be injected  
  */  
 Blogger.injectScript = function (jsname) {  
    var scr = document.createElement('script');  
    scr.setAttribute('type','text/javascript');  
    scr.setAttribute('src',jsname);  
      
    var body = document.getElementsByTagName('body')[0];  
    body.appendChild(scr);  
 };  
   
 /**  
  * This is the callback method of the first blogger api call. Currently it does all  
  * the work (get title, image(s), preview text...), but at a later point we hope  
  * the blogger REST-api will support at least images as an additional resource type.   
  * In this case it is easy to add a second callback method correponding to the image[s]  
  * of the first post only.  
  * @param response The response of the google server after our api call  
  */  
 Blogger.handleBlog = function(response) {  
    //extract image url  
    var imgTag = response.items[0].content.match('(\\u003cimg.*?(/\\u003e))')[0];  
    var imgUrl = imgTag.match('http:.*?(?=\")');  
      
    //output  
    var aName = "blogger_link";  
    this.echo('<a id="' + aName + '" class="' + aName + '" href="' + response.items[0].url + '"></a>', this.htmlOut);  
    this.echo('<p class="blogger_title">' + response.items[0].title + '</p>', aName);  
      
    //Maybe a post has no image  
    //TODO: In this case, other information from the post could be shown  
    if(imgUrl != null) {  
       this.echo('<img class="blogger_image" alt="" src="' + imgUrl + '"/>', aName);  
    }  
    this.echo('</a>');  
 };  
   
 /**  
  * The first method of the script.  
  */  
 Blogger.init = function() {  
    //Inject script to obtain blog-data from google/blogger  
    var callback = 'Blogger.handleBlog';  
    var jsname = this.gAPI_URL + this.blogID + '/posts?callback=' + callback + '&key=' + this.apiKey;  
    this.injectScript(jsname);  
    return;  
 };  
   
   
 Blogger();  

Of course, you have to replace the values of the variablesapiKey and blogID with your personal data.

There are two techniques used here that may require explanation for beginners:
First, the data is received in JSON format via JSON with Padding (JSONP). You will easily find guides on this by using the internet.
And secondly there is the dynamic javascript injection in injectScript, which I borrowed from http://javascript.about.com/library/bladdjs.htm.

Additionally, there are a few things that I wanted to comment on here:
First thing is: please don't forget that I am an intern and this is actually my first try in anything javascript related. This is my first attempt of a pure js version.

You can also find a version of this script as a jquery-plugin under http://dl.dropbox.com/u/19826318/Blogger/bloggerJQP.js
In this case, only jquery has to be loaded, followed by the script call.

Secondly, you might have seen some passages in the code which refer to the current status of the blogger api. I really hope, there will be some improvement there as far as resource types are concerned. At least, the developer in charge has already received and approved a feature request upon this.

The code is well documented I hope, and there are classes/IDs given to the output later on which allow easy CSS-styling.

Used in a website, the html might look like the following:
1:  <html>  
2:   <head>  
3:    <title>JavaScript-Test</title>  
4:   </head>  
5:   <body>  
6:    <div id='blogger_output'><p>Neues aus meinem Blog:</p></div>  
7:    <script src="blogger.js" type="text/javascript"></script>  
8:   </body>  
9:  </html>  
...where the <div>-tag's id "blogger_output" is required for the script to be able to write the content into.

Result: 
Title and image of the post, all linking to the original post-url
Title and image of the post, all linking to the original post-url

I hope, this might be useful for some web-developer or intern out there. Please leave a comment if you liked it or if you have suggestions on how to improve this:)

See you soon,
suluke







Helpful links:
Getting started of the blogger JSON api 2.0
Code formatter for blogger

Dienstag, 8. Mai 2012

Why b43 driver does not load, even though brcmsmac is blacklisted

Hello world!
For some time now, I am trying to switch from my Microsoft Windows installation to a Linux one, Fedora 17beta to be precise. I am progressing very fast, but here and there it takes some time to get some things working for which you had a tool on Windows that doesn't exist on linux and which is too sophisticated for wine.


The hardest issue so far was the following:
In Windows 7HP it is fairly easy to turn your laptop's wireless card into a hotspot and thus sharing its ethernet connection with some other devices, in my case my smartphone and tablet. This is somehow important to me, because my room is simply too remote from our usual router, and my devices running android's apps have to be updated regularly. For the task of turning my notebook into a hotspot there exist several tools, simply go to www.alternativeto.net and pick the one you like best. I personally got along best with Virtual Router, since it is open source, free, and somehow light-weight. I can also recommend Virtual Wifi Router Version 2, it doesn't even require an installation, but somehow there are some graphical glitches.


Ok, let's get back to the original topic. Under Linux, those tools do NOT exist, there is only one software package that I could find that provides this feature, but of course not with a nice graphical UI. It is called "hostapd". For more advanced users it should be easy to get it running and there are a lot of guides covering how to get it to work with different dhcp servers etc.


BUT that is not the initial problem. Wireless in Linux is a world for itself, and especially the drivers and their features vary like animals in a zoo. Hostapd needs special drivers complying with the new mac80211 stack, which provides host-mode functionality. My notebook includes a broadcom card called BCM43225, and the only driver that promised to have this feature was b43, only working with my card since kernel 3.2.


So I initiated everything - I installed the firmwarecutter (b43-fwcutter), blacklisted the originally used driver brcmsmac and since it did not work from the beginning (of course) I even posted stupid questions into a forum. Finally I decided to compile my own kernel, completely stripped of brcmsmac, which I assumed to be interfering with b43. And then --- boom! I stumbled upon this option in the kernel configuration tool
Wireless LAN --> Broadcom43xx wireless support --> Hardware support that overlaps with the brcmsmac driver
Screenshot of xconfig












I hope you see, what the point is. It is possible to disable b43's support for all cards that can be used with brcmsmac, and the developers of Fedora promptly used this "feature". But why would you do that??? I mean, read <<<HERE>>> and you will get the impression that the kernel hackers themself are more convinced with their own work than with the new driver programmed by Broadcom. Is it really so complicated to filter drivers so that only one is used at a time for the same hardware that you have to hardcode limitations into overlapping drivers?


I spent hours on searching the web for someone maybe having the same problem. "Why does b43 not feel responsible for BCM43225", "why doesn't it load automatically?" etc. The answer is: The distributors (I'm sure Ubuntu does the same) couldn't imagine someone wanting to have more features in the driver. Ok, I might be a bit demanding - for a product that I use for free and that is so great. Dear Linux community, you are awesome. And I have to apologize if I sound  reproaching. In the end it is Broadcom's fault, since they didn't cooperate and still do not add all the features to their drivers. Please consider this article as constructive criticism.


I hope that if there is someone out there that wants to do something similar will find this post so that he doesn't have to waste so much time.


Yours sincerly,
suluke