UNPKG

shrtn

Version:

Low-fat URL shortener

141 lines (111 loc) 3.1 kB
var redis = require('redis'); var events = require('events'); function Config(){ var config = { 'key length': 1, 'chars': 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' }; this.set = function(key, value){ config[key] = value; return true; } this.get = function(key, fallback){ if(key in config){ return config[key]; } else { return fallback ? fallback : undefined; } } } var config = new Config(); function getRedisClient(){ var client = config.get('redis client'); if(client){ return client; } else { throw "Please configure shrtn's redis client using something like shrtn.config.set('redis client', redis.createClient())"; } } function isURL(s){ var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/ return regexp.test(s); } function generateId(callback){ var id = ''; var redisClient = getRedisClient(); var chars = config.get('chars').toString(); var keyLength = new Number(config.get('key length')); // check for the number of existing keys redisClient.keys('*', function(error, response){ // while half of the number of possible random keys // is less than the number of keys set, increase the // number of random keys possible by increasing key // length. while(Math.pow(chars.length, keyLength)/2 < response.length){ keyLength ++; } config.set('key length', keyLength); for (var i=0; i < keyLength; i++){ id += chars[Math.floor(Math.random() * chars.length)]; } callback(id); }); } function shorten(long, callback){ var redisClient = getRedisClient(); if (!(isURL(long))){ var response = { 'status': 'ERROR', 'message': 'Invalid URL: '+ long } if(typeof(callback) === 'function'){callback(response)} shrtn.emit('invalid url', response); return false; } generateId(function(newId){ redisClient.setnx(newId, long, function(err, res){ if(res){ var response = { 'status': 'OK', 'id': newId, 'long': long } if(typeof(callback) === 'function'){callback(response)} shrtn.emit('shortened', response); return true; } else { // the attempted ID is taken shorten(long, callback); } }); }); } function expand(id, callback){ var redisClient = getRedisClient(); redisClient.get(id, function(err, response){ if (response){ var result = { 'status': 'OK', 'long': response, 'id': id } if(typeof(callback) === 'function'){callback(result)} shrtn.emit('expanded', result); return true; } else { var result = { 'status': 'ERROR', 'message': 'Key not found' } if(typeof(callback) === 'function'){callback(result)} shrtn.emit('key not found', result); return false; } }); } var shrtn = new events.EventEmitter(); shrtn.config = config; shrtn.shorten = shorten; shrtn.expand = expand; module.exports = shrtn;