1 from os.path import join, abspath, exists
2 from django.db import models
3 from waiter.settings import WAITER_ROOT, WAITER_URL
4 from django.core.urlresolvers import reverse
6 class WaitedFile(models.Model):
7 path = models.CharField(max_length=255, unique=True, db_index=True)
8 task = models.CharField(max_length=64, null=True, editable=False)
9 description = models.CharField(max_length=255, null=True, blank=True)
13 abs_path = abspath(join(WAITER_ROOT, path))
14 if not abs_path.startswith(WAITER_ROOT):
15 raise ValueError('Path not inside WAITER_ROOT.')
19 def exists(cls, path):
20 """Returns opened file or None.
22 `path` is relative to WAITER_ROOT.
23 Won't open a path leading outside of WAITER_ROOT.
25 abs_path = cls.abspath(path)
26 # Pre-fetch objects to avoid minor race condition
27 relevant = [o.id for o in cls.objects.filter(path=path)]
30 cls.objects.filter(id__in=relevant).delete()
36 def order(cls, path, task_creator, description=None):
38 Returns an URL for the user to follow.
39 If the file is ready, returns download URL.
40 If not, starts preparing it and returns waiting URL.
42 already = cls.exists(path)
44 waited, created = cls.objects.get_or_create(path=path)
47 waited.task = task_creator(cls.abspath(path))
49 waited.description = description
51 # TODO: it the task exists, if stale delete, send some mail and restart
52 return reverse("waiter", args=[path])
53 return join(WAITER_URL, path)