[Django]-Link generator using django or any python module

2👍

Yes it would be ok to allow django to generate the urls. This being exclusive from handling the urls, with urls.py. Typically you don’t want django to handle the serving of files see the static file docs[1] about this, so get the notion of using url patterns out of your head.

What you might want to do is generate a random key using a hash, like md5/sha1. Store the file and the key, datetime it’s added in the database, create the download directory in a root directory that’s available from your webserver like apache or nginx… suggest nginx), Since it’s temporary, you’ll want to add a cron job that checks if the time since the url was generated has expired, cleans up the file and removes the db entry. This should be a django command for manage.py

Please note this is example code written just for this and not tested! It may not work the way you were planning on achieving this goal, but it works. If you want the dl to be pw protected also, then look into httpbasic auth. you can generate and remove entries on the fly in a httpd.auth file using htpasswd and the subprocess module when you create the link or at registration time.

import hashlib, random, datetime, os, shutil
# model to hold link info. has these fields: key (charfield), filepath (filepathfield)
# datetime (datetimefield), url (charfield), orgpath (filepathfield of the orignal path
# or a foreignkey to the files model.
from models import MyDlLink 
# settings.py for the app
from myapp import settings as myapp_settings

# full path and name of file to dl.
def genUrl(filepath):
  # create a onetime salt for randomness
  salt = ''.join(['{0}'.format(random.randrange(10) for i in range(10)])
  key = hashlib('{0}{1}'.format(salt, filepath).hexdigest()
  newpath = os.path.join(myapp_settings.DL_ROOT, key)
  shutil.copy2(fname, newpath)
  newlink = MyDlink()
  newlink.key = key
  newlink.date = datetime.datetime.now()
  newlink.orgpath = filepath
  newlink.newpath = newpath
  newlink.url = "{0}/{1}/{2}".format(myapp_settings.DL_URL, key, os.path.basename(fname))

  newlink.save()
  return newlink


# in commands
def check_url_expired():
  maxage = datetime.timedelta(days=7)
  now = datetime.datetime.now()
  for link in MyDlink.objects.all():
     if(now - link.date) > maxage:
       os.path.remove(link.newpath)
           link.delete()

[1] http://docs.djangoproject.com/en/1.2/howto/static-files/

4👍

A simple scheme might be to use a hash digest of username and timestamp:

from datetime import datetime
from hashlib import sha1

user = 'bob'
time = datetime.now().isoformat()
plain = user + '\0' + time
token = sha1(plain)
print token.hexdigest()
"1e2c5078bd0de12a79d1a49255a9bff9737aa4a4"

Next you store that token in a memcache with an expiration time. This way any of your webservers can reach it and the token will auto-expire. Finally add a Django url handler for ‘^download/.+’ where the controller just looks up that token in the memcache to determine if the token is valid. You can even store the filename to be downloaded as the token’s value in memcache.

1👍

It sounds like you are suggesting using some kind of dynamic url conf.

Why not forget your concerns by simplifying and setting up a single url that captures a large encoded string that depends on user/time?

(r'^download/(?P<encrypted_id>(.*)/$', 'download_file'), # use your own regexp


def download_file(request, encrypted_id):
    decrypted = decrypt(encrypted_id)
    _file = get_file(decrypted)
    return _file

A lot of sites just use a get param too.

www.example.com/download_file/?09248903483o8a908423028a0df8032

If you are concerned about performance, look at the answers in this post: Having Django serve downloadable files

Where the use of the apache x-sendfile module is highlighted.


Another alternative is to simply redirect to the static file served by whatever means from django.

Leave a comment