diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-01-30 21:21:24 -0500 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2011-01-30 21:21:24 -0500 |
commit | 6ddb2c7c07d740e77ba78a8475495c8dc9ae3124 (patch) | |
tree | 05caaa0a1240e0bec85c69c70d8c171e68cfdd87 | |
parent | ec15fc285f62f713e4ee3f16c489757d04e8a94d (diff) | |
download | askbot-6ddb2c7c07d740e77ba78a8475495c8dc9ae3124.tar.gz askbot-6ddb2c7c07d740e77ba78a8475495c8dc9ae3124.tar.bz2 askbot-6ddb2c7c07d740e77ba78a8475495c8dc9ae3124.zip |
added a management command to recalculate response counts for the inboxes
-rw-r--r-- | askbot/doc/source/management-commands.rst | 2 | ||||
-rw-r--r-- | askbot/management/__init__.py | 82 | ||||
-rw-r--r-- | askbot/management/commands/fix_inbox_counts.py | 46 |
3 files changed, 130 insertions, 0 deletions
diff --git a/askbot/doc/source/management-commands.rst b/askbot/doc/source/management-commands.rst index 34c47155..188654bf 100644 --- a/askbot/doc/source/management-commands.rst +++ b/askbot/doc/source/management-commands.rst @@ -112,6 +112,8 @@ The commands from this section will help fix those issues. +--------------------------------+-------------------------------------------------------------+ | `fix_answer_counts` | recalculates answer counts for all questions | +--------------------------------+-------------------------------------------------------------+ +| `fix_inbox_counts` | recalculates response counts in the user inboxes | ++--------------------------------+-------------------------------------------------------------+ | `fix_revisionless_posts` | adds a revision record to posts that lack them | +--------------------------------+-------------------------------------------------------------+ | `fix_question_tags` | takes tag names from the record on the question table | diff --git a/askbot/management/__init__.py b/askbot/management/__init__.py index e69de29b..1e2b2aaf 100644 --- a/askbot/management/__init__.py +++ b/askbot/management/__init__.py @@ -0,0 +1,82 @@ +import sys +from django.core.management.base import NoArgsCommand +from django.db import transaction +from askbot.models import signals +from askbot.utils import console + +FORMAT_STRING = '%6.2f%%'#to print progress in percent + +class NoArgsJob(NoArgsCommand): + """Base class for a job command - + the one that runs the same operation on + sets of items - each item operation in its own + transaction and prints progress in % of items + completed + + The subclass must implement __init__() method + where self.batches data structure must be defined as follows + (#the whole thing is a tuple + {#batch is described by a dictionary + 'title': <string>, + 'query_set': <query set for the items>, + 'function': <function or callable that performs + an operation on a single item + and returns True if item was changed + False otherwise + item is given as argument + >, + 'items_changed_message': <string with one %d placeholder>, + 'nothing_changed_message': <string> + }, + #more batch descriptions + ) + """ + batches = () + + def handle_noargs(self, **options): + """handler function that removes all signal listeners + then runs the job and finally restores the listerers + """ + signal_data = signals.pop_all_db_signal_receivers() + self.run_command(**options) + signals.set_all_db_signal_receivers(signal_data) + + def run_command(self, **options): + """runs the batches""" + for batch in self.batches: + self.run_batch(batch) + + @transaction.commit_manually + def run_batch(self, batch): + """runs the single batch + prints batch title + then loops through the query set + and prints progress in % + afterwards there will be a short summary + """ + + sys.stdout.write(batch['title']) + changed_count = 0 + checked_count = 0 + total_count = batch['query_set'].count() + + if total_count == 0: + return + + for item in batch['query_set'].all(): + + item_changed = batch['function'](item) + transaction.commit() + + if item_changed: + changed_count += 1 + checked_count += 1 + + progress = 100*float(checked_count)/float(total_count) + console.print_progress(FORMAT_STRING, progress) + print FORMAT_STRING % 100 + + if changed_count: + print batch['changed_count_message'] % changed_count + else: + print batch['nothing_changed_message'] diff --git a/askbot/management/commands/fix_inbox_counts.py b/askbot/management/commands/fix_inbox_counts.py new file mode 100644 index 00000000..c2ffffdc --- /dev/null +++ b/askbot/management/commands/fix_inbox_counts.py @@ -0,0 +1,46 @@ +from askbot.management import NoArgsJob +from askbot import models +from askbot import const + +ACTIVITY_TYPES = const.RESPONSE_ACTIVITY_TYPES_FOR_DISPLAY +ACTIVITY_TYPES += (const.TYPE_ACTIVITY_MENTION,) + +def fix_inbox_counts(user): + old_new_count = user.new_response_count + old_seen_count = user.seen_response_count + new_new_count = models.ActivityAuditStatus.objects.filter( + user = user, + status = models.ActivityAuditStatus.STATUS_NEW, + activity__activity_type__in = ACTIVITY_TYPES + ).count() + new_seen_count = models.ActivityAuditStatus.objects.filter( + user = user, + status = models.ActivityAuditStatus.STATUS_SEEN, + activity__activity_type__in = ACTIVITY_TYPES + ).count() + + (changed1, changed2) = (False, False) + if new_new_count != old_new_count: + user.new_response_count = new_new_count + changed1 = True + if new_seen_count != old_seen_count: + user.seen_response_count = new_seen_count + changed2 = True + if changed1 or changed2: + user.save() + return True + return False + +class Command(NoArgsJob): + """definition of the job that fixes response counts + destined for the user inboxes + """ + def __init__(self, *args, **kwargs): + self.batches = ({ + 'title': 'Checking inbox item counts for all users: ', + 'query_set': models.User.objects.all(), + 'function': fix_inbox_counts, + 'changed_count_message': 'Corrected records for %d users', + 'nothing_changed_message': 'No problems found' + },) + super(Command, self).__init__(*args, **kwargs) |