gremmie@1
|
1 """
|
gremmie@1
|
2 Models for the news application.
|
gremmie@1
|
3 """
|
bgneal@997
|
4 import datetime
|
gremmie@1
|
5
|
bgneal@1002
|
6 from django.core.urlresolvers import reverse
|
gremmie@1
|
7 from django.db import models
|
bgneal@49
|
8 from django.contrib.auth.models import User
|
gremmie@1
|
9 from tagging.fields import TagField
|
gremmie@1
|
10
|
bgneal@997
|
11 from core.markup import site_markup
|
bgneal@997
|
12
|
bgneal@997
|
13
|
bgneal@997
|
14 # News App versions
|
bgneal@997
|
15 NEWS_VERSION = 2
|
bgneal@997
|
16
|
gremmie@1
|
17
|
gremmie@1
|
18 class Category(models.Model):
|
bgneal@54
|
19 """News stories belong to categories"""
|
bgneal@240
|
20 title = models.CharField(max_length=64)
|
bgneal@240
|
21 slug = models.SlugField(max_length=64)
|
bgneal@54
|
22 icon = models.ImageField(upload_to='news/categories/', blank=True)
|
bgneal@1001
|
23 forum_slug = models.CharField(
|
bgneal@1001
|
24 max_length=80,
|
bgneal@1001
|
25 default='',
|
bgneal@1001
|
26 blank=True,
|
bgneal@1001
|
27 help_text=("Identifies the forum to create comment threads in for "
|
bgneal@1001
|
28 "stories in this category. If blank, no comment threads "
|
bgneal@1001
|
29 "will be created for stories in this category."))
|
gremmie@1
|
30
|
bgneal@54
|
31 def __unicode__(self):
|
bgneal@54
|
32 return self.title
|
gremmie@1
|
33
|
bgneal@54
|
34 def num_stories(self):
|
bgneal@987
|
35 return Story.objects.filter(category=self.pk).count()
|
gremmie@1
|
36
|
bgneal@54
|
37 class Meta:
|
bgneal@54
|
38 verbose_name_plural = 'Categories'
|
bgneal@54
|
39 ordering = ('title', )
|
gremmie@1
|
40
|
gremmie@1
|
41
|
bgneal@204
|
42 class StoryBase(models.Model):
|
bgneal@204
|
43 """Abstract model to collect common fields."""
|
bgneal@54
|
44 title = models.CharField(max_length=255)
|
bgneal@54
|
45 submitter = models.ForeignKey(User)
|
bgneal@54
|
46 category = models.ForeignKey(Category)
|
bgneal@999
|
47 short_text = models.TextField(default='', blank=True)
|
bgneal@998
|
48 long_text = models.TextField(default='', blank=True)
|
bgneal@204
|
49 date_submitted = models.DateTimeField(db_index=True)
|
bgneal@54
|
50 allow_comments = models.BooleanField(default=True)
|
bgneal@54
|
51 tags = TagField()
|
bgneal@218
|
52 front_page_expiration = models.DateField(null=True, blank=True)
|
bgneal@277
|
53 update_date = models.DateTimeField(db_index=True, blank=True)
|
bgneal@462
|
54 priority = models.IntegerField(db_index=True, default=0, blank=True)
|
bgneal@486
|
55 meta_description = models.TextField(blank=True)
|
bgneal@997
|
56 short_markup = models.TextField(default='')
|
bgneal@997
|
57 long_markup = models.TextField(default='', blank=True)
|
bgneal@997
|
58 admin_content = models.TextField(default='', blank=True)
|
bgneal@997
|
59 version = models.SmallIntegerField(default=NEWS_VERSION)
|
gremmie@1
|
60
|
bgneal@204
|
61 class Meta:
|
bgneal@204
|
62 abstract = True
|
bgneal@204
|
63
|
bgneal@182
|
64 def save(self, *args, **kwargs):
|
bgneal@204
|
65 if not self.pk:
|
bgneal@997
|
66 self.date_submitted = datetime.datetime.now()
|
bgneal@277
|
67 self.update_date = self.date_submitted
|
bgneal@277
|
68 else:
|
bgneal@277
|
69 self.update_date = datetime.datetime.now()
|
bgneal@204
|
70
|
bgneal@1000
|
71 if self.version >= 2:
|
bgneal@1000
|
72 self.short_text = kwargs.pop('short_text', '')
|
bgneal@1000
|
73 if not self.short_text and self.short_markup:
|
bgneal@1000
|
74 self.short_text = site_markup(self.short_markup)
|
bgneal@997
|
75
|
bgneal@1000
|
76 self.long_text = kwargs.pop('long_text', '')
|
bgneal@1000
|
77 if not self.long_text and self.long_markup:
|
bgneal@1000
|
78 self.long_text = site_markup(self.long_markup)
|
bgneal@997
|
79
|
bgneal@997
|
80 super(StoryBase, self).save(*args, **kwargs)
|
bgneal@997
|
81
|
bgneal@997
|
82
|
bgneal@997
|
83 class PendingStory(StoryBase):
|
bgneal@997
|
84 """Stories submitted by users are held pending admin approval"""
|
gremmie@1
|
85
|
bgneal@54
|
86 def __unicode__(self):
|
bgneal@54
|
87 return self.title
|
gremmie@1
|
88
|
bgneal@54
|
89 class Meta:
|
bgneal@997
|
90 ordering = ['-date_submitted']
|
bgneal@54
|
91 verbose_name_plural = 'Pending Stories'
|
gremmie@1
|
92
|
gremmie@1
|
93
|
bgneal@204
|
94 class Story(StoryBase):
|
bgneal@54
|
95 """Model for news stories"""
|
bgneal@1001
|
96 forums_topic = models.OneToOneField('forums.Topic', blank=True, null=True,
|
bgneal@1001
|
97 on_delete=models.SET_NULL,
|
bgneal@1001
|
98 db_index=False,
|
bgneal@1001
|
99 help_text="Forum topic used for comments")
|
gremmie@1
|
100
|
bgneal@54
|
101 def get_absolute_url(self):
|
bgneal@1002
|
102 return reverse('news-story', args=[str(self.id)])
|
gremmie@1
|
103
|
bgneal@54
|
104 def __unicode__(self):
|
bgneal@54
|
105 return self.title
|
gremmie@1
|
106
|
bgneal@54
|
107 class Meta:
|
bgneal@997
|
108 ordering = ['-date_submitted']
|
bgneal@226
|
109 verbose_name = 'news story'
|
bgneal@226
|
110 verbose_name_plural = 'news stories'
|
gremmie@1
|
111
|
bgneal@54
|
112 def can_comment_on(self):
|
bgneal@1001
|
113 # Only used for version 0 stories
|
bgneal@54
|
114 now = datetime.datetime.now()
|
bgneal@204
|
115 delta = now - self.date_submitted
|
bgneal@204
|
116 return self.allow_comments and delta.days < 30
|
bgneal@220
|
117
|
bgneal@1001
|
118 def forums_comment_count(self):
|
bgneal@1001
|
119 """Returns number of comments for V2 news stories."""
|
bgneal@1001
|
120 if self.forums_topic:
|
bgneal@1001
|
121 return max(0, self.forums_topic.post_count - 1)
|
bgneal@1001
|
122 return 0
|
bgneal@1001
|
123
|
bgneal@220
|
124 def search_title(self):
|
bgneal@220
|
125 return self.title
|
bgneal@220
|
126
|
bgneal@220
|
127 def search_summary(self):
|
bgneal@220
|
128 return u"\n".join((self.short_text, self.long_text))
|
bgneal@484
|
129
|
bgneal@484
|
130 def ogp_tags(self):
|
bgneal@484
|
131 """
|
bgneal@484
|
132 Returns a dict of Open Graph Protocol meta tags.
|
bgneal@484
|
133
|
bgneal@484
|
134 """
|
bgneal@486
|
135 desc = self.meta_description.strip()
|
bgneal@486
|
136 if not desc:
|
bgneal@486
|
137 desc = 'News article submitted by %s on %s.' % (
|
bgneal@486
|
138 self.submitter.username,
|
bgneal@486
|
139 self.date_submitted.strftime('%B %d, %Y'))
|
bgneal@486
|
140
|
bgneal@484
|
141 return {
|
bgneal@484
|
142 'og:title': self.title,
|
bgneal@484
|
143 'og:type': 'article',
|
bgneal@484
|
144 'og:url': self.get_absolute_url(),
|
bgneal@484
|
145 'og:image': self.category.icon.url,
|
bgneal@486
|
146 'og:description': desc,
|
bgneal@484
|
147 }
|