diff options
author | root <root@u15356270.onlinehome-server.com> | 2009-11-13 20:18:55 -0500 |
---|---|---|
committer | root <root@u15356270.onlinehome-server.com> | 2009-11-13 20:31:40 -0500 |
commit | 7e4f1d542e00b4d3121da6ae5524e95867f2371b (patch) | |
tree | 5a3edfb81cc137dbc877f75f9bde80e9720b3ba0 /forum/models.py | |
parent | 3a4b6ad43221abc0e0ff345d9368c3348b312128 (diff) | |
download | askbot-7e4f1d542e00b4d3121da6ae5524e95867f2371b.tar.gz askbot-7e4f1d542e00b4d3121da6ae5524e95867f2371b.tar.bz2 askbot-7e4f1d542e00b4d3121da6ae5524e95867f2371b.zip |
better comments, email subscriptions, corrected view counter, some ie7 issues, wiki optional with settings.WIKI_ON, site can be mounted on arbitrary url prefix, english language improvements, added feedback form, versioned css and js files to force browser cache reload when settings.RESOURCE_REVISION is incremented , other fixes
Diffstat (limited to 'forum/models.py')
-rw-r--r-- | forum/models.py | 141 |
1 files changed, 110 insertions, 31 deletions
diff --git a/forum/models.py b/forum/models.py index f647ba12..39058bea 100644 --- a/forum/models.py +++ b/forum/models.py @@ -2,7 +2,7 @@ import datetime import hashlib from urllib import quote_plus, urlencode -from django.db import models +from django.db import models, IntegrityError from django.utils.html import strip_tags from django.core.urlresolvers import reverse from django.contrib.auth.models import User @@ -11,33 +11,61 @@ from django.contrib.contenttypes.models import ContentType from django.template.defaultfilters import slugify from django.db.models.signals import post_delete, post_save, pre_save from django.utils.translation import ugettext as _ +from django.utils.safestring import mark_safe import django.dispatch import settings from forum.managers import * from const import * -class EmailFeed(models.Model): - #subscription key for unsubscribe by visiting emailed link - key = models.CharField(max_length=32) - #generic relation with feed content (i.e. question or tags) - feed_content_type = models.ForeignKey(ContentType,related_name='content_emailfeed') - feed_id = models.PositiveIntegerField() - content = generic.GenericForeignKey('feed_content_type','feed_id') - #generic relation with owner - either nameless email or User - subscriber_content_type = models.ForeignKey(ContentType,related_name='subscriber_emailfeed') - subscriber_id = models.PositiveIntegerField() - subscriber = generic.GenericForeignKey('subscriber_content_type','subscriber_id') - added_at = models.DateTimeField(default=datetime.datetime.now) - reported_at = models.DateTimeField(default=datetime.datetime.now) - - #getter functions rely on implementations of similar functions in content - #of subscriber objects - def get_update_summary(self): - return self.content.get_update_summary(last_reported_at = self.reported_at,recipient_email = self.get_email()) - - def get_email(self): - return self.subscriber.email +def get_object_comments(self): + comments = self.comments.all().order_by('id') + return comments + +def post_get_last_update_info(self): + when = self.added_at + who = self.author + if self.last_edited_at and self.last_edited_at > when: + when = self.last_edited_at + who = self.last_edited_by + comments = self.comments.all() + if len(comments) > 0: + for c in comments: + if c.added_at > when: + when = c.added_at + who = c.user + return when, who + +class EmailFeedSetting(models.Model): + DELTA_TABLE = { + 'w':datetime.timedelta(7), + 'd':datetime.timedelta(1), + 'n':datetime.timedelta(-1), + } + FEED_TYPES = ( + ('q_all',_('Entire forum')), + ('q_ask',_('Questions that I asked')), + ('q_ans',_('Questions that I answered')), + ('q_sel',_('Individually selected questions')), + ) + UPDATE_FREQUENCY = ( + ('w',_('Weekly')), + ('d',_('Daily')), + ('n',_('No email')), + ) + subscriber = models.ForeignKey(User) + feed_type = models.CharField(max_length=16,choices=FEED_TYPES) + frequency = models.CharField(max_length=8,choices=UPDATE_FREQUENCY,default='n') + added_at = models.DateTimeField(auto_now_add=True) + reported_at = models.DateTimeField(null=True) + + def save(self,*args,**kwargs): + type = self.feed_type + subscriber = self.subscriber + similar = self.__class__.objects.filter(feed_type=type,subscriber=subscriber).exclude(pk=self.id) + if len(similar) > 0: + raise IntegrityError('email feed setting already exists') + super(EmailFeedSetting,self).save(*args,**kwargs) class Tag(models.Model): name = models.CharField(max_length=255, unique=True) @@ -45,7 +73,6 @@ class Tag(models.Model): deleted = models.BooleanField(default=False) deleted_at = models.DateTimeField(null=True, blank=True) deleted_by = models.ForeignKey(User, null=True, blank=True, related_name='deleted_tags') - email_feeds = generic.GenericRelation(EmailFeed) # Denormalised data used_count = models.PositiveIntegerField(default=0) @@ -136,6 +163,7 @@ class Question(models.Model): locked = models.BooleanField(default=False) locked_by = models.ForeignKey(User, null=True, blank=True, related_name='locked_questions') locked_at = models.DateTimeField(null=True, blank=True) + followed_by = models.ManyToManyField(User, related_name='followed_questions') # Denormalised data score = models.IntegerField(default=0) vote_up_count = models.IntegerField(default=0) @@ -155,7 +183,6 @@ class Question(models.Model): comments = generic.GenericRelation(Comment) votes = generic.GenericRelation(Vote) flagged_items = generic.GenericRelation(FlaggedItem) - email_feeds = generic.GenericRelation(EmailFeed) objects = QuestionManager() @@ -212,6 +239,22 @@ class Question(models.Model): def get_latest_revision(self): return self.revisions.all()[0] + get_comments = get_object_comments + + def get_last_update_info(self): + + when, who = post_get_last_update_info(self) + + answers = self.answers.all() + if len(answers) > 0: + for a in answers: + a_when, a_who = a.get_last_update_info() + if a_when > when: + when = a_when + who = a_who + + return when, who + def get_update_summary(self,last_reported_at=None,recipient_email=''): edited = False if self.last_edited_at and self.last_edited_at > last_reported_at: @@ -240,7 +283,7 @@ class Question(models.Model): answer_comments.append(comment) #create the report - if edited or comments or new_answers or modified_answers or answer_comments: + if edited or new_answers or modified_answers or answer_comments: out = [] if edited: out.append(_('%(author)s modified the question') % {'author':self.last_edited_by.username}) @@ -274,6 +317,11 @@ class Question(models.Model): class Meta: db_table = u'question' +class QuestionView(models.Model): + question = models.ForeignKey(Question, related_name='viewed') + who = models.ForeignKey(User, related_name='question_views') + when = models.DateTimeField() + class FavoriteQuestion(models.Model): """A favorite Question of a User.""" question = models.ForeignKey(Question) @@ -303,7 +351,8 @@ class QuestionRevision(models.Model): return self.question.title def get_absolute_url(self): - return '/%s%s/%s' % (_('questions/'),self.question.id,_('revisions')) + print 'in QuestionRevision.get_absolute_url()' + return reverse('question_revisions', args=[self.question.id]) def save(self, **kwargs): """Looks up the next available revision number.""" @@ -383,6 +432,9 @@ class Answer(models.Model): objects = AnswerManager() + get_comments = get_object_comments + get_last_update_info = post_get_last_update_info + def get_user_vote(self, user): votes = self.votes.filter(user=user) if votes.count() > 0: @@ -397,7 +449,7 @@ class Answer(models.Model): return self.question.title def get_absolute_url(self): - return '%s%s#%s' % (reverse('question', args=[self.question.id]), self.question.title, self.id) + return '%s%s#%s' % (reverse('question', args=[self.question.id]), slugify(self.question.title), self.id) class Meta: db_table = u'answer' @@ -415,7 +467,7 @@ class AnswerRevision(models.Model): text = models.TextField() def get_absolute_url(self): - return '/%s%s/%s' % (_('answers/'),self.answer.id,_('revisions')) + return reverse('answer_revisions', kwargs={'id':self.answer.id}) def get_question_title(self): return self.answer.question.title @@ -538,7 +590,7 @@ class Book(models.Model): questions = models.ManyToManyField(Question, related_name='book', db_table='book_question') def get_absolute_url(self): - return '%s' % reverse('book', args=[self.short_name]) + return reverse('book', args=[self.short_name]) def __unicode__(self): return self.title @@ -577,7 +629,6 @@ class AnonymousEmail(models.Model): key = models.CharField(max_length=32) email = models.EmailField(null=False,unique=True) isvalid = models.BooleanField(default=False) - feeds = generic.GenericRelation(EmailFeed) # User extend properties QUESTIONS_PER_PAGE_CHOICES = ( @@ -586,11 +637,30 @@ QUESTIONS_PER_PAGE_CHOICES = ( (50, u'50'), ) +def user_is_username_taken(cls,username): + try: + cls.objects.get(username=username) + return True + except cls.MultipleObjectsReturned: + return True + except cls.DoesNotExist: + return False + +def user_get_q_sel_email_feed_frequency(self): + print 'looking for frequency for user %s' % self + try: + feed_setting = EmailFeedSetting.objects.get(subscriber=self,feed_type='q_sel') + except Exception, e: + print 'have error %s' % e.message + raise e + print 'have freq=%s' % feed_setting.frequency + return feed_setting.frequency + +User.add_to_class('is_approved', models.BooleanField(default=False)) User.add_to_class('email_isvalid', models.BooleanField(default=False)) User.add_to_class('email_key', models.CharField(max_length=32, null=True)) User.add_to_class('reputation', models.PositiveIntegerField(default=1)) User.add_to_class('gravatar', models.CharField(max_length=32)) -User.add_to_class('email_feeds', generic.GenericRelation(EmailFeed)) User.add_to_class('favorite_questions', models.ManyToManyField(Question, through=FavoriteQuestion, related_name='favorited_by')) @@ -608,6 +678,8 @@ User.add_to_class('website', models.URLField(max_length=200, blank=True)) User.add_to_class('location', models.CharField(max_length=100, blank=True)) User.add_to_class('date_of_birth', models.DateField(null=True, blank=True)) User.add_to_class('about', models.TextField(blank=True)) +User.add_to_class('is_username_taken',classmethod(user_is_username_taken)) +User.add_to_class('get_q_sel_email_feed_frequency',user_get_q_sel_email_feed_frequency) # custom signal tags_updated = django.dispatch.Signal(providing_args=["question"]) @@ -630,7 +702,14 @@ def delete_messages(self): def get_profile_url(self): """Returns the URL for this User's profile.""" return '%s%s/' % (reverse('user', args=[self.id]), slugify(self.username)) + +def get_profile_link(self): + profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(),self.username) + logging.debug('in get profile link %s' % profile_link) + return mark_safe(profile_link) + User.add_to_class('get_profile_url', get_profile_url) +User.add_to_class('get_profile_link', get_profile_link) User.add_to_class('get_messages', get_messages) User.add_to_class('delete_messages', delete_messages) |