Skip to content

Commit dbe2653

Browse files
committed
Implemented compile script.
1 parent 7cf2944 commit dbe2653

19 files changed

+259
-563
lines changed

common.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
## Common code used in all compiled versions of shorty.
6+
7+
class ShortyError(Exception):
8+
9+
def __init__(self, reason):
10+
self.reason = str(reason)
11+
12+
def __str__(self):
13+
return repr(self.reason)
14+
15+
"""Do a http request"""
16+
def request(url, parameters=None, username_pass=None, post_data=None):
17+
18+
# build url + parameters
19+
if parameters:
20+
url_params = '%s?%s' % (url, urlencode(parameters))
21+
else:
22+
url_params = url
23+
24+
# if username and pass supplied, build basic auth header
25+
headers = {}
26+
if username_pass:
27+
headers['Authorization'] = 'Basic %s' % base64.b64encode('%s:%s' % username_pass)
28+
29+
# send request
30+
try:
31+
req = Request(url_params, headers=headers)
32+
if post_data:
33+
req.add_data(post_data)
34+
return urlopen(req)
35+
except URLError, e:
36+
raise ShortyError(e)
37+
38+
def get_redirect(url):
39+
40+
class StopRedirectHandler(HTTPRedirectHandler):
41+
def http_error_301(self, req, fp, code, smg, headers):
42+
return None
43+
def http_error_302(self, req, fp, code, smg, headers):
44+
return None
45+
o = build_opener(StopRedirectHandler())
46+
try:
47+
o.open(url)
48+
except HTTPError, e:
49+
if e.code == 301 or e.code == 302:
50+
return e.headers['Location']
51+
else:
52+
raise ShortyError(e)
53+
except URLError, e:
54+
raise ShortyError(e)
55+
return None
56+
57+
"""Base interface that all services implement."""
58+
class Service(object):
59+
60+
def shrink(self, bigurl):
61+
"""Take a big url and make it smaller"""
62+
return None
63+
64+
def expand(self, tinyurl):
65+
"""Take a tiny url and make it bigger"""
66+
return get_redirect(tinyurl)
67+
68+
"""
69+
Shrink the given url for the specified service domain.
70+
Returns the tiny url OR None if service not supported.
71+
"""
72+
def shrink(service_domain, bigurl, *args, **kargs):
73+
74+
s = services.get(service_domain)
75+
if not s:
76+
return None
77+
return s.shrink(bigurl, *args, **kargs)
78+
79+
"""
80+
Expand tiny url into its full url.
81+
Returns long url if successful or None if failure.
82+
"""
83+
def expand(tinyurl):
84+
85+
turl = urlparse(tinyurl)
86+
domain = turl.netloc.lower()
87+
if domain.startswith('www.'):
88+
# strip off www. if present
89+
domain = domain[4:]
90+
s = services.get(domain)
91+
if not s:
92+
return get_redirect(tinyurl)
93+
return s.expand(tinyurl)

compile.py

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# Shorty module compiler
2+
# Copyright 2009 Joshua Roesslein
3+
# See LICENSE
4+
5+
import sys
6+
import os
7+
8+
_services = dict()
9+
10+
# remove any template comments
11+
def remove_comments(text):
12+
13+
output = str()
14+
for line in text.splitlines():
15+
if line.startswith('##'): continue
16+
output += line + '\n'
17+
return output
18+
19+
# process module source
20+
def process_module(name, source):
21+
22+
output = str()
23+
24+
# iterate through source and process any @ tags
25+
for line in source.splitlines():
26+
if line.startswith('##'):
27+
# is a url tag?
28+
pos = line.find('@url')
29+
if pos >= 0:
30+
urls = line[pos+4:].split()
31+
_services.update(dict((url.strip(), name) for url in urls))
32+
output += '# %s\n' % name
33+
else:
34+
output += line + '\n'
35+
36+
# write out service global instance
37+
output += '%s = %s()\n' % (name, name.capitalize())
38+
39+
return output
40+
41+
def compile_shorty(services):
42+
43+
# open shorty.py file
44+
sfp = open('shorty.py', 'w')
45+
46+
# write out the header (license/ascii art/etc)
47+
header = open('header', 'r')
48+
sfp.write(header.read())
49+
header.close()
50+
51+
# write out imports
52+
imports = open('imports.py', 'r')
53+
sfp.write(remove_comments(imports.read()))
54+
imports.close()
55+
56+
# write out common code
57+
common = open('common.py', 'r')
58+
sfp.write(remove_comments(common.read()))
59+
common.close()
60+
61+
# write service module code
62+
for service in services:
63+
try:
64+
module = open('services/%s.py' % service, 'r')
65+
except IOError:
66+
print '%s not found! Skipping' % service
67+
continue
68+
69+
sfp.write(process_module(service, module.read()))
70+
module.close()
71+
72+
# write out services dict
73+
sfp.write('\nservices = {\n')
74+
for k,v in _services.items():
75+
sfp.write(" '%s': %s,\n" % (k,v))
76+
sfp.write('}\n\n')
77+
78+
sfp.close()
79+
80+
if __name__ == '__main__':
81+
82+
# make sure enough args are provided
83+
if len(sys.argv) < 2:
84+
print 'Usage: compile.py <services>'
85+
print ' services -- names of the services to include in compiled module'
86+
print 'Example: compile.py sandbox tinyurl bitly'
87+
88+
# get list of services to compile
89+
if sys.argv[1] == '--all':
90+
services = list(m.split('.')[0] for m in os.listdir('services'))
91+
else:
92+
services = sys.argv[1:]
93+
94+
# compile shorty
95+
compile_shorty(services)
96+

header

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""
2+
_ _
3+
___| |__ ___ _ __| |_ _ _
4+
/ __| '_ \ / _ \| '__| __| | | |
5+
\__ \ | | | (_) | | | |_| |_| |
6+
|___/_| |_|\___/|_| \__|\__, |
7+
__/ |
8+
|___/
9+
10+
Access many URL shortening services from one library.
11+
12+
Python 2.4+
13+
Versions before 2.6 require simplejson.
14+
15+
http://gitorious.org/shorty
16+
17+
MIT License
18+
Copyright (c) 2009 Joshua Roesslein <jroesslein at gmail.com>
19+
20+
Permission is hereby granted, free of charge, to any person obtaining a copy
21+
of this software and associated documentation files (the "Software"), to deal
22+
in the Software without restriction, including without limitation the rights
23+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
24+
copies of the Software, and to permit persons to whom the Software is
25+
furnished to do so, subject to the following conditions:
26+
27+
The above copyright notice and this permission notice shall be included in
28+
all copies or substantial portions of the Software.
29+
30+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
31+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
32+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
34+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
35+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
36+
THE SOFTWARE.
37+
"""
38+
## !!! This file is machine generated !! ##

imports.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
## Do all importing here
6+
from urllib2 import urlopen, Request, URLError, HTTPError, HTTPRedirectHandler, build_opener
7+
from urllib import urlencode, quote
8+
from urlparse import urlparse
9+
from random import randint
10+
import base64
11+
12+
try:
13+
import json
14+
except:
15+
import simplejson as json

services/agd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# a.gd
5+
## @url a.gd
66
class Agd(Service):
77

88
def shrink(self, bigurl, tag=None, password=None, expires=None):

services/bitly.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# bit.ly
5+
## @url bit.ly
66
class Bitly(Service):
77

88
version = '2.0.1'

services/bukme.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# buk.me
5+
## @url buk.me
66
class Bukme(Service):
77

88
def _process(self, resp):

services/chilpit.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# chilp.it
5+
## @url chilp.it
66
class Chilpit(Service):
77

88
def shrink(self, bigurl):

services/cligs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
## Shorty
22
## Copyright 2009 Joshua Roesslein
33

4-
# cli.gs
4+
## @url cli.gs
55
class Cligs(Service):
66

77
def __init__(self, apikey=None, appid=None):

services/digg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# digg
5+
## @url digg.com
66
class Digg(Service):
77

88
def __init__(self, appkey=None):

services/fongs.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# fon.gs
5+
## @url fon.gs
66
class Fongs(Service):
77

88
def shrink(self, bigurl, tag=None):

services/fwd4me.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# fwd4.me
5+
## @url fwd4.me
66
class Fwd4me(Service):
77

88
ecodes = {

services/isgd.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# is.gd
5+
## @url is.gd
66
class Isgd(Service):
77

88
def shrink(self, bigurl):

services/sandbox.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5+
## @url sandbox.com
6+
## used for testing
57
class Sandbox(Service):
68

79
def __init__(self, length=4, letters='abcdefghijklmnopqrstuvwxyz'):
@@ -24,12 +26,12 @@ def shrink(self, bigurl):
2426

2527
# store url and return tiny link
2628
self.urls[tpath] = bigurl
27-
return 'http://sandbox/' + tpath
29+
return 'http://sandbox.com/' + tpath
2830

2931
def expand(self, tinyurl):
3032
# lookup big url and return
3133
turl = urlparse(tinyurl)
32-
if turl.netloc != 'sandbox':
34+
if turl.netloc != 'sandbox.com':
3335
raise ShortyError('Not a sandbox url')
3436
return self.urls.get(turl.path.strip('/'))
3537

services/tinyurl.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# tinyurl.com
5+
## @url tinyurl.com
66
class Tinyurl(Service):
77

88
def shrink(self, bigurl):

services/trim.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# tr.im
5+
## @url tr.im
66
class Trim(Service):
77

88
def __init__(self, apikey=None, username_pass=None):

services/tweetburner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# tweetburner.com
5+
## @url tweetburner.com twurl.nl
66
class Tweetburner(Service):
77

88
def shrink(self, bigurl):

services/urlborg.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
## Copyright 2009 Joshua Roesslein
33
## See LICENSE
44

5-
# urlborg.com
5+
## @url urlborg.com ub0.cc
66
class Urlborg(Service):
77

88
def __init__(self, apikey=None):

0 commit comments

Comments
 (0)