Yarnline (a Ravelry Mashup)
A while ago, I spotted TimelineJS, a JavaScript library to create gorgeous timelines, and earmarked it to a future app. Last week, I finally get to play with it by creating Yarnline, an itsy-bitsy mashup app that takes the projects of a Ravelry user and display them in a chronological manner, like so:
The app is running on my home server (but requires you to
have a Ravelry account). The code
itself is, for once, fairly banal. It’s
using
One wouldn’t know by looking at the code, but getting the OAuth was… quite the challenge. Between the request tokens, the access tokens, the passing of urls between the client, the service provider and the app, I have to admit that at some points I was finding the whole thing oddly reminescent of this video. Mind you, the documentation of the module was generally helpful, but left some questions unanswered. Like, how get back your access token without running back to the web service every time you need it. After a few hours of head-desk interfacting, though, I think I figured it out:
use Net::OAuth::Client;
use Net::OAuth::AccessToken;
get '/auth' => sub {
# that one is simple...
redirect auth_client->authorize_url;
};
get '/auth/callback' => sub {
# get the access token from the web service...
my $access = auth_client->get_access_token(
param( 'oauth_token' ),
param( 'oauth_verifier' ),
);
# ... and keep the information you need to rebuild it
session rav_token => $access->token;
session rav_token_secret => $access->token_secret;
session username => param 'username';
forward '/';
};
get '/timeline/:raveler' => sub {
# access_token() is the good part there
my $projects = from_json(
access_token->get(
join '/', '/projects', $raveler, 'list.json'
)->content
);
# and do something with $projects...
};
# and yes, those two functions just scream to
# be Dancer::Pluginified
sub auth_client() {
my $rav = config->{ravelry};
return Net::OAuth::Client->new(
$rav->{tokens}{consumer_key},
$rav->{tokens}{consumer_secret},
site => 'https://api.ravelry.com',
request_token_path => '/oauth/request_token',
authorize_path => '/oauth/authorize',
access_token_path => '/oauth/access_token',
callback => uri_for( $rav->{callback} ),
session => &session,
);
}
sub access_token {
return Net::OAuth::AccessToken->new(
client => auth_client(),
token => session( 'rav_token' ),
token_secret => session( 'rav_token_secret' ),
);
}
Oh yeah, and today I began to switch the templates from Mason to my experiment-in-progress, Template::Caribou. How that went? Well, that’s a story for another blog entry…