]> git.openstreetmap.org Git - osqa.git/blob - forum/models/__init__.py
12a0239565b2b9097409109e3206fcb28d15390c
[osqa.git] / forum / models / __init__.py
1 from question import Question ,QuestionRevision, QuestionView, AnonymousQuestion, FavoriteQuestion\r
2 from answer import Answer, AnonymousAnswer, AnswerRevision\r
3 from tag import Tag, MarkedTag\r
4 from meta import Vote, Comment, FlaggedItem\r
5 from user import Activity, AnonymousEmail, EmailFeedSetting, AuthKeyUserAssociation\r
6 from repute import Badge, Award, Repute\r
7 \r
8 from base import *\r
9 \r
10 # User extend properties\r
11 QUESTIONS_PER_PAGE_CHOICES = (\r
12    (10, u'10'),\r
13    (30, u'30'),\r
14    (50, u'50'),\r
15 )\r
16 \r
17 def user_is_username_taken(cls,username):\r
18     try:\r
19         cls.objects.get(username=username)\r
20         return True\r
21     except cls.MultipleObjectsReturned:\r
22         return True\r
23     except cls.DoesNotExist:\r
24         return False\r
25 \r
26 def user_get_q_sel_email_feed_frequency(self):\r
27     #print 'looking for frequency for user %s' % self\r
28     try:\r
29         feed_setting = EmailFeedSetting.objects.get(subscriber=self,feed_type='q_sel')\r
30     except Exception, e:\r
31         #print 'have error %s' % e.message\r
32         raise e\r
33     #print 'have freq=%s' % feed_setting.frequency\r
34     return feed_setting.frequency\r
35 \r
36 User.add_to_class('is_approved', models.BooleanField(default=False))\r
37 User.add_to_class('email_isvalid', models.BooleanField(default=False))\r
38 User.add_to_class('email_key', models.CharField(max_length=32, null=True))\r
39 User.add_to_class('reputation', models.PositiveIntegerField(default=1))\r
40 User.add_to_class('gravatar', models.CharField(max_length=32))\r
41 \r
42 #User.add_to_class('favorite_questions',\r
43 #                  models.ManyToManyField(Question, through=FavoriteQuestion,\r
44 #                                         related_name='favorited_by'))\r
45 \r
46 #User.add_to_class('badges', models.ManyToManyField(Badge, through=Award,\r
47 #                                                   related_name='awarded_to'))\r
48 User.add_to_class('gold', models.SmallIntegerField(default=0))\r
49 User.add_to_class('silver', models.SmallIntegerField(default=0))\r
50 User.add_to_class('bronze', models.SmallIntegerField(default=0))\r
51 User.add_to_class('questions_per_page',\r
52                   models.SmallIntegerField(choices=QUESTIONS_PER_PAGE_CHOICES, default=10))\r
53 User.add_to_class('last_seen',\r
54                   models.DateTimeField(default=datetime.datetime.now))\r
55 User.add_to_class('real_name', models.CharField(max_length=100, blank=True))\r
56 User.add_to_class('website', models.URLField(max_length=200, blank=True))\r
57 User.add_to_class('location', models.CharField(max_length=100, blank=True))\r
58 User.add_to_class('date_of_birth', models.DateField(null=True, blank=True))\r
59 User.add_to_class('about', models.TextField(blank=True))\r
60 User.add_to_class('is_username_taken',classmethod(user_is_username_taken))\r
61 User.add_to_class('get_q_sel_email_feed_frequency',user_get_q_sel_email_feed_frequency)\r
62 User.add_to_class('hide_ignored_questions', models.BooleanField(default=False))\r
63 User.add_to_class('tag_filter_setting',\r
64                     models.CharField(\r
65                                         max_length=16,\r
66                                         choices=TAG_EMAIL_FILTER_CHOICES,\r
67                                         default='ignored'\r
68                                      )\r
69                  )\r
70 \r
71 # custom signal\r
72 tags_updated = django.dispatch.Signal(providing_args=["question"])\r
73 edit_question_or_answer = django.dispatch.Signal(providing_args=["instance", "modified_by"])\r
74 delete_post_or_answer = django.dispatch.Signal(providing_args=["instance", "deleted_by"])\r
75 mark_offensive = django.dispatch.Signal(providing_args=["instance", "mark_by"])\r
76 user_updated = django.dispatch.Signal(providing_args=["instance", "updated_by"])\r
77 user_logged_in = django.dispatch.Signal(providing_args=["session"])\r
78 \r
79 \r
80 def get_messages(self):\r
81     messages = []\r
82     for m in self.message_set.all():\r
83         messages.append(m.message)\r
84     return messages\r
85 \r
86 def delete_messages(self):\r
87     self.message_set.all().delete()\r
88 \r
89 def get_profile_url(self):\r
90     """Returns the URL for this User's profile."""\r
91     return '%s%s/' % (reverse('user', args=[self.id]), slugify(self.username))\r
92 \r
93 def get_profile_link(self):\r
94     profile_link = u'<a href="%s">%s</a>' % (self.get_profile_url(),self.username)\r
95     logging.debug('in get profile link %s' % profile_link)\r
96     return mark_safe(profile_link)\r
97 \r
98 User.add_to_class('get_profile_url', get_profile_url)\r
99 User.add_to_class('get_profile_link', get_profile_link)\r
100 User.add_to_class('get_messages', get_messages)\r
101 User.add_to_class('delete_messages', delete_messages)\r
102 \r
103 def calculate_gravatar_hash(instance, **kwargs):\r
104     """Calculates a User's gravatar hash from their email address."""\r
105     if kwargs.get('raw', False):\r
106         return\r
107     instance.gravatar = hashlib.md5(instance.email).hexdigest()\r
108 \r
109 def record_ask_event(instance, created, **kwargs):\r
110     if created:\r
111         activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ASK_QUESTION)\r
112         activity.save()\r
113 \r
114 def record_answer_event(instance, created, **kwargs):\r
115     if created:\r
116         activity = Activity(user=instance.author, active_at=instance.added_at, content_object=instance, activity_type=TYPE_ACTIVITY_ANSWER)\r
117         activity.save()\r
118 \r
119 def record_comment_event(instance, created, **kwargs):\r
120     if created:\r
121         from django.contrib.contenttypes.models import ContentType\r
122         question_type = ContentType.objects.get_for_model(Question)\r
123         question_type_id = question_type.id\r
124         if (instance.content_type_id == question_type_id):\r
125             type = TYPE_ACTIVITY_COMMENT_QUESTION\r
126         else:\r
127             type = TYPE_ACTIVITY_COMMENT_ANSWER\r
128         activity = Activity(user=instance.user, active_at=instance.added_at, content_object=instance, activity_type=type)\r
129         activity.save()\r
130 \r
131 def record_revision_question_event(instance, created, **kwargs):\r
132     if created and instance.revision <> 1:\r
133         activity = Activity(user=instance.author, active_at=instance.revised_at, content_object=instance, activity_type=TYPE_ACTIVITY_UPDATE_QUESTION)\r
134         activity.save()\r
135 \r
136 def record_revision_answer_event(instance, created, **kwargs):\r
137     if created and instance.revision <> 1:\r
138         activity = Activity(user=instance.author, active_at=instance.revised_at, content_object=instance, activity_type=TYPE_ACTIVITY_UPDATE_ANSWER)\r
139         activity.save()\r
140 \r
141 def record_award_event(instance, created, **kwargs):\r
142     """\r
143     After we awarded a badge to user, we need to record this activity and notify user.\r
144     We also recaculate awarded_count of this badge and user information.\r
145     """\r
146     if created:\r
147         activity = Activity(user=instance.user, active_at=instance.awarded_at, content_object=instance,\r
148             activity_type=TYPE_ACTIVITY_PRIZE)\r
149         activity.save()\r
150 \r
151         instance.badge.awarded_count += 1\r
152         instance.badge.save()\r
153 \r
154         if instance.badge.type == Badge.GOLD:\r
155             instance.user.gold += 1\r
156         if instance.badge.type == Badge.SILVER:\r
157             instance.user.silver += 1\r
158         if instance.badge.type == Badge.BRONZE:\r
159             instance.user.bronze += 1\r
160         instance.user.save()\r
161 \r
162 def notify_award_message(instance, created, **kwargs):\r
163     """\r
164     Notify users when they have been awarded badges by using Django message.\r
165     """\r
166     if created:\r
167         user = instance.user\r
168         user.message_set.create(message=u"Congratulations, you have received a badge '%s'" % instance.badge.name)\r
169 \r
170 def record_answer_accepted(instance, created, **kwargs):\r
171     """\r
172     when answer is accepted, we record this for question author - who accepted it.\r
173     """\r
174     if not created and instance.accepted:\r
175         activity = Activity(user=instance.question.author, active_at=datetime.datetime.now(), \\r
176             content_object=instance, activity_type=TYPE_ACTIVITY_MARK_ANSWER)\r
177         activity.save()\r
178 \r
179 def update_last_seen(instance, created, **kwargs):\r
180     """\r
181     when user has activities, we update 'last_seen' time stamp for him\r
182     """\r
183     user = instance.user\r
184     user.last_seen = datetime.datetime.now()\r
185     user.save()\r
186 \r
187 def record_vote(instance, created, **kwargs):\r
188     """\r
189     when user have voted\r
190     """\r
191     if created:\r
192         if instance.vote == 1:\r
193             vote_type = TYPE_ACTIVITY_VOTE_UP\r
194         else:\r
195             vote_type = TYPE_ACTIVITY_VOTE_DOWN\r
196 \r
197         activity = Activity(user=instance.user, active_at=instance.voted_at, content_object=instance, activity_type=vote_type)\r
198         activity.save()\r
199 \r
200 def record_cancel_vote(instance, **kwargs):\r
201     """\r
202     when user canceled vote, the vote will be deleted.\r
203     """\r
204     activity = Activity(user=instance.user, active_at=datetime.datetime.now(), content_object=instance, activity_type=TYPE_ACTIVITY_CANCEL_VOTE)\r
205     activity.save()\r
206 \r
207 def record_delete_question(instance, delete_by, **kwargs):\r
208     """\r
209     when user deleted the question\r
210     """\r
211     if instance.__class__ == "Question":\r
212         activity_type = TYPE_ACTIVITY_DELETE_QUESTION\r
213     else:\r
214         activity_type = TYPE_ACTIVITY_DELETE_ANSWER\r
215 \r
216     activity = Activity(user=delete_by, active_at=datetime.datetime.now(), content_object=instance, activity_type=activity_type)\r
217     activity.save()\r
218 \r
219 def record_mark_offensive(instance, mark_by, **kwargs):\r
220     activity = Activity(user=mark_by, active_at=datetime.datetime.now(), content_object=instance, activity_type=TYPE_ACTIVITY_MARK_OFFENSIVE)\r
221     activity.save()\r
222 \r
223 def record_update_tags(question, **kwargs):\r
224     """\r
225     when user updated tags of the question\r
226     """\r
227     activity = Activity(user=question.author, active_at=datetime.datetime.now(), content_object=question, activity_type=TYPE_ACTIVITY_UPDATE_TAGS)\r
228     activity.save()\r
229 \r
230 def record_favorite_question(instance, created, **kwargs):\r
231     """\r
232     when user add the question in him favorite questions list.\r
233     """\r
234     if created:\r
235         activity = Activity(user=instance.user, active_at=datetime.datetime.now(), content_object=instance, activity_type=TYPE_ACTIVITY_FAVORITE)\r
236         activity.save()\r
237 \r
238 def record_user_full_updated(instance, **kwargs):\r
239     activity = Activity(user=instance, active_at=datetime.datetime.now(), content_object=instance, activity_type=TYPE_ACTIVITY_USER_FULL_UPDATED)\r
240     activity.save()\r
241 \r
242 def post_stored_anonymous_content(sender,user,session_key,signal,*args,**kwargs):\r
243     aq_list = AnonymousQuestion.objects.filter(session_key = session_key)\r
244     aa_list = AnonymousAnswer.objects.filter(session_key = session_key)\r
245     import settings\r
246     if settings.EMAIL_VALIDATION == 'on':#add user to the record\r
247         for aq in aq_list:\r
248             aq.author = user\r
249             aq.save()\r
250         for aa in aa_list:\r
251             aa.author = user\r
252             aa.save()\r
253         #maybe add pending posts message?\r
254     else: #just publish the questions\r
255         for aq in aq_list:\r
256             aq.publish(user)\r
257         for aa in aa_list:\r
258             aa.publish(user)\r
259 \r
260 #signal for User modle save changes\r
261 \r
262 pre_save.connect(calculate_gravatar_hash, sender=User)\r
263 post_save.connect(record_ask_event, sender=Question)\r
264 post_save.connect(record_answer_event, sender=Answer)\r
265 post_save.connect(record_comment_event, sender=Comment)\r
266 post_save.connect(record_revision_question_event, sender=QuestionRevision)\r
267 post_save.connect(record_revision_answer_event, sender=AnswerRevision)\r
268 post_save.connect(record_award_event, sender=Award)\r
269 post_save.connect(notify_award_message, sender=Award)\r
270 post_save.connect(record_answer_accepted, sender=Answer)\r
271 post_save.connect(update_last_seen, sender=Activity)\r
272 post_save.connect(record_vote, sender=Vote)\r
273 post_delete.connect(record_cancel_vote, sender=Vote)\r
274 delete_post_or_answer.connect(record_delete_question, sender=Question)\r
275 delete_post_or_answer.connect(record_delete_question, sender=Answer)\r
276 mark_offensive.connect(record_mark_offensive, sender=Question)\r
277 mark_offensive.connect(record_mark_offensive, sender=Answer)\r
278 tags_updated.connect(record_update_tags, sender=Question)\r
279 post_save.connect(record_favorite_question, sender=FavoriteQuestion)\r
280 user_updated.connect(record_user_full_updated, sender=User)\r
281 user_logged_in.connect(post_stored_anonymous_content)\r
282 \r
283 Question = Question\r
284 QuestionRevision = QuestionRevision\r
285 QuestionView = QuestionView\r
286 FavoriteQuestion = FavoriteQuestion\r
287 AnonymousQuestion = AnonymousQuestion\r
288 \r
289 Answer = Answer\r
290 AnswerRevision = AnswerRevision\r
291 AnonymousAnswer = AnonymousAnswer\r
292 \r
293 Tag = Tag\r
294 Comment = Comment\r
295 Vote = Vote\r
296 FlaggedItem = FlaggedItem\r
297 MarkedTag = MarkedTag\r
298 \r
299 Badge = Badge\r
300 Award = Award\r
301 Repute = Repute\r
302 \r
303 Activity = Activity\r
304 EmailFeedSetting = EmailFeedSetting\r
305 AnonymousEmail = AnonymousEmail\r
306 AuthKeyUserAssociation = AuthKeyUserAssociation\r
307 \r
308 __all__ = [\r
309         'Question',\r
310         'QuestionRevision',\r
311         'QuestionView',\r
312         'FavoriteQuestion',\r
313         'AnonymousQuestion',\r
314 \r
315         'Answer',\r
316         'AnswerRevision',\r
317         'AnonymousAnswer',\r
318 \r
319         'Tag',\r
320         'Comment',\r
321         'Vote',\r
322         'FlaggedItem',\r
323         'MarkedTag',\r
324 \r
325         'Badge',\r
326         'Award',\r
327         'Repute',\r
328 \r
329         'Activity',\r
330         'EmailFeedSetting',\r
331         'AnonymousEmail',\r
332         'AuthKeyUserAssociation',\r
333 \r
334         'User'\r
335         ]\r
336 \r
337 \r
338 from forum.modules import get_modules_script_classes\r
339 \r
340 for k, v in get_modules_script_classes('models', models.Model).items():\r
341     if not k in __all__:\r
342         __all__.append(k)\r
343         exec "%s = v" % k