annotate downloads/models.py @ 1054:5b8062cce722

Top-bar search is working. A few small visual tweaks.
author Brian Neal <bgneal@gmail.com>
date Mon, 07 Mar 2016 19:55:26 -0600
parents eeaf387803c6
children f0ac48aa8c64
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
bgneal@1035 7 from django.contrib.auth.models import User
bgneal@1035 8 from django.core.urlresolvers import reverse
gremmie@1 9 from django.db import models
gremmie@1 10 from django.template.defaultfilters import filesizeformat
gremmie@1 11
bgneal@128 12 from core.markup import site_markup
bgneal@124 13
gremmie@1 14
gremmie@1 15 class Category(models.Model):
gremmie@1 16 """Downloads belong to categories."""
gremmie@1 17 title = models.CharField(max_length=64)
bgneal@241 18 slug = models.SlugField(max_length=64)
gremmie@1 19 description = models.TextField(blank=True)
bgneal@192 20 count = models.IntegerField(default=0, blank=True)
gremmie@1 21
gremmie@1 22 class Meta:
gremmie@1 23 verbose_name_plural = 'Categories'
gremmie@1 24 ordering = ('title', )
gremmie@1 25
gremmie@1 26 def __unicode__(self):
gremmie@1 27 return self.title
gremmie@1 28
gremmie@1 29
gremmie@1 30 def download_path(instance, filename):
gremmie@1 31 """
gremmie@1 32 Creates a path for a download. Uses the current date to avoid filename
gremmie@1 33 clashes. Uses the current microsecond also to make the directory name
gremmie@1 34 harder to guess.
gremmie@1 35 """
gremmie@1 36 now = datetime.datetime.now()
gremmie@1 37 parts = ['downloads']
bgneal@210 38 parts.extend([str(p) for p in (now.year, now.month, now.day)])
bgneal@210 39 parts.append(hex((now.hour * 3600 + now.minute * 60 + now.second) * 1000 + (
bgneal@210 40 now.microsecond / 1000))[2:])
gremmie@1 41 parts.append(filename)
gremmie@1 42 return os.path.join(*parts)
gremmie@1 43
gremmie@1 44
gremmie@1 45 class PublicDownloadManager(models.Manager):
gremmie@1 46 """The manager for all public downloads."""
bgneal@740 47 def get_queryset(self):
bgneal@740 48 return super(PublicDownloadManager, self).get_queryset().filter(
bgneal@190 49 is_public=True).select_related()
gremmie@1 50
gremmie@1 51
bgneal@204 52 class DownloadBase(models.Model):
bgneal@204 53 """Abstract model to collect common download fields."""
gremmie@1 54 title = models.CharField(max_length=128)
gremmie@1 55 category = models.ForeignKey(Category)
gremmie@1 56 description = models.TextField()
gremmie@1 57 html = models.TextField(blank=True)
gremmie@1 58 file = models.FileField(upload_to=download_path)
gremmie@1 59 user = models.ForeignKey(User)
bgneal@277 60 date_added = models.DateTimeField(db_index=True)
bgneal@1028 61 ip_address = models.GenericIPAddressField('IP Address')
bgneal@277 62 update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@204 63
bgneal@204 64 class Meta:
bgneal@204 65 abstract = True
bgneal@204 66
bgneal@204 67 def size(self):
bgneal@661 68 try:
bgneal@661 69 return filesizeformat(self.file.size)
bgneal@661 70 except OSError:
bgneal@661 71 return '?'
bgneal@204 72
bgneal@1023 73 def save(self, *args, **kwargs):
bgneal@1023 74 if not self.pk:
bgneal@1023 75 self.date_added = datetime.datetime.now()
bgneal@1023 76 self.update_date = self.date_added
bgneal@1023 77 else:
bgneal@1023 78 self.update_date = datetime.datetime.now()
bgneal@1023 79
bgneal@1023 80 self.html = kwargs.pop('html', None)
bgneal@1023 81 if not self.html and self.description:
bgneal@1023 82 self.html = site_markup(self.description)
bgneal@1023 83 super(DownloadBase, self).save(*args, **kwargs)
bgneal@1023 84
bgneal@204 85
bgneal@204 86 class PendingDownload(DownloadBase):
bgneal@204 87 """This model represents pending downloads created by users. These pending
bgneal@204 88 downloads must be approved by an admin before they turn into "real"
bgneal@204 89 Downloads and are visible on site.
bgneal@204 90 """
bgneal@204 91 class Meta:
bgneal@204 92 ordering = ('date_added', )
bgneal@204 93
bgneal@204 94 def __unicode__(self):
bgneal@204 95 return self.title
bgneal@204 96
bgneal@204 97
bgneal@204 98 class Download(DownloadBase):
bgneal@204 99 """Model to represent a download."""
gremmie@1 100 hits = models.IntegerField(default=0)
gremmie@1 101 average_score = models.FloatField(default=0.0)
gremmie@1 102 total_votes = models.IntegerField(default=0)
gremmie@1 103 is_public = models.BooleanField(default=False, db_index=True)
gremmie@1 104
gremmie@1 105 # Managers:
gremmie@1 106 objects = models.Manager()
gremmie@1 107 public_objects = PublicDownloadManager()
gremmie@1 108
gremmie@1 109 def __unicode__(self):
gremmie@1 110 return self.title
gremmie@1 111
bgneal@14 112 def get_absolute_url(self):
bgneal@1035 113 return reverse('downloads-details', args=[str(self.pk)])
bgneal@14 114
gremmie@1 115 def vote(self, vote_value):
gremmie@1 116 """receives a vote_value and updates internal score accordingly"""
gremmie@1 117 total_score = self.average_score * self.total_votes
gremmie@1 118 total_score += vote_value
gremmie@1 119 self.total_votes += 1
gremmie@1 120 self.average_score = total_score / self.total_votes
gremmie@1 121 return self.average_score
gremmie@1 122
bgneal@221 123 def search_title(self):
bgneal@221 124 return self.title
bgneal@221 125
bgneal@221 126 def search_summary(self):
bgneal@221 127 return self.description
bgneal@221 128
gremmie@1 129
gremmie@1 130 class AllowedExtensionManager(models.Manager):
gremmie@1 131 def get_extension_list(self):
gremmie@1 132 return self.values_list('extension', flat=True)
gremmie@1 133
gremmie@1 134
gremmie@1 135 class AllowedExtension(models.Model):
gremmie@1 136 """Model to represent the list of allowed file extensions."""
bgneal@206 137 extension = models.CharField(max_length=8, help_text="e.g. .txt")
gremmie@1 138
gremmie@1 139 objects = AllowedExtensionManager()
gremmie@1 140
gremmie@1 141 def __unicode__(self):
gremmie@1 142 return self.extension
gremmie@1 143
gremmie@1 144 class Meta:
gremmie@1 145 ordering = ('extension', )
gremmie@1 146
gremmie@1 147
gremmie@1 148 class VoteRecord(models.Model):
gremmie@1 149 """Model to record the date that a user voted on a download."""
gremmie@1 150 download = models.ForeignKey(Download)
gremmie@1 151 user = models.ForeignKey(User)
gremmie@1 152 vote_date = models.DateTimeField(auto_now_add=True)
gremmie@1 153
gremmie@1 154 def __unicode__(self):
bgneal@192 155 return u"%s voted on '%s' on %s" % (
bgneal@412 156 self.user.username,
bgneal@412 157 self.download.title,
gremmie@1 158 self.vote_date.strftime('%b %d, %Y %H:%M:%S'))
gremmie@1 159
gremmie@1 160 class Meta:
gremmie@1 161 ordering = ('-vote_date', )