3456c9177eaf492e83c4493110424cfa4748cc50
[philo.git] / contrib / penfield / models.py
1 from django.db import models
2 from django.conf import settings
3 from philo.models import Tag, Titled, Entity, MultiView, Page, register_value_model
4 from django.conf.urls.defaults import url, patterns
5 from django.http import Http404, HttpResponse
6 from datetime import datetime
7
8
9 class Blog(Entity, Titled):
10         @property
11         def entry_tags(self):
12                 """ Returns a QuerySet of Tags that are used on any entries in this blog. """
13                 return Tag.objects.filter(blogentries__blog=self)
14
15
16 class BlogEntry(Entity, Titled):
17         blog = models.ForeignKey(Blog, related_name='entries')
18         author = models.ForeignKey(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='blogentries')
19         date = models.DateTimeField(default=datetime.now)
20         content = models.TextField()
21         excerpt = models.TextField()
22         tags = models.ManyToManyField(Tag, related_name='blogentries')
23         
24         class Meta:
25                 ordering = ['-date']
26                 verbose_name_plural = "blog entries"
27
28
29 register_value_model(BlogEntry)
30
31
32 class BlogView(MultiView):
33         ENTRY_PERMALINK_STYLE_CHOICES = (
34                 ('D', 'Year, month, and day'),
35                 ('M', 'Year and month'),
36                 ('Y', 'Year'),
37                 ('B', 'Custom base'),
38                 ('N', 'No base')
39         )
40         
41         blog = models.ForeignKey(Blog, related_name='blogviews')
42         
43         index_page = models.ForeignKey(Page, related_name='blog_index_related')
44         entry_page = models.ForeignKey(Page, related_name='blog_entry_related')
45         entry_archive_page = models.ForeignKey(Page, related_name='blog_entry_archive_related', null=True, blank=True)
46         tag_page = models.ForeignKey(Page, related_name='blog_tag_related')
47         tag_archive_page = models.ForeignKey(Page, related_name='blog_tag_archive_related', null=True, blank=True)
48         
49         entry_permalink_style = models.CharField(max_length=1, choices=ENTRY_PERMALINK_STYLE_CHOICES)
50         entry_permalink_base = models.CharField(max_length=255, blank=False, default='entries')
51         tag_permalink_base = models.CharField(max_length=255, blank=False, default='tags')
52         
53         @property
54         def urlpatterns(self):
55                 base_patterns = patterns('',
56                         url(r'^$', self.index_view),
57                         url((r'^(?:%s)/?$' % self.tag_permalink_base), self.tag_archive_view),
58                         url((r'^(?:%s)/(?P<tag>[-\w]+)/?$' % self.tag_permalink_base), self.tag_view)
59                 )
60                 if self.entry_permalink_style == 'D':
61                         entry_patterns = patterns('',
62                                 url(r'^(?P<year>\d{4})/?$', self.entry_archive_view),
63                                 url(r'^(?P<year>\d{4})/(?P<month>\d{2})/?$', self.entry_archive_view),
64                                 url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/?$', self.entry_archive_view),
65                                 url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[-\w]+)/?$', self.entry_view)
66                         )
67                 elif self.entry_permalink_style == 'M':
68                         entry_patterns = patterns('',
69                                 url(r'^(?P<year>\d{4})/?$', self.entry_archive_view),
70                                 url(r'^(?P<year>\d{4})/(?P<month>\d{2})/?$', self.entry_archive_view),
71                                 url(r'^(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)/?$', self.entry_view)
72                         )
73                 elif self.entry_permalink_style == 'Y':
74                         entry_patterns = patterns('',
75                                 url(r'^(?P<year>\d{4})/?$', self.entry_archive_view),
76                                 url(r'^(?P<year>\d{4})/(?P<slug>[-\w]+)/?$', self.entry_view)
77                         )
78                 elif self.entry_permalink_style == 'B':
79                         entry_patterns = patterns('',
80                                 url((r'^(?:%s)/?$' % self.entry_permalink_base), self.entry_archive_view),
81                                 url((r'^(?:%s)/(?P<slug>[-\w]+)/?$' % self.entry_permalink_base), self.entry_view)
82                         )
83                 else:
84                         entry_patterns = patterns('',
85                                 url(r'^(?P<slug>[-\w]+)/?$', self.entry_view)
86                         )
87                 return base_patterns + entry_patterns
88         
89         def index_view(self, request, node=None, extra_context=None):
90                 context = {}
91                 context.update(extra_context or {})
92                 context.update({'blog': self.blog})
93                 return self.index_page.render_to_response(node, request, extra_context=context)
94         
95         def entry_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None):
96                 entries = self.blog.entries.all()
97                 if year:
98                         entries = entries.filter(date__year=year)
99                 if month:
100                         entries = entries.filter(date__month=month)
101                 if day:
102                         entries = entries.filter(date__day=day)
103                 try:
104                         entry = entries.get(slug=slug)
105                 except:
106                         raise Http404
107                 context = {}
108                 context.update(extra_context or {})
109                 context.update({'blog': self.blog, 'entry': entry})
110                 return self.entry_page.render_to_response(node, request, extra_context=context)
111         
112         def entry_archive_view(self, request, year=None, month=None, day=None, node=None, extra_context=None):
113                 if not self.entry_archive_page:
114                         raise Http404
115                 entries = self.blog.entries.all()
116                 if year:
117                         entries = entries.filter(date__year=year)
118                 if month:
119                         entries = entries.filter(date__month=month)
120                 if day:
121                         entries = entries.filter(date__day=day)
122                 context = {}
123                 context.update(extra_context or {})
124                 context.update({'blog': self.blog, 'year': year, 'month': month, 'day': day, 'entries': entries})
125                 return self.entry_archive_page.render_to_response(node, request, extra_context=context)
126         
127         def tag_view(self, request, tag, node=None, extra_context=None):
128                 try:
129                         tag = self.blog.entry_tags.filter(slug=tag)
130                 except:
131                         raise Http404
132                 entries = self.blog.entries.filter(tags=tag)
133                 context = {}
134                 context.update(extra_context or {})
135                 context.update({'blog': self.blog, 'tag': tag, 'entries': entries})
136                 return self.tag_page.render_to_response(node, request, extra_context=context)
137         
138         def tag_archive_view(self, request, node=None, extra_context=None):
139                 if not self.tag_archive_page:
140                         raise Http404
141                 context = {}
142                 context.update(extra_context or {})
143                 context.update({'blog': self.blog})
144                 return self.tag_archive_page.render_to_response(node, request, extra_context=context)
145
146
147 class Newsletter(Entity, Titled):
148         pass
149
150
151 class NewsletterArticle(Entity, Titled):
152         newsletter = models.ForeignKey(Newsletter, related_name='articles')
153         authors = models.ManyToManyField(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='newsletterarticles')
154         date = models.DateTimeField(default=datetime.now)
155         lede = models.TextField(null=True, blank=True)
156         full_text = models.TextField()
157
158
159 register_value_model(NewsletterArticle)
160
161
162 class NewsletterIssue(Entity, Titled):
163         newsletter = models.ForeignKey(Newsletter, related_name='issues')
164         number = models.PositiveIntegerField()
165         articles = models.ManyToManyField(NewsletterArticle)
166
167
168 class NewsletterView(MultiView):
169         ARTICLE_PERMALINK_STYLE_CHOICES = (
170                 ('D', 'Year, month, and day'),
171                 ('M', 'Year and month'),
172                 ('Y', 'Year'),
173                 ('S', 'Slug only')
174         )
175         
176         newsletter = models.ForeignKey(Newsletter, related_name='newsletterviews')
177         
178         index_page = models.ForeignKey(Page, related_name='newsletter_index_related')
179         article_page = models.ForeignKey(Page, related_name='newsletter_article_related')
180         article_archive_page = models.ForeignKey(Page, related_name='newsletter_article_archive_related', null=True, blank=True)
181         issue_page = models.ForeignKey(Page, related_name='newsletter_issue_related')
182         issue_archive_page = models.ForeignKey(Page, related_name='newsletter_issue_archive_related', null=True, blank=True)
183         
184         article_permalink_style = models.CharField(max_length=1, choices=ARTICLE_PERMALINK_STYLE_CHOICES)
185         article_permalink_base = models.CharField(max_length=255, blank=False, default='articles')
186         issue_permalink_base = models.CharField(max_length=255, blank=False, default='issues')
187         
188         @property
189         def urlpatterns(self):
190                 base_patterns = patterns('',
191                         url(r'^$', self.index_view),
192                         url((r'^(?:%s)/?$' % self.issue_permalink_base), self.issue_archive_view),
193                         url((r'^(?:%s)/(?P<number>\d+)/?$' % self.issue_permalink_base), self.issue_view)
194                 )
195                 article_patterns = patterns('',
196                         url((r'^(?:%s)/?$' % self.article_permalink_base), self.article_archive_view)
197                 )
198                 if self.article_permalink_style in 'DMY':
199                         article_patterns += patterns('',
200                                 url((r'^(?:%s)/(?P<year>\d{4})/?$' % self.article_permalink_base), self.article_archive_view)
201                         )
202                         if self.article_permalink_style in 'DM':
203                                 article_patterns += patterns('',
204                                         url((r'^(?:%s)/(?P<year>\d{4})/(?P<month>\d{2})/?$' % self.article_permalink_base), self.article_archive_view)
205                                 )
206                                 if self.article_permalink_style == 'D':
207                                         article_patterns += patterns('',
208                                                 url((r'^(?:%s)/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/?$' % self.article_permalink_base), self.article_archive_view),
209                                                 url((r'^(?:%s)/(?P<year>\d{4})/(?P<month>\d{2})/(?P<day>\d{2})/(?P<slug>[-\w]+)/?$' % self.article_permalink_base), self.article_view)
210                                         )
211                                 else:
212                                         article_patterns += patterns('',
213                                                 url((r'^(?:%s)/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[-\w]+)/?$' % self.article_permalink_base), self.article_view)
214                                         )
215                         else:
216                                 article_patterns += patterns('',
217                                         url((r'^(?:%s)/(?P<year>\d{4})/(?P<slug>[-\w]+)/?$' % self.article_permalink_base), self.article_view)
218                                 )
219                 else:
220                         article_patterns += patterns('',
221                                 url((r'^(?:%s)/(?P<slug>[-\w]+)/?$' % self.article_permalink_base), self.article_view)
222                         )
223                 return base_patterns + article_patterns
224         
225         def index_view(self, request, node=None, extra_context=None):
226                 context = {}
227                 context.update(extra_context or {})
228                 context.update({'newsletter': self.newsletter})
229                 return self.index_page.render_to_response(node, request, extra_context=context)
230         
231         def article_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None):
232                 articles = self.newsletter.articles.all()
233                 if year:
234                         articles = articles.filter(date__year=year)
235                 if month:
236                         articles = articles.filter(date__month=month)
237                 if day:
238                         articles = articles.filter(date__day=day)
239                 try:
240                         article = articles.get(slug=slug)
241                 except:
242                         raise Http404
243                 context = {}
244                 context.update(extra_context or {})
245                 context.update({'newsletter': self.newsletter, 'article': article})
246                 return self.article_page.render_to_response(node, request, extra_context=context)
247         
248         def article_archive_view(self, request, year=None, month=None, day=None, node=None, extra_context=None):
249                 if not self.article_archive_page:
250                         raise Http404
251                 articles = self.newsletter.articles.all()
252                 if year:
253                         articles = articles.filter(date__year=year)
254                 if month:
255                         articles = articles.filter(date__month=month)
256                 if day:
257                         articles = articles.filter(date__day=day)
258                 context = {}
259                 context.update(extra_context or {})
260                 context.update({'newsletter': self.newsletter, 'year': year, 'month': month, 'day': day, 'articles': articles})
261                 return self.article_archive_page.render_to_response(node, request, extra_context=context)
262         
263         def issue_view(self, request, number, node=None, extra_context=None):
264                 try:
265                         issue = self.newsletter.issues.get(number=number)
266                 except:
267                         raise Http404
268                 context = {}
269                 context.update(extra_context or {})
270                 context.update({'newsletter': self.newsletter, 'issue': issue})
271                 return self.issue_page.render_to_response(node, request, extra_context=context)
272         
273         def issue_archive_view(self, request, node=None, extra_context=None):
274                 if not self.issue_archive_page:
275                         raise Http404
276                 context = {}
277                 context.update(extra_context or {})
278                 context.update({'newsletter': self.newsletter})
279                 return self.issue_archive_page.render_to_response(node, request, extra_context=context)