summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-11-07 22:55:15 -0300
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-11-07 22:55:15 -0300
commit8d6ad91d93302194833ea187c465e5ac0c6795c5 (patch)
tree7add97c8fc118c59c6c6082f57e80807bbd75fe2
parente4945502f2b079b9e53d1646800a7fcba1a0526a (diff)
parent761971c39e0ae517997868c582290076e969c4f2 (diff)
downloadaskbot-8d6ad91d93302194833ea187c465e5ac0c6795c5.tar.gz
askbot-8d6ad91d93302194833ea187c465e5ac0c6795c5.tar.bz2
askbot-8d6ad91d93302194833ea187c465e5ac0c6795c5.zip
Merge branch 'tomasz'
-rw-r--r--askbot/admin.py8
-rw-r--r--askbot/management/commands/send_email_alerts.py8
-rw-r--r--askbot/models/__init__.py6
-rw-r--r--askbot/models/answer.py11
-rw-r--r--askbot/models/base.py102
-rw-r--r--askbot/models/post.py102
-rw-r--r--askbot/models/question.py13
-rw-r--r--askbot/views/users.py68
-rw-r--r--askbot/views/writers.py4
9 files changed, 154 insertions, 168 deletions
diff --git a/askbot/admin.py b/askbot/admin.py
index af62ed84..34722416 100644
--- a/askbot/admin.py
+++ b/askbot/admin.py
@@ -31,10 +31,7 @@ class VoteAdmin(admin.ModelAdmin):
class FavoriteQuestionAdmin(admin.ModelAdmin):
""" admin class"""
-class QuestionRevisionAdmin(admin.ModelAdmin):
- """ admin class"""
-
-class AnswerRevisionAdmin(admin.ModelAdmin):
+class PostRevisionAdmin(admin.ModelAdmin):
""" admin class"""
class AwardAdmin(admin.ModelAdmin):
@@ -52,8 +49,7 @@ admin.site.register(models.Answer, AnswerAdmin)
admin.site.register(models.Comment, CommentAdmin)
admin.site.register(models.Vote, VoteAdmin)
admin.site.register(models.FavoriteQuestion, FavoriteQuestionAdmin)
-admin.site.register(models.QuestionRevision, QuestionRevisionAdmin)
-admin.site.register(models.AnswerRevision, AnswerRevisionAdmin)
+admin.site.register(models.PostRevision, PostRevisionAdmin)
admin.site.register(models.Award, AwardAdmin)
admin.site.register(models.Repute, ReputeAdmin)
admin.site.register(models.Activity, ActivityAdmin)
diff --git a/askbot/management/commands/send_email_alerts.py b/askbot/management/commands/send_email_alerts.py
index 330e1cc9..c904cdde 100644
--- a/askbot/management/commands/send_email_alerts.py
+++ b/askbot/management/commands/send_email_alerts.py
@@ -3,8 +3,8 @@ from django.core.management.base import NoArgsCommand
from django.core.urlresolvers import reverse
from django.db import connection
from django.db.models import Q, F
-from askbot.models import User, Question, Answer, Tag, QuestionRevision
-from askbot.models import AnswerRevision, Activity, EmailFeedSetting
+from askbot.models import User, Question, Answer, Tag, PostRevision
+from askbot.models import Activity, EmailFeedSetting
from askbot.models import Comment
from askbot.models.question import get_tag_summary_from_questions
from django.utils.translation import ugettext as _
@@ -336,7 +336,7 @@ class Command(NoArgsCommand):
#collect info on all sorts of news that happened after
#the most recent emailing to the user about this question
- q_rev = QuestionRevision.objects.filter(
+ q_rev = PostRevision.objects.question_revisions().filter(
question=q,
revised_at__gt=emailed_at
)
@@ -359,7 +359,7 @@ class Command(NoArgsCommand):
new_ans = new_ans.exclude(author=user)
meta_data['new_ans'] = len(new_ans)
- ans_rev = AnswerRevision.objects.filter(
+ ans_rev = PostRevision.objects.answer_revisions().filter(
answer__question = q,
answer__deleted = False,
revised_at__gt = emailed_at
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index 6e23c8f3..807a29b7 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -19,10 +19,10 @@ import askbot
from askbot import exceptions as askbot_exceptions
from askbot import const
from askbot.conf import settings as askbot_settings
-from askbot.models.question import Question, QuestionRevision
+from askbot.models.question import Question
from askbot.models.question import QuestionView, AnonymousQuestion
from askbot.models.question import FavoriteQuestion
-from askbot.models.answer import Answer, AnonymousAnswer, AnswerRevision
+from askbot.models.answer import Answer, AnonymousAnswer
from askbot.models.tag import Tag, MarkedTag
from askbot.models.meta import Vote, Comment
from askbot.models.user import EmailFeedSetting, ActivityAuditStatus, Activity
@@ -2644,13 +2644,11 @@ __all__ = [
'signals',
'Question',
- 'QuestionRevision',
'QuestionView',
'FavoriteQuestion',
'AnonymousQuestion',
'Answer',
- 'AnswerRevision',
'AnonymousAnswer',
'PostRevision',
diff --git a/askbot/models/answer.py b/askbot/models/answer.py
index a694e737..cd9699ec 100644
--- a/askbot/models/answer.py
+++ b/askbot/models/answer.py
@@ -217,7 +217,7 @@ class Answer(content.Content, DeletableContent):
comment = const.POST_STATUS['default_version']
else:
comment = 'No.%s Revision' % rev_no
- return AnswerRevision.objects.create(
+ return PostRevision.objects.create_answer_revision(
answer=self,
author=author,
revised_at=revised_at,
@@ -300,15 +300,6 @@ class Answer(content.Content, DeletableContent):
return self.html
-class AnswerRevision(PostRevision):
- """A revision of an Answer."""
-
- class Meta:
- app_label = 'askbot'
- proxy = True
-
-
-
class AnonymousAnswer(AnonymousContent):
question = models.ForeignKey('Question', related_name='anonymous_answers')
diff --git a/askbot/models/base.py b/askbot/models/base.py
index b4492f0f..5ac2ac7a 100644
--- a/askbot/models/base.py
+++ b/askbot/models/base.py
@@ -1,18 +1,20 @@
import datetime
import cgi
-from django.core.urlresolvers import reverse
+import logging
+
from django.db import models
from django.utils.html import strip_tags
from django.contrib.auth.models import User
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.contrib.sitemaps import ping_google
+
#todo: maybe merge askbot.utils.markup and forum.utils.html
from askbot.utils import markup
from askbot.utils.diff import textDiff as htmldiff
from askbot.utils.html import sanitize_html
from django.utils import html
-import logging
+
#todo: following methods belong to a future common post class
def parse_post_text(post):
@@ -216,102 +218,6 @@ class DeletableContent(models.Model):
app_label = 'askbot'
-class ContentRevision(models.Model):
- """
- Base class for QuestionRevision and AnswerRevision
- """
- QUESTION_REVISION_TEMPLATE_NO_TAGS = (
- '<h3>%(title)s</h3>\n'
- '<div class="text">%(html)s</div>\n'
- )
-
- QUESTION_REVISION = 1
- ANSWER_REVISION = 2
- REVISION_TYPE_CHOICES = (
- (QUESTION_REVISION, 'question'),
- (ANSWER_REVISION, 'answer'),
- )
- REVISION_TYPE_CHOICES_DICT = dict(REVISION_TYPE_CHOICES)
-
- revision_type = models.SmallIntegerField(choices=REVISION_TYPE_CHOICES)
-
- revision = models.PositiveIntegerField()
- author = models.ForeignKey(User, related_name='%(class)ss')
- revised_at = models.DateTimeField()
- summary = models.CharField(max_length=300, blank=True)
- text = models.TextField()
-
- # Question-specific fields
- title = models.CharField(max_length=300, blank=True, default='')
- tagnames = models.CharField(max_length=125, blank=True, default='')
- is_anonymous = models.BooleanField(default=False)
-
- class Meta:
- abstract = True
- app_label = 'askbot'
- ordering = ('-revision',)
-
- def revision_type_str(self):
- return self.REVISION_TYPE_CHOICES_DICT[self.revision_type]
-
- def __unicode__(self):
- return u'%s - revision %s of %s' % (self.revision_type_str(), self.revision, self.title)
-
- def parent(self):
- if self.is_question_revision():
- return self.question
- elif self.is_answer_revision():
- return self.answer
-
- def save(self, **kwargs):
- """Determines the revistion type and then looks up the next available revision number if not set."""
-
- if not self.revision_type:
- # HACK: determine revision_type based on class name - until we have a better way or until make a switch to PostRevision
- # After `revision_type` is set, we can just use it
- if self.__class__.__name__ == 'QuestionRevision':
- self.revision_type = self.QUESTION_REVISION
- elif self.__class__.__name__ == 'AnswerRevision':
- self.revision_type = self.ANSWER_REVISION
-
- if not self.revision:
- # TODO: Maybe use Max() aggregation?
- # TODO: Handle IntegrityError if revision id is already occupied?
- self.revision = self.parent().revisions.values_list('revision', flat=True)[0] + 1
-
- super(ContentRevision, self).save(**kwargs)
-
- def is_question_revision(self):
- return self.revision_type == self.QUESTION_REVISION
-
- def is_answer_revision(self):
- return self.revision_type == self.ANSWER_REVISION
-
- @models.permalink
- def get_absolute_url(self):
- if self.is_question_revision():
- return 'question_revisions', (self.question.id,), {}
- elif self.is_answer_revision():
- return 'answer_revisions', (), {'id':self.answer.id}
-
- def get_question_title(self):
- #INFO: ack-grepping shows that it's only used for Questions, so there's no code for Answers
- return self.question.title
-
- def as_html(self, **kwargs):
- markdowner = markup.get_parser()
- sanitized_html = sanitize_html(markdowner.convert(self.text))
-
- if self.is_question_revision():
- return self.QUESTION_REVISION_TEMPLATE_NO_TAGS % {
- 'title': self.title,
- 'html': sanitized_html
- }
- elif self.is_answer_revision():
- return sanitized_html
-
-
-
class AnonymousContent(models.Model):
"""
Base class for AnonymousQuestion and AnonymousAnswer
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 17f0eb2c..c61e8877 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -1,14 +1,59 @@
from django.db import models
-from askbot.models.base import ContentRevision
+from askbot.utils import markup
+from askbot.utils.html import sanitize_html
#class Post(models.Model):
# pass
-class PostRevision(ContentRevision):
+class PostRevisionManager(models.Manager):
+ def create_question_revision(self, *kargs, **kwargs):
+ kwargs['revision_type'] = self.model.QUESTION_REVISION
+ return self.create(*kargs, **kwargs)
+
+ def create_answer_revision(self, *kargs, **kwargs):
+ kwargs['revision_type'] = self.model.ANSWER_REVISION
+ return self.create(*kargs, **kwargs)
+
+ def question_revisions(self):
+ return self.filter(revision_type=self.model.QUESTION_REVISION)
+
+ def answer_revisions(self):
+ return self.filter(revision_type=self.model.ANSWER_REVISION)
+
+
+class PostRevision(models.Model):
+ QUESTION_REVISION_TEMPLATE_NO_TAGS = (
+ '<h3>%(title)s</h3>\n'
+ '<div class="text">%(html)s</div>\n'
+ )
+
+ QUESTION_REVISION = 1
+ ANSWER_REVISION = 2
+ REVISION_TYPE_CHOICES = (
+ (QUESTION_REVISION, 'question'),
+ (ANSWER_REVISION, 'answer'),
+ )
+ REVISION_TYPE_CHOICES_DICT = dict(REVISION_TYPE_CHOICES)
+
answer = models.ForeignKey('askbot.Answer', related_name='revisions', null=True, blank=True)
question = models.ForeignKey('askbot.Question', related_name='revisions', null=True, blank=True)
+ revision_type = models.SmallIntegerField(choices=REVISION_TYPE_CHOICES)
+
+ revision = models.PositiveIntegerField()
+ author = models.ForeignKey('auth.User', related_name='%(class)ss')
+ revised_at = models.DateTimeField()
+ summary = models.CharField(max_length=300, blank=True)
+ text = models.TextField()
+
+ # Question-specific fields
+ title = models.CharField(max_length=300, blank=True, default='')
+ tagnames = models.CharField(max_length=125, blank=True, default='')
+ is_anonymous = models.BooleanField(default=False)
+
+ objects = PostRevisionManager()
+
class Meta:
# INFO: This `unique_together` constraint might be problematic for databases in which
# 2+ NULLs cannot be stored in an UNIQUE column.
@@ -16,3 +61,56 @@ class PostRevision(ContentRevision):
unique_together = (('answer', 'revision'), ('question', 'revision'))
ordering = ('-revision',)
app_label = 'askbot'
+
+ def revision_type_str(self):
+ return self.REVISION_TYPE_CHOICES_DICT[self.revision_type]
+
+ def __unicode__(self):
+ return u'%s - revision %s of %s' % (self.revision_type_str(), self.revision, self.title)
+
+ def parent(self):
+ if self.is_question_revision():
+ return self.question
+ elif self.is_answer_revision():
+ return self.answer
+
+ def save(self, **kwargs):
+ """Determines the revistion type and then looks up the next available revision number if not set."""
+
+ if not self.revision:
+ # TODO: Maybe use Max() aggregation?
+ # TODO: Handle IntegrityError if revision id is already occupied?
+ self.revision = self.parent().revisions.values_list('revision', flat=True)[0] + 1
+
+ self.full_clean() # Make sure that everything is ok, in particular that `revision_type` and `revision` are set to valid values
+
+ super(PostRevision, self).save(**kwargs)
+
+ def is_question_revision(self):
+ return self.revision_type == self.QUESTION_REVISION
+
+ def is_answer_revision(self):
+ return self.revision_type == self.ANSWER_REVISION
+
+ @models.permalink
+ def get_absolute_url(self):
+ if self.is_question_revision():
+ return 'question_revisions', (self.question.id,), {}
+ elif self.is_answer_revision():
+ return 'answer_revisions', (), {'id':self.answer.id}
+
+ def get_question_title(self):
+ #INFO: ack-grepping shows that it's only used for Questions, so there's no code for Answers
+ return self.question.title
+
+ def as_html(self, **kwargs):
+ markdowner = markup.get_parser()
+ sanitized_html = sanitize_html(markdowner.convert(self.text))
+
+ if self.is_question_revision():
+ return self.QUESTION_REVISION_TEMPLATE_NO_TAGS % {
+ 'title': self.title,
+ 'html': sanitized_html
+ }
+ elif self.is_answer_revision():
+ return sanitized_html
diff --git a/askbot/models/question.py b/askbot/models/question.py
index c2145f73..7f38bd5c 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -24,8 +24,6 @@ from askbot.models import signals
from askbot import const
from askbot.utils.lists import LazyList
from askbot.utils.slug import slugify
-from askbot.utils import markup
-from askbot.utils.html import sanitize_html
from askbot.utils import mysql
#todo: too bad keys are duplicated see const sort methods
@@ -760,7 +758,7 @@ class Question(content.Content, DeletableContent):
# Create a new revision
latest_revision = self.get_latest_revision()
- QuestionRevision.objects.create(
+ PostRevision.objects.create_question_revision(
question = self,
title = latest_revision.title,
author = retagged_by,
@@ -838,7 +836,7 @@ class Question(content.Content, DeletableContent):
else:
comment = 'No.%s Revision' % rev_no
- return QuestionRevision.objects.create(
+ return PostRevision.objects.create_question_revision(
question = self,
revision = rev_no,
title = self.title,
@@ -1007,13 +1005,6 @@ class FavoriteQuestion(models.Model):
def __unicode__(self):
return '[%s] favorited at %s' %(self.user, self.added_at)
-class QuestionRevision(PostRevision):
- """A revision of a Question."""
-
- class Meta:
- app_label = 'askbot'
- proxy = True
-
class AnonymousQuestion(AnonymousContent):
"""question that was asked before logging in
diff --git a/askbot/views/users.py b/askbot/views/users.py
index f1f29f71..09acad07 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -38,27 +38,30 @@ from askbot.templatetags import extra_tags
question_type = ContentType.objects.get_for_model(models.Question)
answer_type = ContentType.objects.get_for_model(models.Answer)
comment_type = ContentType.objects.get_for_model(models.Comment)
-question_revision_type = ContentType.objects.get_for_model(
- models.QuestionRevision
- )
-
-answer_revision_type = ContentType.objects.get_for_model(
- models.AnswerRevision
- )
+post_revision_type = ContentType.objects.get_for_model(models.PostRevision)
repute_type = ContentType.objects.get_for_model(models.Repute)
+
question_type_id = question_type.id
answer_type_id = answer_type.id
comment_type_id = comment_type.id
-question_revision_type_id = question_revision_type.id
-answer_revision_type_id = answer_revision_type.id
+post_revision_type_id = post_revision_type.id
repute_type_id = repute_type.id
#todo: queries in the user activity summary view must be redone
-def get_related_object_type_name(content_type_id):
- if content_type_id in (question_type_id, question_revision_type_id,):
+def get_related_object_type_name(content_type_id, object_id):
+# if content_type_id in (question_type_id, question_revision_type_id,):
+# return 'question'
+# elif content_type_id in (answer_type_id, answer_revision_type_id,):
+# return 'answer'
+
+ if content_type_id == question_type_id:
return 'question'
- elif content_type_id in (answer_type_id, answer_revision_type_id,):
+ elif content_type_id == answer_type_id:
return 'answer'
+ elif content_type_id == post_revision_type_id:
+ post_revision = models.PostRevision.objects.get(id=object_id)
+ return post_revision.revision_type_str()
+
return None
def owner_or_moderator_required(f):
@@ -556,18 +559,20 @@ def user_recent(request, user, context):
# question revisions
revisions = models.Activity.objects.extra(
select={
- 'title' : 'question_revision.title',
- 'question_id' : 'question_revision.question_id',
+ 'title' : 'askbot_postrevision.title',
+ 'question_id' : 'askbot_postrevision.question_id',
'added_at' : 'activity.active_at',
'activity_type' : 'activity.activity_type',
- 'summary' : 'question_revision.summary'
+ 'summary' : 'askbot_postrevision.summary'
},
- tables=['activity', 'question_revision', 'question'],
- where=['activity.content_type_id = %s AND activity.object_id = question_revision.id AND '+
- 'question_revision.id=question.id AND NOT question.deleted AND '+
- 'activity.user_id = question_revision.author_id AND activity.user_id = %s AND '+
- 'activity.activity_type=%s'],
- params=[question_revision_type_id, user.id, const.TYPE_ACTIVITY_UPDATE_QUESTION],
+ tables=['activity', 'askbot_postrevision', 'question'],
+ where=['''
+ activity.content_type_id=%s AND activity.object_id=askbot_postrevision.id AND
+ askbot_postrevision.question_id=question.id AND askbot_postrevision.revision_type=%s AND NOT question.deleted AND
+ activity.user_id=askbot_postrevision.author_id AND activity.user_id=%s AND
+ activity.activity_type=%s
+ '''],
+ params=[post_revision_type_id, models.PostRevision.QUESTION_REVISION, user.id, const.TYPE_ACTIVITY_UPDATE_QUESTION],
order_by=['-activity.active_at']
).values(
'title',
@@ -590,16 +595,17 @@ def user_recent(request, user, context):
'answer_id' : 'answer.id',
'added_at' : 'activity.active_at',
'activity_type' : 'activity.activity_type',
- 'summary' : 'answer_revision.summary'
+ 'summary' : 'askbot_postrevision.summary'
},
- tables=['activity', 'answer_revision', 'question', 'answer'],
-
- where=['activity.content_type_id = %s AND activity.object_id = answer_revision.id AND '+
- 'activity.user_id = answer_revision.author_id AND activity.user_id = %s AND '+
- 'answer_revision.answer_id=answer.id AND answer.question_id = question.id AND '+
- 'NOT question.deleted AND NOT answer.deleted AND '+
- 'activity.activity_type=%s'],
- params=[answer_revision_type_id, user.id, const.TYPE_ACTIVITY_UPDATE_ANSWER],
+ tables=['activity', 'askbot_postrevision', 'question', 'answer'],
+ where=['''
+ activity.content_type_id=%s AND activity.object_id=askbot_postrevision.id AND
+ askbot_postrevision.answer_id=answer.id AND askbot_postrevision.revision_type=%s AND
+ answer.question_id=question.id AND NOT question.deleted AND NOT answer.deleted AND
+ activity.user_id=askbot_postrevision.author_id AND activity.user_id=%s AND
+ activity.activity_type=%s
+ '''],
+ params=[post_revision_type_id, models.PostRevision.ANSWER_REVISION, user.id, const.TYPE_ACTIVITY_UPDATE_ANSWER],
order_by=['-activity.active_at']
).values(
'title',
@@ -662,7 +668,7 @@ def user_recent(request, user, context):
'activity_type'
)
for award in awards:
- related_object_type = get_related_object_type_name(award['content_type_id'])
+ related_object_type = get_related_object_type_name(content_type_id=award['content_type_id'], object_id=award['object_id'])
activities.append(
AwardEvent(
award['awarded_at'],
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 8b07681a..b7b7e96d 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -363,7 +363,7 @@ def edit_question(request, id):
if revision_form.is_valid():
# Replace with those from the selected revision
rev_id = revision_form.cleaned_data['revision']
- selected_revision = models.QuestionRevision.objects.get(
+ selected_revision = models.PostRevision.objects.question_revisions().get(
question = question,
revision = rev_id
)
@@ -448,7 +448,7 @@ def edit_answer(request, id):
if revision_form.is_valid():
# Replace with those from the selected revision
rev = revision_form.cleaned_data['revision']
- selected_revision = models.AnswerRevision.objects.get(
+ selected_revision = models.PostRevision.objects.answer_revisions().get(
answer = answer,
revision = rev
)