summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-06-23 01:27:15 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2010-06-23 01:27:15 -0400
commit4261942ef2123940a3741bc7b29863fa1518c359 (patch)
treea4693e6da707711f6f5b92906ce6b55f9e4dcdef
parente85adf774cdd0f583950e26204712d8158ed7ffa (diff)
downloadaskbot-4261942ef2123940a3741bc7b29863fa1518c359.tar.gz
askbot-4261942ef2123940a3741bc7b29863fa1518c359.tar.bz2
askbot-4261942ef2123940a3741bc7b29863fa1518c359.zip
fixed a bug with response deletion, added a test case and fixed robots.txt url
-rw-r--r--askbot/models/__init__.py22
-rw-r--r--askbot/models/meta.py30
-rw-r--r--askbot/models/user.py1
-rw-r--r--askbot/tests.py92
-rw-r--r--askbot/urls.py2
-rw-r--r--askbot/views/readers.py76
6 files changed, 168 insertions, 55 deletions
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index bbda9773..7ed64cd4 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -226,6 +226,24 @@ def flag_post(user, post, timestamp=None, cancel=False):
)
auth.onFlaggedItem(flag, post, user, timestamp=timestamp)
+def user_increment_response_count(user):
+ """increment response counter for user
+ by one
+ """
+ user.response_count += 1
+
+def user_decrement_response_count(user):
+ """decrement response count for the user
+ by one, log critical error if count would go below zero
+ but limit decrementation at zero exactly
+ """
+ if user.response_count > 0:
+ user.response_count -= 1
+ else:
+ logging.critical(
+ 'response count wanted to go below zero'
+ )
+
User.add_to_class('is_username_taken',classmethod(user_is_username_taken))
User.add_to_class(
'get_q_sel_email_feed_frequency',
@@ -241,6 +259,8 @@ 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)
User.add_to_class('toggle_favorite_question', toggle_favorite_question)
+User.add_to_class('decrement_response_count', user_decrement_response_count)
+User.add_to_class('increment_response_count', user_increment_response_count)
#todo: move this to askbot/utils ??
def format_instant_notification_body(
@@ -379,7 +399,7 @@ def record_post_update_activity(
assert(updated_by not in receiving_users)
for user in set(receiving_users) | set(newly_mentioned_users):
- user.response_count += 1
+ user.increment_response_count()
user.save()
#todo: weird thing is that only comments need the receiving_users
diff --git a/askbot/models/meta.py b/askbot/models/meta.py
index 00ee60c7..370fefac 100644
--- a/askbot/models/meta.py
+++ b/askbot/models/meta.py
@@ -1,4 +1,5 @@
import datetime
+from django.contrib.contenttypes.models import ContentType
from django.db import models
from askbot import const
from askbot.models import base
@@ -192,12 +193,35 @@ class Comment(base.MetaContent, base.UserContent):
return self.added_at
def delete(self, **kwargs):
+ """deletes comment and concomitant response activity
+ records, as well as mention records, while preserving
+ integrity or response counts for the users
+ """
#todo: not very good import in models of other models
#todo: potentially a circular import
from askbot.models.user import Activity
- Activity.objects.get_mentions(
- mentioned_in = self
- ).delete()
+ comment_content_type = ContentType.objects.get_for_model(self)
+ comment_id = self.id
+
+ #on these activities decrement response counter
+ #todo: implement a custom delete method on these
+ #all this should pack into Activity.responses.filter( somehow ).delete()
+ response_activity_types = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY
+ activities = Activity.objects.filter(
+ content_type = comment_content_type,
+ object_id = comment_id,
+ activity_type__in = response_activity_types
+ )
+ for activity in activities:
+ for user in activity.receiving_users.all():
+ user.decrement_response_count()
+ user.save()
+ activities.delete()
+
+ #mentions - simply delete
+ mentions = Activity.objects.get_mentions(mentioned_in = self)
+ mentions.delete()
+
super(Comment,self).delete(**kwargs)
def get_absolute_url(self):
diff --git a/askbot/models/user.py b/askbot/models/user.py
index 5fe18858..40445d70 100644
--- a/askbot/models/user.py
+++ b/askbot/models/user.py
@@ -12,7 +12,6 @@ from django.utils.translation import ugettext as _
from askbot import const
from askbot.utils import functions
-
class ResponseAndMentionActivityManager(models.Manager):
def get_query_set(self):
response_types = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY
diff --git a/askbot/tests.py b/askbot/tests.py
index 12eb03a3..dcdf0782 100644
--- a/askbot/tests.py
+++ b/askbot/tests.py
@@ -129,6 +129,95 @@ class UpdateNotificationTests(TestCase):
comment = 'comment33'
)
+ def post_then_delete_answer_comment(self):
+ pass
+
+ def post_then_delete_answer(self):
+ pass
+
+ def post_then_delete_question_comment(self):
+ pass
+
+ def post_mention_in_question_then_delete(self):
+ pass
+
+ def post_mention_in_answer_then_delete(self):
+ pass
+
+ def post_mention_in_question_then_edit_out(self):
+ pass
+
+ def post_mention_in_answer_then_edit_out(self):
+ pass
+
+ def test_post_mention_in_question_comment_then_delete(self):
+ self.reset_response_counts()
+ time.sleep(1)
+ timestamp = datetime.datetime.now()
+ comment = self.question.add_comment(
+ user = self.u11,
+ comment = '@user12 howyou doin?',
+ added_at = timestamp
+ )
+ comment.delete()
+ notifications = get_re_notif_after(timestamp)
+ self.assertEqual(len(notifications), 0)
+ self.reload_users()
+ self.assertEqual(
+ [
+ self.u11.response_count,
+ self.u12.response_count,
+ self.u13.response_count,
+ self.u14.response_count,
+ self.u21.response_count,
+ self.u22.response_count,
+ self.u23.response_count,
+ self.u24.response_count,
+ self.u31.response_count,
+ self.u32.response_count,
+ self.u33.response_count,
+ self.u34.response_count,
+ ],
+ [
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ]
+ )
+ self.reset_response_counts()
+ time.sleep(1)
+ timestamp = datetime.datetime.now()
+ comment = self.answer1.add_comment(
+ user = self.u21,
+ comment = 'hey @user22 blah',
+ added_at = timestamp
+ )
+ comment.delete()
+ notifications = get_re_notif_after(timestamp)
+ self.assertEqual(len(notifications), 0)
+ self.reload_users()
+ self.assertEqual(
+ [
+ self.u11.response_count,
+ self.u12.response_count,
+ self.u13.response_count,
+ self.u14.response_count,
+ self.u21.response_count,
+ self.u22.response_count,
+ self.u23.response_count,
+ self.u24.response_count,
+ self.u31.response_count,
+ self.u32.response_count,
+ self.u33.response_count,
+ self.u34.response_count,
+ ],
+ [
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ 0, 0, 0, 0,
+ ]
+ )
+
def test_self_comments(self):
self.reset_response_counts()
time.sleep(1)
@@ -636,7 +725,7 @@ class AnonymousVisitorTests(TestCase):
def try_url(
url_name, status_code=200, template=None,
kwargs={}, redirect_url=None, follow=False,
- data = {}
+ data = {},
):
url = reverse(url_name, kwargs = kwargs)
url_info = 'getting url %s' % url
@@ -656,6 +745,7 @@ class AnonymousVisitorTests(TestCase):
self.assertEqual(r.template[0].name, template)
try_url('sitemap')
+ try_url('feeds', kwargs={'url':'rss'})
try_url('about', template='about.html')
try_url('privacy', template='privacy.html')
try_url('logout', template='logout.html')
diff --git a/askbot/urls.py b/askbot/urls.py
index 1a3b59cb..9274f6dc 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -189,7 +189,7 @@ urlpatterns = patterns('',
name='read_message'
),
url(
- r'^feeds/rss/$',
+ r'^feeds/(?P<url>.*)/$',
'django.contrib.syndication.views.feed',
{'feed_dict': feeds},
name='feeds'
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 07390289..80246d51 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -332,66 +332,46 @@ def question(request, id):#refactor - long subroutine. display question body, an
#2) question view count per user
if request.user.is_authenticated():
+
+ #get response notifications
+ ACTIVITY_TYPES = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY
+ ACTIVITY_TYPES += (const.TYPE_ACTIVITY_MENTION,)
+ response_activities = Activity.objects.filter(
+ receiving_users = request.user,
+ activity_type__in = ACTIVITY_TYPES,
+ )
try:
question_view = QuestionView.objects.get(
who=request.user,
question=question
)
- #another task - remove the response alert if it exists
- ACTIVITY_TYPES = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY
- ACTIVITY_TYPES += (const.TYPE_ACTIVITY_MENTION,)
- response_activities = Activity.objects.filter(
- receiving_users = request.user,
- activity_type__in = ACTIVITY_TYPES,
+ response_activities = response_activities.filter(
active_at__gt = question_view.when
)
-
- for activity in response_activities:
- post = activity.content_object
- if hasattr(post, 'get_origin_post'):
- if question == post.get_origin_post():
- activity.receiving_users.remove(request.user)
- if request.user.response_count > 0:
- request.user.response_count -= 1
- request.user.save()
- else:
- logging.critical(
- 'response count wanted to go below zero'
- )
- else:
- logging.critical(
- 'activity content object has no get_origin_post method'
- )
-
except QuestionView.DoesNotExist:
- question_view = QuestionView(who=request.user, question=question)
- #todo: cleanup this cut/paste
- ACTIVITY_TYPES = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY
- ACTIVITY_TYPES += (const.TYPE_ACTIVITY_MENTION,)
- response_activities = Activity.objects.filter(
- receiving_users = request.user,
- activity_type__in = ACTIVITY_TYPES,
- )
-
- for activity in response_activities:
- post = activity.content_object
- if hasattr(post, 'get_origin_post'):
- if question == post.get_origin_post():
- activity.receiving_users.remove(request.user)
- if request.user.response_count > 0:
- request.user.response_count -= 1
- request.user.save()
- else:
- logging.critical(
- 'response count wanted to go below zero'
+ question_view = QuestionView(
+ who=request.user,
+ question=question
)
- else:
- logging.critical(
- 'activity content object has no get_origin_post method'
- )
question_view.when = datetime.datetime.now()
question_view.save()
+ #filter response activities (already directed to the qurrent user
+ #as per the query in the beginning of this if branch)
+ #that refer to the children of the currently
+ #viewed question and clear them for the current user
+ for activity in response_activities:
+ post = activity.content_object
+ if hasattr(post, 'get_origin_post'):
+ if question == post.get_origin_post():
+ activity.receiving_users.remove(request.user)
+ request.user.decrement_response_count()
+ request.user.save()
+ else:
+ logging.critical(
+ 'activity content object has no get_origin_post method'
+ )
+
return render_to_response('question.html', {
'view_name': 'question',
'active_tab': 'questions',