from forum.models import *\r
from forum.models.base import marked_deleted\r
from forum.models.meta import vote_canceled\r
+from forum.models.answer import answer_accepted\r
from forum.authentication import user_updated\r
from forum.const import *\r
\r
\r
def record_revision_event(instance, created, **kwargs):\r
if created and instance.revision <> 1 and instance.node.node_type in ('question', 'answer',):\r
- activity_type = instance.node == 'question' and TYPE_ACTIVITY_UPDATE_QUESTION or TYPE_ACTIVITY_UPDATE_ANSWER\r
+ activity_type = instance.node.node_type == 'question' and TYPE_ACTIVITY_UPDATE_QUESTION or TYPE_ACTIVITY_UPDATE_ANSWER\r
activity = Activity(user=instance.author, active_at=instance.revised_at, content_object=instance, activity_type=activity_type)\r
activity.save()\r
\r
post_save.connect(record_award_event, sender=Award)\r
\r
\r
-def record_answer_accepted(instance, created, **kwargs):\r
- if not created and 'accepted' in instance.get_dirty_fields() and instance.accepted:\r
- activity = Activity(user=instance.question.author, active_at=datetime.datetime.now(), \\r
- content_object=instance, activity_type=TYPE_ACTIVITY_MARK_ANSWER)\r
- activity.save()\r
+def record_answer_accepted(answer, user, **kwargs):\r
+ activity = Activity(user=user, active_at=datetime.datetime.now(), content_object=answer, activity_type=TYPE_ACTIVITY_MARK_ANSWER)\r
+ activity.save()\r
\r
-post_save.connect(record_answer_accepted, sender=Answer)\r
+answer_accepted.connect(record_answer_accepted)\r
\r
\r
def update_last_seen(instance, **kwargs):\r
self.accepted_at = datetime.datetime.now()
self.accepted_by = user
self.save()
- self.question.answer_accepted = True
+ self.question.accepted_answer = self
self.question.save()
+ answer_accepted.send(sender=Answer, answer=self, user=user)
return True
return False
- def unmark_accepted(self):
+ def unmark_accepted(self, user):
if self.accepted:
self.accepted = False
self.save()
- self.question.answer_accepted = False
+ self.question.accepted_answer = None
self.question.save()
+ answer_accepted_canceled.send(sender=Answer, answer=self, user=user)
return True
return False
def __unicode__(self):
return self.html
+answer_accepted = django.dispatch.Signal(providing_args=['answer', 'user'])
+answer_accepted_canceled = django.dispatch.Signal(providing_args=['answer', 'user'])
class AnswerRevision(NodeRevision):
class Meta:
question_view = django.dispatch.Signal(providing_args=['instance', 'user'])
class Question(QandA):
- answer_accepted = models.BooleanField(default=False)
+ accepted_answer = models.OneToOneField('Answer', null=True, related_name="question_accepting")
closed = models.BooleanField(default=False)
closed_by = models.ForeignKey(User, null=True, blank=True, related_name='closed_questions')
closed_at = models.DateTimeField(null=True, blank=True)
return self.title
+ @property
+ def answer_accepted(self):
+ return self.accepted_answer is not None
+
def delete(self):
super(Question, self).delete()
try:
return super(UndeletedObjectManager, self).get_query_set().exclude(used_count=0)
-class Tag(DeletableContent):
+class Tag(BaseModel, DeletableContent):
name = models.CharField(max_length=255, unique=True)
created_by = models.ForeignKey(User, related_name='created_tags')
marked_by = models.ManyToManyField(User, related_name="marked_tags", through="MarkedTag")
from django.db.models.signals import post_save\r
from forum.models.meta import vote_canceled\r
+from forum.models.answer import answer_accepted, answer_accepted_canceled\r
\r
from forum.models import *\r
from forum.const import *\r
\r
post_save.connect(on_flagged_item, sender=FlaggedItem)\r
\r
+def on_answer_accepted(answer, user, **kwargs):\r
+ if user == answer.question.author and not user == answer.author:\r
+ user.reputes.create(\r
+ value=int(settings.REP_GAIN_BY_ACCEPTING), question=answer.question,\r
+ reputation_type=TYPE_REPUTATION_GAIN_BY_ACCEPTING_ANSWER)\r
\r
-def on_answer_accepted_switch(instance, created, **kwargs):\r
- if not created and 'accepted' in instance.get_dirty_fields() and (\r
- not instance.accepted_by == instance.question.author):\r
- repute_type, repute_value = instance.accepted and (\r
- TYPE_REPUTATION_GAIN_BY_ANSWER_ACCEPTED, int(settings.REP_GAIN_BY_ACCEPTED)) or (\r
- TYPE_REPUTATION_LOST_BY_ACCEPTED_ANSWER_CANCELED, -int(settings.REP_LOST_BY_ACCEPTED_CANCELED))\r
+ if not user == answer.author:\r
+ answer.author.reputes.create(\r
+ value=int(settings.REP_GAIN_BY_ACCEPTED), question=answer.question,\r
+ reputation_type=TYPE_REPUTATION_GAIN_BY_ANSWER_ACCEPTED)\r
\r
- instance.author.reputes.create(value=repute_value, question=instance.question, reputation_type=repute_type)\r
- \r
- if instance.accepted_by == instance.question.author:\r
- repute_type, repute_value = instance.accepted and (\r
- TYPE_REPUTATION_GAIN_BY_ACCEPTING_ANSWER, int(settings.REP_GAIN_BY_ACCEPTING)) or (\r
- TYPE_REPUTATION_LOST_BY_CANCELLING_ACCEPTED_ANSWER, -int(settings.REP_LOST_BY_CANCELING_ACCEPTED))\r
+answer_accepted.connect(on_answer_accepted)\r
\r
- instance.question.author.reputes.create(value=repute_value, question=instance.question, reputation_type=repute_type)\r
\r
-post_save.connect(on_answer_accepted_switch, sender=Answer)\r
+def on_answer_accepted_canceled(answer, user, **kwargs):\r
+ if user == answer.accepted_by:\r
+ user.reputes.create(\r
+ value=-int(settings.REP_LOST_BY_CANCELING_ACCEPTED), question=answer.question,\r
+ reputation_type=TYPE_REPUTATION_LOST_BY_CANCELLING_ACCEPTED_ANSWER)\r
+\r
+ if not user == answer.author:\r
+ answer.author.reputes.create(\r
+ value=-int(settings.REP_LOST_BY_ACCEPTED_CANCELED), question=answer.question,\r
+ reputation_type=TYPE_REPUTATION_LOST_BY_ACCEPTED_ANSWER_CANCELED)\r
+\r
+answer_accepted_canceled.connect(on_answer_accepted)\r
\r
\r
def on_vote(instance, created, **kwargs):\r
commands = {}
if answer.accepted:
- answer.unmark_accepted()
+ answer.unmark_accepted(user)
commands['unmark_accepted'] = [answer.id]
else:
- try:
- accepted = question.answers.get(accepted=True)
- accepted.unmark_accepted()
+ if question.accepted_answer is not None:
+ accepted = question.accepted_answer
+ accepted.unmark_accepted(user)
commands['unmark_accepted'] = [accepted.id]
- except:
- #import sys, traceback
- #traceback.print_exc(file=sys.stdout)
- pass
answer.mark_accepted(user)
commands['mark_accepted'] = [answer.id]
response = func(request, *args, **kwargs)\r
response['success'] = True\r
except Exception, e:\r
- import sys, traceback\r
- traceback.print_exc(file=sys.stdout)\r
+ #import sys, traceback\r
+ #traceback.print_exc(file=sys.stdout)\r
\r
response = {\r
'success': False,\r
@decorators.render('questions.html', 'unanswered')
def unanswered(request):
- return question_list(request, Question.objects.filter(answer_accepted=False),
+ return question_list(request, Question.objects.filter(accepted_answer=None),
_('Open questions without an accepted answer'))
@decorators.render('questions.html', 'questions')
return (view_id, view_dic[view_id])
def update_question_view_times(request, question):
- if not 'question_view_times' in request.session:
- request.session['question_view_times'] = {}
+ if not 'last_seen_in_question' in request.session:
+ request.session['last_seen_in_question'] = {}
- last_seen = request.session['question_view_times'].get(question.id,None)
+ last_seen = request.session['last_seen_in_question'].get(question.id,None)
- if not last_seen or last_seen < question.last_activity_at:
+ if (not last_seen) or last_seen < question.last_activity_at:
question_view.send(sender=update_question_view_times, instance=question, user=request.user)
- request.session['question_view_times'][question.id] = datetime.datetime.now()
+ request.session['last_seen_in_question'][question.id] = datetime.datetime.now()
- request.session['question_view_times'][question.id] = datetime.datetime.now()
+ request.session['last_seen_in_question'][question.id] = datetime.datetime.now()
def question(request, id, slug):
question = get_object_or_404(Question, id=id)