Skip to content

Commit 7cf2944

Browse files
committed
Move services into their own modules.
1 parent 601463e commit 7cf2944

File tree

14 files changed

+418
-0
lines changed

14 files changed

+418
-0
lines changed

services/agd.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# a.gd
6+
class Agd(Service):
7+
8+
def shrink(self, bigurl, tag=None, password=None, expires=None):
9+
post_param = {'url': bigurl}
10+
if tag:
11+
post_param['tag'] = tag
12+
if password:
13+
post_param['pass'] = password
14+
if expires:
15+
post_param['validTill'] = expires
16+
resp = request('http://a.gd/?module=ShortURL&file=Add&mode=API',
17+
post_data = urlencode(post_param))
18+
url = resp.read()
19+
if url.startswith('http://'):
20+
return url
21+
else:
22+
raise ShortyError(url[url.find('>')+1:url.rfind('<')])
23+

services/bitly.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# bit.ly
6+
class Bitly(Service):
7+
8+
version = '2.0.1'
9+
10+
def __init__(self, login=None, apikey=None, password=None):
11+
self.login = login
12+
self.apikey = apikey
13+
self.password = password
14+
15+
def _setup(self):
16+
parameters = {'version': self.version}
17+
if self.apikey:
18+
parameters['apiKey'] = self.apikey
19+
parameters['login'] = self.login
20+
username_pass = None
21+
elif self.password:
22+
username_pass = (self.login, self.password)
23+
else:
24+
raise ShortyError('Must set an apikey or password')
25+
return parameters, username_pass
26+
27+
def shrink(self, bigurl):
28+
if not self.login:
29+
raise ShortyError('Must set a login')
30+
parameters, username_pass = self._setup()
31+
parameters['longUrl'] = bigurl
32+
resp = request('http://api.bit.ly/shorten', parameters, username_pass)
33+
jdata = json.loads(resp.read())
34+
if jdata['errorCode'] != 0:
35+
raise ShortyError(jdata['errorMessage'])
36+
return str(jdata['results'][bigurl]['shortUrl'])
37+
38+
def expand(self, tinyurl):
39+
if not self.login:
40+
return get_redirect(tinyurl)
41+
parameters, username_pass = self._setup()
42+
parameters['shortUrl'] = tinyurl
43+
resp = request('http://api.bit.ly/expand', parameters, username_pass)
44+
jdata = json.loads(resp.read())
45+
if jdata['errorCode'] != 0:
46+
raise ShortyError(jdata['errorMessage'])
47+
return str(jdata['results'].values()[0]['longUrl'])
48+

services/bukme.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# buk.me
6+
class Bukme(Service):
7+
8+
def _process(self, resp):
9+
# bukme returns some markup after the url, so chop it off
10+
url = resp[:resp.find('<')]
11+
if url.startswith('http://'):
12+
return url
13+
else:
14+
raise ShortyError(url)
15+
16+
def shrink(self, bigurl, tag=None):
17+
parameters = {'url': bigurl}
18+
if tag:
19+
parameters['buk'] = tag
20+
resp = request('http://buk.me/api.php', parameters)
21+
return self._process(resp.read())
22+
23+
def expand(self, tinyurl):
24+
resp = request('http://buk.me/api.php', {'rev': tinyurl})
25+
return self._process(resp.read())
26+

services/chilpit.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# chilp.it
6+
class Chilpit(Service):
7+
8+
def shrink(self, bigurl):
9+
resp = request('http://chilp.it/api.php', {'url': bigurl})
10+
url = resp.read()
11+
if url.startswith('http://'):
12+
return url
13+
else:
14+
raise ShortyError(url)
15+
16+
def expand(self, tinyurl):
17+
turl = urlparse(tinyurl)
18+
if turl.netloc.lstrip('www.') != 'chilp.it':
19+
raise ShortyError('Not a chilp.it url')
20+
resp = request('http://p.chilp.it/api.php?' + turl.path.strip('/'))
21+
url = resp.read()
22+
if url.startswith('http://'):
23+
return url
24+
else:
25+
raise ShortyError(url)
26+
27+
# get click stats of the tinyurl
28+
def stats(self, tinyurl):
29+
turl = urlparse(tinyurl)
30+
if turl.netloc.lstrip('www.') != 'chilp.it':
31+
raise ShortyError('Not a chilp.it url')
32+
resp = request('http://s.chilp.it/api.php?' + turl.query)
33+
hit_count = resp.read()
34+
try:
35+
return int(hit_count)
36+
except:
37+
raise ShortyError('Url not found or invalid')
38+

services/cligs.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
4+
# cli.gs
5+
class Cligs(Service):
6+
7+
def __init__(self, apikey=None, appid=None):
8+
self.apikey = apikey
9+
self.appid = appid
10+
11+
def shrink(self, bigurl, title=None):
12+
parameters = {'url': bigurl}
13+
if title:
14+
parameters['title'] = title
15+
if self.apikey:
16+
parameters['key'] = self.apikey
17+
if self.appid:
18+
parameters['appid'] = self.appid
19+
resp = request('http://cli.gs/api/v1/cligs/create', parameters)
20+
return resp.read()
21+
22+
def expand(self, tinyurl):
23+
# TODO: debug this some more, not working properly
24+
'''resp = request('http://cli.gs/api/v1/cligs/expand', {'clig': tinyurl})
25+
return resp.read()'''
26+
return get_redirect(tinyurl)
27+

services/digg.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# digg
6+
class Digg(Service):
7+
8+
def __init__(self, appkey=None):
9+
self.appkey = appkey
10+
self.itemid = None
11+
self.view_count = None
12+
13+
def shrink(self, bigurl):
14+
if not self.appkey:
15+
raise ShortyError('Must set an appkey')
16+
resp = request('http://services.digg.com/url/short/create',
17+
{'url': bigurl, 'appkey': self.appkey, 'type': 'json'})
18+
jdata = json.loads(resp.read())['shorturls'][0]
19+
self.itemid = jdata['itemid']
20+
self.view_count = jdata['view_count']
21+
return str(jdata['short_url'])
22+
23+
def expand(self, tinyurl):
24+
if self.appkey:
25+
turl = urlparse(tinyurl)
26+
if turl.netloc != 'digg.com' and turl.netloc != 'www.digg.com':
27+
raise ShortyError('Not a valid digg url')
28+
resp = request('http://services.digg.com/url/short/%s' % quote(
29+
turl.path.strip('/')),
30+
{'appkey': self.appkey, 'type': 'json'})
31+
jdata = json.loads(resp.read())['shorturls'][0]
32+
self.itemid = jdata['itemid']
33+
self.view_count = jdata['view_count']
34+
return str(jdata['link'])
35+
else:
36+
self.itemid = None
37+
self.view_count = None
38+
return get_redirect(tinyurl)
39+

services/fongs.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# fon.gs
6+
class Fongs(Service):
7+
8+
def shrink(self, bigurl, tag=None):
9+
parameters = {'url': bigurl}
10+
if tag:
11+
parameters['linkname'] = tag
12+
resp = request('http://fon.gs/create.php', parameters)
13+
data = resp.read()
14+
if data.startswith('OK:'):
15+
return data.lstrip('OK: ')
16+
elif data.startswith('MODIFIED:'):
17+
return data.lstrip('MODIFIED: ')
18+
else:
19+
raise ShortyError(data)
20+
21+
# check if the given tag is taken
22+
# returns true if available false if taken
23+
def check(self, tag):
24+
resp = request('http://fon.gs/check.php', {'linkname': tag})
25+
data = resp.read()
26+
if data.startswith('AVAILABLE'):
27+
return True
28+
elif data.startswith('TAKEN'):
29+
return False
30+
else:
31+
raise ShortyError(data)
32+
33+
def expand(self, tinyurl):
34+
if tinyurl[-1] != '/':
35+
turl = tinyurl + '/'
36+
else:
37+
turl = tinyurl
38+
return Service.expand(self, turl)
39+

services/fwd4me.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# fwd4.me
6+
class Fwd4me(Service):
7+
8+
ecodes = {
9+
'1': 'Invalid long url',
10+
'2': 'Invalid api key',
11+
'3': 'Account suspended or revoked',
12+
'4': 'Long url is black listed',
13+
'5': 'Internal system error'
14+
}
15+
16+
def shrink(self, bigurl):
17+
resp = request('http://api.fwd4.me/', {'url': bigurl})
18+
data = resp.read()
19+
if data.startswith('ERROR:'):
20+
ecode = data.lstrip('ERROR:')
21+
raise ShortyError(Fwd4me.ecodes.get(ecode, 'Unkown error'))
22+
else:
23+
return data
24+

services/isgd.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# is.gd
6+
class Isgd(Service):
7+
8+
def shrink(self, bigurl):
9+
resp = request('http://is.gd/api.php', {'longurl': bigurl})
10+
turl = resp.read()
11+
if turl.startswith('Error:'):
12+
raise ShortyError(turl)
13+
return turl
14+

services/sandbox.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
class Sandbox(Service):
6+
7+
def __init__(self, length=4, letters='abcdefghijklmnopqrstuvwxyz'):
8+
self.urls = {}
9+
self.letters = letters
10+
self.length = length
11+
self.base = len(letters) - 1
12+
13+
def shrink(self, bigurl):
14+
# generate the tiny path
15+
tpath = ''
16+
while True:
17+
for i in range(self.length):
18+
tpath += self.letters[randint(0, self.base)]
19+
if self.urls.has_key(tpath):
20+
# tpath already in use, regen another
21+
tpath = ''
22+
else:
23+
break
24+
25+
# store url and return tiny link
26+
self.urls[tpath] = bigurl
27+
return 'http://sandbox/' + tpath
28+
29+
def expand(self, tinyurl):
30+
# lookup big url and return
31+
turl = urlparse(tinyurl)
32+
if turl.netloc != 'sandbox':
33+
raise ShortyError('Not a sandbox url')
34+
return self.urls.get(turl.path.strip('/'))
35+

services/tinyurl.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# tinyurl.com
6+
class Tinyurl(Service):
7+
8+
def shrink(self, bigurl):
9+
resp = request('http://tinyurl.com/api-create.php', {'url': bigurl})
10+
return resp.read()
11+

services/trim.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# tr.im
6+
class Trim(Service):
7+
8+
def __init__(self, apikey=None, username_pass=None):
9+
self.apikey = apikey
10+
self.username_pass = username_pass
11+
12+
def shrink(self, bigurl, custom=None, searchtags=None, privacycode=None,
13+
newtrim=False, sandbox=False):
14+
parameters = {}
15+
parameters['url'] = bigurl
16+
if custom:
17+
parameters['custom'] = custom
18+
if searchtags:
19+
parameters['searchtags'] = searchtags
20+
if privacycode:
21+
parameters['privacycode'] = privacycode
22+
if newtrim:
23+
parameters['newtrim'] = '1'
24+
if sandbox:
25+
parameters['sandbox'] = '1'
26+
if self.apikey:
27+
parameters['api_key'] = self.apikey
28+
resp = request('http://api.tr.im/api/trim_url.json', parameters, self.username_pass)
29+
jdata = json.loads(resp.read())
30+
self.status = (int(jdata['status']['code']), str(jdata['status']['message']))
31+
if not 200 <= self.status[0] < 300:
32+
raise ShortyError(self.status[1])
33+
self.trimpath = str(jdata['trimpath'])
34+
self.reference = str(jdata['reference'])
35+
self.destination = str(jdata['destination'])
36+
self.domain = str(jdata['domain'])
37+
return str(jdata['url'])
38+
39+
def expand(self, tinyurl):
40+
turl = urlparse(tinyurl)
41+
if turl.netloc != 'tr.im' and turl.netloc != 'www.tr.im':
42+
raise ShortyError('Not a valid tr.im url')
43+
parameters = {'trimpath': turl.path.strip('/')}
44+
if self.apikey:
45+
parameters['api_key'] = self.apikey
46+
resp = request('http://api.tr.im/api/trim_destination.json', parameters)
47+
jdata = json.loads(resp.read())
48+
self.status = (int(jdata['status']['code']), str(jdata['status']['message']))
49+
if not 200 <= self.status[0] < 300:
50+
raise ShortyError(self.status[1])
51+
return str(jdata['destination'])
52+

services/tweetburner.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Shorty
2+
## Copyright 2009 Joshua Roesslein
3+
## See LICENSE
4+
5+
# tweetburner.com
6+
class Tweetburner(Service):
7+
8+
def shrink(self, bigurl):
9+
resp = request('http://tweetburner.com/links', post_data='link[url]=%s' % bigurl)
10+
return resp.read()
11+

0 commit comments

Comments
 (0)