source: main/waeup.sirp/trunk/src/waeup/sirp/accesscodes/accesscodes.py @ 5088

Last change on this file since 5088 was 5086, checked in by uli, 15 years ago

Split creation of batches and batch entry creation. This is needed,
because we cannot add persistent access codes inside a yet not stored
persistent container (?!).

File size: 3.1 KB
Line 
1"""Components to handle access codes.
2"""
3import grok
4from random import SystemRandom as random
5from waeup.sirp.interfaces import IWAeUPSIRPPluggable
6from waeup.sirp.accesscodes.interfaces import (
7    IAccessCode, IAccessCodeBatch, IAccessCodeBatchContainer
8    )
9
10class AccessCode(grok.Model):
11    grok.implements(IAccessCode)
12
13    def __init__(self, batch_serial, random_num, cost,
14                 invalidation_date=None, student_id=None):
15        self.batch_serial = batch_serial
16        self.random_num = random_num
17        self.cost = cost
18        self.invalidation_date = invalidation_date
19        self.student_id = student_id
20
21    @property
22    def representation(self):
23        return '%s-%s-%s' % (
24            self.batch_prefix, self.batch_num, self.random_num)
25
26    @property
27    def batch(self):
28        return getattr(self, '__parent__', None)
29
30    @property
31    def batch_prefix(self):
32        if self.batch is None:
33            return ''
34        return self.batch.prefix
35
36    @property
37    def batch_num(self):
38        if self.batch is None:
39            return ''
40        return self.batch.num
41
42class AccessCodeBatch(grok.Container):
43    """A batch of access codes.
44    """
45    grok.implements(IAccessCodeBatch)
46
47    def __init__(self, creation_date, creator, batch_prefix, cost,
48                 entry_num, num=None):
49        super(AccessCodeBatch, self).__init__()
50        self.creation_date = creation_date
51        self.creator = creator
52        self.prefix = batch_prefix
53        self.cost = cost
54        self.entry_num = entry_num
55        self.num = num
56
57    def createEntries(self):
58        """Create the entries for this batch.
59        """
60        self._used = []
61        for num in range(self.entry_num):
62            random_num = self.getNewRandomNum()
63            ac = AccessCode(num, random_num, self.cost)
64            self[str(num)] = ac
65        del self._used
66
67    def getNewRandomNum(self):
68        """Create a random number of 10 digits.
69
70        The number is returned as string.
71        """
72        result = ''
73        while result == '' or result in self._used:
74            result = ''
75            for x in range(10):
76                result += str(random().randint(0, 9))
77        return result
78
79class AccessCodeBatchContainer(grok.Container):
80    grok.implements(IAccessCodeBatchContainer)
81
82    def addBatch(self, batch):
83        """Add a batch.
84        """
85        batch.num = self.getNum(batch.prefix)
86        key = "%s-%s" % (batch.prefix, batch.num)
87        self[key] = batch
88        batch.createEntries()
89        self._p_changed = True
90        self.curr_num += 1
91
92    def getNum(self, prefix):
93        """Get next unused num for given prefix.
94        """
95        num = 1
96        prefix = prefix.upper()
97        while self.get('%s-%s' % (prefix, num), None):
98            num += 1
99        return num
100       
101class AccessCodePlugin(grok.GlobalUtility):
102    grok.name('accesscodes')
103    grok.implements(IWAeUPSIRPPluggable)
104
105    def setup(self, site, name, logger):
106        site['accesscodes'] = AccessCodeBatchContainer()
107        logger.info('Installed container for access code batches.')
108        return
109
110    def update(self, site, name, logger):
111        pass
Note: See TracBrowser for help on using the repository browser.