2 from string import lower
4 from django.core.exceptions import MultipleObjectsReturned
5 from django.db.models.signals import post_save
7 from forum.models import Badge, Node, Action
8 from forum.actions import AwardAction
12 installed = dict([(b.cls, b) for b in Badge.objects.all()])
14 class BadgesMeta(type):
18 def __new__(mcs, name, bases, dic):
19 badge = type.__new__(mcs, name, bases, dic)
21 if not dic.get('abstract', False):
22 if not name in installed:
23 ondb = Badge(cls=name, type=dic.get('type', Badge.BRONZE))
26 ondb = installed[name]
32 def hook(action, new):
33 user = inst.award_to(action)
36 badge.award(user, action, badge.award_once)
38 for action in badge.listen_to:
41 BadgesMeta.by_class[name] = inst
42 BadgesMeta.by_id[ondb.id] = inst
46 class AbstractBadge(object):
47 __metaclass__ = BadgesMeta
54 raise NotImplementedError
57 def description(self):
58 raise NotImplementedError
61 def award(cls, user, action, once=False):
62 db_object = Badge.objects.get(id=cls.ondb)
66 awarded = AwardAction.get_for(user, db_object)
69 awarded = AwardAction.get_for(user, db_object, node)
71 trigger = isinstance(action, Action) and action or None
74 AwardAction(user=user, node=node).save(data=dict(badge=db_object, trigger=trigger))
75 except MultipleObjectsReturned:
77 logging.error('Found multiple %s badges awarded for user %s (%s)' % (self.name, user.username, user.id))
79 logging.error('Found multiple %s badges awarded for user %s (%s) and node %s' % (self.name, user.username, user.id, node.id))