X-Git-Url: http://git.ithinksw.org/philo.git/blobdiff_plain/2380185d894e5a62a20b91a0c5a3a48497fb3cfb..6523713debf3076d8bac93e3262bc589faee286d:/contrib/penfield/models.py?ds=inline diff --git a/contrib/penfield/models.py b/contrib/penfield/models.py index 7da8e08..e433b84 100644 --- a/contrib/penfield/models.py +++ b/contrib/penfield/models.py @@ -2,12 +2,14 @@ from django.db import models from django.conf import settings from philo.models import Tag, Titled, Entity, MultiView, Page, register_value_model from philo.exceptions import ViewCanNotProvideSubpath -from django.conf.urls.defaults import url, patterns +from django.conf.urls.defaults import url, patterns, include from django.core.urlresolvers import reverse -from django.http import Http404, HttpResponse +from django.http import Http404 from datetime import datetime -from philo.contrib.penfield.utils import paginate +from philo.utils import paginate from philo.contrib.penfield.validators import validate_pagination_count +from django.utils.feedgenerator import Atom1Feed, Rss201rev2Feed +from philo.contrib.penfield.utils import FeedMultiViewMixin class Blog(Entity, Titled): @@ -15,13 +17,18 @@ class Blog(Entity, Titled): def entry_tags(self): """ Returns a QuerySet of Tags that are used on any entries in this blog. """ return Tag.objects.filter(blogentries__blog=self).distinct() + + @property + def entry_dates(self): + dates = {'year': self.entries.dates('date', 'year', order='DESC'), 'month': self.entries.dates('date', 'month', order='DESC'), 'day': self.entries.dates('date', 'day', order='DESC')} + return dates register_value_model(Blog) class BlogEntry(Entity, Titled): - blog = models.ForeignKey(Blog, related_name='entries') + blog = models.ForeignKey(Blog, related_name='entries', blank=True, null=True) author = models.ForeignKey(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='blogentries') date = models.DateTimeField(default=datetime.now) content = models.TextField() @@ -36,7 +43,7 @@ class BlogEntry(Entity, Titled): register_value_model(BlogEntry) -class BlogView(MultiView): +class BlogView(MultiView, FeedMultiViewMixin): ENTRY_PERMALINK_STYLE_CHOICES = ( ('D', 'Year, month, and day'), ('M', 'Year and month'), @@ -57,92 +64,105 @@ class BlogView(MultiView): entry_permalink_style = models.CharField(max_length=1, choices=ENTRY_PERMALINK_STYLE_CHOICES) entry_permalink_base = models.CharField(max_length=255, blank=False, default='entries') tag_permalink_base = models.CharField(max_length=255, blank=False, default='tags') + feed_suffix = models.CharField(max_length=255, blank=False, default=FeedMultiViewMixin.feed_suffix) + feeds_enabled = models.BooleanField() def __unicode__(self): return u'BlogView for %s' % self.blog.title + @property + def per_page(self): + return self.entries_per_page + + @property + def feed_title(self): + return self.blog.title + def get_subpath(self, obj): if isinstance(obj, BlogEntry): if obj.blog == self.blog: - entry_view_args = {'slug': obj.slug} + kwargs = {'slug': obj.slug} if self.entry_permalink_style in 'DMY': - entry_view_args.update({'year': str(obj.date.year).zfill(4)}) + kwargs.update({'year': str(obj.date.year).zfill(4)}) if self.entry_permalink_style in 'DM': - entry_view_args.update({'month': str(obj.date.month).zfill(2)}) + kwargs.update({'month': str(obj.date.month).zfill(2)}) if self.entry_permalink_style == 'D': - entry_view_args.update({'day': str(obj.date.day).zfill(2)}) - return reverse(self.entry_view, urlconf=self, kwargs=entry_view_args) + kwargs.update({'day': str(obj.date.day).zfill(2)}) + return reverse(self.entry_view, urlconf=self, kwargs=kwargs) elif isinstance(obj, Tag): if obj in self.blog.entry_tags: - return reverse(self.tag_view, urlconf=self, kwargs={'tag_slugs': obj.slug}) + return reverse('entries_by_tag', urlconf=self, kwargs={'tag_slugs': obj.slug}) + elif isinstance(obj, (str, unicode)): + split_obj = obj.split(':') + if len(split_obj) > 1: + kwargs = {} + try: + kwargs.update({'year': str(int(split_obj[1])).zfill(4)}) + if len(split_obj) > 2: + kwargs.update({'month': str(int(split_obj[2])).zfill(2)}) + if len(split_obj) > 3: + kwargs.update({'day': str(int(split_obj[3])).zfill(2)}) + return reverse('entries_by_day', urlconf=self, kwargs=kwargs) + return reverse('entries_by_month', urlconf=self, kwargs=kwargs) + return reverse('entries_by_year', urlconf=self, kwargs=kwargs) + except: + pass raise ViewCanNotProvideSubpath + def get_context(self): + return {'blog': self.blog} + @property def urlpatterns(self): - base_patterns = patterns('', - url(r'^$', self.index_view), - url((r'^(?:%s)/?$' % self.tag_permalink_base), self.tag_archive_view), - url((r'^(?:%s)/(?P[-\w]+[-+/\w]*)/?$' % self.tag_permalink_base), self.tag_view) + urlpatterns = patterns('', + url(r'^', include(self.feed_patterns(self.get_all_entries, self.index_page, 'index'))), + url((r'^(?:%s)/(?P[-\w]+[-+/\w]*)/' % self.tag_permalink_base), include(self.feed_patterns(self.get_entries_by_tag, self.tag_page, 'entries_by_tag'))) ) + if self.tag_archive_page: + urlpatterns += patterns('', + url((r'^(?:%s)/?$' % self.tag_permalink_base), self.tag_archive_view) + ) + + if self.entry_archive_page: + if self.entry_permalink_style in 'DMY': + urlpatterns += patterns('', + url(r'^(?P\d{4})/', include(self.feed_patterns(self.get_entries_by_ymd, self.entry_archive_page, 'entries_by_year'))) + ) + if self.entry_permalink_style in 'DM': + urlpatterns += patterns('', + url(r'^(?P\d{4})/(?P\d{2})/?$', include(self.feed_patterns(self.get_entries_by_ymd, self.entry_archive_page, 'entries_by_month'))), + ) + if self.entry_permalink_style == 'D': + urlpatterns += patterns('', + url(r'^(?P\d{4})/(?P\d{2})/(?P\d{2})/?$', include(self.feed_patterns(self.get_entries_by_ymd, self.entry_archive_page, 'entries_by_day'))) + ) + if self.entry_permalink_style == 'D': - entry_patterns = patterns('', - url(r'^(?P\d{4})/?$', self.entry_archive_view), - url(r'^(?P\d{4})/(?P\d{2})/?$', self.entry_archive_view), - url(r'^(?P\d{4})/(?P\d{2})/(?P\d{2})/?$', self.entry_archive_view), + urlpatterns += patterns('', url(r'^(?P\d{4})/(?P\d{2})/(?P\d{2})/(?P[-\w]+)/?$', self.entry_view) ) elif self.entry_permalink_style == 'M': - entry_patterns = patterns('', - url(r'^(?P\d{4})/?$', self.entry_archive_view), - url(r'^(?P\d{4})/(?P\d{2})/?$', self.entry_archive_view), + urlpatterns += patterns('', url(r'^(?P\d{4})/(?P\d{2})/(?P[-\w]+)/?$', self.entry_view) ) elif self.entry_permalink_style == 'Y': - entry_patterns = patterns('', - url(r'^(?P\d{4})/?$', self.entry_archive_view), + urlpatterns += patterns('', url(r'^(?P\d{4})/(?P[-\w]+)/?$', self.entry_view) ) elif self.entry_permalink_style == 'B': - entry_patterns = patterns('', - url((r'^(?:%s)/?$' % self.entry_permalink_base), self.entry_archive_view), + urlpatterns += patterns('', url((r'^(?:%s)/(?P[-\w]+)/?$' % self.entry_permalink_base), self.entry_view) ) else: - entry_patterns = patterns('', + urlpatterns = patterns('', url(r'^(?P[-\w]+)/?$', self.entry_view) ) - return base_patterns + entry_patterns + return urlpatterns - def index_view(self, request, node=None, extra_context=None): - entries = self.blog.entries.all() - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None - context = {} - context.update(extra_context or {}) - context.update({'blog': self.blog, 'entries': entries, 'paginated_page': paginated_page}) - return self.index_page.render_to_response(node, request, extra_context=context) + def get_all_entries(self, request, node=None, extra_context=None): + return self.blog.entries.all(), extra_context - def entry_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None): - entries = self.blog.entries.all() - if year: - entries = entries.filter(date__year=year) - if month: - entries = entries.filter(date__month=month) - if day: - entries = entries.filter(date__day=day) - try: - entry = entries.get(slug=slug) - except: - raise Http404 - context = {} - context.update(extra_context or {}) - context.update({'blog': self.blog, 'entry': entry}) - return self.entry_page.render_to_response(node, request, extra_context=context) - - def entry_archive_view(self, request, year=None, month=None, day=None, node=None, extra_context=None): + def get_entries_by_ymd(self, request, year=None, month=None, day=None, node=None, extra_context=None): if not self.entry_archive_page: raise Http404 entries = self.blog.entries.all() @@ -152,17 +172,12 @@ class BlogView(MultiView): entries = entries.filter(date__month=month) if day: entries = entries.filter(date__day=day) - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None - context = {} - context.update(extra_context or {}) - context.update({'blog': self.blog, 'year': year, 'month': month, 'day': day, 'entries': entries, 'paginated_page': paginated_page}) - return self.entry_archive_page.render_to_response(node, request, extra_context=context) + + context = extra_context or {} + context.update({'year': year, 'month': month, 'day': day}) + return entries, context - def tag_view(self, request, tag_slugs, node=None, extra_context=None): + def get_entries_by_tag(self, request, node=None, extra_context=None): tags = [] for tag_slug in tag_slugs.replace('+', '/').split('/'): if tag_slug: # ignore blank slugs, handles for multiple consecutive separators (+ or /) @@ -173,22 +188,34 @@ class BlogView(MultiView): tags.append(tag) if len(tags) <= 0: raise Http404 - + entries = self.blog.entries.all() for tag in tags: entries = entries.filter(tags=tag) if entries.count() <= 0: raise Http404 - if self.entries_per_page: - paginated_page = paginate(request, entries, self.entries_per_page) - entries = paginated_page.object_list - else: - paginated_page = None - context = {} + return entries, extra_context + + def get_obj_description(self, obj): + return obj.excerpt + + def entry_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None): + entries = self.blog.entries.all() + if year: + entries = entries.filter(date__year=year) + if month: + entries = entries.filter(date__month=month) + if day: + entries = entries.filter(date__day=day) + try: + entry = entries.get(slug=slug) + except: + raise Http404 + context = self.get_context() context.update(extra_context or {}) - context.update({'blog': self.blog, 'tags': tags, 'entries': entries, 'paginated_page': paginated_page}) - return self.tag_page.render_to_response(node, request, extra_context=context) + context.update({'entry': entry}) + return self.entry_page.render_to_response(node, request, extra_context=context) def tag_archive_view(self, request, node=None, extra_context=None): if not self.tag_archive_page: @@ -203,6 +230,9 @@ class Newsletter(Entity, Titled): pass +register_value_model(Newsletter) + + class NewsletterArticle(Entity, Titled): newsletter = models.ForeignKey(Newsletter, related_name='articles') authors = models.ManyToManyField(getattr(settings, 'PHILO_PERSON_MODULE', 'auth.User'), related_name='newsletterarticles') @@ -211,6 +241,7 @@ class NewsletterArticle(Entity, Titled): full_text = models.TextField() class Meta: + get_latest_by = 'date' ordering = ['-date'] unique_together = (('newsletter', 'slug'),) @@ -221,14 +252,17 @@ register_value_model(NewsletterArticle) class NewsletterIssue(Entity, Titled): newsletter = models.ForeignKey(Newsletter, related_name='issues') number = models.PositiveIntegerField() - articles = models.ManyToManyField(NewsletterArticle) + articles = models.ManyToManyField(NewsletterArticle, related_name='issues') class Meta: ordering = ['-number'] unique_together = (('newsletter', 'number'),) -class NewsletterView(MultiView): +register_value_model(NewsletterIssue) + + +class NewsletterView(MultiView, FeedMultiViewMixin): ARTICLE_PERMALINK_STYLE_CHOICES = ( ('D', 'Year, month, and day'), ('M', 'Year and month'), @@ -248,69 +282,99 @@ class NewsletterView(MultiView): article_permalink_base = models.CharField(max_length=255, blank=False, default='articles') issue_permalink_base = models.CharField(max_length=255, blank=False, default='issues') + feed_suffix = models.CharField(max_length=255, blank=False, default=FeedMultiViewMixin.feed_suffix) + feeds_enabled = models.BooleanField() + + @property + def feed_title(self): + return self.newsletter.title + + def get_subpath(self, obj): + if isinstance(obj, NewsletterArticle): + if obj.newsletter == self.newsletter: + kwargs = {'slug': obj.slug} + if self.article_permalink_style in 'DMY': + kwargs.update({'year': str(obj.date.year).zfill(4)}) + if self.article_permalink_style in 'DM': + kwargs.update({'month': str(obj.date.month).zfill(2)}) + if self.article_permalink_style == 'D': + kwargs.update({'day': str(obj.date.day).zfill(2)}) + return reverse(self.article_view, urlconf=self, kwargs=kwargs) + elif isinstance(obj, NewsletterIssue): + if obj.newsletter == self.newsletter: + return reverse('issue', urlconf=self, kwargs={'number': str(obj.number)}) + raise ViewCanNotProvideSubpath + @property def urlpatterns(self): - base_patterns = patterns('', - url(r'^$', self.index_view), - url((r'^(?:%s)/?$' % self.issue_permalink_base), self.issue_archive_view), - url((r'^(?:%s)/(?P\d+)/?$' % self.issue_permalink_base), self.issue_view) - ) - article_patterns = patterns('', - url((r'^(?:%s)/?$' % self.article_permalink_base), self.article_archive_view) + urlpatterns = patterns('', + url(r'^', include(self.feed_patterns(self.get_all_articles, self.index_page, 'index'))), + url(r'^(?:%s)/(?P\d+)/' % self.issue_permalink_base, include(self.feed_patterns(self.get_articles_by_issue, self.issue_page, 'issue'))) ) - if self.article_permalink_style in 'DMY': - article_patterns += patterns('', - url((r'^(?:%s)/(?P\d{4})/?$' % self.article_permalink_base), self.article_archive_view) + if self.issue_archive_page: + urlpatterns += patterns('', + url(r'^(?:%s)/$' % self.issue_permalink_base, self.issue_archive_view) ) - if self.article_permalink_style in 'DM': - article_patterns += patterns('', - url((r'^(?:%s)/(?P\d{4})/(?P\d{2})/?$' % self.article_permalink_base), self.article_archive_view) + if self.article_archive_page: + urlpatterns += patterns('', + url(r'^(?:%s)/' % self.article_permalink_base, include(self.feed_patterns(self.get_all_articles, self.article_archive_page, 'articles'))) + ) + if self.article_permalink_style in 'DMY': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/' % self.article_permalink_base, include(self.feed_patterns(self.get_articles_by_ymd, self.article_archive_page, 'articles_by_year'))) ) - if self.article_permalink_style == 'D': - article_patterns += patterns('', - url((r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P\d{2})/?$' % self.article_permalink_base), self.article_archive_view), - url((r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P\d{2})/(?P[-\w]+)/?$' % self.article_permalink_base), self.article_view) - ) - else: - article_patterns += patterns('', - url((r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P[-\w]+)/?$' % self.article_permalink_base), self.article_view) + if self.article_permalink_style in 'DM': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/(?P\d{2})/' % self.article_permalink_base, include(self.feed_patterns(self.get_articles_by_ymd, self.article_archive_page, 'articles_by_month'))) ) - else: - article_patterns += patterns('', - url((r'^(?:%s)/(?P\d{4})/(?P[-\w]+)/?$' % self.article_permalink_base), self.article_view) - ) - else: - article_patterns += patterns('', - url((r'^(?:%s)/(?P[-\w]+)/?$' % self.article_permalink_base), self.article_view) + if self.article_permalink_style == 'D': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P\d{2})/' % self.article_permalink_base, include(self.feed_patterns(self.get_articles_by_ymd, self.article_archive_page, 'articles_by_day'))) + ) + + if self.article_permalink_style == 'Y': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/(?P[\w-]+)/$' % self.article_permalink_base, self.article_view) + ) + elif self.article_permalink_style == 'M': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P[\w-]+)/$' % self.article_permalink_base, self.article_view) ) - return base_patterns + article_patterns + elif self.article_permalink_style == 'D': + urlpatterns += patterns('', + url(r'^(?:%s)/(?P\d{4})/(?P\d{2})/(?P\d{2})/(?P[\w-]+)/$' % self.article_permalink_base, self.article_view) + ) + else: + urlpatterns += patterns('', + url(r'^(?:%s)/(?P[-\w]+)/?$' % self.article_permalink_base, self.article_view) + ) + + return urlpatterns - def index_view(self, request, node=None, extra_context=None): - context = {} - context.update(extra_context or {}) - context.update({'newsletter': self.newsletter}) - return self.index_page.render_to_response(node, request, extra_context=context) + def get_context(self): + return {'newsletter': self.newsletter} - def article_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None): - articles = self.newsletter.articles.all() - if year: - articles = articles.filter(date__year=year) + def get_all_articles(self, request, node, extra_context=None): + return self.newsletter.articles.all(), extra_context + + def get_articles_by_ymd(self, request, year, month=None, day=None, node=None, extra_context=None): + articles = self.newsletter.articles.filter(dat__year=year) if month: articles = articles.filter(date__month=month) if day: articles = articles.filter(date__day=day) + return articles + + def get_articles_by_issue(self, request, number, node=None, extra_context=None): try: - article = articles.get(slug=slug) + issue = self.newsletter.issues.get(number=number) except: raise Http404 - context = {} - context.update(extra_context or {}) - context.update({'newsletter': self.newsletter, 'article': article}) - return self.article_page.render_to_response(node, request, extra_context=context) + context = extra_context or {} + context.update({'issue': issue}) + return issue.articles.all(), context - def article_archive_view(self, request, year=None, month=None, day=None, node=None, extra_context=None): - if not self.article_archive_page: - raise Http404 + def article_view(self, request, slug, year=None, month=None, day=None, node=None, extra_context=None): articles = self.newsletter.articles.all() if year: articles = articles.filter(date__year=year) @@ -318,20 +382,14 @@ class NewsletterView(MultiView): articles = articles.filter(date__month=month) if day: articles = articles.filter(date__day=day) - context = {} - context.update(extra_context or {}) - context.update({'newsletter': self.newsletter, 'year': year, 'month': month, 'day': day, 'articles': articles}) - return self.article_archive_page.render_to_response(node, request, extra_context=context) - - def issue_view(self, request, number, node=None, extra_context=None): try: - issue = self.newsletter.issues.get(number=number) + article = articles.get(slug=slug) except: raise Http404 context = {} context.update(extra_context or {}) - context.update({'newsletter': self.newsletter, 'issue': issue}) - return self.issue_page.render_to_response(node, request, extra_context=context) + context.update({'newsletter': self.newsletter, 'article': article}) + return self.article_page.render_to_response(node, request, extra_context=context) def issue_archive_view(self, request, node=None, extra_context=None): if not self.issue_archive_page: @@ -339,4 +397,7 @@ class NewsletterView(MultiView): context = {} context.update(extra_context or {}) context.update({'newsletter': self.newsletter}) - return self.issue_archive_page.render_to_response(node, request, extra_context=context) \ No newline at end of file + return self.issue_archive_page.render_to_response(node, request, extra_context=context) + + def get_obj_description(self, obj): + return obj.lede or obj.full_text \ No newline at end of file