gremmie@1: """
gremmie@1: Models for the downloads application.
gremmie@1: """
gremmie@1: import os
gremmie@1: 
gremmie@1: import datetime
gremmie@1: from django.db import models
gremmie@1: from django.contrib.auth.models import User
gremmie@1: from django.template.defaultfilters import filesizeformat
gremmie@1: 
bgneal@128: from core.markup import site_markup
bgneal@124: 
gremmie@1: 
gremmie@1: class Category(models.Model):
gremmie@1:     """Downloads belong to categories."""
gremmie@1:     title = models.CharField(max_length=64)
bgneal@241:     slug = models.SlugField(max_length=64)
gremmie@1:     description = models.TextField(blank=True)
bgneal@192:     count = models.IntegerField(default=0, blank=True)
gremmie@1: 
gremmie@1:     class Meta:
gremmie@1:         verbose_name_plural = 'Categories'
gremmie@1:         ordering = ('title', )
gremmie@1: 
gremmie@1:     def __unicode__(self):
gremmie@1:         return self.title
gremmie@1: 
gremmie@1: 
gremmie@1: def download_path(instance, filename):
gremmie@1:     """
gremmie@1:     Creates a path for a download. Uses the current date to avoid filename
gremmie@1:     clashes. Uses the current microsecond also to make the directory name
gremmie@1:     harder to guess.
gremmie@1:     """
gremmie@1:     now = datetime.datetime.now()
gremmie@1:     parts = ['downloads']
bgneal@210:     parts.extend([str(p) for p in (now.year, now.month, now.day)])
bgneal@210:     parts.append(hex((now.hour * 3600 + now.minute * 60 + now.second) * 1000 + (
bgneal@210:         now.microsecond / 1000))[2:])
gremmie@1:     parts.append(filename)
gremmie@1:     return os.path.join(*parts)
gremmie@1: 
gremmie@1: 
gremmie@1: class PublicDownloadManager(models.Manager):
gremmie@1:     """The manager for all public downloads."""
gremmie@1:     def get_query_set(self):
bgneal@190:         return super(PublicDownloadManager, self).get_query_set().filter(
bgneal@190:                 is_public=True).select_related()
gremmie@1: 
gremmie@1: 
bgneal@204: class DownloadBase(models.Model):
bgneal@204:     """Abstract model to collect common download fields."""
gremmie@1:     title = models.CharField(max_length=128)
gremmie@1:     category = models.ForeignKey(Category)
gremmie@1:     description = models.TextField()
gremmie@1:     html = models.TextField(blank=True)
gremmie@1:     file = models.FileField(upload_to=download_path)
gremmie@1:     user = models.ForeignKey(User)
bgneal@277:     date_added = models.DateTimeField(db_index=True)
gremmie@1:     ip_address = models.IPAddressField('IP Address')
bgneal@277:     update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@204: 
bgneal@204:     class Meta:
bgneal@204:         abstract = True
bgneal@204: 
bgneal@204:     def size(self):
bgneal@204:         return filesizeformat(self.file.size)
bgneal@204: 
bgneal@204: 
bgneal@204: class PendingDownload(DownloadBase):
bgneal@204:     """This model represents pending downloads created by users. These pending
bgneal@204:     downloads must be approved by an admin before they turn into "real"
bgneal@204:     Downloads and are visible on site.
bgneal@204:     """
bgneal@204:     class Meta:
bgneal@204:         ordering = ('date_added', )
bgneal@204: 
bgneal@204:     def __unicode__(self):
bgneal@204:         return self.title
bgneal@204: 
bgneal@204:     def save(self, *args, **kwargs):
bgneal@204:         if not self.pk:
bgneal@204:             self.date_added = datetime.datetime.now()
bgneal@277:             self.update_date = self.date_added
bgneal@277:         else:
bgneal@277:             self.update_date = datetime.datetime.now()
bgneal@277: 
bgneal@204:         self.html = site_markup(self.description)
bgneal@204:         super(PendingDownload, self).save(*args, **kwargs)
bgneal@204: 
bgneal@204: 
bgneal@204: class Download(DownloadBase):
bgneal@204:     """Model to represent a download."""
gremmie@1:     hits = models.IntegerField(default=0)
gremmie@1:     average_score = models.FloatField(default=0.0)
gremmie@1:     total_votes = models.IntegerField(default=0)
gremmie@1:     is_public = models.BooleanField(default=False, db_index=True)
gremmie@1: 
gremmie@1:     # Managers:
gremmie@1:     objects = models.Manager()
gremmie@1:     public_objects = PublicDownloadManager()
gremmie@1: 
gremmie@1:     def __unicode__(self):
gremmie@1:         return self.title
gremmie@1: 
bgneal@14:     @models.permalink
bgneal@14:     def get_absolute_url(self):
bgneal@23:         return ('downloads-details', [str(self.id)])
bgneal@14: 
bgneal@182:     def save(self, *args, **kwargs):
bgneal@277:         if not self.pk:
bgneal@277:             self.date_added = datetime.datetime.now()
bgneal@277:             self.update_date = self.date_added
bgneal@277:         else:
bgneal@277:             self.update_date = datetime.datetime.now()
bgneal@277: 
bgneal@128:         self.html = site_markup(self.description)
bgneal@182:         super(Download, self).save(*args, **kwargs)
gremmie@1: 
gremmie@1:     def vote(self, vote_value):
gremmie@1:         """receives a vote_value and updates internal score accordingly"""
gremmie@1:         total_score = self.average_score * self.total_votes
gremmie@1:         total_score += vote_value
gremmie@1:         self.total_votes += 1
gremmie@1:         self.average_score = total_score / self.total_votes
gremmie@1:         return self.average_score
gremmie@1: 
bgneal@221:     def search_title(self):
bgneal@221:         return self.title
bgneal@221: 
bgneal@221:     def search_summary(self):
bgneal@221:         return self.description
bgneal@221: 
gremmie@1: 
gremmie@1: class AllowedExtensionManager(models.Manager):
gremmie@1:     def get_extension_list(self):
gremmie@1:         return self.values_list('extension', flat=True)
gremmie@1: 
gremmie@1: 
gremmie@1: class AllowedExtension(models.Model):
gremmie@1:     """Model to represent the list of allowed file extensions."""
bgneal@206:     extension = models.CharField(max_length=8, help_text="e.g. .txt")
gremmie@1: 
gremmie@1:     objects = AllowedExtensionManager()
gremmie@1: 
gremmie@1:     def __unicode__(self):
gremmie@1:         return self.extension
gremmie@1: 
gremmie@1:     class Meta:
gremmie@1:         ordering = ('extension', )
gremmie@1: 
gremmie@1: 
gremmie@1: class VoteRecord(models.Model):
gremmie@1:     """Model to record the date that a user voted on a download."""
gremmie@1:     download = models.ForeignKey(Download)
gremmie@1:     user = models.ForeignKey(User)
gremmie@1:     vote_date = models.DateTimeField(auto_now_add=True)
gremmie@1: 
gremmie@1:     def __unicode__(self):
bgneal@192:         return u"%s voted on '%s' on %s" % (
bgneal@412:                 self.user.username,
bgneal@412:                 self.download.title,
gremmie@1:                 self.vote_date.strftime('%b %d, %Y %H:%M:%S'))
gremmie@1: 
gremmie@1:     class Meta:
gremmie@1:         ordering = ('-vote_date', )