Генератор ссылок с использованием Django или любого модуля Python - PullRequest
3 голосов
/ 16 марта 2011

Я хочу создать для моих пользователей временную ссылку для скачивания. Это нормально, если я использую Django для генерации ссылки с использованием шаблонов URL? Это может быть правильный способ сделать это. Потому что может случиться так, что я не понимаю некоторые процессы, как это работает. И это переполнит мою память или что-то еще. Какой-то пример или инструменты будут оценены. Возможно, некоторые модули nginx, apache?

Итак, чего я хочу добиться, так это создать шаблон URL, который зависит от пользователя и времени. Дескрипт его конец и возврат в просмотр файла.

Ответы [ 3 ]

4 голосов
/ 16 марта 2011

Простая схема может заключаться в использовании хэш-дайджеста имени пользователя и отметки времени:

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"

Затем вы сохраняете этот токен в memcache со сроком действия. Таким образом, любой из ваших веб-серверов сможет связаться с ним, и токен автоматически истечет. Наконец, добавьте обработчик URL-адреса Django для '^ download /.+', где контроллер просто ищет этот токен в memcache, чтобы определить, является ли токен действительным. Вы даже можете сохранить имя файла для загрузки в качестве значения токена в memcache.

2 голосов
/ 16 марта 2011

Да, было бы нормально разрешить django генерировать URL-адреса.Это исключительная возможность обработки URL-адресов с помощью urls.py.Как правило, вы не хотите, чтобы django управлял обслуживанием файлов, смотрите статические файлы docs [1] по этому поводу, так что получите представление об использовании шаблонов url из своей головы.

Что вы можете сделать, это сгенерировать случайный ключ, используя хеш, например, md5 / sha1.Сохраните файл и ключ, дату и время его добавления в базе данных, создайте каталог для загрузки в корневом каталоге, доступном с вашего веб-сервера, например, apache или nginx ... предложить nginx), поскольку он временный, вам нужно добавить cronЗадание, которое проверяет, истекло ли время с момента создания URL-адреса, очищает файл и удаляет запись в базе данных.Это должна быть команда django для manage.py

Обратите внимание, это пример кода, написанного только для этого и не проверенного!Это может не сработать так, как вы планировали достичь этой цели, но это работает.Если вы хотите, чтобы dl также был защищен pw, посмотрите в httpbasic auth.вы можете создавать и удалять записи на лету в файле httpd.auth с помощью htpasswd и модуля подпроцесса при создании ссылки или во время регистрации.

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/

1 голос
/ 16 марта 2011

Звучит так, как будто вы предлагаете использовать какой-то динамический URL-адрес.

Почему бы не забыть о своих проблемах, упростив и настроив один URL-адрес, который захватывает большую закодированную строку, зависящую от пользователя / времени?

(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

Многие сайты просто используют параметр get.

www.example.com / download_file /? 09248903483o8a908423028a0df8032

Если вы беспокоитесь о производительности, посмотритеответы на этот пост: Наличие в Django загружаемых файлов

Где выделено использование модуля apache x-sendfile.


Другой альтернативой являетсяпросто перенаправьте на статический файл, обслуживаемый любыми средствами из django.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...