"""Components to handle access codes. """ import grok from random import SystemRandom as random from waeup.sirp.interfaces import IWAeUPSIRPPluggable from waeup.sirp.accesscodes.interfaces import ( IAccessCode, IAccessCodeBatch, IAccessCodeBatchContainer ) class AccessCode(grok.Model): grok.implements(IAccessCode) def __init__(self, batch_serial, random_num, cost, invalidation_date=None, student_id=None): self.batch_serial = batch_serial self.random_num = random_num self.cost = cost self.invalidation_date = invalidation_date self.student_id = student_id @property def representation(self): return '%s-%s-%s' % ( self.batch_prefix, self.batch_num, self.random_num) @property def batch(self): return getattr(self, '__parent__', None) @property def batch_prefix(self): if self.batch is None: return '' return self.batch.prefix @property def batch_num(self): if self.batch is None: return '' return self.batch.num class AccessCodeBatch(grok.Container): """A batch of access codes. """ grok.implements(IAccessCodeBatch) def __init__(self, creation_date, creator, batch_prefix, cost, entry_num, num=None): super(AccessCodeBatch, self).__init__() self.creation_date = creation_date self.creator = creator self.prefix = batch_prefix self.cost = cost self.entry_num = entry_num self.num = num def createEntries(self): """Create the entries for this batch. """ self._used = [] for num in range(self.entry_num): random_num = self.getNewRandomNum() ac = AccessCode(num, random_num, self.cost) self[str(num)] = ac del self._used def getNewRandomNum(self): """Create a random number of 10 digits. The number is returned as string. """ result = '' while result == '' or result in self._used: result = '' for x in range(10): result += str(random().randint(0, 9)) return result class AccessCodeBatchContainer(grok.Container): grok.implements(IAccessCodeBatchContainer) def addBatch(self, batch): """Add a batch. """ batch.num = self.getNum(batch.prefix) key = "%s-%s" % (batch.prefix, batch.num) self[key] = batch batch.createEntries() self._p_changed = True self.curr_num += 1 def getNum(self, prefix): """Get next unused num for given prefix. """ num = 1 prefix = prefix.upper() while self.get('%s-%s' % (prefix, num), None): num += 1 return num class AccessCodePlugin(grok.GlobalUtility): grok.name('accesscodes') grok.implements(IWAeUPSIRPPluggable) def setup(self, site, name, logger): site['accesscodes'] = AccessCodeBatchContainer() logger.info('Installed container for access code batches.') return def update(self, site, name, logger): pass