:mod:`waeup.sirp.accesscodes.accesscodes` -- access codes (aka PINs) ******************************************************************** .. module:: waeup.sirp.accesscodes.accesscodes Components that represent access codes and related. .. :doctest: Access codes are created as parts of batches. We therefore have to create a batch first. Here we create a batch of three entries, with a cost of ``12.12`` per code, the batch prefix ``APP``, batch number ``10``, creator ID ``Fred`` and some arbitrary creation date: >>> import datetime >>> from waeup.sirp.accesscodes.accesscodes import AccessCodeBatch >>> batch = AccessCodeBatch( ... datetime.datetime(2009, 12, 23), 'Fred','APP', 12.12, 3, num=10) The entries of a batch have to be created manually. This is, because we cannot add persistent objects in a still not persisted container: >>> batch.createEntries() Now we have three accesscodes stored in the batch: >>> sorted(list(batch.items())) [(u'0', >> ac = batch['0'] >>> ac.representation 'APP-10-<10-DIGITS>' The main point about a batch is that it can act as a dictionary for the generated access codes: >>> ac_codes = list(batch.values()) >>> [x.representation for x in ac_codes] ['APP-10-...', 'APP-10-...', 'APP-10-...'] `Accesscode` and `AccessCodeBatch` classes implement the respective interfaces: >>> from waeup.sirp.accesscodes.accesscodes import ( ... AccessCode, AccessCodeBatch) >>> from waeup.sirp.accesscodes.interfaces import( ... IAccessCode, IAccessCodeBatch) >>> from zope.interface.verify import verifyClass >>> verifyClass(IAccessCode, AccessCode) True >>> verifyClass(IAccessCodeBatch, AccessCodeBatch) True Access codes without that are not part of a batch, will give strange representations: >>> ac = AccessCode(None, '9999999999', 12.12) >>> ac.representation '--<10-DIGITS>' Access code plugin ================== .. class:: AccessCodePlugin .. attribute:: grok.implements(IWAeUPSIRPPluggable) .. attribute:: grok.name('accesscodes') .. method:: setup(site, name, logger) Create an accesscodebatch container in ``site``. Any events are logged to ``logger``. .. method:: update(site, name, logger) Check if ``site`` contains an accesscodebatch container and add it if missing. Any events are logged to ``logger``. The AccessCodePlugin is available as a global named utility for the IWAeUPSIRPPluggable interface named ``accesscodes``. It is looked up by a university instance when created. >>> from zope.component import getUtility >>> from waeup.sirp.interfaces import IWAeUPSIRPPluggable >>> plugin = getUtility(IWAeUPSIRPPluggable, name='accesscodes') >>> plugin It provides a `setup()` and an `update()` method. Both have to be fed with a site object (the `IUniversity` instance to modify), a logger and a name. We create a faked site and a logger: >>> import logging >>> faked_site = dict() >>> logger = logging.getLogger('ac_test') >>> logger.setLevel(logging.DEBUG) >>> ch = logging.FileHandler('ac_tests.log', 'w') >>> ch.setLevel(logging.DEBUG) >>> logger.addHandler(ch) Now we can install our stuff in the faked site: >>> plugin.setup(faked_site, 'blah', logger) The faked site now has an access code container: >>> faked_site.keys() ['accesscodes'] The action is described in the log: >>> print open('ac_tests.log', 'r').read() Installed container for access code batches. We can also update an existing site, by calling `update()`: >>> plugin.update(faked_site, 'blah', logger) There was nothing to do for the updater: >>> print open('ac_tests.log', 'r').read() Installed container for access code batches. AccessCodePlugin: Updating site at {'accesscodes'...: Nothing to do. But if we remove the created batch container and call the updater, it will create a new one: >>> del faked_site['accesscodes'] >>> plugin.update(faked_site, 'blah', logger) >>> print open('ac_tests.log', 'r').read() Installed container for access code batches. AccessCodePlugin: Updating site at {'accesscodes'...: Nothing to do. Updating site at {}. Installing access codes. Installed container for access code batches. Clean up: >>> import os >>> os.unlink('ac_tests.log')