summaryrefslogtreecommitdiffstats
path: root/forum/models/question.py
diff options
context:
space:
mode:
Diffstat (limited to 'forum/models/question.py')
-rwxr-xr-xforum/models/question.py157
1 files changed, 133 insertions, 24 deletions
diff --git a/forum/models/question.py b/forum/models/question.py
index 7ad17555..8f59c448 100755
--- a/forum/models/question.py
+++ b/forum/models/question.py
@@ -1,15 +1,18 @@
from base import *
from tag import Tag
-#todo: take care of copy-paste markdowner stuff maybe make html automatic field?
from forum.const import CONST
-from markdown2 import Markdown
-from django.utils.html import strip_tags
from forum.utils.html import sanitize_html
+from markdown2 import Markdown
+from django.utils.html import strip_tags
import datetime
markdowner = Markdown(html4tags=True)
+from forum.utils.lists import LazyList
+
class QuestionManager(models.Manager):
- def create_new(self, title=None,author=None,added_at=None, wiki=False,tagnames=None,summary=None, text=None):
+ def create_new(cls, title=None,author=None,added_at=None, wiki=False,tagnames=None, text=None):
+ html = sanitize_html(markdowner.convert(text))
+ summary = strip_tags(html)[:120]
question = Question(
title = title,
author = author,
@@ -18,7 +21,7 @@ class QuestionManager(models.Manager):
last_activity_by = author,
wiki = wiki,
tagnames = tagnames,
- html = sanitize_html(markdowner.convert(text)),
+ html = html,
summary = summary
)
if question.wiki:
@@ -28,16 +31,11 @@ class QuestionManager(models.Manager):
question.save()
- # create the first revision
- QuestionRevision.objects.create(
- question = question,
- revision = 1,
- title = question.title,
- author = author,
- revised_at = added_at,
- tagnames = question.tagnames,
- summary = CONST['default_version'],
- text = text
+ question.add_revision(
+ author=author,
+ text=text,
+ comment=CONST['default_version'],
+ revised_at=added_at,
)
return question
@@ -74,6 +72,9 @@ class QuestionManager(models.Manager):
return False
+ #todo: why not make this into a method of class Question?
+ # also it is actually strange - why do we need the answer_count
+ # field if the count depends on who is requesting this?
def update_answer_count(self, question):
"""
Executes an UPDATE query to update denormalised data with the
@@ -105,17 +106,25 @@ class QuestionManager(models.Manager):
Questions with the individual tags will be added to list if above questions are not full.
"""
#print datetime.datetime.now()
- questions = list(self.filter(tagnames = question.tagnames, deleted=False).all())
- tags_list = question.tags.all()
- for tag in tags_list:
- extend_questions = self.filter(tags__id = tag.id, deleted=False)[:50]
- for item in extend_questions:
- if item not in questions and len(questions) < 10:
- questions.append(item)
+ manager = self
+
+ def get_data():
+ questions = list(manager.filter(tagnames = question.tagnames, deleted=False).all())
+
+ tags_list = question.tags.all()
+ for tag in tags_list:
+ extend_questions = manager.filter(tags__id = tag.id, deleted=False)[:50]
+ for item in extend_questions:
+ if item not in questions and len(questions) < 10:
+ questions.append(item)
+
+ #print datetime.datetime.now()
+ return questions
+
+ return LazyList(get_data)
+
- #print datetime.datetime.now()
- return questions
class Question(Content, DeletableContent):
title = models.CharField(max_length=300)
@@ -150,6 +159,105 @@ class Question(Content, DeletableContent):
except Exception:
logging.debug('problem pinging google did you register you sitemap with google?')
+ 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')
+ # Update the Question itself
+ self.tagnames = tagnames
+ self.last_edited_at = retagged_at
+ self.last_activity_at = retagged_at
+ self.last_edited_by = retagged_by
+ self.last_activity_by = retagged_by
+
+ # Update the Question's tag associations
+ tags_updated = self.objects.update_tags(self,
+ form.cleaned_data['tags'], request.user)
+
+ # Create a new revision
+ latest_revision = self.get_latest_revision()
+ QuestionRevision.objects.create(
+ question = self,
+ title = latest_revision.title,
+ author = retagged_by,
+ revised_at = retagged_at,
+ tagnames = tagnames,
+ summary = CONST['retagged'],
+ text = latest_revision.text
+ )
+ # send tags updated singal
+ tags_updated.send(sender=question.__class__, question=self)
+
+ def apply_edit(self, edited_at=None, edited_by=None, title=None,\
+ text=None, comment=None, tags=None, wiki=False):
+
+ latest_revision = self.get_latest_revision()
+ #a hack to allow partial edits - important for SE loader
+ if title is None:
+ title = self.title
+ if text is None:
+ text = latest_revision.text
+ if tags is None:
+ tags = latest_revision.tagnames
+
+ if edited_by is None:
+ raise Exception('parameter edited_by is required')
+
+ if edited_at is None:
+ edited_at = datetime.datetime.now()
+
+ #todo: have this copy-paste in few places
+ html = sanitize_html(markdowner.convert(text))
+ question_summary = strip_tags(html)[:120]
+
+ # Update the Question itself
+ self.title = title
+ self.last_edited_at = edited_at
+ self.last_activity_at = edited_at
+ self.last_edited_by = edited_by
+ self.last_activity_by = edited_by
+ self.tagnames = tags
+ self.summary = question_summary
+ self.html = html
+
+ #wiki is an eternal trap whence there is no exit
+ if self.wiki == False and wiki == True:
+ self.wiki = True
+
+ self.save()
+
+ # Update the Question tag associations
+ if latest_revision.tagnames != tags:
+ tags_updated = Question.objects.update_tags(self, tags, edited_by)
+
+ # Create a new revision
+ self.add_revision(
+ author = edited_by,
+ text = text,
+ revised_at = edited_at,
+ comment = comment,
+ )
+
+ def add_revision(self,author=None, text=None, comment=None, revised_at=None):
+ if None in (author, text, comment):
+ raise Exception('author, text and revised_at are required arguments')
+ rev_no = self.revisions.all().count() + 1
+ if comment in (None, ''):
+ if rev_no == 1:
+ comment = CONST['default_version']
+ else:
+ comment = 'No.%s Revision' % rev_no
+
+ return QuestionRevision.objects.create(
+ question = self,
+ revision = rev_no,
+ title = self.title,
+ author = author,
+ revised_at = revised_at,
+ tagnames = self.tagnames,
+ summary = comment,
+ text = text
+ )
+
def save(self, **kwargs):
"""
Overridden to manually manage addition of tags when the object
@@ -335,6 +443,7 @@ class AnonymousQuestion(AnonymousContent):
def publish(self,user):
added_at = datetime.datetime.now()
qm = QuestionManager()
+ #todo: use as classmethod instead??
qm.create_new(title=self.title, author=user, added_at=added_at,
wiki=self.wiki, tagnames=self.tagnames,
summary=self.summary, text=self.text)