26
from friends.shorteners import isgd, ougd, tinyurlcom, linkeecom
32
'linkee.com': linkeecom,
33
'tinyurl.com': tinyurlcom,
26
from urllib.parse import quote
28
from friends.utils.base import LINKIFY_REGEX as replace_urls
29
from friends.utils.http import Downloader
32
# These strings define the shortening services. If you want to add a
33
# new shortener to this list, the shortening service must take the URL
34
# as a parameter, and return the plaintext URL as the result. No JSON
35
# or XML parsing is supported. The strings below must contain exactly
36
# one instance of '{}' to represent where the long URL goes in the
37
# service. This is typically at the very end, but doesn't have to be.
39
'is.gd': 'http://is.gd/api.php?longurl={}',
40
'linkee.com': 'http://api.linkee.com/1.0/shorten?format=text&input={}',
41
'ou.gd': 'http://ou.gd/api.php?format=simple&action=shorturl&url={}',
42
'tinyurl.com': 'http://tinyurl.com/api-create.php?url={}',
43
'durl.me': 'http://durl.me/api/Create.do?type=json&longurl={}',
38
"""The default URL 'shortener' which doesn't shorten at all.
40
If the chosen shortener isn't found, or is disabled, then this one is
41
returned. It supports the standard API but just returns the original URL
46
def shorten(self, url):
48
"""Each instance of this class represents a unique shortening service."""
50
def __init__(self, domain=None):
51
"""Determine which shortening service this instance will use."""
52
self.template = URLS.get(domain)
55
# Disable shortening if no shortener found.
56
if None in (domain, self.template):
57
self.make = lambda url: url
60
if "json" in self.template:
64
"""Shorten the URL by querying the shortening service."""
65
if Short.already(url):
66
# Don't re-shorten an already-short URL.
51
"""Look up a URL shortener by name.
53
:param name: The name of a shortener.
55
:return: An object supporting the `shorten(url)` method.
57
return PROTOCOLS.get(name, NoShortener).URLShortener()
60
def is_shortened(url):
61
"""True if the URL has been shortened by a known shortener."""
62
# What if we tried to URL shorten http://tinyurl.com/something???
63
for module in PROTOCOLS.values():
64
if url.startswith(module.URLShortener.fqdn):
69
self.template.format(quote(url, safe=''))).get_string().strip()
71
def sub(self, message):
72
"""Find *all* of the URLs in a string and shorten all of them."""
73
return replace_urls(lambda match: self.make(match.group(0)), message)
76
"""Grab URLs swiftly with regex."""
77
# Avoids writing JSON code that is service-specific.
78
find = re.compile('https?://{}[^\"]+'.format(self.domain)).findall
79
for short in find(Short.make(self, url)):
83
# Used for checking if URLs have already been shortened.
84
already = re.compile(r'https?://({})/'.format('|'.join(URLS))).match