Tuesday, 17 February 2009

Fontrouter Open Sourced

I learned that Fontrouter has been open sourced under Apache License 2.0 two days ago. The download site has been moved to http://code.google.com/p/fontrouter/. This is both a good news and bad news.

The good news is that there may be more people or organisations to work on the project, hopefully, giving it more resources that it deserves.

The bad news is that oasisfeng may not provide as much support to the general public as he used to, which had been excellent in the past. The once very active Fontrouter Forum is now in ruins - real support activities have dwindled and spams are rampant.

I sincerely hope that the Fontrouter project will continue and grow.

Related posts:

Thursday, 12 February 2009

SyntaxHilighter 2

I have been using SyntaxHighlighter 1.5 on my blog site from day one. Since I don't have my own file server to host the SyntaxHighlighter files, I have been borrowing the URLs from java.dzone .

A few days ago, I noticed that all my code snippets in my blogs were not being processed. I first thought it was a temporary glitch from blogger.com or java.dzone. Today, I realised that SyntaxHighlighter has released v2.0 and obviously java.dzone had upgraded promptly. So I upgraded my blog site to use v2.0 as well by following the official instructions. I also noticed that the author of SyntaxHighlighter is kind enough to host the files from the package which is good for bloggers like me (who do not have their own file servers on the internet).

Wednesday, 11 February 2009

Facebook API in Erlang

I have heard of Facebook APIs and Facebook applications so today I decided to check out what they can do.

Based on documentation on Facebook, an Application is something that is hosted on an external server (such as your ISP or company web/application server) and can be invoked/accessed from a Facebook page. This seems very disappointing - I first thought a Facebook Application was something you can create using Facebook widgets and be hosted on Facebook servers. This model is not appealing to me, then again, I am not an advertiser.

Nevertheless, I decided to give Facebook API a try. Looking through the list of supported languages, Java was discontinued by Facebook (what do you expect from a PHP shop?!) So the natural choice is Erlang using Erlang2Facebook client library. Before using the library, I had to prepare my environment:

  1. Install the latest Erlang - OTP R12B (v5.6.5). My old OTP R11B would not work because the library uses some new functions from the standard library (e.g. decode_packet).
  2. Download mochiweb_util.erl and mochijson2.erl as they are used by the erlang_facebook library.
  3. Download the erlang_facebook.erl

The Facebook APIs are RESTful services which support both GET and POST methods. Most API calls require a signature input parameter which is a MD5 hash of all the input parameters concatenated alphabetically. This is explained in Facebook Developers Wiki. Also, many API calls require the uid or session_key as input parameters. It is a bit convoluted to get the session key:

  1. Create your own Application by following the instructions from Facebook so that you will get your own API Key, Application Secret, etc.
  2. To get a session_key value, you have to get auth_token by accessing the URL: http://www.facebook.com/login.php?api_key=1f5f..., which will forward to your application's host's URL with an input parameter for the auth_key. In my case, it forwards to the URL: http://romenlaw.blogspot.com/?auth_token=e1761... So now I have an auth_token.
  3. Once I have the auth_token, I can call facebook.auth.getSession API to get the session_key and uid

In Erlang, this is shown below:

Erlang (BEAM) emulator version 5.6.5 [smp:2] [async-threads:0]

Eshell V5.6.5  (abort with ^G)
1> c("/projects/facebook_erl/erlang_facebook.erl").
{ok,erlang_facebook}
2> 
2> c("/projects/facebook_erl/mochiweb_util.erl").
{ok,mochiweb_util}
3> 
3> c("/projects/facebook_erl/mochijson2.erl").
{ok,mochijson2}
4> 
4> [ApiKey, Secret, AppId]=["1fef...", "99f2...", "41..."].
...
9> erlang_facebook:custom(ApiKey, Secret, "facebook.auth.getSession", [{"auth_token", "c92b9...this is the auth_token copied from step 2 above"}]).
{struct,[{<<"session_key">>,
          <<"2.Ryk_v_nVtG...">>},
         {<<"uid">>,109...},
         {<<"expires">>,123...}]}
...
19> erlang_facebook:custom(ApiKey, Secret, "facebook.users.getLoggedInUser", [{"session_key", SessionKey}]).
109...(same as the uid returned by getSession call above)
28> [Fid]=erlang_facebook:custom(ApiKey, Secret, "facebook.friends.get", [{"uid", "1092201851"}]).
[598...]
31> erlang_facebook:custom(ApiKey, Secret, "facebook.friends.get", [{"uid", "598..."}]).            
{struct,[{<<"error_code">>,10},
         {<<"error_msg">>,
          <<"Application does not have permission for this action">>},
         {<<"request_args">>,
...
36> erlang_facebook:custom(ApiKey, Secret, "facebook.users.getInfo", [{"uids", "109..."},{"fields", "uid, first_name, last_name, name, sex, birthday, affiliations, locale, profile_url, proxied_email"}]).
[{struct,[{<<"affiliations">>,
           [{struct,[{<<"nid">>,67...},
                     {<<"name">>,<<"Australia">>},
                     {<<"type">>,<<"region">>},
                     {<<"status">>,<<>>},
                     {<<"year">>,0}]}]},
          {<<"birthday">>,null},
          {<<"first_name">>,<<"Romen">>},
          {<<"last_name">>,<<"Law">>},
          {<<"name">>,<<"Romen Law">>},
          {<<"sex">>,null},
          {<<"uid">>,109...},
          {<<"locale">>,<<"en_US">>},
          {<<"profile_url">>,
           <<"http://www.facebook.com/people/Romen-Law/109...">>},
          {<<"proxied_email">>,
           <<"apps+419..."...>>}]}]