add stage2 app (with participant view mostly ready)
[edumed.git] / stage2 / models.py
1 # -*- coding: utf-8 -*-
2 import os
3 import random
4 import string
5
6 from django.contrib.auth.models import User
7 from django.core.urlresolvers import reverse
8 from django.db import models
9 from jsonfield import JSONField
10
11 from contact.models import Contact
12
13
14 class Participant(models.Model):
15     contact = models.ForeignKey(Contact, null=True)
16     key = models.CharField(max_length=30, unique=True)
17     first_name = models.CharField(max_length=100)
18     last_name = models.CharField(max_length=100)
19     email = models.EmailField(max_length=100, unique=True)
20     key_sent = models.BooleanField(default=False)
21
22     def __unicode__(self):
23         return ', '.join((self.last_name, self.first_name, self.email))
24
25     # copy-paste from wtem
26     @classmethod
27     def generate_key(cls):
28         key = ''
29         while not key or key in [record['key'] for record in cls.objects.values('key')]:
30             key = ''.join(random.choice(string.ascii_uppercase + string.ascii_lowercase + string.digits)
31                           for i in range(30))
32         return key
33
34     # copy-paste from wtem
35     @classmethod
36     def create(cls, first_name, last_name, email, key=None, contact=None):
37         return cls.objects.create(
38             contact=contact,
39             key=key if key else cls.generate_key(),
40             first_name=first_name,
41             last_name=last_name,
42             email=email)
43
44     def check(self, key):
45         return key == self.key
46
47
48 class Assignment(models.Model):
49     title = models.CharField(max_length=128)
50     content = models.TextField()
51     deadline = models.DateTimeField()
52     max_points = models.IntegerField()
53     file_descriptions = JSONField()
54
55     class Meta:
56         ordering = ['deadline']
57
58     def __unicode__(self):
59         return self.title
60
61
62 class Answer(models.Model):
63     participant = models.ForeignKey(Participant)
64     assignment = models.ForeignKey(Assignment)
65
66     class Meta:
67         unique_together = ['participant', 'assignment']
68
69
70 def attachment_path(instance, filename):
71     answer = instance.answer
72     return 'stage2/attachment/%s/%s/%s' % (answer.participant_id, answer.assignment_id, filename)
73
74
75 class Attachment(models.Model):
76     answer = models.ForeignKey(Answer)
77     file_no = models.IntegerField()
78     file = models.FileField(upload_to=attachment_path)
79
80     def filename(self):
81         return os.path.basename(self.file.name)
82
83     def download_url(self):
84         return reverse(
85             'stage2_participant_file',
86             args=(self.answer.assignment_id, self.file_no,
87                   self.answer.participant_id, self.answer.participant.key))
88
89
90 class Mark(models.Model):
91     expert = models.ForeignKey(User)
92     answer = models.ForeignKey(Answer)
93     points = models.DecimalField(max_digits=3, decimal_places=1)
94
95     class Meta:
96         unique_together = ['expert', 'answer']