thomblr

convrt yr tumblr <3 to bookmrks
git clone https://wehaveforgeathome.hates.computer/thomblr.git
Log | Files | Refs | LICENSE

commit 813bd75bf01edc2ebb9712341f17f3cb49481a2a
Author: Ryan Wolf <rwolf@borderstylo.com>
Date:   Wed, 23 Mar 2011 08:19:01 +0000

parses phot tumbles

Diffstat:
Arouter.js | 48++++++++++++++++++++++++++++++++++++++++++++++++
Aserver.js | 81+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Astatic/fav.png | 0
Astatic/index.html | 33+++++++++++++++++++++++++++++++++
Atemplates/.gitignore | 0
Atumblr.js | 23+++++++++++++++++++++++
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 &hearts; 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); +};