X-Git-Url: https://git.mdrn.pl/wolnelektury.git/blobdiff_plain/053d581a43e6a5b4125185eebe3a4cd2aa556bdd..6e0b282242bf227d1dba35b2748b7cadb48741db:/apps/waiter/models.py diff --git a/apps/waiter/models.py b/apps/waiter/models.py new file mode 100644 index 000000000..fd9730131 --- /dev/null +++ b/apps/waiter/models.py @@ -0,0 +1,53 @@ +from os.path import join, abspath, exists +from django.db import models +from waiter.settings import WAITER_ROOT, WAITER_URL +from django.core.urlresolvers import reverse + +class WaitedFile(models.Model): + path = models.CharField(max_length=255, unique=True, db_index=True) + task = models.CharField(max_length=64, null=True, editable=False) + description = models.CharField(max_length=255, null=True, blank=True) + + @staticmethod + def abspath(path): + abs_path = abspath(join(WAITER_ROOT, path)) + if not abs_path.startswith(WAITER_ROOT): + raise ValueError('Path not inside WAITER_ROOT.') + return abs_path + + @classmethod + def exists(cls, path): + """Returns opened file or None. + + `path` is relative to WAITER_ROOT. + Won't open a path leading outside of WAITER_ROOT. + """ + abs_path = cls.abspath(path) + # Pre-fetch objects to avoid minor race condition + relevant = [o.id for o in cls.objects.filter(path=path)] + print abs_path + if exists(abs_path): + cls.objects.filter(id__in=relevant).delete() + return True + else: + return False + + @classmethod + def order(cls, path, task_creator, description=None): + """ + Returns an URL for the user to follow. + If the file is ready, returns download URL. + If not, starts preparing it and returns waiting URL. + """ + already = cls.exists(path) + if not already: + waited, created = cls.objects.get_or_create(path=path) + if created: + # TODO: makedirs + waited.task = task_creator(cls.abspath(path)) + print waited.task + waited.description = description + waited.save() + # TODO: it the task exists, if stale delete, send some mail and restart + return reverse("waiter", args=[path]) + return join(WAITER_URL, path)