commit 813bd75bf01edc2ebb9712341f17f3cb49481a2a
Author: Ryan Wolf <rwolf@borderstylo.com>
Date: Wed, 23 Mar 2011 08:19:01 +0000
parses phot tumbles
Diffstat:
6 files changed, 185 insertions(+), 0 deletions(-)
diff --git a/router.js b/router.js
@@ -0,0 +1,48 @@
+var http = require('http');
+var url_parse = require('url').parse;
+
+var routes = {};
+
+var methods = ['get', 'put', 'post', 'delete'];
+
+methods.forEach(function (method) { routes[method] = []; });
+
+var addRoute = function (method, pattern, callback) {
+ if (!(pattern instanceof RegExp)) {
+ pattern = new RegExp(
+ '^\/' + pattern.replace(/\//g, '\\\/').replace(/\:\w+/g, '([^\/]+)') + '$'
+ );
+ }
+ // TODO: generate regex from string pattern like Davis
+ routes[method].push({ regex: pattern, callback: callback });
+};
+
+methods.forEach(function (method) {
+ exports[method] = function (pattern, callback) {
+ addRoute(method, pattern, callback);
+ };
+});
+
+exports.notFound = function (response) {
+ response.writeHead(404);
+ response.end('Not Found\n');
+};
+
+exports.server = http.createServer(function (request, response) {
+ var method = request.method.toLowerCase();
+ var path = url_parse(request.url).pathname.replace(/\/$/, '');
+ console.log(method + ': ' + path);
+ var matchingRoutes = routes[method].filter(function (route) {
+ return route.regex.test(path);
+ });
+ if (path == '' && exports.index) {
+ matchingRoutes = [ { callback: exports.index } ];
+ }
+ // TODO: handle no matches 404
+ if (matchingRoutes.length == 0) { return exports.notFound(response); }
+ // TODO: handle multiple matches 5**
+ var route = matchingRoutes[0];
+ var match = path.match(route.regex);
+ match.shift();
+ route.callback.apply(route.callback, [request, response].concat(match));
+});
diff --git a/server.js b/server.js
@@ -0,0 +1,81 @@
+var sys = require('sys'),
+ fs = require('fs'),
+ http = require('http'),
+ path = require('path'),
+ urlParse = require('url').parse,
+ paperboy = require('paperboy'),
+ xml2js = require('xml2js'),
+ webroot = path.join(path.dirname(__filename), 'static'),
+ router = require('./router'),
+ tumblr = require('./tumblr');
+
+router.server.listen(2666);
+
+paperboy.filepath = function (webroot, urlString) {
+ var url = urlParse(urlString),
+ file = url.pathname.split('/').pop(),
+ fp = path.normalize(path.join(webroot, file));
+ return([null, fp]);
+};
+
+/**
+ * subroutines
+ **/
+
+var sendStatic = function (request, response) {
+ paperboy.deliver(webroot, request, response);
+};
+
+/**
+ * static assets
+ **/
+
+router.get('thoms/index.html', sendStatic);
+router.get('thoms/fav.png', sendStatic);
+
+/**
+ * the one and only interesting call
+ **/
+
+router.get('thoms/likes', function (request, response) {
+ var url = urlParse(request.url, true);
+ if (!url.query) {
+ response.writeHead(400);
+ response.end('Bad Request');
+ return;
+ }
+ var email = encodeURIComponent(url.query.email),
+ password = encodeURIComponent(url.query.password);
+ if (!email || !password) {
+ response.writeHead(400);
+ response.end('Bad Request');
+ return;
+ }
+ var path = '/api/likes?email=' + email + '&password=' + password;
+ var client = http.createClient(80, 'www.tumblr.com');
+ var crequest = client.request('GET', path, {'host': 'www.tumblr.com'});
+ crequest.on('response', function (cresponse) {
+ if (cresponse.statusCode != 200) {
+ response.writeHead(400);
+ response.end('Bad Request');
+ return;
+ }
+ var parser = new xml2js.Parser();
+ var body = '';
+ cresponse.setEncoding('utf8');
+ cresponse.on('data', function (chunk) { body += chunk; });
+ cresponse.on('end', function (chunk) {
+ if (chunk) { body += chunk; }
+ parser.parseString(body);
+ });
+ parser.addListener('end', function(result) {
+ response.writeHead(200);
+ if (!result.posts.post) { return response.end(''); }
+ result.posts.post.forEach(function (post) {
+ response.write(tumblr.serialize(post) + '\n');
+ });
+ response.end();
+ });
+ });
+ crequest.end();
+});
diff --git a/static/fav.png b/static/fav.png
Binary files differ.
diff --git a/static/index.html b/static/index.html
@@ -0,0 +1,33 @@
+<html>
+ <head>
+ <title>thoms | convert yr tumblr ♥ to bookmrks</title>
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
+ <script type="text/javascript">
+ $(document).ready(function () {
+ var e = $('#email'),
+ p = $('#password'),
+ l = $('#likes');
+ var handleChange = function () {
+ var email = encodeURIComponent(e.val() || ''),
+ password = encodeURIComponent(p.val() || '');
+ l.attr('href', 'likes?email=' + email + '&password=' + password);
+ };
+ $.each(['focus', 'blur', 'keyup', 'change', 'click'], function (i, e) {
+ $('#email, #password')[e](handleChange);
+ });
+ });
+ </script>
+ </head>
+ <body>
+ <h1>thoms</h1>
+ <h2>convrt yr tumblr <img src="fav.png" /> to bookmrks</h2>
+ <ol>
+ <li><input id="email" size="30" type="text" placeholder="enter your tumblr email address" /></li>
+ <li><input id="password" size="30" type="password" placeholder="enter your tumblr password" /></li>
+ <li><a id="likes" href="likes?email=foo&password=bar" target="_blank">open this link in a new tab</a></li>
+ <li>save that tab as "bookmarks.html"</li>
+ <li><a href="#" target="_blank">open this link in a new tab</a></li>
+ <li>follow the instructions on that tab to import "bookmarks.html"</li>
+ </ol>
+ </body>
+</html>
diff --git a/templates/.gitignore b/templates/.gitignore
diff --git a/tumblr.js b/tumblr.js
@@ -0,0 +1,23 @@
+var sys = require('sys');
+
+var regular = function (post) {
+ return post['@'].url;
+};
+
+var photo = function (post) {
+ var tumblelog = post.tumblelog['@'].url.replace(/\/$/, ''),
+ generic = post['photo-url'][0]['#'],
+ link = post['photo-link-url'];
+ if (!link || tumblelog == link.replace(/\/$/, '')) {
+ return generic;
+ };
+ return link;
+};
+
+exports.serialize = function (post) {
+ switch (post['@'].type) {
+ case 'photo':
+ return photo(post);
+ }
+ return sys.inspect(post);
+};