summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-01-30 21:21:24 -0500
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2011-01-30 21:21:24 -0500
commit6ddb2c7c07d740e77ba78a8475495c8dc9ae3124 (patch)
tree05caaa0a1240e0bec85c69c70d8c171e68cfdd87
parentec15fc285f62f713e4ee3f16c489757d04e8a94d (diff)
downloadaskbot-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.rst2
-rw-r--r--askbot/management/__init__.py82
-rw-r--r--askbot/management/commands/fix_inbox_counts.py46
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)