Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 245 lines (194 sloc) 7.878 kB
c35fd13 @peterbe form for adding new posts with markdown display format
authored
1 import time
2 import os
dd35852 @peterbe initial commit
authored
3 import uuid
4 import datetime
5 from django.db import models
62c0d0e @peterbe related search works
authored
6 from django.core.cache import cache
cbbd33a @peterbe admin, sitemaps and replies
authored
7 from django.db.models.signals import post_save, pre_save, pre_delete
d208cb1 @peterbe akismet and celery stuff
authored
8 from django.dispatch import receiver
c35fd13 @peterbe form for adding new posts with markdown display format
authored
9 from django.conf import settings
6bae2ca @peterbe static image content
authored
10 from . import utils
dd35852 @peterbe initial commit
authored
11
12
13 class ArrayField(models.CharField):
14
15 __metaclass__ = models.SubfieldBase
16 description = "basic field for storing string arrays"
17
18 def __init__(self, *args, **kwargs):
19 kwargs['max_length'] = kwargs.get('max_length', 200)
20 super(ArrayField, self).__init__(*args, **kwargs)
21
22 def to_python(self, value):
23 if isinstance(value, list):
24 return value
25
26 return value.split('|')
27
28 def get_prep_value(self, value):
29 return '|'.join(value)
30
31
32 class Category(models.Model):
33 name = models.CharField(max_length=100)
34
35 def __repr__(self):
36 return '<%s: %r>' % (self.__class__.__name__, self.name)
37
cbbd33a @peterbe admin, sitemaps and replies
authored
38 def __unicode__(self):
39 return self.name
40
dd35852 @peterbe initial commit
authored
41
42 class BlogItem(models.Model):
15d474e @peterbe adding basic search
authored
43 """
44 Indexes executed for this:
45
46 CREATE INDEX plog_blogitem_text_eng_idx ON plog_blogitem
47 USING gin(to_tsvector('english', text));
48
49 CREATE INDEX plog_blogitem_title_eng_idx ON plog_blogitem
50 USING gin(to_tsvector('english', title));
51
52 REINDEX TABLE plog_blogitem;
53
54
55 """
dd35852 @peterbe initial commit
authored
56 oid = models.CharField(max_length=100, db_index=True)
57 title = models.CharField(max_length=200)
58 alias = models.CharField(max_length=200, null=True)
59 bookmark = models.BooleanField(default=False)
60 text = models.TextField()
61 text_rendered = models.TextField(blank=True)
62 summary = models.TextField()
63 url = models.URLField(null=True)
cbbd33a @peterbe admin, sitemaps and replies
authored
64 pub_date = models.DateTimeField(db_index=True)
dd35852 @peterbe initial commit
authored
65 display_format = models.CharField(max_length=20)
66 categories = models.ManyToManyField(Category)
67 keywords = ArrayField(max_length=500)
68 plogrank = models.FloatField(null=True)
69 codesyntax = models.CharField(max_length=20, blank=True)
ff52fe7 @peterbe ability to hide comments and stuff
authored
70 disallow_comments = models.BooleanField(default=False)
71 hide_comments = models.BooleanField(default=False)
6bae2ca @peterbe static image content
authored
72 modify_date = models.DateTimeField(default=utils.utc_now)
dd35852 @peterbe initial commit
authored
73
74 def __repr__(self):
75 return '<%s: %r>' % (self.__class__.__name__, self.oid)
76
4d11c8b @peterbe adding feed and upgrading bootstrap css
authored
77 @models.permalink
78 def get_absolute_url(self):
79 return ('blog_post', [self.oid])
80
81 @property
82 def rendered(self):
6bae2ca @peterbe static image content
authored
83 return self._render()
84
85 def _render(self, refresh=False):
86 if not self.text_rendered or refresh:
4d11c8b @peterbe adding feed and upgrading bootstrap css
authored
87 if self.display_format == 'structuredtext':
6bae2ca @peterbe static image content
authored
88 self.text_rendered = utils.stx_to_html(self.text, self.codesyntax)
4d11c8b @peterbe adding feed and upgrading bootstrap css
authored
89 else:
c35fd13 @peterbe form for adding new posts with markdown display format
authored
90 self.text_rendered = utils.markdown_to_html(self.text, self.codesyntax)
6bae2ca @peterbe static image content
authored
91 self.text_rendered = utils.cache_prefix_files(self.text_rendered)
4d11c8b @peterbe adding feed and upgrading bootstrap css
authored
92 self.save()
93 return self.text_rendered
94
62c0d0e @peterbe related search works
authored
95 def count_comments(self):
96 cache_key = 'nocomments:%s' % self.pk
97 count = cache.get(cache_key)
98 if count is None:
99 count = self._count_comments()
100 cache.set(cache_key, count, 60 * 60 * 24)
101 return count
102
103 def _count_comments(self):
cbbd33a @peterbe admin, sitemaps and replies
authored
104 return BlogComment.objects.filter(blogitem=self, approved=True).count()
105
106 def __unicode__(self):
107 return self.title
62c0d0e @peterbe related search works
authored
108
dd35852 @peterbe initial commit
authored
109
110 class BlogComment(models.Model):
15d474e @peterbe adding basic search
authored
111 """
112 Indexes executed for this:
113
114 CREATE INDEX plog_blogcomment_comment_eng_idx ON plog_blogcomment
115 USING gin(to_tsvector('english', comment));
116
117 REINDEX TABLE plog_blogcomment;
118
119 """
120
dd35852 @peterbe initial commit
authored
121 oid = models.CharField(max_length=100, db_index=True)
122 blogitem = models.ForeignKey(BlogItem, null=True)
123 parent = models.ForeignKey('BlogComment', null=True)
124 approved = models.BooleanField(default=False)
125 comment = models.TextField()
126 comment_rendered = models.TextField(blank=True, null=True)
6bae2ca @peterbe static image content
authored
127 add_date = models.DateTimeField(default=utils.utc_now)
dd35852 @peterbe initial commit
authored
128 name = models.CharField(max_length=100, blank=True)
129 email = models.CharField(max_length=100, blank=True)
d208cb1 @peterbe akismet and celery stuff
authored
130 user_agent = models.CharField(max_length=300, blank=True, null=True)
131 ip_address = models.IPAddressField(blank=True, null=True)
132 akismet_pass = models.NullBooleanField(null=True)
dd35852 @peterbe initial commit
authored
133
cbbd33a @peterbe admin, sitemaps and replies
authored
134 def __repr__(self):
135 return ('<%s: %r (%sapproved)>' %
136 (self.__class__.__name__, self.oid + ' ' +self.comment[:20],
137 self.approved and '' or 'not '))
138
dd35852 @peterbe initial commit
authored
139 @property
140 def rendered(self):
141 if not self.comment_rendered:
6bae2ca @peterbe static image content
authored
142 self.comment_rendered = utils.render_comment_text(self.comment)
dd35852 @peterbe initial commit
authored
143 self.save()
144 return self.comment_rendered
145
146 @classmethod
147 def next_oid(cls):
148 return 'c' + uuid.uuid4().hex[:6]
15d474e @peterbe adding basic search
authored
149
150 def get_absolute_url(self):
151 return self.blogitem.get_absolute_url() + '#%s' % self.oid
152
153 def correct_blogitem_parent(self):
154 assert self.blogitem is None
155 if self.parent.blogitem is None:
156 self.parent.correct_blogitem_parent()
157 self.blogitem = self.parent.blogitem
158 self.save()
62c0d0e @peterbe related search works
authored
159
160
c35fd13 @peterbe form for adding new posts with markdown display format
authored
161 def _uploader_dir(instance, filename):
162 def fp(filename):
163 return os.path.join('peterbecom/static',
164 'plog',
165 instance.blogitem.oid,
166 filename)
167 a, b = os.path.splitext(filename)
168 filename = '%s.%s%s' % (a, int(time.time()), b)
169 return fp(filename)
170
171
172 class BlogFile(models.Model):
173 blogitem = models.ForeignKey(BlogItem)
174 file = models.FileField(upload_to=_uploader_dir)
175 add_date = models.DateTimeField(default=utils.utc_now)
176 modify_date = models.DateTimeField(default=utils.utc_now)
177
178 def __repr__(self):
179 return '<%s: %r>' % (self.__class__.__name__, self.blogitem.oid)
180
181
cbbd33a @peterbe admin, sitemaps and replies
authored
182 @receiver(pre_delete, sender=BlogComment)
62c0d0e @peterbe related search works
authored
183 @receiver(post_save, sender=BlogComment)
184 @receiver(post_save, sender=BlogItem)
185 def invalidate_blogitem_comment_count(sender, instance, **kwargs):
186 if sender is BlogItem:
187 pk = instance.pk
188 elif sender is BlogComment:
189 if instance.blogitem is None:
7a826dc @peterbe adding new-comments feature
authored
190 if not instance.parent: # legacy
191 return
62c0d0e @peterbe related search works
authored
192 instance.correct_blogitem_parent() # legacy
cbbd33a @peterbe admin, sitemaps and replies
authored
193 pk = instance.blogitem_id
62c0d0e @peterbe related search works
authored
194 else:
195 raise NotImplementedError(sender)
196 cache_key = 'nocomments:%s' % pk
197 cache.delete(cache_key)
cbbd33a @peterbe admin, sitemaps and replies
authored
198
199
e7c1f02 @peterbe caching works for the home page
authored
200 #@receiver(pre_delete, sender=BlogComment)
201 @receiver(post_save, sender=BlogComment)
202 @receiver(post_save, sender=BlogItem)
203 def invalidate_latest_comment_add_dates(sender, instance, **kwargs):
204 cache_key = 'latest_comment_add_date'
205 cache.delete(cache_key)
206
207 if sender is BlogItem:
208 pk = instance.pk
209 elif sender is BlogComment:
210 if instance.blogitem is None:
211 instance.correct_blogitem_parent() # legacy
212 pk = instance.blogitem_id
213 else:
214 raise NotImplementedError(sender)
215 cache_key = 'latest_comment_add_date:%s' % pk
216 cache.delete(cache_key)
217
218
219 @receiver(post_save, sender=BlogComment)
220 @receiver(post_save, sender=BlogItem)
221 def invalidate_latest_comment_add_date_by_oid(sender, instance, **kwargs):
222 if sender is BlogItem:
223 oid = instance.oid
224 elif sender is BlogComment:
225 oid = instance.blogitem.oid
226 else:
227 raise NotImplementedError(sender)
228 cache_key = 'latest_comment_add_date:%s' % oid
229 cache.delete(cache_key)
230
231
c35fd13 @peterbe form for adding new posts with markdown display format
authored
232 @receiver(pre_save, sender=BlogFile)
cbbd33a @peterbe admin, sitemaps and replies
authored
233 @receiver(pre_save, sender=BlogComment)
234 @receiver(pre_save, sender=BlogItem)
235 def update_modify_date(sender, instance, **kwargs):
236 if getattr(instance, '_modify_date_set', False):
237 return
c35fd13 @peterbe form for adding new posts with markdown display format
authored
238 if sender is BlogItem or sender is BlogFile:
6bae2ca @peterbe static image content
authored
239 instance.modify_date = utils.utc_now()
cbbd33a @peterbe admin, sitemaps and replies
authored
240 elif sender is BlogComment:
241 if instance.blogitem:
6bae2ca @peterbe static image content
authored
242 instance.blogitem.modify_date = utils.utc_now()
cbbd33a @peterbe admin, sitemaps and replies
authored
243 else:
244 raise NotImplementedError(sender)
Something went wrong with that request. Please try again.