diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index b36137863c..20aea9365e 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -24,7 +24,7 @@ from django.utils.translation import ungettext from django.utils.safestring import mark_safe from django.utils.html import escape -from django.db import models +from django.db import models, transaction from django.db.models import Count from django.conf import settings as django_settings from django.contrib.contenttypes.models import ContentType @@ -66,6 +66,7 @@ from askbot.utils.html import site_url from askbot.utils.db import table_exists from askbot.utils.url_utils import strip_path +from askbot.utils import functions from askbot import mail from askbot import signals @@ -3451,6 +3452,7 @@ def get_reply_to_addresses(user, post): return primary_addr, secondary_addr +@transaction.commit_manually def notify_author_of_published_revision(revision=None, was_approved=False, **kwargs): """notifies author about approved post revision, assumes that we have the very first revision @@ -3458,7 +3460,9 @@ def notify_author_of_published_revision(revision=None, was_approved=False, **kwa #only email about first revision if revision.should_notify_author_about_publishing(was_approved): from askbot.tasks import notify_author_of_published_revision_celery_task + transaction.commit() notify_author_of_published_revision_celery_task.delay(revision.pk) + transaction.commit() #todo: move to utils @@ -3470,6 +3474,7 @@ def calculate_gravatar_hash(instance, **kwargs): instance.gravatar = hashlib.md5(clean_email).hexdigest() +@transaction.commit_manually def record_post_update_activity( post, newly_mentioned_users=None, @@ -3492,16 +3497,19 @@ def record_post_update_activity( from askbot import tasks + mentioned_ids = [u.id for u in newly_mentioned_users] + + transaction.commit() tasks.record_post_update_celery_task.delay( post_id=post.id, - post_content_type_id=ContentType.objects.get_for_model(post).id, - newly_mentioned_user_id_list=[u.id for u in newly_mentioned_users], + newly_mentioned_user_id_list=mentioned_ids, updated_by_id=updated_by.id, suppress_email=suppress_email, timestamp=timestamp, created=created, diff=diff, ) + transaction.commit() def record_award_event(instance, created, **kwargs): @@ -3605,6 +3613,37 @@ def record_user_visit(user, timestamp, **kwargs): User.objects.filter(id=user.id).update(**update_data) +@transaction.commit_manually +def record_question_visit(request, question, **kwargs): + if functions.not_a_robot_request(request): + #todo: split this out into a subroutine + #todo: merge view counts per user and per session + #1) view count per session + if 'question_view_times' not in request.session: + request.session['question_view_times'] = {} + + last_seen = request.session['question_view_times'].get(question.id, None) + + update_view_count = False + if question.thread.last_activity_by_id != request.user.id: + if last_seen: + if last_seen < question.thread.last_activity_at: + update_view_count = True + else: + update_view_count = True + + request.session['question_view_times'][question.id] = \ + datetime.datetime.now() + #2) run the slower jobs in a celery task + from askbot import tasks + transaction.commit() + tasks.record_question_visit.delay( + question_post_id=question.id, + user_id=request.user.id, + update_view_count=update_view_count + ) + transaction.commit() + def record_vote(instance, created, **kwargs): """ when user have voted @@ -3943,11 +3982,14 @@ def group_membership_changed(**kwargs): GROUP_MEMBERSHIP_LEVELS.pop(gm_key, None) +@transaction.commit_manually def tweet_new_post(sender, user=None, question=None, answer=None, form_data=None, **kwargs): """seends out tweets about the new post""" from askbot.tasks import tweet_new_post_task post = question or answer + transaction.commit() tweet_new_post_task.delay(post.id) + transaction.commit() def autoapprove_reputable_user(user=None, reputation_before=None, *args, **kwargs): """if user is 'watched' we change status to 'approved' @@ -4178,6 +4220,10 @@ def record_spam_rejection( record_user_visit, dispatch_uid='record_user_visit' ) +signals.question_visited.connect( + record_question_visit, + dispatch_uid='record_question_visit' +) #set up a possibility for the users to follow others try: diff --git a/askbot/models/post.py b/askbot/models/post.py index 17230fa5a5..a9166ce95a 100644 --- a/askbot/models/post.py +++ b/askbot/models/post.py @@ -8,7 +8,7 @@ from django.conf import settings as django_settings from django.contrib.auth.models import User from django.core import urlresolvers -from django.db import models +from django.db import models, transaction from django.utils import html as html_utils from django.utils.text import truncate_html_words from django.utils.translation import activate as activate_language @@ -778,6 +778,7 @@ def remove_from_groups(self, groups): ).delete() + @transaction.commit_manually def issue_update_notifications( self, updated_by=None, @@ -845,12 +846,14 @@ def issue_update_notifications( cache.cache.set(cache_key, True, django_settings.NOTIFICATION_DELAY_TIME) from askbot.tasks import send_instant_notifications_about_activity_in_post + transaction.commit() send_instant_notifications_about_activity_in_post.apply_async(( update_activity.pk, self.id, notify_sets['for_email']), - countdown = django_settings.NOTIFICATION_DELAY_TIME + countdown=django_settings.NOTIFICATION_DELAY_TIME ) + transaction.commit() def make_private(self, user, group_id=None): """makes post private within user's groups diff --git a/askbot/signals.py b/askbot/signals.py index f075d6d639..948f68da04 100644 --- a/askbot/signals.py +++ b/askbot/signals.py @@ -45,6 +45,9 @@ answer_edited = django.dispatch.Signal( providing_args=['answer', 'user', 'form_data'] ) +question_visited = django.dispatch.Signal( + providing_args=['request', 'question'] +) post_updated = django.dispatch.Signal( providing_args=[ @@ -112,6 +115,7 @@ def pop_all_db_signal_receivers(): pre_delete, post_delete, post_syncdb, + question_visited, ) if 'm2m_changed' in globals(): signals += (m2m_changed, ) diff --git a/askbot/tasks.py b/askbot/tasks.py index 84cdc5b213..4c80b00113 100644 --- a/askbot/tasks.py +++ b/askbot/tasks.py @@ -141,7 +141,6 @@ def notify_author_of_published_revision_celery_task(revision_id): @task(ignore_result=True) def record_post_update_celery_task( post_id, - post_content_type_id, newly_mentioned_user_id_list=None, updated_by_id=None, suppress_email=False, @@ -151,8 +150,7 @@ def record_post_update_celery_task( ): #reconstitute objects from the database updated_by = User.objects.get(id=updated_by_id) - post_content_type = ContentType.objects.get(id=post_content_type_id) - post = post_content_type.get_object_for_this_type(id=post_id) + post = Post.objects.get(id=post_id) newly_mentioned_users = User.objects.filter( id__in=newly_mentioned_user_id_list ) diff --git a/askbot/views/moderation.py b/askbot/views/moderation.py index 8733d6cffa..aa1faf89ee 100644 --- a/askbot/views/moderation.py +++ b/askbot/views/moderation.py @@ -221,9 +221,6 @@ def moderate_post_edits(request): post_data = simplejson.loads(request.raw_post_data) #{'action': 'decline-with-reason', 'items': ['posts'], 'reason': 1, 'edit_ids': [827]} - import pdb - pdb.set_trace() - memo_set = models.ActivityAuditStatus.objects.filter(id__in=post_data['edit_ids']) result = { 'message': '', diff --git a/askbot/views/readers.py b/askbot/views/readers.py index 1e45397abf..096770d5b8 100644 --- a/askbot/views/readers.py +++ b/askbot/views/readers.py @@ -32,30 +32,27 @@ from django.http import QueryDict from django.conf import settings as django_settings -import askbot -from askbot import exceptions +from askbot import conf, const, exceptions, models, signals +from askbot.conf import settings as askbot_settings from askbot.forms import AnswerForm -from askbot.forms import ShowQuestionForm -from askbot.forms import GetUserItemsForm from askbot.forms import GetDataForPostForm +from askbot.forms import GetUserItemsForm from askbot.forms import PageField -from askbot.utils.loading import load_module -from askbot import conf -from askbot import models +from askbot.forms import ShowQuestionForm from askbot.models.post import MockPost from askbot.models.tag import Tag -from askbot import const +from askbot.search.state_manager import SearchState, DummySearchState from askbot.startup_procedures import domain_is_bad +from askbot.templatetags import extra_tags from askbot.utils import functions +from askbot.utils.decorators import anonymous_forbidden, ajax_only, get_only from askbot.utils.diff import textDiff as htmldiff from askbot.utils.html import sanitize_html -from askbot.utils.decorators import anonymous_forbidden, ajax_only, get_only +from askbot.utils.loading import load_module from askbot.utils.translation import get_language_name from askbot.utils.url_utils import reverse_i18n -from askbot.search.state_manager import SearchState, DummySearchState -from askbot.templatetags import extra_tags -from askbot.conf import settings as askbot_settings from askbot.views import context +import askbot # used in index page #todo: - take these out of const or settings @@ -558,33 +555,10 @@ def question(request, id):#refactor - long subroutine. display question body, an page_objects = objects_list.page(show_page) #count visits - #import ipdb; ipdb.set_trace() - if functions.not_a_robot_request(request): - #todo: split this out into a subroutine - #todo: merge view counts per user and per session - #1) view count per session - update_view_count = False - if 'question_view_times' not in request.session: - request.session['question_view_times'] = {} - - last_seen = request.session['question_view_times'].get(question_post.id, None) - - if thread.last_activity_by_id != request.user.id: - if last_seen: - if last_seen < thread.last_activity_at: - update_view_count = True - else: - update_view_count = True - - request.session['question_view_times'][question_post.id] = \ - datetime.datetime.now() - #2) run the slower jobs in a celery task - from askbot import tasks - tasks.record_question_visit.delay( - question_post_id=question_post.id, - user_id=request.user.id, - update_view_count=update_view_count - ) + signals.question_visited.send(None, + request=request, + question=question_post, + ) paginator_data = { 'is_paginated' : (objects_list.count > const.ANSWERS_PAGE_SIZE),