Mercurial > public > sg101
changeset 1001:c6c3ba5cf6eb
V2 news stories use forums for comments.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Thu, 26 Nov 2015 00:27:42 -0600 |
parents | abd4c02aefdb |
children | 28d68f97cb26 |
files | forums/tools.py news/admin.py news/fixtures/news_categories.json news/migrations/0006_category_forum_slug.py news/migrations/0007_auto_20151125_2300.py news/models.py news/templatetags/news_tags.py news/utils.py news/views.py sg101/templates/news/story.html sg101/templates/news/story_summary.html |
diffstat | 11 files changed, 265 insertions(+), 137 deletions(-) [+] |
line wrap: on
line diff
--- a/forums/tools.py Tue Nov 24 22:55:18 2015 -0600 +++ b/forums/tools.py Thu Nov 26 00:27:42 2015 -0600 @@ -88,6 +88,7 @@ 'sticky' - if True, the post will be stickied 'locked' - if True, the post will be locked + The new topic is returned. """ try: forum = Forum.objects.get(slug=forum_slug) @@ -110,6 +111,7 @@ notify_new_topic(topic) notify_new_post(post) + return topic def auto_favorite(post):
--- a/news/admin.py Tue Nov 24 22:55:18 2015 -0600 +++ b/news/admin.py Thu Nov 26 00:27:42 2015 -0600 @@ -4,6 +4,7 @@ from django.contrib import admin from django.conf import settings +from forums.tools import create_topic from news.models import PendingStory from news.models import Story from news.models import Category @@ -11,9 +12,14 @@ import ftfy +COMMENT_THREAD_BODY = ("This topic was automatically created to discuss the " + "news story [{title}]({url}).") + + class CategoryAdmin(admin.ModelAdmin): prepopulated_fields = {'slug': ("title", )} - list_display = ['title', 'slug'] + list_display = ['title', 'slug', 'forum_slug'] + list_editable = ['forum_slug'] class PendingStoryAdmin(admin.ModelAdmin): @@ -21,7 +27,7 @@ list_filter = ['date_submitted'] search_fields = ['title', 'short_text', 'long_text'] date_hierarchy = 'date_submitted' - actions = ['approve_story'] + actions = ['approve_stories'] readonly_fields = ['update_date', 'version'] raw_id_fields = ['submitter'] @@ -48,31 +54,43 @@ }), ] - def approve_story(self, request, qs): + def approve_stories(self, request, qs): for pending_story in qs: - story = Story( - title=pending_story.title, - submitter=pending_story.submitter, - category=pending_story.category, - short_text=pending_story.short_text, - long_text=pending_story.long_text, - date_submitted=pending_story.date_submitted, - allow_comments=pending_story.allow_comments, - tags=pending_story.tags, - front_page_expiration=pending_story.front_page_expiration, - priority=pending_story.priority, - meta_description=pending_story.meta_description, - short_markup=pending_story.short_markup, - long_markup=pending_story.long_markup, - admin_content=pending_story.admin_content) - story.save() - pending_story.delete() + self._approve_story(pending_story) count = len(qs) msg = "1 story" if count == 1 else "%d stories" % count self.message_user(request, "%s approved." % msg) - approve_story.short_description = "Approve selected pending stories" + approve_stories.short_description = "Approve selected pending stories" + + def _approve_story(self, pending_story): + story = Story( + title=pending_story.title, + submitter=pending_story.submitter, + category=pending_story.category, + short_text=pending_story.short_text, + long_text=pending_story.long_text, + date_submitted=pending_story.date_submitted, + allow_comments=pending_story.allow_comments, + tags=pending_story.tags, + front_page_expiration=pending_story.front_page_expiration, + priority=pending_story.priority, + meta_description=pending_story.meta_description, + short_markup=pending_story.short_markup, + long_markup=pending_story.long_markup, + admin_content=pending_story.admin_content) + story.save() + pending_story.delete() + + # Create comment thread if configured to do so. + forum_slug = story.category.forum_slug + if story.allow_comments and forum_slug: + post_body = COMMENT_THREAD_BODY.format(title=story.title, + url=story.get_absolute_url()) + topic = create_topic(forum_slug, story.submitter, story.title, post_body) + story.forums_topic = topic + story.save() class Media: js = ['js/news_admin.js'] + settings.GPP_THIRD_PARTY_JS['tiny_mce']
--- a/news/fixtures/news_categories.json Tue Nov 24 22:55:18 2015 -0600 +++ b/news/fixtures/news_categories.json Thu Nov 26 00:27:42 2015 -0600 @@ -1,101 +1,112 @@ [ - { - "pk": 2, - "model": "news.category", - "fields": { - "icon": "news/categories/Articles.png", - "slug": "articles", - "title": "Articles" - } - }, - { - "pk": 3, - "model": "news.category", - "fields": { - "icon": "news/categories/Bands.png", - "slug": "bands", - "title": "Bands" - } - }, - { - "pk": 11, - "model": "news.category", - "fields": { - "icon": "news/categories/Featured_Video.png", - "slug": "featured-videos", - "title": "Featured Videos" - } - }, - { - "pk": 4, - "model": "news.category", - "fields": { - "icon": "news/categories/Gear.png", - "slug": "gear", - "title": "Gear" - } - }, - { - "pk": 5, - "model": "news.category", - "fields": { - "icon": "news/categories/Interviews.png", - "slug": "interviews", - "title": "Interviews" - } - }, - { - "pk": 6, - "model": "news.category", - "fields": { - "icon": "news/categories/Reviews.png", - "slug": "reviews", - "title": "Reviews" - } - }, - { - "pk": 7, - "model": "news.category", - "fields": { - "icon": "news/categories/Show_Announcements.png", - "slug": "show-announcements", - "title": "Show Announcements" - } - }, - { - "pk": 8, - "model": "news.category", - "fields": { - "icon": "news/categories/Show_Reports.png", - "slug": "show-reports", - "title": "Show Reports" - } - }, - { - "pk": 1, - "model": "news.category", - "fields": { - "icon": "news/categories/Site_News.png", - "slug": "site-news", - "title": "Site News" - } - }, - { - "pk": 9, - "model": "news.category", - "fields": { - "icon": "news/categories/Surf_Scene_News.png", - "slug": "surf-scene-news", - "title": "Surf Scene News" - } - }, - { - "pk": 10, - "model": "news.category", - "fields": { - "icon": "news/categories/Guitar_Tabs.png", - "slug": "tablature", - "title": "Tablature" - } - } -] \ No newline at end of file +{ + "fields": { + "forum_slug": "surfguitar101-website", + "icon": "news/categories/Site_News.png", + "slug": "site-news", + "title": "Site News" + }, + "model": "news.category", + "pk": 1 +}, +{ + "fields": { + "forum_slug": "surf-music", + "icon": "news/categories/Articles.png", + "slug": "articles", + "title": "Articles" + }, + "model": "news.category", + "pk": 2 +}, +{ + "fields": { + "forum_slug": "surf-music", + "icon": "news/categories/Bands.png", + "slug": "bands", + "title": "Bands" + }, + "model": "news.category", + "pk": 3 +}, +{ + "fields": { + "forum_slug": "gear", + "icon": "news/categories/Gear.png", + "slug": "gear", + "title": "Gear" + }, + "model": "news.category", + "pk": 4 +}, +{ + "fields": { + "forum_slug": "surf-music", + "icon": "news/categories/Interviews.png", + "slug": "interviews", + "title": "Interviews" + }, + "model": "news.category", + "pk": 5 +}, +{ + "fields": { + "forum_slug": "music-reviews", + "icon": "news/categories/Reviews.png", + "slug": "reviews", + "title": "Reviews" + }, + "model": "news.category", + "pk": 6 +}, +{ + "fields": { + "forum_slug": "gigs", + "icon": "news/categories/Show_Announcements.png", + "slug": "show-announcements", + "title": "Show Announcements" + }, + "model": "news.category", + "pk": 7 +}, +{ + "fields": { + "forum_slug": "surf-music", + "icon": "news/categories/Show_Reports.png", + "slug": "show-reports", + "title": "Show Reports" + }, + "model": "news.category", + "pk": 8 +}, +{ + "fields": { + "forum_slug": "surf-music", + "icon": "news/categories/Surf_Scene_News.png", + "slug": "surf-scene-news", + "title": "Surf Scene News" + }, + "model": "news.category", + "pk": 9 +}, +{ + "fields": { + "forum_slug": "surf-musician", + "icon": "news/categories/Guitar_Tabs.png", + "slug": "tablature", + "title": "Tablature" + }, + "model": "news.category", + "pk": 10 +}, +{ + "fields": { + "forum_slug": "surf-videos", + "icon": "news/categories/Featured_Video.png", + "slug": "featured-videos", + "title": "Featured Videos" + }, + "model": "news.category", + "pk": 11 +} +]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/news/migrations/0006_category_forum_slug.py Thu Nov 26 00:27:42 2015 -0600 @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('news', '0005_auto_20151121_1445'), + ] + + operations = [ + migrations.AddField( + model_name='category', + name='forum_slug', + field=models.CharField(default=b'', help_text=b'Identifies the forum to create comment threads in for stories in this category', max_length=80, blank=True), + preserve_default=True, + ), + ]
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/news/migrations/0007_auto_20151125_2300.py Thu Nov 26 00:27:42 2015 -0600 @@ -0,0 +1,28 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import models, migrations +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('forums', '__first__'), + ('news', '0006_category_forum_slug'), + ] + + operations = [ + migrations.AddField( + model_name='story', + name='forums_topic', + field=models.OneToOneField(null=True, on_delete=django.db.models.deletion.SET_NULL, blank=True, to='forums.Topic', help_text=b'Forum topic used for comments', db_index=False), + preserve_default=True, + ), + migrations.AlterField( + model_name='category', + name='forum_slug', + field=models.CharField(default=b'', help_text=b'Identifies the forum to create comment threads in for stories in this category. If blank, no comment threads will be created for stories in this category.', max_length=80, blank=True), + preserve_default=True, + ), + ]
--- a/news/models.py Tue Nov 24 22:55:18 2015 -0600 +++ b/news/models.py Thu Nov 26 00:27:42 2015 -0600 @@ -19,6 +19,13 @@ title = models.CharField(max_length=64) slug = models.SlugField(max_length=64) icon = models.ImageField(upload_to='news/categories/', blank=True) + forum_slug = models.CharField( + max_length=80, + default='', + blank=True, + help_text=("Identifies the forum to create comment threads in for " + "stories in this category. If blank, no comment threads " + "will be created for stories in this category.")) def __unicode__(self): return self.title @@ -85,6 +92,10 @@ class Story(StoryBase): """Model for news stories""" + forums_topic = models.OneToOneField('forums.Topic', blank=True, null=True, + on_delete=models.SET_NULL, + db_index=False, + help_text="Forum topic used for comments") @models.permalink def get_absolute_url(self): @@ -99,10 +110,17 @@ verbose_name_plural = 'news stories' def can_comment_on(self): + # Only used for version 0 stories now = datetime.datetime.now() delta = now - self.date_submitted return self.allow_comments and delta.days < 30 + def forums_comment_count(self): + """Returns number of comments for V2 news stories.""" + if self.forums_topic: + return max(0, self.forums_topic.post_count - 1) + return 0 + def search_title(self): return self.title
--- a/news/templatetags/news_tags.py Tue Nov 24 22:55:18 2015 -0600 +++ b/news/templatetags/news_tags.py Thu Nov 26 00:27:42 2015 -0600 @@ -17,9 +17,10 @@ def current_news(): # Defer the tags field because we are going to get all the # tags out in 1 query later... - stories = Story.objects.defer('tags').exclude( - front_page_expiration__lt=datetime.date.today()).order_by( - '-priority', '-date_submitted')[:10] + stories = Story.objects.defer('tags')\ + .exclude(front_page_expiration__lt=datetime.date.today())\ + .select_related('forums_topic')\ + .order_by('-priority', '-date_submitted')[:10] attach_extra_attrs(stories)
--- a/news/utils.py Tue Nov 24 22:55:18 2015 -0600 +++ b/news/utils.py Thu Nov 26 00:27:42 2015 -0600 @@ -28,17 +28,25 @@ for story in stories_dict.values(): story.tag_list = [] - story.comment_count = 0 + if story.version == 0: + story.comment_count = 0 + elif story.forums_topic: + # for convenience/consistency with old models... + story.comment_count = story.forums_comment_count() # attach tags for item in tagged_items: stories_dict[item.object_id].tag_list.append(item.tag.name) - # Now get all the comment counts out in one fell swoop + # Now get all the comment counts out in one fell swoop. This is only needed + # for older news stories... - story_ids = Comment.objects.filter(content_type=ct, - object_id__in=story_ids).values_list('object_id', flat=True) + story_ids = [pk for pk in story_ids if stories_dict[pk].version == 0] - # compute comment_count - for story_id in story_ids: - stories_dict[story_id].comment_count += 1 + if story_ids: + story_ids = Comment.objects.filter(content_type=ct, + object_id__in=story_ids).values_list('object_id', flat=True) + + # compute comment_count + for story_id in story_ids: + stories_dict[story_id].comment_count += 1
--- a/news/views.py Tue Nov 24 22:55:18 2015 -0600 +++ b/news/views.py Thu Nov 26 00:27:42 2015 -0600 @@ -42,7 +42,8 @@ def index(request): # Defer the tags field because we are going to get all the # tags out in 1 query later... - stories = Story.objects.all().defer('tags').select_related() + stories = Story.objects.all().defer('tags').select_related( + 'submitter', 'category', 'forums_topic') paginator = create_paginator(stories) page = get_page(request.GET) @@ -75,7 +76,8 @@ def archive(request, year, month): stories = Story.objects.defer('tags').filter(date_submitted__year=year, - date_submitted__month=month).select_related() + date_submitted__month=month).select_related( + 'submitter', 'category', 'forums_topic') paginator = create_paginator(stories) page = get_page(request.GET) try: @@ -110,7 +112,8 @@ def category(request, slug): category = get_object_or_404(Category, slug=slug) - stories = Story.objects.defer('tags').filter(category=category).select_related() + stories = Story.objects.defer('tags').filter(category=category).select_related( + 'submitter', 'category', 'forums_topic') paginator = create_paginator(stories) page = get_page(request.GET) try: @@ -129,7 +132,8 @@ ####################################################################### def story(request, story_id): - story = get_object_or_404(Story, pk=story_id) + story = get_object_or_404(Story.objects.select_related( + 'submitter', 'category', 'forums_topic'), pk=story_id) return render_to_response('news/story.html', { 'story': story, }, @@ -174,7 +178,8 @@ def tag(request, tag_name): tag = get_object_or_404(Tag, name=tag_name) stories = TaggedItem.objects.get_by_model( - Story.objects.defer('tags').select_related(), tag) + Story.objects.defer('tags').select_related( + 'submitter', 'category', 'forums_topic'), tag) paginator = create_paginator(stories) page = get_page(request.GET) try:
--- a/sg101/templates/news/story.html Tue Nov 24 22:55:18 2015 -0600 +++ b/sg101/templates/news/story.html Thu Nov 26 00:27:42 2015 -0600 @@ -55,6 +55,8 @@ {% endif %} {% social_sharing story.title story.get_absolute_url %} </div> + +{% if story.version == 0 %} {% get_comment_count for story as comment_count %} <p>This story has <span id="comment-count">{{ comment_count }}</span> comment{{ comment_count|pluralize }}.</p> <hr /> @@ -66,5 +68,12 @@ <p>Comments are closed for this story. If you'd like to share your thoughts on this story with the site staff, you can <a href="{% url 'contact-form' %}">contact us directly</a>.</p> {% endif %} +{% else %} + {% if story.forums_topic %} + <a href="{{ story.forums_topic.get_absolute_url }}">{{ story.forums_comment_count }} comment{{ story.forums_comment_count|pluralize }}</a> + {% else %} + <p><em>Comments are disabled.</em></p> + {% endif %} +{% endif %} </div> {% endblock %}
--- a/sg101/templates/news/story_summary.html Tue Nov 24 22:55:18 2015 -0600 +++ b/sg101/templates/news/story_summary.html Thu Nov 26 00:27:42 2015 -0600 @@ -30,7 +30,15 @@ <p> Category: <a href="{% url 'news-category' slug=story.category.slug %}">{{ story.category.title }}</a> <img src="{{ STATIC_URL }}icons/comments.png" alt="Comments" title="Comments" /> -<a href="{{ story.get_absolute_url }}">{{ story.comment_count }} comment{{ story.comment_count|pluralize }}</a> +{% if story.version == 0 %} + <a href="{{ story.get_absolute_url }}">{{ story.comment_count }} comment{{ story.comment_count|pluralize }}</a> +{% else %} + {% if story.forums_topic %} + <a href="{{ story.forums_topic.get_absolute_url }}">{{ story.comment_count }} comment{{ story.comment_count|pluralize }}</a> + {% else %} + <em>Comments are disabled</em> + {% endif %} +{% endif %} <a href="{{ story.get_absolute_url }}"><img src="{{ STATIC_URL }}icons/link.png" alt="Permalink" title="Permalink" /></a> {% if user.is_authenticated %} <a href="{% url 'news.views.email_story' story.id %}"><img src="{{ STATIC_URL }}icons/email_go.png"