gremmie@1: """
gremmie@1: Models for the news application.
gremmie@1: """
bgneal@997: import datetime
gremmie@1: 
bgneal@1002: from django.core.urlresolvers import reverse
gremmie@1: from django.db import models
bgneal@49: from django.contrib.auth.models import User
gremmie@1: from tagging.fields import TagField
gremmie@1: 
bgneal@997: from core.markup import site_markup
bgneal@997: 
bgneal@997: 
bgneal@997: # News App versions
bgneal@997: NEWS_VERSION = 2
bgneal@997: 
gremmie@1: 
gremmie@1: class Category(models.Model):
bgneal@54:     """News stories belong to categories"""
bgneal@240:     title = models.CharField(max_length=64)
bgneal@240:     slug = models.SlugField(max_length=64)
bgneal@54:     icon = models.ImageField(upload_to='news/categories/', blank=True)
bgneal@1001:     forum_slug = models.CharField(
bgneal@1001:             max_length=80,
bgneal@1001:             default='',
bgneal@1001:             blank=True,
bgneal@1001:             help_text=("Identifies the forum to create comment threads in for "
bgneal@1001:                        "stories in this category. If blank, no comment threads "
bgneal@1001:                        "will be created for stories in this category."))
gremmie@1: 
bgneal@54:     def __unicode__(self):
bgneal@54:         return self.title
gremmie@1: 
bgneal@54:     def num_stories(self):
bgneal@987:         return Story.objects.filter(category=self.pk).count()
gremmie@1: 
bgneal@54:     class Meta:
bgneal@54:         verbose_name_plural = 'Categories'
bgneal@54:         ordering = ('title', )
gremmie@1: 
gremmie@1: 
bgneal@204: class StoryBase(models.Model):
bgneal@204:     """Abstract model to collect common fields."""
bgneal@54:     title = models.CharField(max_length=255)
bgneal@54:     submitter = models.ForeignKey(User)
bgneal@54:     category = models.ForeignKey(Category)
bgneal@999:     short_text = models.TextField(default='', blank=True)
bgneal@998:     long_text = models.TextField(default='', blank=True)
bgneal@204:     date_submitted = models.DateTimeField(db_index=True)
bgneal@54:     allow_comments = models.BooleanField(default=True)
bgneal@54:     tags = TagField()
bgneal@218:     front_page_expiration = models.DateField(null=True, blank=True)
bgneal@277:     update_date = models.DateTimeField(db_index=True, blank=True)
bgneal@462:     priority = models.IntegerField(db_index=True, default=0, blank=True)
bgneal@486:     meta_description = models.TextField(blank=True)
bgneal@1005:     short_markup = models.TextField(default='', blank=True)
bgneal@997:     long_markup = models.TextField(default='', blank=True)
bgneal@997:     admin_content = models.TextField(default='', blank=True)
bgneal@997:     version = models.SmallIntegerField(default=NEWS_VERSION)
gremmie@1: 
bgneal@204:     class Meta:
bgneal@204:         abstract = True
bgneal@204: 
bgneal@182:     def save(self, *args, **kwargs):
bgneal@204:         if not self.pk:
bgneal@997:             self.date_submitted = datetime.datetime.now()
bgneal@277:             self.update_date = self.date_submitted
bgneal@277:         else:
bgneal@277:             self.update_date = datetime.datetime.now()
bgneal@204: 
bgneal@1000:         if self.version >= 2:
bgneal@1000:             self.short_text = kwargs.pop('short_text', '')
bgneal@1000:             if not self.short_text and self.short_markup:
bgneal@1000:                 self.short_text = site_markup(self.short_markup)
bgneal@997: 
bgneal@1000:             self.long_text = kwargs.pop('long_text', '')
bgneal@1000:             if not self.long_text and self.long_markup:
bgneal@1000:                 self.long_text = site_markup(self.long_markup)
bgneal@997: 
bgneal@997:         super(StoryBase, self).save(*args, **kwargs)
bgneal@997: 
bgneal@997: 
bgneal@997: class PendingStory(StoryBase):
bgneal@997:     """Stories submitted by users are held pending admin approval"""
gremmie@1: 
bgneal@54:     def __unicode__(self):
bgneal@54:         return self.title
gremmie@1: 
bgneal@54:     class Meta:
bgneal@997:         ordering = ['-date_submitted']
bgneal@54:         verbose_name_plural = 'Pending Stories'
gremmie@1: 
gremmie@1: 
bgneal@204: class Story(StoryBase):
bgneal@54:     """Model for news stories"""
bgneal@1001:     forums_topic = models.OneToOneField('forums.Topic', blank=True, null=True,
bgneal@1001:                                         on_delete=models.SET_NULL,
bgneal@1001:                                         db_index=False,
bgneal@1001:                                         help_text="Forum topic used for comments")
gremmie@1: 
bgneal@54:     def get_absolute_url(self):
bgneal@1002:         return reverse('news-story', args=[str(self.id)])
gremmie@1: 
bgneal@54:     def __unicode__(self):
bgneal@54:         return self.title
gremmie@1: 
bgneal@54:     class Meta:
bgneal@997:         ordering = ['-date_submitted']
bgneal@226:         verbose_name = 'news story'
bgneal@226:         verbose_name_plural = 'news stories'
gremmie@1: 
bgneal@54:     def can_comment_on(self):
bgneal@1001:         # Only used for version 0 stories
bgneal@54:         now = datetime.datetime.now()
bgneal@204:         delta = now - self.date_submitted
bgneal@204:         return self.allow_comments and delta.days < 30
bgneal@220: 
bgneal@1001:     def forums_comment_count(self):
bgneal@1001:         """Returns number of comments for V2 news stories."""
bgneal@1001:         if self.forums_topic:
bgneal@1001:             return max(0, self.forums_topic.post_count - 1)
bgneal@1001:         return 0
bgneal@1001: 
bgneal@220:     def search_title(self):
bgneal@220:         return self.title
bgneal@220: 
bgneal@220:     def search_summary(self):
bgneal@220:         return u"\n".join((self.short_text, self.long_text))
bgneal@484: 
bgneal@484:     def ogp_tags(self):
bgneal@484:         """
bgneal@484:         Returns a dict of Open Graph Protocol meta tags.
bgneal@484: 
bgneal@484:         """
bgneal@486:         desc = self.meta_description.strip()
bgneal@486:         if not desc:
bgneal@486:             desc = 'News article submitted by %s on %s.' % (
bgneal@486:                     self.submitter.username,
bgneal@486:                     self.date_submitted.strftime('%B %d, %Y'))
bgneal@486: 
bgneal@484:         return {
bgneal@484:             'og:title': self.title,
bgneal@484:             'og:type': 'article',
bgneal@484:             'og:url': self.get_absolute_url(),
bgneal@484:             'og:image': self.category.icon.url,
bgneal@486:             'og:description': desc,
bgneal@484:         }