summaryrefslogtreecommitdiffstats
path: root/forum/models
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-05-17 02:01:51 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-05-17 02:01:51 -0400
commit4b27cf51837cac1cc79ef79b1006a52bf5d5d18d (patch)
tree3ed61da9efd9aeaeadb80fd538dc34902cef7e1a /forum/models
parent7a7c938c785aa91d9106a4ce1ddd50da8bd66951 (diff)
downloadaskbot-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__.py5
-rw-r--r--forum/models/answer.py3
-rw-r--r--forum/models/base.py14
-rw-r--r--forum/models/meta.py23
-rw-r--r--forum/models/question.py12
-rw-r--r--forum/models/user.py87
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