gremmie@1
|
1 """
|
gremmie@1
|
2 Models for the downloads application.
|
gremmie@1
|
3 """
|
gremmie@1
|
4 import os
|
gremmie@1
|
5
|
gremmie@1
|
6 import datetime
|
gremmie@1
|
7 from django.db import models
|
gremmie@1
|
8 from django.contrib.auth.models import User
|
gremmie@1
|
9 from django.template.loader import render_to_string
|
gremmie@1
|
10 from django.template.defaultfilters import filesizeformat
|
gremmie@1
|
11
|
gremmie@1
|
12
|
gremmie@1
|
13 class Category(models.Model):
|
gremmie@1
|
14 """Downloads belong to categories."""
|
gremmie@1
|
15 title = models.CharField(max_length=64)
|
gremmie@1
|
16 description = models.TextField(blank=True)
|
gremmie@1
|
17
|
gremmie@1
|
18 class Meta:
|
gremmie@1
|
19 verbose_name_plural = 'Categories'
|
gremmie@1
|
20 ordering = ('title', )
|
gremmie@1
|
21
|
gremmie@1
|
22 def __unicode__(self):
|
gremmie@1
|
23 return self.title
|
gremmie@1
|
24
|
gremmie@1
|
25 def num_downloads(self):
|
gremmie@1
|
26 return Download.public_objects.filter(category=self.pk).count()
|
gremmie@1
|
27
|
gremmie@1
|
28
|
gremmie@1
|
29 def download_path(instance, filename):
|
gremmie@1
|
30 """
|
gremmie@1
|
31 Creates a path for a download. Uses the current date to avoid filename
|
gremmie@1
|
32 clashes. Uses the current microsecond also to make the directory name
|
gremmie@1
|
33 harder to guess.
|
gremmie@1
|
34 """
|
gremmie@1
|
35 now = datetime.datetime.now()
|
gremmie@1
|
36 parts = ['downloads']
|
gremmie@1
|
37 parts.extend([str(p) for p in (now.year, now.month, now.day, now.microsecond)])
|
gremmie@1
|
38 parts.append(filename)
|
gremmie@1
|
39 return os.path.join(*parts)
|
gremmie@1
|
40
|
gremmie@1
|
41
|
gremmie@1
|
42 class PublicDownloadManager(models.Manager):
|
gremmie@1
|
43 """The manager for all public downloads."""
|
gremmie@1
|
44 def get_query_set(self):
|
gremmie@1
|
45 return super(PublicDownloadManager, self).get_query_set().filter(is_public=True)
|
gremmie@1
|
46
|
gremmie@1
|
47
|
gremmie@1
|
48 class Download(models.Model):
|
gremmie@1
|
49 """Model to represent a download."""
|
gremmie@1
|
50 title = models.CharField(max_length=128)
|
gremmie@1
|
51 category = models.ForeignKey(Category)
|
gremmie@1
|
52 description = models.TextField()
|
gremmie@1
|
53 html = models.TextField(blank=True)
|
gremmie@1
|
54 file = models.FileField(upload_to=download_path)
|
gremmie@1
|
55 user = models.ForeignKey(User)
|
gremmie@1
|
56 date_added = models.DateTimeField(auto_now_add=True)
|
gremmie@1
|
57 ip_address = models.IPAddressField('IP Address')
|
gremmie@1
|
58 hits = models.IntegerField(default=0)
|
gremmie@1
|
59 average_score = models.FloatField(default=0.0)
|
gremmie@1
|
60 total_votes = models.IntegerField(default=0)
|
gremmie@1
|
61 is_public = models.BooleanField(default=False, db_index=True)
|
gremmie@1
|
62
|
gremmie@1
|
63 # Managers:
|
gremmie@1
|
64 objects = models.Manager()
|
gremmie@1
|
65 public_objects = PublicDownloadManager()
|
gremmie@1
|
66
|
gremmie@1
|
67 def __unicode__(self):
|
gremmie@1
|
68 return self.title
|
gremmie@1
|
69
|
gremmie@1
|
70 def save(self, force_insert=False, force_update=False):
|
gremmie@1
|
71 html = render_to_string('downloads/markdown.html', {'data': self.description})
|
gremmie@1
|
72 self.html = html.strip()
|
gremmie@1
|
73 super(Download, self).save(force_insert, force_update)
|
gremmie@1
|
74
|
gremmie@1
|
75 def vote(self, vote_value):
|
gremmie@1
|
76 """receives a vote_value and updates internal score accordingly"""
|
gremmie@1
|
77 total_score = self.average_score * self.total_votes
|
gremmie@1
|
78 total_score += vote_value
|
gremmie@1
|
79 self.total_votes += 1
|
gremmie@1
|
80 self.average_score = total_score / self.total_votes
|
gremmie@1
|
81 return self.average_score
|
gremmie@1
|
82
|
gremmie@1
|
83 def size(self):
|
gremmie@1
|
84 return filesizeformat(self.file.size)
|
gremmie@1
|
85
|
gremmie@1
|
86
|
gremmie@1
|
87 class AllowedExtensionManager(models.Manager):
|
gremmie@1
|
88 def get_extension_list(self):
|
gremmie@1
|
89 return self.values_list('extension', flat=True)
|
gremmie@1
|
90
|
gremmie@1
|
91
|
gremmie@1
|
92 class AllowedExtension(models.Model):
|
gremmie@1
|
93 """Model to represent the list of allowed file extensions."""
|
gremmie@1
|
94 extension = models.CharField(max_length=8)
|
gremmie@1
|
95
|
gremmie@1
|
96 objects = AllowedExtensionManager()
|
gremmie@1
|
97
|
gremmie@1
|
98 def __unicode__(self):
|
gremmie@1
|
99 return self.extension
|
gremmie@1
|
100
|
gremmie@1
|
101 class Meta:
|
gremmie@1
|
102 ordering = ('extension', )
|
gremmie@1
|
103
|
gremmie@1
|
104
|
gremmie@1
|
105 class VoteRecord(models.Model):
|
gremmie@1
|
106 """Model to record the date that a user voted on a download."""
|
gremmie@1
|
107 download = models.ForeignKey(Download)
|
gremmie@1
|
108 user = models.ForeignKey(User)
|
gremmie@1
|
109 vote_date = models.DateTimeField(auto_now_add=True)
|
gremmie@1
|
110
|
gremmie@1
|
111 def __unicode__(self):
|
gremmie@1
|
112 return "%s voted on '%s' on %s" % (
|
gremmie@1
|
113 self.user.username,
|
gremmie@1
|
114 self.download.title,
|
gremmie@1
|
115 self.vote_date.strftime('%b %d, %Y %H:%M:%S'))
|
gremmie@1
|
116
|
gremmie@1
|
117 class Meta:
|
gremmie@1
|
118 ordering = ('-vote_date', )
|