jQuery Lifestream and followmy.tv

I’m a big fan of doing as much as possible client side and I’ve been following Christian Vuerings his ‘Lifestream‘ plugin for a while now. It shows you a stream of your online activies and does this all in Javascript. (Well, technically it relies quite heavily upon Yahoo!’s YQL so there is a server involved for communication and some basic filtering.) The actual mash-up is fairly straightforward, it’s just the last x items (date based) that should be shown.

In between studying for my exams I got bored and decided I need a new front page for my www domain. My last one was from 2 years ago when I needed a portfolio for an internship. The old site wasn’t that bad, but it wasn’t snazzy either. It was all static HTML with a couple of screenshots of what I had created so far. As a portfolio I think it sufficed. But since I’m not in looking for work right now, I decided I should put up something different.

Enter Lifestream.

I pulled down the latest html5boilerplate goodies, downloaded a copy of the lifestream plugin, configured it (which is stupidly simple) all in under 20 minutes. Most of that time was spent dealing with trying to improve on the ‘design’ (I decided to go with the old simple-is-more-and-I-shouldn’t-attempt-design-ever credo.)

I was pretty content with how easy it was to support:

  • Foursquare
  • Github
  • Google Reader
  • Last.FM
  • Reddit
  • Stackoverflow
  • Twitter
  • My blog (I had to create a small patch to the lifestream-wordpress ‘service’, I’ll send a pull request in a bit! – Merged in)
But then I got bored again! I wrote the reddit service when I got bored during my previous exams, so naturally, I had to create one now. Another social media site I use a lot (and that I find actually useful!) is followmy.tv. You can keep track when shows are airing, which episodes you’ve seen, comment, …
One problem though, they don’t have an API or XML feed. I asked the developers on twitter, but they haven’t responded yet.
So I did the obvious next thing, screen scrape! Using YQL it’s getting way easier to do these kind of things.
select * from html where url="http://followmy.tv/u/simong" and (xpath = '//div[@id="recent-eps"]/ul/li' or xpath = '//ul[@class="activity-feed"]/li')

is the query to get the recent episodes you watched or your general activity stream (loved a show, followed a new show, etc…). The results are returned to you via jsonp (which is all nicely encapsulated by jquery, so you don’t really need to care about the how)

Now that I’ve got the actual activity stream in json, it’s fairly easy to parse out the right content and sticking it in the big stream. If the followmy.tv devs don’t respond in the next couple of weeks I’ll clean up this service and send Christian a pull request so this ends up in the main repo.

In the meantime, here’s what I’m using right now:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
$.fn.lifestream.feeds.followmytv = function( config, callback ) {
    var parseDate = function(s) {
        var d = new Date();
        if (s.match(/[0-9]{1,2} minutes? ago/)) {
            var m = parseInt(s.replace(/\D/, ''), 10);
            d.setTime(d.getTime() - m*60*1000);
        }
        else if (s.match(/[0-9]{1,2} hours? ago/)) {
            var m = parseInt(s.replace(/\D/, ''), 10);
            d.setTime(d.getTime() - m*60*60*1000);
        }
        else if (s.match(/[0-9]{1,2} days? ago/)) {
            var m = parseInt(s.replace(/\D/, ''), 10);
            d.setTime(d.getTime() - m*24*60*60*1000);
        }
        else if (s== 'Just watched') {
            d = new Date();
        } 
        else {
            d = new Date(s);
        }
 
        return d;
    }
 
 
    var parseRecentlyWatched = function ( input ) {
        var output = [];
        for (var i = 0, j = input.results.length;i < j; i++) {
            var $p = $(input.results[i]), o = {'config': config};
            if ($("div", $p).length > 0) {
                // Something you watched.
                var time = $("div.time", $p).text(),
                    d = parseDate(time); 
                o.html = "watched " + $("div.desc", $p).html();
                o.date = d;
            } else {
                // Recent activity bar.
                var time = $("span", $p).text();
                var d = parseDate(time);
                $p = $p.remove("span");
                var s = $p.text().replace(config.user, "").replace("You are ", "").replace("You ", "");
 
                o.date = d;
                o.html = s;
            }
            output.push(o);
        }
        return output;
    };
 
    $.ajax({
             url: $.fn.lifestream.createYqlUrl('select * from html where ' + 'url="http://followmy.tv/u/' + config.user + '" and ' + '(xpath = \'//div[@id="recent-eps"]/ul/li\' or xpath = \'//ul[@class="activity-feed"]/li\')', 'xml'),
             dataType: "jsonp",
             success: function ( data ) {
               callback(parseRecentlyWatched(data));
             }
           });
};

Tags: , ,