# HG changeset patch # User Brian Neal # Date 1313542928 0 # Node ID 3b30286adba5735c75f410d7d1815e291362d1e5 # Parent ad4b63fbc5846500b17397f3e4ab29be4e75e734 Smarter search index updating for forums. This work is for #227. diff -r ad4b63fbc584 -r 3b30286adba5 gpp/bio/search_indexes.py --- a/gpp/bio/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/bio/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,7 +1,7 @@ """Haystack search index for the bio application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from bio.models import UserProfile diff -r ad4b63fbc584 -r 3b30286adba5 gpp/custom_search.py --- a/gpp/custom_search.py Sun Aug 07 03:38:42 2011 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,62 +0,0 @@ -""" -This module contains custom code to tailor the Haystack search application to -our needs. - -""" -import urllib - -from django import forms -from haystack.forms import ModelSearchForm -from queued_search.indexes import QueuedSearchIndex - - -MODEL_CHOICES = ( - ('forums.topic', 'Forum Topics'), - ('forums.post', 'Forum Posts'), - ('news.story', 'News Stories'), - ('bio.userprofile', 'User Profiles'), - ('weblinks.link', 'Links'), - ('downloads.download', 'Downloads'), - ('podcast.item', 'Podcasts'), - ('ygroup.post', 'Yahoo Group Archives'), -) - - -class CustomModelSearchForm(ModelSearchForm): - """ - This customized ModelSearchForm allows us to explictly label and order - the model choices. - - """ - q = forms.CharField(required=False, label='', - widget=forms.TextInput(attrs={'class': 'text', 'size': 48})) - - def __init__(self, *args, **kwargs): - super(CustomModelSearchForm, self).__init__(*args, **kwargs) - self.fields['models'] = forms.MultipleChoiceField(choices=MODEL_CHOICES, - label='', widget=forms.CheckboxSelectMultiple) - - -class CondQueuedSearchIndex(QueuedSearchIndex): - """ - This customized version of QueuedSearchIndex conditionally enqueues items - to be indexed by calling the can_index() method. - - """ - def can_index(self, instance): - """ - The default is to index all instances. Override this method to - customize the behavior. This will be called on all update operations. - - """ - return True - - def enqueue(self, action, instance): - """ - This method enqueues the instance only if the can_index() method - returns True. - - """ - if (action == 'update' and self.can_index(instance) or - action == 'delete'): - super(CondQueuedSearchIndex, self).enqueue(action, instance) diff -r ad4b63fbc584 -r 3b30286adba5 gpp/custom_search/forms.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/custom_search/forms.py Wed Aug 17 01:02:08 2011 +0000 @@ -0,0 +1,34 @@ +""" +This module contains custom forms to tailor the Haystack search application to +our needs. + +""" +from django import forms +from haystack.forms import ModelSearchForm + + +MODEL_CHOICES = ( + ('forums.topic', 'Forum Topics'), + ('forums.post', 'Forum Posts'), + ('news.story', 'News Stories'), + ('bio.userprofile', 'User Profiles'), + ('weblinks.link', 'Links'), + ('downloads.download', 'Downloads'), + ('podcast.item', 'Podcasts'), + ('ygroup.post', 'Yahoo Group Archives'), +) + + +class CustomModelSearchForm(ModelSearchForm): + """ + This customized ModelSearchForm allows us to explictly label and order + the model choices. + + """ + q = forms.CharField(required=False, label='', + widget=forms.TextInput(attrs={'class': 'text', 'size': 48})) + + def __init__(self, *args, **kwargs): + super(CustomModelSearchForm, self).__init__(*args, **kwargs) + self.fields['models'] = forms.MultipleChoiceField(choices=MODEL_CHOICES, + label='', widget=forms.CheckboxSelectMultiple) diff -r ad4b63fbc584 -r 3b30286adba5 gpp/custom_search/indexes.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gpp/custom_search/indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -0,0 +1,31 @@ +""" +This module contains custom search indexes to tailor the Haystack search +application to our needs. + +""" +from queued_search.indexes import QueuedSearchIndex + + +class CondQueuedSearchIndex(QueuedSearchIndex): + """ + This customized version of QueuedSearchIndex conditionally enqueues items + to be indexed by calling the can_index() method. + + """ + def can_index(self, instance): + """ + The default is to index all instances. Override this method to + customize the behavior. This will be called on all update operations. + + """ + return True + + def enqueue(self, action, instance): + """ + This method enqueues the instance only if the can_index() method + returns True. + + """ + if (action == 'update' and self.can_index(instance) or + action == 'delete'): + super(CondQueuedSearchIndex, self).enqueue(action, instance) diff -r ad4b63fbc584 -r 3b30286adba5 gpp/downloads/search_indexes.py --- a/gpp/downloads/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/downloads/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,7 +1,7 @@ """Haystack search index for the downloads application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from downloads.models import Download diff -r ad4b63fbc584 -r 3b30286adba5 gpp/forums/forms.py --- a/gpp/forums/forms.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/forums/forms.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,5 +1,6 @@ """ Forms for the forums application. + """ from django import forms from django.conf import settings @@ -9,6 +10,7 @@ from forums.models import Post from forums.attachments import AttachmentProcessor import forums.permissions as perms +from forums.signals import notify_new_topic, notify_new_post class NewPostForm(forms.Form): @@ -55,6 +57,7 @@ user_ip=ip) post.save() self.attach_proc.save_attachments(post) + notify_new_post(post) return post @@ -131,6 +134,9 @@ self.attach_proc.save_attachments(post) + notify_new_topic(topic) + notify_new_post(post) + return topic diff -r ad4b63fbc584 -r 3b30286adba5 gpp/forums/search_indexes.py --- a/gpp/forums/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/forums/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,9 +1,10 @@ """Haystack search index for the weblinks application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from forums.models import Forum, Topic, Post +from forums.signals import topic_content_update, post_content_update class TopicIndex(CondQueuedSearchIndex): @@ -17,6 +18,12 @@ def get_updated_field(self): return 'update_date' + def _setup_save(self, model): + topic_content_update.connect(self.enqueue_save) + + def _teardown_save(self, model): + topic_content_update.disconnect(self.enqueue_save) + def can_index(self, instance): return instance.forum.id in Forum.objects.public_forum_ids() @@ -33,6 +40,12 @@ def get_updated_field(self): return 'update_date' + def _setup_save(self, model): + post_content_update.connect(self.enqueue_save) + + def _teardown_save(self, model): + post_content_update.disconnect(self.enqueue_save) + def can_index(self, instance): return instance.topic.forum.id in Forum.objects.public_forum_ids() diff -r ad4b63fbc584 -r 3b30286adba5 gpp/forums/signals.py --- a/gpp/forums/signals.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/forums/signals.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,8 +1,10 @@ """ -Signal handlers for the forums application. +Signal handlers & signals for the forums application. + """ from django.db.models.signals import post_save from django.db.models.signals import post_delete +import django.dispatch from forums.models import Forum, Topic, Post from forums.views.subscriptions import notify_topic_subscribers @@ -65,3 +67,54 @@ post_save.connect(on_post_save, sender=Post, dispatch_uid='forums.signals') post_delete.connect(on_post_delete, sender=Post, dispatch_uid='forums.signals') + + +# Signals for the forums application. +# +# This signal is sent when a topic has had its textual content (title) changed. +# The provided arguments are: +# sender - the topic model instance +# instance - the topic model instance +# created - True if the topic is new, False if updated + +topic_content_update = django.dispatch.Signal(providing_args=['action']) + +# This signal is sent when a post has had its textual content (body) changed. +# The provided arguments are: +# sender - the post model instance +# instance - the topic model instance +# created - True if the post is new, False if updated + +post_content_update = django.dispatch.Signal(providing_args=['action']) + + +def notify_new_topic(topic): + """ + Sends the topic_content_update signal for a new topic instance. + + """ + topic_content_update.send_robust(topic, instance=topic, created=True) + + +def notify_updated_topic(topic): + """ + Sends the topic_content_update signal for an updated topic instance. + + """ + topic_content_update.send_robust(topic, instance=topic, created=False) + + +def notify_new_post(post): + """ + Sends the post_content_update signal for a new post instance. + + """ + post_content_update.send_robust(post, instance=post, created=True) + + +def notify_updated_post(post): + """ + Sends the post_content_update signal for an updated post instance. + + """ + post_content_update.send_robust(post, instance=post, created=False) diff -r ad4b63fbc584 -r 3b30286adba5 gpp/forums/views/main.py --- a/gpp/forums/views/main.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/forums/views/main.py Wed Aug 17 01:02:08 2011 +0000 @@ -36,6 +36,8 @@ from forums.attachments import AttachmentProcessor import forums.permissions as perms +from forums.signals import (notify_new_topic, notify_updated_topic, + notify_new_post, notify_updated_post) ####################################################################### @@ -440,10 +442,12 @@ post = form.save(commit=False) post.touch() post.save() + notify_updated_post(post) # if we are editing a first post, save the parent topic as well if topic_name: post.topic.save() + notify_updated_topic(post.topic) # Save any attachments form.attach_proc.save_attachments(post) @@ -590,6 +594,7 @@ post.user = request.user post.user_ip = request.META.get("REMOTE_ADDR", "") post.save() + notify_new_post(post) # Save any attachments form.attach_proc.save_attachments(post) @@ -1102,6 +1107,7 @@ if len(posts) > 0: new_topic = Topic(forum=new_forum, name=new_name, user=posts[0].user) new_topic.save() + notify_new_topic(new_topic) for post in posts: post.topic = new_topic post.save() diff -r ad4b63fbc584 -r 3b30286adba5 gpp/news/search_indexes.py --- a/gpp/news/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/news/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,7 +1,7 @@ """Haystack search index for the news application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from news.models import Story diff -r ad4b63fbc584 -r 3b30286adba5 gpp/podcast/search_indexes.py --- a/gpp/podcast/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/podcast/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,7 +1,7 @@ """Haystack search index for the news application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from podcast.models import Item diff -r ad4b63fbc584 -r 3b30286adba5 gpp/urls.py --- a/gpp/urls.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/urls.py Wed Aug 17 01:02:08 2011 +0000 @@ -7,7 +7,7 @@ from news.feeds import LatestNewsFeed from forums.feeds import ForumsFeed -from custom_search import CustomModelSearchForm +from custom_search.forms import CustomModelSearchForm admin.autodiscover() diff -r ad4b63fbc584 -r 3b30286adba5 gpp/weblinks/search_indexes.py --- a/gpp/weblinks/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/weblinks/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -1,7 +1,7 @@ """Haystack search index for the weblinks application.""" from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from weblinks.models import Link diff -r ad4b63fbc584 -r 3b30286adba5 gpp/ygroup/search_indexes.py --- a/gpp/ygroup/search_indexes.py Sun Aug 07 03:38:42 2011 +0000 +++ b/gpp/ygroup/search_indexes.py Wed Aug 17 01:02:08 2011 +0000 @@ -4,7 +4,7 @@ """ from haystack.indexes import * from haystack import site -from custom_search import CondQueuedSearchIndex +from custom_search.indexes import CondQueuedSearchIndex from ygroup.models import Post