]> git.openstreetmap.org Git - osqa.git/blob - forum/badges/base.py
Fix error reported at http://meta.osqa.net/question/1660/just-been-awarded-student...
[osqa.git] / forum / badges / base.py
1 import re
2 from string import lower
3
4 from django.contrib.contenttypes.models import ContentType
5 from django.db.models.signals import post_save
6
7 from forum.models import Badge, Node
8 from forum.actions import AwardAction
9
10 import logging
11
12 installed = dict([(b.cls, b) for b in Badge.objects.all()])
13
14 class BadgesMeta(type):
15     by_class = {}
16     by_id = {}
17
18     def __new__(mcs, name, bases, dic):
19         badge = type.__new__(mcs, name, bases, dic)
20
21         if not dic.get('abstract', False):
22             if not name in installed:
23                 badge.ondb = Badge(cls=name, type=dic.get('type', Badge.BRONZE))
24                 badge.ondb.save()
25             else:
26                 badge.ondb = installed[name]
27
28             inst = badge()
29
30             def hook(action, new):
31                 user = inst.award_to(action)
32
33                 if user:
34                     badge.award(user, action, badge.award_once)
35
36             for action in badge.listen_to:
37                 action.hook(hook)
38
39             BadgesMeta.by_class[name] = badge
40             badge.ondb.__dict__['_class'] = inst
41             BadgesMeta.by_id[badge.ondb.id] = badge
42
43         return badge
44
45 class AbstractBadge(object):
46     __metaclass__ = BadgesMeta
47
48     abstract = True
49     award_once = False
50
51     @property
52     def name(self):
53         raise NotImplementedError
54
55     @property
56     def description(self):
57         raise NotImplementedError
58
59     @classmethod
60     def award(cls, user, action, once=False):
61         if once:
62             node = None
63             awarded = AwardAction.get_for(user, cls.ondb)
64         else:
65             node = action.node
66             awarded = AwardAction.get_for(user, cls.ondb, node)
67
68         if not awarded:
69             AwardAction(user=user, node=node, ip=action.ip).save(data=dict(badge=cls.ondb, trigger=action))