Christian Heilmann

You are currently browsing the archives for the hacking category.

Archive for the ‘hacking’ Category

Currency conversion API on a shoestring

Saturday, June 21st, 2008

Someone just came to our table at Mashed08 and asked if Yahoo! offers a currency conversion API. We don’t, but a few lines of PHP allows you to get the information from the Yahoo finance site:


function convert($from,$to){
$url= ‘http://finance.yahoo.com/currency/convert?amt=1&from=’.$from.’&to=’.$to.’&submit=Convert’;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$feed = curl_exec($ch);
curl_close($ch);
preg_match_all(“/tabledata1”>([^<]+)/”,$feed,$cells);
return $cells[1][1];
}

echo convert(‘USD’,’GBP’);

There’s a whole list of currency codes available on oanda.

A few more lines turns this into a JSON API:


header(‘Content-type:text/javascript’);
$from = $_GET[‘from’];
$to = $_GET[‘to’];
$callback = $_GET[‘callback’];
if(preg_match(“/[A-Z|a-z]{3}/”,$to) && preg_match(“/[A-Z|a-z]{3}/”,$from)){
$to = strToUpper($to);
$from = strToUpper($from);
$url= ‘http://finance.yahoo.com/currency/convert?’ .
‘amt=1&from=’.$from.’&to=’.$to.’&submit=Convert’;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$feed = curl_exec($ch);
curl_close($ch);
preg_match_all(“/tabledata1”>([^<]+)/”,$feed,$cells);
if(is_numeric($cells[1][1])){
$out = ‘{“from”:”’.$from.’”,”to”:”’.$to.’”,”factor”:”’.$cells[1][1].’”}’;
} else {
$out = ‘{error not convert currencies, are you sure about the names?”}’;
}

} else {
$out = ‘{error Currency format, must be three letters”}’;
}

if(isset($callback)){
if(preg_match(“/[a-z|A-Z|_|-|$|0-9|.]/”,$callback)){
$out = $callback.’(‘.$out.’)’;
} else {
$out = ‘{error callback method name”}’;
}

}
echo $out;

You have several parameters:

  • from (mandatory): three letter currency code (upper or lower case)
  • to (mandatory): three letter currency code (upper or lower case)
  • callback (optional): the name of the callback method that should be wrapped around the resulting object

If something goes wrong, the API will return an object with an error property, otherwise you’ll get an object with three properties:

  • from: the original currency
  • to: the target currency
  • factor: the conversion factor

Say you store this as convert.php somewhere, then you could do the following:




This is a terrible dirty hack and if Yahoo finance ever changes their HTML (and they will), this will cease to work.

Building Easy Flickr – Step by Step

Monday, June 16th, 2008

As several people asked how I did the easier Flickr interface, I wrote up some step-by-step instructions, analyzing the issues and then taking the API to work around them.

An easier interface to Flickr

Check out How to create an alternative Flickr interface – step by step.

This is one example where providing a good API can empower developers to remove barriers you might not be aware of for you. I hope to be able to show you more of those in the future.

The code examples are available and are licensed with BSD, so feel free to re-use them.

Is it time to take mashups and use them to solve real issues?

Monday, June 2nd, 2008

This is my presentation given at the BarCamp4 at Gcap in London, talking about my recent move to start doing more mashups again and what lead to it.

My mashup and accessibility fatigue

In a nutshell I have to say that I was getting tired of ethical hacking and mashups. Far too many people just create mashups for the sake of putting some information together or prove a technical concept but I just couldn’t see the use of what was produced. We create a lot of ideas, prototypes, proofs of concept, celebrate them as being cool and then never re-visit or turn them into projects.

I was also bored with the accessibility movement on the web. Instead of concentrating on solutions for people we ran in circles demanding technical solutions or implementation of standards that don’t make much sense in the real world. It was much more important to be compliant with something than to really deliver for the people who needed us to remove barriers for them. It is all about demanding things to be done rather than doing them. And I felt that I wasted my time trying to get something done in this surrounding.

Boost #1: The social innovation camp

That changed drastically when I was a judge at the Social Innovation Camp. The concept of the camp was brilliant: allow people who have real world problems to draft up an idea how modern technology like web sites and social networks could help solving or at least making these problems smaller. The entries were massive and ranged from simple things like sharing sites (rent a drill instead of buying one and let it collect dust) to personal growth/learning monitoring systems.

Boost #2: Enabled by design

The project that stood out the most for me was Enabled by design which is a showcase site for people with disabilities showing the world what problems they have fulfilling certain day to day tasks (say cutting food) and what tools are available to overcome these problems.

The second idea of enabled by design is that it should become a place where product designers and production companies could get information about what products are needed and then can start designing and producing those in more appealing ways. Most assistive technology and products are ugly, and they don’t have to be – actually that makes the person who just had to start to use them to fulfill tasks previously easy for them feel even worse. People get as excited about product design as we get about APIs and mashing things up – both of these great amounts of energies could be targeted to solve real-life needs of real people.

Boost #3 – Ability 2.0 conference and accessihacking YouTube

With my mindset of giving the accessibility world a swift kick up the backside I gave my talk Fencing-in the habitat at the Accessibility2.0 conference pointing out the useless energy we waste on technical solutions built to satisfy ourselves rather than making a difference for the end user.

One of the other talks that day was Antonia Hyde talking about the issues users with learning disabilities are facing on the web, especially in regards to online video. Well, I thought to myself, as YouTube has an API, and I’ve been playing around with it already, why not have a go at an accessible YouTube player. I’ve created a prototype and sent that out to Antonia and some other accessibility contacts and the feedback was awesome.

What confused me most was that I got feedback from schools and blind people thanking me for the player and finally being able to use YouTube. I liked that a lot – realizing that I helped far more people than I thought by tackling something I hadn’t tried before – thinking in detail about the needs of people with learning disabilities!

The player is going strong and I am now writing documentation for the 2.0 version which will feature a search, playlists created by bookmarking in del.icio.us and more features like zoom.

Question: What about the future?

Am I weird (don’t answer that out of context) or is there something in there? Are there more developers out there who are stuck in a rut mashing up data without ever really making a difference with it, or do I care to go there just because I have so much exposure to this world?

I am imagining (and already started) planning an event for exactly that – social and accessible hacking of currently used internet services. We could have a hackday weekend with spokespeople from different agencies explaining the issues that people with disabilities have to use for example flickr, youtube, last FM and so on and a bunch of hackers to have a go at building alternative interfaces based on the APIs of these companies. I would also like to get people from these companies there to learn about the hacks and maybe take on some of the learnings and put them in the live systems.

The question is: would that be something you want?

Making twitter multilingual with a hack of the Google Translation API

Monday, March 31st, 2008

After helping to fix the Yahoo search result pages with the correct language attributes to make them accessible for screen reader users I was wondering how this could be done with user generated content. The easiest option of course would be to ask the user to provide the right language in the profile, but if you are bilingual like me you actually write in different languages. The other option would be to offer me as the user to pick the language when I type it, which is annoying.

I then stumbled across Google’s Ajax Translation API and thought it should be very easy to marry it with for example the JSON output of the twitter API to add the correct lang attributes on the fly.

Alas, this was not as easy as I thought. On the surface it is very easy to use Google’s API to tell me what language a certain text is likely to be:


var text = “¿Dónde está el baño?”;
google.language.detect(text, function(result) {
if (!result.error) {
var language = ‘unknown’;
for (l in google.language.Languages) {
if (google.language.Languages[l] result.language) {
language = l;
break;
}

}
var container = document.getElementById("detection");
container.innerHTML = text + " is: " + language + "";
}

});

However, if you want to use this in a loop you are out of luck. The google.language.detect method fires off an internal XHR call and the result set only gives you an error code, the confidence level, a isReliable boolean and the language code. This is a lot but there is no way to tell the function that gets the results which text was analyzed. It would be great if the API repeated the text or at least allowed you to set a unique ID for the current XHR request.

As Ajax requests return in random order, there is no way of telling which result works for which text, so I was stuck.

Enter Firebug. Analyzing the requests going through I realized there is a REST URL being called by the internal methods of google.language. In the case of translation this is:


http://www.google.com/uds/GlangDetect?callback={CALLBACK_METHOD}&context={NUMBER}&q={URL_ENCODED_TEXT}&key=notsupplied&v=1.0

You can use the number and an own callback method to create SCRIPT nodes in the document getting these results back. The return call is:


CALLBACK_METHOD(‘NUMBER’,{“language” : “es”,”isReliable” : true,”confidence” : 0.24716422},200,null,200)

However, as I am already using PHP to pull information from another service, I ended up using curl for the whole proof of concept to make twitter speak in natural language:


    // curl the twitter feed
    $url = ‘http://twitter.com/statuses/public_timeline.rss’;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $twitterdata = curl_exec($ch);
    curl_close($ch);
    // get all the descriptions
    preg_match_all(“/([^<]+)/msi”, $twitterdata,$descs);
    // skip the main feed description
    foreach($descs[1] as $key=>$d){
    if($key=0){
    continue;
    }

    // assemble REST call and curl the result
    $url = ‘http://www.google.com/uds/GlangDetect?callback=’ .
    ‘feedresult&context=’ . $key . ‘&q=’ . urlencode($d) .
    ‘&key=notsupplied&v=1.0’;
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $langcode = curl_exec($ch);
    curl_close($ch);
    // get the language
    preg_match(“/”language”:”([^”]+)”/”,$langcode,$res);
    // write out the list item
    echo ‘

  • ‘.$d.’
  • ‘;
    }

    ?>

Check out the result: Public twitter feed with natural language support

I will do some pure JavaScript solutions soon, too. This could be a great chance to make UGC a lot more accessible.

Thanks to Mark Thomas and Tim Huegdon for bouncing off ideas about how to work around the XHR issue.