annotate downloads/models.py @ 631:f36d1a168be7

For issue 27, disable login dialog button during POST. This seems to prevent multiple logins most of the time. You can still bang on the enter key and sometimes get more through.
author Brian Neal <bgneal@gmail.com>
date Wed, 14 Nov 2012 20:57:05 -0600
parents ee87ea74d46b
children 15dbe0ccda95
rev   line source
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.defaultfilters import filesizeformat
gremmie@1 10
bgneal@128 11 from core.markup import site_markup
bgneal@124 12
gremmie@1 13
gremmie@1 14 class Category(models.Model):
gremmie@1 15 """Downloads belong to categories."""
gremmie@1 16 title = models.CharField(max_length=64)
bgneal@241 17 slug = models.SlugField(max_length=64)
gremmie@1 18 description = models.TextField(blank=True)
bgneal@192 19 count = models.IntegerField(default=0, blank=True)
gremmie@1 20
gremmie@1 21 class Meta:
gremmie@1 22 verbose_name_plural = 'Categories'
gremmie@1 23 ordering = ('title', )
gremmie@1 24
gremmie@1 25 def __unicode__(self):
gremmie@1 26 return self.title
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']
bgneal@210 37 parts.extend([str(p) for p in (now.year, now.month, now.day)])
bgneal@210 38 parts.append(hex((now.hour * 3600 + now.minute * 60 + now.second) * 1000 + (
bgneal@210 39 now.microsecond / 1000))[2:])
gremmie@1 40 parts.append(filename)
gremmie@1 41 return os.path.join(*parts)
gremmie@1 42
gremmie@1 43
gremmie@1 44 class PublicDownloadManager(models.Manager):
gremmie@1 45 """The manager for all public downloads."""
gremmie@1 46 def get_query_set(self):
bgneal@190 47 return super(PublicDownloadManager, self).get_query_set().filter(
bgneal@190 48 is_public=True).select_related()
gremmie@1 49
gremmie@1 50
bgneal@204 51 class DownloadBase(models.Model):
bgneal@204 52 """Abstract model to collect common download fields."""
gremmie@1 53 title = models.CharField(max_length=128)
gremmie@1 54 category = models.ForeignKey(Category)
gremmie@1 55 description = models.TextField()
gremmie@1 56 html = models.TextField(blank=True)
gremmie@1 57 file = models.FileField(upload_to=download_path)
gremmie@1 58 user = models.ForeignKey(User)
bgneal@277 59 date_added = models.DateTimeField(db_index=True)
gremmie@1 60 ip_address = models.IPAddressField('IP Address')
bgneal@277 61 update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@204 62
bgneal@204 63 class Meta:
bgneal@204 64 abstract = True
bgneal@204 65
bgneal@204 66 def size(self):
bgneal@204 67 return filesizeformat(self.file.size)
bgneal@204 68
bgneal@204 69
bgneal@204 70 class PendingDownload(DownloadBase):
bgneal@204 71 """This model represents pending downloads created by users. These pending
bgneal@204 72 downloads must be approved by an admin before they turn into "real"
bgneal@204 73 Downloads and are visible on site.
bgneal@204 74 """
bgneal@204 75 class Meta:
bgneal@204 76 ordering = ('date_added', )
bgneal@204 77
bgneal@204 78 def __unicode__(self):
bgneal@204 79 return self.title
bgneal@204 80
bgneal@204 81 def save(self, *args, **kwargs):
bgneal@204 82 if not self.pk:
bgneal@204 83 self.date_added = datetime.datetime.now()
bgneal@277 84 self.update_date = self.date_added
bgneal@277 85 else:
bgneal@277 86 self.update_date = datetime.datetime.now()
bgneal@277 87
bgneal@204 88 self.html = site_markup(self.description)
bgneal@204 89 super(PendingDownload, self).save(*args, **kwargs)
bgneal@204 90
bgneal@204 91
bgneal@204 92 class Download(DownloadBase):
bgneal@204 93 """Model to represent a download."""
gremmie@1 94 hits = models.IntegerField(default=0)
gremmie@1 95 average_score = models.FloatField(default=0.0)
gremmie@1 96 total_votes = models.IntegerField(default=0)
gremmie@1 97 is_public = models.BooleanField(default=False, db_index=True)
gremmie@1 98
gremmie@1 99 # Managers:
gremmie@1 100 objects = models.Manager()
gremmie@1 101 public_objects = PublicDownloadManager()
gremmie@1 102
gremmie@1 103 def __unicode__(self):
gremmie@1 104 return self.title
gremmie@1 105
bgneal@14 106 @models.permalink
bgneal@14 107 def get_absolute_url(self):
bgneal@23 108 return ('downloads-details', [str(self.id)])
bgneal@14 109
bgneal@182 110 def save(self, *args, **kwargs):
bgneal@277 111 if not self.pk:
bgneal@277 112 self.date_added = datetime.datetime.now()
bgneal@277 113 self.update_date = self.date_added
bgneal@277 114 else:
bgneal@277 115 self.update_date = datetime.datetime.now()
bgneal@277 116
bgneal@128 117 self.html = site_markup(self.description)
bgneal@182 118 super(Download, self).save(*args, **kwargs)
gremmie@1 119
gremmie@1 120 def vote(self, vote_value):
gremmie@1 121 """receives a vote_value and updates internal score accordingly"""
gremmie@1 122 total_score = self.average_score * self.total_votes
gremmie@1 123 total_score += vote_value
gremmie@1 124 self.total_votes += 1
gremmie@1 125 self.average_score = total_score / self.total_votes
gremmie@1 126 return self.average_score
gremmie@1 127
bgneal@221 128 def search_title(self):
bgneal@221 129 return self.title
bgneal@221 130
bgneal@221 131 def search_summary(self):
bgneal@221 132 return self.description
bgneal@221 133
gremmie@1 134
gremmie@1 135 class AllowedExtensionManager(models.Manager):
gremmie@1 136 def get_extension_list(self):
gremmie@1 137 return self.values_list('extension', flat=True)
gremmie@1 138
gremmie@1 139
gremmie@1 140 class AllowedExtension(models.Model):
gremmie@1 141 """Model to represent the list of allowed file extensions."""
bgneal@206 142 extension = models.CharField(max_length=8, help_text="e.g. .txt")
gremmie@1 143
gremmie@1 144 objects = AllowedExtensionManager()
gremmie@1 145
gremmie@1 146 def __unicode__(self):
gremmie@1 147 return self.extension
gremmie@1 148
gremmie@1 149 class Meta:
gremmie@1 150 ordering = ('extension', )
gremmie@1 151
gremmie@1 152
gremmie@1 153 class VoteRecord(models.Model):
gremmie@1 154 """Model to record the date that a user voted on a download."""
gremmie@1 155 download = models.ForeignKey(Download)
gremmie@1 156 user = models.ForeignKey(User)
gremmie@1 157 vote_date = models.DateTimeField(auto_now_add=True)
gremmie@1 158
gremmie@1 159 def __unicode__(self):
bgneal@192 160 return u"%s voted on '%s' on %s" % (
bgneal@412 161 self.user.username,
bgneal@412 162 self.download.title,
gremmie@1 163 self.vote_date.strftime('%b %d, %Y %H:%M:%S'))
gremmie@1 164
gremmie@1 165 class Meta:
gremmie@1 166 ordering = ('-vote_date', )