Activate your free membership today | Log-in

Tuesday, December 23rd, 2008

Lengthening Out URLs

Category: JSON, JavaScript, Usability, Utility

In our age of information and technology, there isn’t as much mystery as there used to be. In that sense, short URLs (e.g., tinyurl.com/123) can be fun! Who knows where you’ll wind up.

Some folks aren’t as happy with uncertainty in hyperlinking; one of them, Darragh Curran, wrote in to tell us about his project: Long URL Please.

Long URL please (http://www.longurlplease.com) is a JSON webservice to
efficiently convert short urls (tinyurl.com/123) to their originals.
I’ve got a simple jquery plugin to take advantage of it, and a firefox
plugin. It’s running on google app engine.

Darragh hates short URLs so much he’s offering to contribute his time to help wipe them off the face of the web:

I’d love to see it used in apps like twhirl/tweetdeck/twitterific, on
microblogging sites and pretty much anywhere that’s got lots of short
urls. In that respect I’ll happily contribute my time to help those
people/teams integrate with the service.

There’s even a bookmarklet.

Posted by Ben Galbraith at 10:22 am
20 Comments

++++-
4.2 rating from 30 votes

Friday, December 12th, 2008

YQL - converting the web to JSON with mock SQL

Category: JSON, JavaScript

I like getting data from the web and I love JSON - as it is easy to use. The issue is that not many things on the web come as JSON from the get-go. Hence we need converters. You can use cURL and beautiful soup or roll your own hell of regular expressions. Alternatively you can use Yahoo Pipes to build your converter. Pipes is the bomb but a lot of people complained that there is no version control and that you need to use the very graphical interface to get to your data (which was the point of Pipes but let's not go there).

AlasRejoice for there is a solution now available and it is called YQL. YQL is a SQL-style language to get information from all kind of web services, and - using oAuth - even Yahoo's social graph. There is a test console available for you to get to grips with all the information it gives you access to (which is a lot!):

The YQL console

Here comes the kicker though: for all the open services that don't need authentication you can use these YQL statements as a REST API with JSON output and an optional callback function for JSON-P by adding it to http://query.yahooapis.com/v1/public/yql?. For example to get the latest three headlines from Ajaxian's RSS feed as JSON and wrap it in a function called leechajaxian do the following:

http://query.yahooapis.com/v1/public/yql?select title from rss where url="http://feeds.feedburner.com/ajaxian" limit 3

The result is:

JAVASCRIPT:
  1.  
  2. leechajaxian({
  3.  "query": {
  4.   "count": "3",
  5.   "created": "2008-12-12T09:01:13Z",
  6.   "lang": "en-US",
  7.   "updated": "2008-12-12T09:01:13Z",
  8.   "uri": "http://query.yahooapis.com/v1/yql?q=select+title+from+rss+where+url%3D%22http%3A%2F%2Ffeeds.feedburner.com%2Fajaxian%22+limit+3",
  9.   "diagnostics": {
  10.    "url": {
  11.     "execution-time": "17",
  12.     "content": "http://feeds.feedburner.com/ajaxian"
  13.    },
  14.    "user-time": "22",
  15.    "service-time": "17",
  16.    "build-version": "2008.12.03.14:01"
  17.   },
  18.   "results": {
  19.    "item": [
  20.     {
  21.      "title": "Travians: Sims meets Cultures, with Ajax"
  22.     },
  23.     {
  24.      "title": "Cappuccino 0.6 Released"
  25.     },
  26.     {
  27.      "title": "The fundamental problems with CSS3"
  28.     }
  29.    ]
  30.   }
  31.  }
  32. });
  33.  

You can also search the web with YQL: http://query.yahooapis.com/v1/public/yql?q=select title,abstract,url from search.web where query="json" limit 3&format=json&callback=leechajaxian

JAVASCRIPT:
  1.  
  2. leechajaxian({
  3.  "query": {
  4.   "count": "3",
  5.   "created": "2008-12-12T09:06:41Z",
  6.   "lang": "en-US",
  7.   "updated": "2008-12-12T09:06:41Z",
  8.   "uri": "http://query.yahooapis.com/v1/yql?q=select+title%2Cabstract%2Curl+from+search.web+where+query%3D%22json%22+limit+3",
  9.   "diagnostics": {
  10.    "url": {
  11.     "execution-time": "43",
  12.     "content": "http://boss.yahooapis.com/ysearch/web/v1/json?count=10&start=0&format=xml"
  13.    },
  14.    "user-time": "45",
  15.    "service-time": "43",
  16.    "build-version": "2008.12.03.14:01"
  17.   },
  18.   "results": {
  19.    "result": [
  20.     {
  21.      "abstract": "Introducing <b>JSON</b> <b>...</b> <b>JSON</b> (JavaScript Object Notation) is a lightweight data-interchange format. <b>...</b> <b>JSON</b> is a text format that is completely language <b>...</b>",
  22.      "title": "<b>JSON</b>",
  23.      "url": "http://www.json.org/"
  24.     },
  25.     {
  26.      "abstract": "The <b>JSON</b> format is specified in RFC 4627 by Douglas Crockford. <b>...</b> Although <b>JSON</b> was based on a subset of the JavaScript programming language <b>...</b>",
  27.      "title": "<b>JSON</b> - Wikipedia, the free encyclopedia",
  28.      "url": "http://en.wikipedia.org/wiki/JSON"
  29.     },
  30.     {
  31.      "abstract": "Matthew Morley has posted his PHP library for <b>JSON</b>-RPC 2.0. <b>...</b> I am think it is great to see the expanding <b>JSON</b> toolset available in JavaScript libraries. <b>...</b>",
  32.      "title": "<b>JSON</b>",
  33.      "url": "http://www.json.com/"
  34.     }
  35.    ]
  36.   }
  37.  }
  38. });
  39.  

What about screenscraping? You can get data from any valid HTML document using XPATH with select * from html. For example to get the first 3 tag links on my blog you can do the following:

http://query.yahooapis.com/v1/public/yql?q=select * from html where url="http://wait-till-i.com" and xpath='//a[@rel="tag"]' limit 3&format=json&callback=leechajaxian

The team is working on making this easier - while we run every page that is indexed through tidy there is still a lot of choking going on (if people wrote valid HTML that wouldn't happen).

YQL is a pretty easy but also versatile language. You can even use complex aggregation and filtering by for example hosting a lot of URLs in a spreadsheet and loading them one by one before aggregating. The example given in the console is "select * from rss where url in (select title from atom where url="http://spreadsheets.google.com/feeds/list/pg_T0Mv3iBwIJoc82J1G8aQ/od6/public/basic") and description like "Wall Street" LIMIT 10 | unique(field="title")"

Happy converting!

Posted by Chris Heilmann at 4:20 pm
15 Comments

++++-
4.5 rating from 44 votes

Monday, November 10th, 2008

yboss - a wrapper for Yahoo’s BOSS API

Category: Examples, JSON, JavaScript, Yahoo!

BOSS - Build Your Own Search Service (the your is silent for reasons I cannot tell you as it would endanger the lives of our agents in the field) is a Yahoo! API to access their search index and get the data back either as XML or JSON. Whilst there is ample documentation available it can still be a bit daunting to use the API purely in JavaScript - especially when you want to have several asynchronous calls - for example when you want to search the images, news and web sites for a certain query.

I've had several complaints of Hackers at the Open Hack Day in Brazil about this and wanted to make their lives easier by writing a wrapper for the API.

This wrapper is yboss and it was a big success at the Hack Day with the winning hack in the BOSS category actually being based on it.

To use the wrapper all you need to do is to embed it in your document

HTML:
  1. <div id="results"></div>
  2. <script type="text/javascript" src="yboss-lib.js"></script>

Then you have access to the get method of the wrapper which searches all the defined search options with the query you provided. You can define a callback method that will be called when all searches have been successfully performed.

JAVASCRIPT:
  1. YBOSS.get(
  2.   {
  3.     searches:'search,images,news',
  4.     query:'obama',
  5.     count:10,
  6.     callback:seeddata
  7.   }
  8. );
  9. function seeddata(o){
  10.  var all = '<h4>Web Sites</h4>' + o.webHTML +
  11.               '<h4>News</h4>' + o.newsHTML +
  12.              '<h4>Images</h4>' + o.imagesHTML;
  13.  var out = document.getElementById('results');
  14.  out.innerHTML = all;
  15. }

The data is provided either as a JSON object with all the mandatory properties for a BOSS result display or - as shown here - as HTML lists that can be written out via innerHTML.

Posted by Chris Heilmann at 6:06 pm
1 Comment

+++--
3.6 rating from 9 votes

Thursday, October 30th, 2008

Language JSONP Service

Category: JSON

Ben Lisbakken, an ex-colleague from Google and all round good guy, has created a simple JSONP service (in the vein of json-time and html-whitelist) that calculates the users language based on browser headers:

http://langdetect.appspot.com/?callback=setLanguage

This will return something like:

setLanguage({"languages": ['en-us', 'en']});

Ben created a nice little sample that shows you content in the language you desire using the AJAX Language API.

Posted by Dion Almaer at 1:19 am
7 Comments

+++--
3.1 rating from 13 votes

Monday, October 13th, 2008

Ruby on jQuery and Closures

Category: JSON, jQuery

Sam Ruby has that way about him that sees things very clearly. He just took a peak at jQuery for the first time and was able to really put into words what I think jQuery enthusiasts like about the library:

The notable thing about this is that despite all of the asynchronous events taking place, the code is sequential (nested, but sequential), and that the JSON results of the AJAX call is immediately available to the function that is invoked when the selection changes.

This is based on the following code that he wrote:

JAVASCRIPT:
  1.  
  2. $("#archive").click(function() {
  3.   $.getJSON('unscanned.cgi', {}, function(unscanned) {
  4.  
  5.     // replace realname input field with a selection list
  6.     var select = $('<select name="realname" id="realname"/>')[0];
  7.     for (var i=0; i<unscanned .length; i++) {
  8.       select.options[i] = new Option(unscanned[i][1], i);
  9.     }
  10.     $('#realname').before(select).remove();
  11.  
  12.     $("#archive").attr("disabled","disabled");
  13.  
  14.     // process selection
  15.     $('#realname').focus().change(function() {
  16.       var icla = unscanned[$("#realname option:selected").val()];
  17.       $("#realname").before('<input type="text" ' +
  18.         'id="realname" name="realname"/>').remove();
  19.       $("#realname").val(icla[1]);
  20.       $("#pubname").val(icla[2]);
  21.       $("#email").val(icla[3]);
  22.       $("#replaces").val(icla[0] + ':' + icla[3]);
  23.       $("#filename").val('').focus();
  24.       $("#archive").removeAttr("disabled");
  25.     });
  26.   });
  27.   return false;
  28. });
  29.  

Those that love jQuery, love the API.

John himself had an example in the comments:

JAVASCRIPT:
  1.  
  2. $(':radio[name=is_user]')
  3.   .change(function(){ $('.depends-isuser')[ this.value == 1 ? ‘show’ : ‘hide’ ](); })
  4.   .change();
  5.  

Posted by Dion Almaer at 6:40 am
1 Comment

++---
2.1 rating from 26 votes

Thursday, July 31st, 2008

JSON Pickle: Serialize your complex Python objects to JSON

Category: JSON, Python

John Paulett wanted to be able to define complex Python model objects, then seamlessly pass them into CouchDB and to client-side Javascript.

To make this happen for objects that are beyond primitive sets he created JSON Pickle which has been used on the Universal Feed Parser, and lets you do the following:

PYTHON:
  1.  
  2. >>> import jsonpickle
  3. >>> from jsonpickle.tests.classes import Thing
  4.  
  5. # Create an object.
  6. >>> obj = Thing('A String')
  7. >>> print obj.name
  8. A String
  9.  
  10. # Use jsonpickle to transform the object into a JSON string.
  11. >>> pickled = jsonpickle.dumps(obj)
  12. >>> print pickled
  13. {"child": null, "classname__": "Thing", "name": "A String", "classmodule__": "jsonpickle.tests.classes"}
  14.  
  15. # Use jsonpickle to recreate a Python object from a JSON string
  16. >>> unpickled = jsonpickle.loads(pickled)
  17. >>> print unpickled.name
  18. A String
  19.  

Posted by Dion Almaer at 7:50 am
1 Comment

+++--
3.5 rating from 22 votes

Monday, June 30th, 2008

JSON Diff Released

Category: JSON, Utility

Tom Robinson has built a useful utility, JSON Diff, which gives you a graphical look at the difference.

JSONDiff

Changed portions are displayed in yellow. Additions are displayed in green. Deletions are displayed in red.

The visualization is live itself, so you can move around the nodes using the triangles.

Posted by Dion Almaer at 11:11 am
5 Comments

++++-
4.2 rating from 17 votes

Monday, June 23rd, 2008

Endpoint Resolver: JavaScript Library to hunt for Location redirects

Category: JSON, JavaScript

Re-posted from my personal blog

Sometimes you can get in the zone just enough to be productive on a plane. On my flight to Mexico City yesterday, I created Endpoint a project that contains a server proxy, JavaScript client, and Greasemonkey Script with a mission. The mission is to take a URL, work out if it is a redirect (via a Location: header), and then return the final endpoint for it.

Why did I do this?

I was brainstorming functionality for a Twitter client with James Strachan (he is working on gtwit) and we talked about how annoying tinyurl / is.gd / snurl / you name it URLs are. They don't tell you where you are going, and you could get Rick Rolled (if you are lucky) or much much worse.

So, I wanted to create a library, and one client (Greasemonkey) to test it out. Then anyone else could use it too to resolve directly from their Web pages.

How does it work

You load up the JavaScript via script src and then you can call resolve, passing the URL and a callback that will get the result. A few examples:

JAVASCRIPT:
  1.  
  2. // Simple version
  3. Endpoint.resolve('http://snurl.com/2luj3', function(url) {
  4.   alert(url);
  5. });
  6.  
  7. // Using the original URL to work out if it has changed
  8. Endpoint.resolve(
  9.   document.getElementById('testurl').value,
  10.   function(url, orig) {
  11.     alert(url);
  12.     alert(Endpoint.isRedirecting(url, orig));
  13.   }
  14. );
  15.  
  16. // How it is used in the Twitter Endpoint Resolver
  17. Endpoint.resolve(url, function(resulturl, originalurl) {
  18.   if (!Endpoint.isRedirecting(resulturl, originalurl)) return;
  19.  
  20.   newtext = newtext.replace(originalurl, resulturl, "g");
  21.   jQuery(el).html(newtext);
  22. });
  23.  

Under the hood, a bunch of stuff is happening. I would love to be able to just use XMLHttpRequest to dynamically hit the URL and look at the headers, but the same-origin policy stops me.

This is why I have the server proxy, which returns a JSONP callback.

When you call resolve(url, callback) the script tag is created on the fly and added to the DOM. The callback function is all handled to allow multiple calls, and then the chain unravels.

Here you can see it all in action, showing how my Twitter stream will go through and the URLs will dynamically change from their tinyurl versions to whereyouaregoing.com: