Skip to content

Instantly share code, notes, and snippets.

@jessex
Created July 10, 2012 04:23
Show Gist options
  • Save jessex/3080996 to your computer and use it in GitHub Desktop.
Save jessex/3080996 to your computer and use it in GitHub Desktop.
Blog snippets: shrtn
def convert_to_code(id, alphabet=ALPHABET):
"""Converts a decimal id number into a shortened URL code. Use the id of the
row in the database with the entered long URL."""
if id <= 0: #invalid codes (autoincrement is always 1 or higher)
return alphabet[0]
base = len(alphabet) #base to convert to (56 for our standard alphabet)
chars = []
while id:
chars.append(alphabet[id % base])
id //= base
chars.reverse() #moved right to left, so reverse order
return ''.join(chars) #convert stored characters to single string
def search_url(url, table, conn):
"""Attempts to find a row in the table in the database conn with the given
url. Returns its id value if it is present, returns False otherwise."""
query = 'select * from %s where original="%s"' % (table, url)
result = conn.execute(query).fetchall()
if not result: #url not in our database, return False
return False
else:
return result[0][0] #return the id of the url
def search_id(id, table, conn):
"""Attempts to find a row in the table in the database conn with the given
id. Returns its url value if it is present, returns False otherwise."""
query = 'select * from %s where id=%d' % (table, id)
result = conn.execute(query).fetchall()
if not result: #id not in our database, return False
return False
else:
return str(result[0][1]) #return the url of the id
def setup_sql(location):
"""Establishes a connection to the sqlite database at location and returns
the database connection object."""
try:
conn = sql.connect(location)
return conn
except sql.OperationalError:
print "Error: could not open database file at '%s'" % location
return None
def lengthen_url(url, conn):
"""Takes in one of our shortened URLs and returns the correct long url."""
#isolate code from shortened url
if not is_valid_short(url): #url was not constructed properly
return "%s404" % OURDOMAIN
code = url[14:] #just the code, ie. h7K9g0
id = resolve_to_id(code) #convert shortened code to id
long = db.search_id(id, db.MYTABLE, conn)
if not long: #id was not found in database
return "%s404" % OURDOMAIN #issue 404
return long #url to perform 301 re-direct on
def resolve_to_id(code, alphabet=ALPHABET):
"""Converts the shortened URL code back to an id number in decimal form. Use
the id to query the database and lookup the long URL."""
base = len(alphabet)
size = len(code)
id = 0
for i in range(0, size): #convert from higher base back to decimal
id += alphabet.index(code[i]) * (base ** (size-i-1))
return id
def insert_url(url, table, conn):
"""Inserts the url into the table in the database conn and returns the id
of the row which was created by the insert."""
query = 'insert into %s values(NULL, "%s")' % (table, url)
c = conn.execute(query)
return c.lastrowid #autoincremented id of the just inserted row
def shorten_url(url, conn):
"""Takes in a standard url and returns a shortened version."""
url = standardize_url(url)
if url is None: #tried to shorten invalid url
return None
#get the id for this url (whether new or otherwise)
id = db.search_url(url, db.MYTABLE, conn)
if not id: #url not yet inserted into database
id = db.insert_url(url, db.MYTABLE, conn) #insert and get its id
code = convert_to_code(id)
return "%s%s" % (OURDOMAIN, code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment