summaryrefslogtreecommitdiffstats
path: root/forum/management/commands
diff options
context:
space:
mode:
Diffstat (limited to 'forum/management/commands')
-rw-r--r--forum/management/commands/__init__.py0
-rw-r--r--forum/management/commands/base_command.py35
-rw-r--r--forum/management/commands/clean_award_badges.py58
-rw-r--r--forum/management/commands/multi_award_badges.py347
-rw-r--r--forum/management/commands/once_award_badges.py350
-rw-r--r--forum/management/commands/sample_command.py7
6 files changed, 797 insertions, 0 deletions
diff --git a/forum/management/commands/__init__.py b/forum/management/commands/__init__.py
new file mode 100644
index 00000000..e69de29b
--- /dev/null
+++ b/forum/management/commands/__init__.py
diff --git a/forum/management/commands/base_command.py b/forum/management/commands/base_command.py
new file mode 100644
index 00000000..c073bf7a
--- /dev/null
+++ b/forum/management/commands/base_command.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+#encoding:utf-8
+#-------------------------------------------------------------------------------
+# Name: Award badges command
+# Purpose: This is a command file croning in background process regularly to
+# query database and award badges for user's special acitivities.
+#
+# Author: Mike, Sailing
+#
+# Created: 22/01/2009
+# Copyright: (c) Mike 2009
+# Licence: GPL V2
+#-------------------------------------------------------------------------------
+
+from datetime import datetime, date
+from django.core.management.base import NoArgsCommand
+from django.db import connection
+from django.shortcuts import get_object_or_404
+from django.contrib.contenttypes.models import ContentType
+
+from forum.models import *
+from forum.const import *
+
+class BaseCommand(NoArgsCommand):
+ def update_activities_auditted(self, cursor, activity_ids):
+ # update processed rows to auditted
+ if len(activity_ids):
+ query = "UPDATE activity SET is_auditted = 1 WHERE id in (%s)"\
+ % ','.join('%s' % item for item in activity_ids)
+ cursor.execute(query)
+
+
+
+
+
diff --git a/forum/management/commands/clean_award_badges.py b/forum/management/commands/clean_award_badges.py
new file mode 100644
index 00000000..df3d2917
--- /dev/null
+++ b/forum/management/commands/clean_award_badges.py
@@ -0,0 +1,58 @@
+#-------------------------------------------------------------------------------
+# Name: Award badges command
+# Purpose: This is a command file croning in background process regularly to
+# query database and award badges for user's special acitivities.
+#
+# Author: Mike
+#
+# Created: 18/01/2009
+# Copyright: (c) Mike 2009
+# Licence: GPL V2
+#-------------------------------------------------------------------------------
+#!/usr/bin/env python
+#encoding:utf-8
+from django.core.management.base import NoArgsCommand
+from django.db import connection
+from django.shortcuts import get_object_or_404
+from django.contrib.contenttypes.models import ContentType
+
+from forum.models import *
+
+class Command(NoArgsCommand):
+ def handle_noargs(self, **options):
+ try:
+ self.clean_awards()
+ except Exception, e:
+ print e
+ finally:
+ connection.close()
+
+ def clean_awards(self):
+ Award.objects.all().delete()
+
+ award_type =ContentType.objects.get_for_model(Award)
+ Activity.objects.filter(content_type=award_type).delete()
+
+ for user in User.objects.all():
+ user.gold = 0
+ user.silver = 0
+ user.bronze = 0
+ user.save()
+
+ for badge in Badge.objects.all():
+ badge.awarded_count = 0
+ badge.save()
+
+ query = "UPDATE activity SET is_auditted = 0"
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ finally:
+ cursor.close()
+ connection.close()
+
+def main():
+ pass
+
+if __name__ == '__main__':
+ main() \ No newline at end of file
diff --git a/forum/management/commands/multi_award_badges.py b/forum/management/commands/multi_award_badges.py
new file mode 100644
index 00000000..723a8cec
--- /dev/null
+++ b/forum/management/commands/multi_award_badges.py
@@ -0,0 +1,347 @@
+#!/usr/bin/env python
+#encoding:utf-8
+#-------------------------------------------------------------------------------
+# Name: Award badges command
+# Purpose: This is a command file croning in background process regularly to
+# query database and award badges for user's special acitivities.
+#
+# Author: Mike, Sailing
+#
+# Created: 22/01/2009
+# Copyright: (c) Mike 2009
+# Licence: GPL V2
+#-------------------------------------------------------------------------------
+
+from datetime import datetime, date
+from django.core.management.base import NoArgsCommand
+from django.db import connection
+from django.shortcuts import get_object_or_404
+from django.contrib.contenttypes.models import ContentType
+
+from forum.models import *
+from forum.const import *
+from base_command import BaseCommand
+"""
+(1, '炼狱法师', 3, '炼狱法师', '删除自己有3个以上赞成票的帖子', 1, 0),
+(2, '压力白领', 3, '压力白领', '删除自己有3个以上反对票的帖子', 1, 0),
+(3, '优秀回答', 3, '优秀回答', '回答好评10次以上', 1, 0),
+(4, '优秀问题', 3, '优秀问题', '问题好评10次以上', 1, 0),
+(5, '评论家', 3, '评论家', '评论10次以上', 0, 0),
+(6, '流行问题', 3, '流行问题', '问题的浏览量超过1000人次', 1, 0),
+(7, '巡逻兵', 3, '巡逻兵', '第一次标记垃圾帖子', 0, 0),
+(8, '清洁工', 3, '清洁工', '第一次撤销投票', 0, 0),
+(9, '批评家', 3, '批评家', '第一次反对票', 0, 0),
+(10, '小编', 3, '小编', '第一次编辑更新', 0, 0),
+(11, '村长', 3, '村长', '第一次重新标签', 0, 0),
+(12, '学者', 3, '学者', '第一次标记答案', 0, 0),
+(13, '学生', 3, '学生', '第一次提问并且有一次以上赞成票', 0, 0),
+(14, '支持者', 3, '支持者', '第一次赞成票', 0, 0),
+(15, '教师', 3, '教师', '第一次回答问题并且得到一个以上赞成票', 0, 0),
+(16, '自传作者', 3, '自传作者', '完整填写用户资料所有选项', 0, 0),
+(17, '自学成才', 3, '自学成才', '回答自己的问题并且有3个以上赞成票', 1, 0),
+(18, '最有价值回答', 1, '最有价值回答', '回答超过100次赞成票', 1, 0),
+(19, '最有价值问题', 1, '最有价值问题', '问题超过100次赞成票', 1, 0),
+(20, '万人迷', 1, '万人迷', '问题被100人以上收藏', 1, 0),
+(21, '著名问题', 1, '著名问题', '问题的浏览量超过10000人次', 1, 0),
+(22, 'alpha用户', 2, 'alpha用户', '内测期间的活跃用户', 0, 0),
+(23, '极好回答', 2, '极好回答', '回答超过25次赞成票', 1, 0),
+(24, '极好问题', 2, '极好问题', '问题超过25次赞成票', 1, 0),
+(25, '受欢迎问题', 2, '受欢迎问题', '问题被25人以上收藏', 1, 0),
+(26, '优秀市民', 2, '优秀市民', '投票300次以上', 0, 0),
+(27, '编辑主任', 2, '编辑主任', '编辑了100个帖子', 0, 0),
+(28, '通才', 2, '通才', '在多个标签领域活跃', 0, 0),
+(29, '专家', 2, '专家', '在一个标签领域活跃出众', 0, 0),
+(30, '老鸟', 2, '老鸟', '活跃超过一年的用户', 0, 0),
+(31, '最受关注问题', 2, '最受关注问题', '问题的浏览量超过2500人次', 1, 0),
+(32, '学问家', 2, '学问家', '第一次回答被投赞成票10次以上', 0, 0),
+(33, 'beta用户', 2, 'beta用户', 'beta期间活跃参与', 0, 0),
+(34, '导师', 2, '导师', '被指定为最佳答案并且赞成票40以上', 1, 0),
+(35, '巫师', 2, '巫师', '在提问60天之后回答并且赞成票5次以上', 1, 0),
+(36, '分类专家', 2, '分类专家', '创建的标签被50个以上问题使用', 1, 0);
+
+
+TYPE_ACTIVITY_ASK_QUESTION=1
+TYPE_ACTIVITY_ANSWER=2
+TYPE_ACTIVITY_COMMENT_QUESTION=3
+TYPE_ACTIVITY_COMMENT_ANSWER=4
+TYPE_ACTIVITY_UPDATE_QUESTION=5
+TYPE_ACTIVITY_UPDATE_ANSWER=6
+TYPE_ACTIVITY_PRIZE=7
+TYPE_ACTIVITY_MARK_ANSWER=8
+TYPE_ACTIVITY_VOTE_UP=9
+TYPE_ACTIVITY_VOTE_DOWN=10
+TYPE_ACTIVITY_CANCEL_VOTE=11
+TYPE_ACTIVITY_DELETE_QUESTION=12
+TYPE_ACTIVITY_DELETE_ANSWER=13
+TYPE_ACTIVITY_MARK_OFFENSIVE=14
+TYPE_ACTIVITY_UPDATE_TAGS=15
+TYPE_ACTIVITY_FAVORITE=16
+TYPE_ACTIVITY_USER_FULL_UPDATED = 17
+"""
+
+class Command(BaseCommand):
+ def handle_noargs(self, **options):
+ try:
+ self.delete_question_be_voted_up_3()
+ self.delete_answer_be_voted_up_3()
+ self.delete_question_be_vote_down_3()
+ self.delete_answer_be_voted_down_3()
+ self.answer_be_voted_up_10()
+ self.question_be_voted_up_10()
+ self.question_view_1000()
+ self.answer_self_question_be_voted_up_3()
+ self.answer_be_voted_up_100()
+ self.question_be_voted_up_100()
+ self.question_be_favorited_100()
+ self.question_view_10000()
+ self.answer_be_voted_up_25()
+ self.question_be_voted_up_25()
+ self.question_be_favorited_25()
+ self.question_view_2500()
+ self.answer_be_accepted_and_voted_up_40()
+ self.question_be_answered_after_60_days_and_be_voted_up_5()
+ self.created_tag_be_used_in_question_50()
+ except Exception, e:
+ print e
+ finally:
+ connection.close()
+
+ def delete_question_be_voted_up_3(self):
+ """
+ (1, '炼狱法师', 3, '炼狱法师', '删除自己有3个以上赞成票的帖子', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM activity act, question q WHERE act.object_id = q.id AND\
+ act.activity_type = %s AND\
+ q.vote_up_count >=3 AND \
+ act.is_auditted = 0" % (TYPE_ACTIVITY_DELETE_QUESTION)
+ self.__process_activities_badge(query, 1, Question)
+
+ def delete_answer_be_voted_up_3(self):
+ """
+ (1, '炼狱法师', 3, '炼狱法师', '删除自己有3个以上赞成票的帖子', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM activity act, answer an WHERE act.object_id = an.id AND\
+ act.activity_type = %s AND\
+ an.vote_up_count >=3 AND \
+ act.is_auditted = 0" % (TYPE_ACTIVITY_DELETE_ANSWER)
+ self.__process_activities_badge(query, 1, Answer)
+
+ def delete_question_be_vote_down_3(self):
+ """
+ (2, '压力白领', 3, '压力白领', '删除自己有3个以上反对票的帖子', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM activity act, question q WHERE act.object_id = q.id AND\
+ act.activity_type = %s AND\
+ q.vote_down_count >=3 AND \
+ act.is_auditted = 0" % (TYPE_ACTIVITY_DELETE_QUESTION)
+ content_type = ContentType.objects.get_for_model(Question)
+ self.__process_activities_badge(query, 2, Question)
+
+ def delete_answer_be_voted_down_3(self):
+ """
+ (2, '压力白领', 3, '压力白领', '删除自己有3个以上反对票的帖子', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM activity act, answer an WHERE act.object_id = an.id AND\
+ act.activity_type = %s AND\
+ an.vote_down_count >=3 AND \
+ act.is_auditted = 0" % (TYPE_ACTIVITY_DELETE_ANSWER)
+ self.__process_activities_badge(query, 2, Answer)
+
+ def answer_be_voted_up_10(self):
+ """
+ (3, '优秀回答', 3, '优秀回答', '回答好评10次以上', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM \
+ activity act, answer a WHERE act.object_id = a.id AND\
+ act.activity_type = %s AND \
+ a.vote_up_count >= 10 AND\
+ act.is_auditted = 0" % (TYPE_ACTIVITY_ANSWER)
+ self.__process_activities_badge(query, 3, Answer)
+
+ def question_be_voted_up_10(self):
+ """
+ (4, '优秀问题', 3, '优秀问题', '问题好评10次以上', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM \
+ activity act, question q WHERE act.object_id = q.id AND\
+ act.activity_type = %s AND \
+ q.vote_up_count >= 10 AND\
+ act.is_auditted = 0" % (TYPE_ACTIVITY_ASK_QUESTION)
+ self.__process_activities_badge(query, 4, Question)
+
+ def question_view_1000(self):
+ """
+ (6, '流行问题', 3, '流行问题', '问题的浏览量超过1000人次', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM \
+ activity act, question q WHERE act.activity_type = %s AND\
+ act.object_id = q.id AND \
+ q.view_count >= 1000 AND\
+ act.object_id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 6)
+ self.__process_activities_badge(query, 6, Question, False)
+
+ def answer_self_question_be_voted_up_3(self):
+ """
+ (17, '自学成才', 3, '自学成才', '回答自己的问题并且有3个以上赞成票', 1, 0),
+ """
+ query = "SELECT act.id, act.user_id, act.object_id FROM \
+ activity act, answer an WHERE act.activity_type = %s AND\
+ act.object_id = an.id AND\
+ an.vote_up_count >= 3 AND\
+ act.user_id = (SELECT user_id FROM question q WHERE q.id = an.question_id) AND\
+ act.object_id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 17)
+ self.__process_activities_badge(query, 17, Question, False)
+
+ def answer_be_voted_up_100(self):
+ """
+ (18, '最有价值回答', 1, '最有价值回答', '回答超过100次赞成票', 1, 0),
+ """
+ query = "SELECT an.id, an.author_id FROM answer an WHERE an.vote_up_count >= 100 AND an.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (18)
+
+ self.__process_badge(query, 18, Answer)
+
+ def question_be_voted_up_100(self):
+ """
+ (19, '最有价值问题', 1, '最有价值问题', '问题超过100次赞成票', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.vote_up_count >= 100 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (19)
+
+ self.__process_badge(query, 19, Question)
+
+ def question_be_favorited_100(self):
+ """
+ (20, '万人迷', 1, '万人迷', '问题被100人以上收藏', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.favourite_count >= 100 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (20)
+
+ self.__process_badge(query, 20, Question)
+
+ def question_view_10000(self):
+ """
+ (21, '著名问题', 1, '著名问题', '问题的浏览量超过10000人次', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.view_count >= 10000 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (21)
+
+ self.__process_badge(query, 21, Question)
+
+ def answer_be_voted_up_25(self):
+ """
+ (23, '极好回答', 2, '极好回答', '回答超过25次赞成票', 1, 0),
+ """
+ query = "SELECT a.id, a.author_id FROM answer a WHERE a.vote_up_count >= 25 AND a.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (23)
+
+ self.__process_badge(query, 23, Answer)
+
+ def question_be_voted_up_25(self):
+ """
+ (24, '极好问题', 2, '极好问题', '问题超过25次赞成票', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.vote_up_count >= 25 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (24)
+
+ self.__process_badge(query, 24, Question)
+
+ def question_be_favorited_25(self):
+ """
+ (25, '受欢迎问题', 2, '受欢迎问题', '问题被25人以上收藏', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.favourite_count >= 25 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (25)
+
+ self.__process_badge(query, 25, Question)
+
+ def question_view_2500(self):
+ """
+ (31, '最受关注问题', 2, '最受关注问题', '问题的浏览量超过2500人次', 1, 0),
+ """
+ query = "SELECT q.id, q.author_id FROM question q WHERE q.view_count >= 2500 AND q.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (31)
+
+ self.__process_badge(query, 31, Question)
+
+ def answer_be_accepted_and_voted_up_40(self):
+ """
+ (34, '导师', 2, '导师', '被指定为最佳答案并且赞成票40以上', 1, 0),
+ """
+ query = "SELECT a.id, a.author_id FROM answer a WHERE a.vote_up_count >= 40 AND\
+ a.accepted = 1 AND\
+ a.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (34)
+
+ self.__process_badge(query, 34, Answer)
+
+ def question_be_answered_after_60_days_and_be_voted_up_5(self):
+ """
+ (35, '巫师', 2, '巫师', '在提问60天之后回答并且赞成票5次以上', 1, 0),
+ """
+ query = "SELECT a.id, a.author_id FROM question q, answer a WHERE q.id = a.question_id AND\
+ DATEDIFF(a.added_at, q.added_at) >= 60 AND\
+ a.vote_up_count >= 5 AND \
+ a.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (35)
+
+ self.__process_badge(query, 35, Answer)
+
+ def created_tag_be_used_in_question_50(self):
+ """
+ (36, '分类专家', 2, '分类专家', '创建的标签被50个以上问题使用', 1, 0);
+ """
+ query = "SELECT t.id, t.created_by_id FROM tag t, auth_user u WHERE t.created_by_id = u.id AND \
+ t. used_count >= 50 AND \
+ t.id NOT IN \
+ (SELECT object_id FROM award WHERE award.badge_id = %s)" % (36)
+
+ self.__process_badge(query, 36, Tag)
+
+ def __process_activities_badge(self, query, badge, content_object, update_auditted=True):
+ content_type = ContentType.objects.get_for_model(content_object)
+
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ if update_auditted:
+ activity_ids = []
+ badge = get_object_or_404(Badge, id=badge)
+ for row in rows:
+ activity_id = row[0]
+ user_id = row[1]
+ object_id = row[2]
+
+ user = get_object_or_404(User, id=user_id)
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=objet_id)
+ award.save()
+
+ if update_auditted:
+ activity_ids.append(activity_id)
+
+ if update_auditted:
+ self.update_activities_auditted(cursor, activity_ids)
+ finally:
+ cursor.close()
+
+ def __process_badge(self, query, badge, content_object):
+ content_type = ContentType.objects.get_for_model(Answer)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ badge = get_object_or_404(Badge, id=badge)
+ for row in rows:
+ object_id = row[0]
+ user_id = row[1]
+
+ user = get_object_or_404(User, id=user_id)
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=object_id)
+ award.save()
+ finally:
+ cursor.close() \ No newline at end of file
diff --git a/forum/management/commands/once_award_badges.py b/forum/management/commands/once_award_badges.py
new file mode 100644
index 00000000..c1a147d7
--- /dev/null
+++ b/forum/management/commands/once_award_badges.py
@@ -0,0 +1,350 @@
+#!/usr/bin/env python
+#encoding:utf-8
+#-------------------------------------------------------------------------------
+# Name: Award badges command
+# Purpose: This is a command file croning in background process regularly to
+# query database and award badges for user's special acitivities.
+#
+# Author: Mike, Sailing
+#
+# Created: 18/01/2009
+# Copyright: (c) Mike 2009
+# Licence: GPL V2
+#-------------------------------------------------------------------------------
+
+from datetime import datetime, date
+from django.db import connection
+from django.shortcuts import get_object_or_404
+from django.contrib.contenttypes.models import ContentType
+
+from forum.models import *
+from forum.const import *
+from base_command import BaseCommand
+"""
+(1, '炼狱法师', 3, '炼狱法师', '删除自己有3个以上赞成票的帖子', 1, 0),
+(2, '压力白领', 3, '压力白领', '删除自己有3个以上反对票的帖子', 1, 0),
+(3, '优秀回答', 3, '优秀回答', '回答好评10次以上', 1, 0),
+(4, '优秀问题', 3, '优秀问题', '问题好评10次以上', 1, 0),
+(5, '评论家', 3, '评论家', '评论10次以上', 0, 0),
+(6, '流行问题', 3, '流行问题', '问题的浏览量超过1000人次', 1, 0),
+(7, '巡逻兵', 3, '巡逻兵', '第一次标记垃圾帖子', 0, 0),
+(8, '清洁工', 3, '清洁工', '第一次撤销投票', 0, 0),
+(9, '批评家', 3, '批评家', '第一次反对票', 0, 0),
+(10, '小编', 3, '小编', '第一次编辑更新', 0, 0),
+(11, '村长', 3, '村长', '第一次重新标签', 0, 0),
+(12, '学者', 3, '学者', '第一次标记答案', 0, 0),
+(13, '学生', 3, '学生', '第一次提问并且有一次以上赞成票', 0, 0),
+(14, '支持者', 3, '支持者', '第一次赞成票', 0, 0),
+(15, '教师', 3, '教师', '第一次回答问题并且得到一个以上赞成票', 0, 0),
+(16, '自传作者', 3, '自传作者', '完整填写用户资料所有选项', 0, 0),
+(17, '自学成才', 3, '自学成才', '回答自己的问题并且有3个以上赞成票', 1, 0),
+(18, '最有价值回答', 1, '最有价值回答', '回答超过100次赞成票', 1, 0),
+(19, '最有价值问题', 1, '最有价值问题', '问题超过100次赞成票', 1, 0),
+(20, '万人迷', 1, '万人迷', '问题被100人以上收藏', 1, 0),
+(21, '著名问题', 1, '著名问题', '问题的浏览量超过10000人次', 1, 0),
+(22, 'alpha用户', 2, 'alpha用户', '内测期间的活跃用户', 0, 0),
+(23, '极好回答', 2, '极好回答', '回答超过25次赞成票', 1, 0),
+(24, '极好问题', 2, '极好问题', '问题超过25次赞成票', 1, 0),
+(25, '受欢迎问题', 2, '受欢迎问题', '问题被25人以上收藏', 1, 0),
+(26, '优秀市民', 2, '优秀市民', '投票300次以上', 0, 0),
+(27, '编辑主任', 2, '编辑主任', '编辑了100个帖子', 0, 0),
+(28, '通才', 2, '通才', '在多个标签领域活跃', 0, 0),
+(29, '专家', 2, '专家', '在一个标签领域活跃出众', 0, 0),
+(30, '老鸟', 2, '老鸟', '活跃超过一年的用户', 0, 0),
+(31, '最受关注问题', 2, '最受关注问题', '问题的浏览量超过2500人次', 1, 0),
+(32, '学问家', 2, '学问家', '第一次回答被投赞成票10次以上', 0, 0),
+(33, 'beta用户', 2, 'beta用户', 'beta期间活跃参与', 0, 0),
+(34, '导师', 2, '导师', '被指定为最佳答案并且赞成票40以上', 1, 0),
+(35, '巫师', 2, '巫师', '在提问60天之后回答并且赞成票5次以上', 1, 0),
+(36, '分类专家', 2, '分类专家', '创建的标签被50个以上问题使用', 1, 0);
+
+
+TYPE_ACTIVITY_ASK_QUESTION=1
+TYPE_ACTIVITY_ANSWER=2
+TYPE_ACTIVITY_COMMENT_QUESTION=3
+TYPE_ACTIVITY_COMMENT_ANSWER=4
+TYPE_ACTIVITY_UPDATE_QUESTION=5
+TYPE_ACTIVITY_UPDATE_ANSWER=6
+TYPE_ACTIVITY_PRIZE=7
+TYPE_ACTIVITY_MARK_ANSWER=8
+TYPE_ACTIVITY_VOTE_UP=9
+TYPE_ACTIVITY_VOTE_DOWN=10
+TYPE_ACTIVITY_CANCEL_VOTE=11
+TYPE_ACTIVITY_DELETE_QUESTION=12
+TYPE_ACTIVITY_DELETE_ANSWER=13
+TYPE_ACTIVITY_MARK_OFFENSIVE=14
+TYPE_ACTIVITY_UPDATE_TAGS=15
+TYPE_ACTIVITY_FAVORITE=16
+TYPE_ACTIVITY_USER_FULL_UPDATED = 17
+"""
+
+BADGE_AWARD_TYPE_FIRST = {
+ TYPE_ACTIVITY_MARK_OFFENSIVE : 7,
+ TYPE_ACTIVITY_CANCEL_VOTE: 8,
+ TYPE_ACTIVITY_VOTE_DOWN : 9,
+ TYPE_ACTIVITY_UPDATE_QUESTION : 10,
+ TYPE_ACTIVITY_UPDATE_ANSWER : 10,
+ TYPE_ACTIVITY_UPDATE_TAGS : 11,
+ TYPE_ACTIVITY_MARK_ANSWER : 12,
+ TYPE_ACTIVITY_VOTE_UP : 14,
+ TYPE_ACTIVITY_USER_FULL_UPDATED: 16
+
+}
+
+class Command(BaseCommand):
+ def handle_noargs(self, **options):
+ try:
+ self.alpha_user()
+ self.beta_user()
+ self.first_type_award()
+ self.first_ask_be_voted()
+ self.first_answer_be_voted()
+ self.first_answer_be_voted_10()
+ self.vote_count_300()
+ self.edit_count_100()
+ self.comment_count_10()
+ except Exception, e:
+ print e
+ finally:
+ connection.close()
+
+ def alpha_user(self):
+ """
+ Before Jan 25, 2009(Chinese New Year Eve and enter into Beta for CNProg), every registered user
+ will be awarded the "Alpha" badge if he has any activities.
+ """
+ alpha_end_date = date(2009, 1, 25)
+ if date.today() < alpha_end_date:
+ badge = get_object_or_404(Badge, id=22)
+ for user in User.objects.all():
+ award = Award.objects.filter(user=user, badge=badge)
+ if award and not badge.multiple:
+ continue
+ activities = Activity.objects.filter(user=user)
+ if len(activities) > 0:
+ new_award = Award(user=user, badge=badge)
+ new_award.save()
+
+ def beta_user(self):
+ """
+ Before Feb 25, 2009, every registered user
+ will be awarded the "Beta" badge if he has any activities.
+ """
+ beta_end_date = date(2009, 2, 25)
+ if date.today() < beta_end_date:
+ badge = get_object_or_404(Badge, id=33)
+ for user in User.objects.all():
+ award = Award.objects.filter(user=user, badge=badge)
+ if award and not badge.multiple:
+ continue
+ activities = Activity.objects.filter(user=user)
+ if len(activities) > 0:
+ new_award = Award(user=user, badge=badge)
+ new_award.save()
+
+ def first_type_award(self):
+ """
+ This will award below badges for users first behaviors:
+
+ (7, '巡逻兵', 3, '巡逻兵', '第一次标记垃圾帖子', 0, 0),
+ (8, '清洁工', 3, '清洁工', '第一次撤销投票', 0, 0),
+ (9, '批评家', 3, '批评家', '第一次反对票', 0, 0),
+ (10, '小编', 3, '小编', '第一次编辑更新', 0, 0),
+ (11, '村长', 3, '村长', '第一次重新标签', 0, 0),
+ (12, '学者', 3, '学者', '第一次标记答案', 0, 0),
+ (14, '支持者', 3, '支持者', '第一次赞成票', 0, 0),
+ (16, '自传作者', 3, '自传作者', '完整填写用户资料所有选项', 0, 0),
+ """
+ activity_types = ','.join('%s' % item for item in BADGE_AWARD_TYPE_FIRST.keys())
+ # ORDER BY user_id, activity_type
+ query = "SELECT id, user_id, activity_type, content_type_id, object_id\
+ FROM activity WHERE is_auditted = 0 AND activity_type IN (%s) ORDER BY user_id, activity_type" % activity_types
+
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+ # collect activity_id in current process
+ activity_ids = []
+ last_user_id = 0
+ last_activity_type = 0
+ for row in rows:
+ activity_ids.append(row[0])
+ user_id = row[1]
+ activity_type = row[2]
+ content_type_id = row[3]
+ object_id = row[4]
+
+ # if the user and activity are same as the last, continue
+ if user_id == last_user_id and activity_type == last_activity_type:
+ continue;
+
+ user = get_object_or_404(User, id=user_id)
+ badge = get_object_or_404(Badge, id=BADGE_AWARD_TYPE_FIRST[activity_type])
+ content_type = get_object_or_404(ContentType, id=content_type_id)
+
+ count = Award.objects.filter(user=user, badge=badge).count()
+ if count and not badge.multiple:
+ continue
+ else:
+ # new award
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=object_id)
+ award.save()
+
+ # set the current user_id and activity_type to last
+ last_user_id = user_id
+ last_activity_type = activity_type
+
+ # update processed rows to auditted
+ self.update_activities_auditted(cursor, activity_ids)
+ finally:
+ cursor.close()
+
+ def first_ask_be_voted(self):
+ """
+ For user asked question and got first upvote, we award him following badge:
+
+ (13, '学生', 3, '学生', '第一次提问并且有一次以上赞成票', 0, 0),
+ """
+ query = "SELECT act.user_id, q.vote_up_count, act.object_id FROM \
+ activity act, question q WHERE act.activity_type = %s AND \
+ act.object_id = q.id AND\
+ act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ASK_QUESTION, 13)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ badge = get_object_or_404(Badge, id=13)
+ content_type = ContentType.objects.get_for_model(Question)
+ awarded_users = []
+ for row in rows:
+ user_id = row[0]
+ vote_up_count = row[1]
+ object_id = row[2]
+ if vote_up_count > 0 and user_id not in awarded_users:
+ user = get_object_or_404(User, id=user_id)
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=object_id)
+ award.save()
+ awarded_users.append(user_id)
+ finally:
+ cursor.close()
+
+ def first_answer_be_voted(self):
+ """
+ When user answerd questions and got first upvote, we award him following badge:
+
+ (15, '教师', 3, '教师', '第一次回答问题并且得到一个以上赞成票', 0, 0),
+ """
+ query = "SELECT act.user_id, a.vote_up_count, act.object_id FROM \
+ activity act, answer a WHERE act.activity_type = %s AND \
+ act.object_id = a.id AND\
+ act.user_id NOT IN (SELECT distinct user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 15)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ awarded_users = []
+ badge = get_object_or_404(Badge, id=15)
+ content_type = ContentType.objects.get_for_model(Answer)
+ for row in rows:
+ user_id = row[0]
+ vote_up_count = row[1]
+ object_id = row[2]
+ if vote_up_count > 0 and user_id not in awarded_users:
+ user = get_object_or_404(User, id=user_id)
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=object_id)
+ award.save()
+ awarded_users.append(user_id)
+ finally:
+ cursor.close()
+
+ def first_answer_be_voted_10(self):
+ """
+ (32, '学问家', 2, '学问家', '第一次回答被投赞成票10次以上', 0, 0)
+ """
+ query = "SELECT act.user_id, act.object_id FROM \
+ activity act, answer a WHERE act.object_id = a.id AND\
+ act.activity_type = %s AND \
+ a.vote_up_count >= 10 AND\
+ act.user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s)" % (TYPE_ACTIVITY_ANSWER, 32)
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ awarded_users = []
+ badge = get_object_or_404(Badge, id=32)
+ content_type = ContentType.objects.get_for_model(Answer)
+ for row in rows:
+ user_id = row[0]
+ if user_id not in awarded_users:
+ user = get_object_or_404(User, id=user_id)
+ object_id = row[1]
+ award = Award(user=user, badge=badge, content_type=content_type, object_id=object_id)
+ award.save()
+ awarded_users.append(user_id)
+ finally:
+ cursor.close()
+
+ def vote_count_300(self):
+ """
+ (26, '优秀市民', 2, '优秀市民', '投票300次以上', 0, 0)
+ """
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE \
+ activity_type = %s OR \
+ activity_type = %s AND \
+ user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) \
+ GROUP BY user_id HAVING vote_count >= 300" % (TYPE_ACTIVITY_VOTE_UP, TYPE_ACTIVITY_VOTE_DOWN, 26)
+
+ self.__award_for_count_num(query, 26)
+
+ def edit_count_100(self):
+ """
+ (27, '编辑主任', 2, '编辑主任', '编辑了100个帖子', 0, 0)
+ """
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE \
+ activity_type = %s OR \
+ activity_type = %s AND \
+ user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) \
+ GROUP BY user_id HAVING vote_count >= 100" % (TYPE_ACTIVITY_UPDATE_QUESTION, TYPE_ACTIVITY_UPDATE_ANSWER, 27)
+
+ self.__award_for_count_num(query, 27)
+
+ def comment_count_10(self):
+ """
+ (5, '评论家', 3, '评论家', '评论10次以上', 0, 0),
+ """
+ query = "SELECT count(*) vote_count, user_id FROM activity WHERE \
+ activity_type = %s OR \
+ activity_type = %s AND \
+ user_id NOT IN (SELECT user_id FROM award WHERE badge_id = %s) \
+ GROUP BY user_id HAVING vote_count >= 10" % (TYPE_ACTIVITY_COMMENT_QUESTION, TYPE_ACTIVITY_COMMENT_ANSWER, 5)
+ self.__award_for_count_num(query, 5)
+
+ def __award_for_count_num(self, query, badge):
+ cursor = connection.cursor()
+ try:
+ cursor.execute(query)
+ rows = cursor.fetchall()
+
+ awarded_users = []
+ badge = get_object_or_404(Badge, id=badge)
+ for row in rows:
+ vote_count = row[0]
+ user_id = row[1]
+
+ if user_id not in awarded_users:
+ user = get_object_or_404(User, id=user_id)
+ award = Award(user=user, badge=badge)
+ award.save()
+ awarded_users.append(user_id)
+ finally:
+ cursor.close()
+
+def main():
+ pass
+
+if __name__ == '__main__':
+ main() \ No newline at end of file
diff --git a/forum/management/commands/sample_command.py b/forum/management/commands/sample_command.py
new file mode 100644
index 00000000..55e67235
--- /dev/null
+++ b/forum/management/commands/sample_command.py
@@ -0,0 +1,7 @@
+from django.core.management.base import NoArgsCommand
+from forum.models import Comment
+
+class Command(NoArgsCommand):
+ def handle_noargs(self, **options):
+ objs = Comment.objects.all()
+ print objs \ No newline at end of file