diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-05-17 02:01:51 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2010-05-17 02:01:51 -0400 |
commit | 4b27cf51837cac1cc79ef79b1006a52bf5d5d18d (patch) | |
tree | 3ed61da9efd9aeaeadb80fd538dc34902cef7e1a /forum/models | |
parent | 7a7c938c785aa91d9106a4ce1ddd50da8bd66951 (diff) | |
download | askbot-4b27cf51837cac1cc79ef79b1006a52bf5d5d18d.tar.gz askbot-4b27cf51837cac1cc79ef79b1006a52bf5d5d18d.tar.bz2 askbot-4b27cf51837cac1cc79ef79b1006a52bf5d5d18d.zip |
added twitter style mentions on comments and started adding instant notification
Diffstat (limited to 'forum/models')
-rw-r--r-- | forum/models/__init__.py | 5 | ||||
-rw-r--r-- | forum/models/answer.py | 3 | ||||
-rw-r--r-- | forum/models/base.py | 14 | ||||
-rw-r--r-- | forum/models/meta.py | 23 | ||||
-rw-r--r-- | forum/models/question.py | 12 | ||||
-rw-r--r-- | forum/models/user.py | 87 |
6 files changed, 132 insertions, 12 deletions
diff --git a/forum/models/__init__.py b/forum/models/__init__.py index 024379db..c3ba280c 100644 --- a/forum/models/__init__.py +++ b/forum/models/__init__.py @@ -2,7 +2,8 @@ from question import Question ,QuestionRevision, QuestionView, AnonymousQuestion from answer import Answer, AnonymousAnswer, AnswerRevision from tag import Tag, MarkedTag from meta import Vote, Comment, FlaggedItem -from user import Activity, ValidationHash, EmailFeedSetting, AuthKeyUserAssociation +from user import Activity, ValidationHash, EmailFeedSetting +from user import Mention, AuthKeyUserAssociation from repute import Badge, Award, Repute from django.core.urlresolvers import reverse from forum.search.indexer import create_fulltext_indexes @@ -470,6 +471,7 @@ Activity = Activity EmailFeedSetting = EmailFeedSetting ValidationHash = ValidationHash AuthKeyUserAssociation = AuthKeyUserAssociation +Mention = Mention __all__ = [ 'Question', @@ -496,6 +498,7 @@ __all__ = [ 'EmailFeedSetting', 'ValidationHash', 'AuthKeyUserAssociation', + 'Mention', 'User', ] diff --git a/forum/models/answer.py b/forum/models/answer.py index 3de6cfc4..7f5c8ae8 100644 --- a/forum/models/answer.py +++ b/forum/models/answer.py @@ -128,6 +128,9 @@ class Answer(Content, DeletableContent): revision=rev_no ) + def get_origin_post(self): + return self.question + def get_user_vote(self, user): if user.__class__.__name__ == "AnonymousUser": return None diff --git a/forum/models/base.py b/forum/models/base.py index fcec47b4..81626405 100644 --- a/forum/models/base.py +++ b/forum/models/base.py @@ -28,6 +28,9 @@ class UserContent(models.Model): abstract = True app_label = 'forum' + def get_last_author(self): + return self.user + class MetaContent(models.Model): """ Base class for Vote, Comment and FlaggedItem @@ -40,7 +43,6 @@ class MetaContent(models.Model): abstract = True app_label = 'forum' - class DeletableContent(models.Model): deleted = models.BooleanField(default=False) deleted_at = models.DateTimeField(null=True, blank=True) @@ -137,7 +139,12 @@ class Content(models.Model): raise Exception('arguments comment and user are required') Comment = models.get_model('forum','Comment')#todo: forum hardcoded - comment = Comment(content_object=self, comment=comment, user=user, added_at=added_at) + comment = Comment( + content_object=self, + comment=comment, + user=user, + added_at=added_at + ) comment.save() self.comment_count = self.comment_count + 1 self.save() @@ -145,6 +152,9 @@ class Content(models.Model): def get_latest_revision(self): return self.revisions.all()[0] + def get_last_author(self): + return self.last_edited_by + def post_get_last_update_info(self):#todo: rename this subroutine when = self.added_at who = self.author diff --git a/forum/models/meta.py b/forum/models/meta.py index 114d2130..0ba07f98 100644 --- a/forum/models/meta.py +++ b/forum/models/meta.py @@ -1,4 +1,6 @@ from base import * +from forum import const +from django.utils.html import urlize class VoteManager(models.Manager): def get_up_vote_count_from_user(self, user): @@ -75,19 +77,36 @@ class FlaggedItem(MetaContent, UserContent): return '[%s] flagged at %s' %(self.user, self.flagged_at) class Comment(MetaContent, UserContent): - comment = models.CharField(max_length=300) - added_at = models.DateTimeField(default=datetime.datetime.now) + comment = models.CharField(max_length = const.COMMENT_HARD_MAX_LENGTH) + added_at = models.DateTimeField(default = datetime.datetime.now) + html = models.CharField(max_length = const.COMMENT_HARD_MAX_LENGTH, default='') class Meta(MetaContent.Meta): ordering = ('-added_at',) db_table = u'comment' + def get_origin_post(self): + return self.content_object.get_origin_post() + def save(self,**kwargs): + from forum.utils.markup import mentionize super(Comment,self).save(**kwargs) + self.html = mentionize(urlize(self.comment, nofollow=True), context_object = self) + #todo - try post_save to install mentions + super(Comment,self).save(**kwargs)#have to save twice!!, b/c need id for generic relation try: ping_google() except Exception: logging.debug('problem pinging google did you register you sitemap with google?') + def delete(self, **kwargs): + from forum.models.user import Mention + ctype = ContentType.objects.get_for_model(self) + Mention.objects.filter( + content_type = ctype, + object_id = self.id + ).delete() + super(Comment,self).delete(**kwargs) + def __unicode__(self): return self.comment diff --git a/forum/models/question.py b/forum/models/question.py index 1d387ab7..584d6bf6 100644 --- a/forum/models/question.py +++ b/forum/models/question.py @@ -301,6 +301,15 @@ class Question(Content, DeletableContent): except Exception: logging.debug('problem pinging google did you register you sitemap with google?') + def get_all_authors(self): + authors = set() + authors.update([r.author for r in self.revisions.all()]) + authors.update([c.user for c in self.comments.all()]) + for a in self.answers.filter(deleted = False): + authors.update([r.author for r in a.revisions.all()]) + authors.update([c.user for c in a.comments.all()]) + return authors + def retag(self, retagged_by=None, retagged_at=None, tagnames=None): if None in (retagged_by, retagged_at, tagnames): raise Exception('arguments retagged_at, retagged_by and tagnames are required') @@ -329,6 +338,9 @@ class Question(Content, DeletableContent): # send tags updated singal tags_updated.send(sender=question.__class__, question=self) + def get_origin_post(self): + return self + def apply_edit(self, edited_at=None, edited_by=None, title=None,\ text=None, comment=None, tags=None, wiki=False): diff --git a/forum/models/user.py b/forum/models/user.py index 5cd0f46d..5636ff9b 100644 --- a/forum/models/user.py +++ b/forum/models/user.py @@ -1,9 +1,11 @@ from base import * from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes import generic from django.contrib.auth.models import User from hashlib import md5 import string from random import Random +from forum import const import datetime from django.utils.translation import ugettext as _ @@ -15,10 +17,10 @@ class Activity(models.Model): user = models.ForeignKey(User) activity_type = models.SmallIntegerField(choices=TYPE_ACTIVITY) active_at = models.DateTimeField(default=datetime.datetime.now) - content_type = models.ForeignKey(ContentType) - object_id = models.PositiveIntegerField() + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() content_object = generic.GenericForeignKey('content_type', 'object_id') - is_auditted = models.BooleanField(default=False) + is_auditted = models.BooleanField(default=False) def __unicode__(self): return u'[%s] was active at %s' % (self.user.username, self.active_at) @@ -27,10 +29,47 @@ class Activity(models.Model): app_label = 'forum' db_table = u'activity' +class MentionManager(models.Manager): + def get_question_list(self): + out = [] + for m in self.all(): + post = m.content_object + if isinstance(post, Question): + out.append(post) + elif isinstance(post, Answer): + out.append(post.question) + elif isinstance(post, Comment): + p = post.content_object + if isinstance(p, Question): + out.append(p) + elif isinstance(p, Answer): + out.append(p.question) + return out + +class Mention(models.Model): + """ + Table holding @mention type entries in the posts + """ + mentioned_by = models.ForeignKey(User, related_name = 'mentions_sent') + mentioned_whom = models.ForeignKey(User, related_name = 'mentions_received') + mentioned_at = models.DateTimeField(default=datetime.datetime.now) + + #have to use generic foreign key here to point to the context of the mention + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() + content_object = generic.GenericForeignKey('content_type', 'object_id') + + objects = MentionManager() + + class Meta: + app_label = 'forum' + db_table = u'mention' + class EmailFeedSetting(models.Model): DELTA_TABLE = { - 'w':datetime.timedelta(7), + 'i':datetime.timedelta(-1),#instant emails are processed separately 'd':datetime.timedelta(1), + 'w':datetime.timedelta(7), 'n':datetime.timedelta(-1), } FEED_TYPES = ( @@ -38,18 +77,52 @@ class EmailFeedSetting(models.Model): ('q_ask',_('Questions that I asked')), ('q_ans',_('Questions that I answered')), ('q_sel',_('Individually selected questions')), + ('m_and_c',_('Mentions and comment responses')), ) UPDATE_FREQUENCY = ( - ('w',_('Weekly')), + ('i',_('Instantly')), ('d',_('Daily')), + ('w',_('Weekly')), ('n',_('No email')), ) - subscriber = models.ForeignKey(User) + + + subscriber = models.ForeignKey(User, related_name='notification_subscriptions') feed_type = models.CharField(max_length=16,choices=FEED_TYPES) - frequency = models.CharField(max_length=8,choices=UPDATE_FREQUENCY,default='n') + frequency = models.CharField( + max_length=8, + choices=const.NOTIFICATION_DELIVERY_SCHEDULE_CHOICES, + default='n', + ) added_at = models.DateTimeField(auto_now_add=True) reported_at = models.DateTimeField(null=True) + #functions for rich comparison + #PRECEDENCE = ('i','d','w','n')#the greater ones are first + #def __eq__(self, other): + # return self.id == other.id + +# def __eq__(self, other): +# return self.id != other.id + +# def __gt__(self, other): +# return PRECEDENCE.index(self.frequency) < PRECEDENCE.index(other.frequency) + +# def __lt__(self, other): +# return PRECEDENCE.index(self.frequency) > PRECEDENCE.index(other.frequency) + +# def __gte__(self, other): +# if self.__eq__(other): +# return True +# else: +# return self.__gt__(other) + +# def __lte__(self, other): +# if self.__eq__(other): +# return True +# else: +# return self.__lt__(other) + def save(self,*args,**kwargs): type = self.feed_type subscriber = self.subscriber |