1 | :mod:`waeup.sirp.accesscodes.accesscodes` -- access codes (aka PINs) |
---|
2 | ******************************************************************** |
---|
3 | |
---|
4 | .. module:: waeup.sirp.accesscodes.accesscodes |
---|
5 | |
---|
6 | Components that represent access codes and related. |
---|
7 | |
---|
8 | .. :doctest: |
---|
9 | |
---|
10 | Access codes are created as parts of batches. We therefore have to |
---|
11 | create a batch first. |
---|
12 | |
---|
13 | Here we create a batch of three entries, with a cost of ``12.12`` per |
---|
14 | code, the batch prefix ``APP``, batch number ``10``, creator ID |
---|
15 | ``Fred`` and some arbitrary creation date: |
---|
16 | |
---|
17 | >>> import datetime |
---|
18 | >>> from waeup.sirp.accesscodes.accesscodes import AccessCodeBatch |
---|
19 | >>> batch = AccessCodeBatch( |
---|
20 | ... datetime.datetime(2009, 12, 23), 'Fred','APP', 12.12, 3, num=10) |
---|
21 | |
---|
22 | The entries of a batch have to be created manually. This is, because |
---|
23 | we cannot add persistent objects in a still not persisted container: |
---|
24 | |
---|
25 | >>> batch.createEntries() |
---|
26 | |
---|
27 | Now we have three accesscodes stored in the batch: |
---|
28 | |
---|
29 | >>> sorted(list(batch.items())) |
---|
30 | [(u'0', <waeup.sirp...AccessCode object at 0x...), ...] |
---|
31 | |
---|
32 | As we can see, access codes entries can be found in a batch by their |
---|
33 | (stringified) serial number. |
---|
34 | |
---|
35 | Each accesscode has a representation: |
---|
36 | |
---|
37 | >>> ac = batch['0'] |
---|
38 | >>> ac.representation |
---|
39 | 'APP-10-<10-DIGITS>' |
---|
40 | |
---|
41 | The main point about a batch is that it can act as a dictionary for |
---|
42 | the generated access codes: |
---|
43 | |
---|
44 | >>> ac_codes = list(batch.values()) |
---|
45 | >>> [x.representation for x in ac_codes] |
---|
46 | ['APP-10-...', 'APP-10-...', 'APP-10-...'] |
---|
47 | |
---|
48 | `Accesscode` and `AccessCodeBatch` classes implement the respective |
---|
49 | interfaces: |
---|
50 | |
---|
51 | >>> from waeup.sirp.accesscodes.accesscodes import ( |
---|
52 | ... AccessCode, AccessCodeBatch) |
---|
53 | >>> from waeup.sirp.accesscodes.interfaces import( |
---|
54 | ... IAccessCode, IAccessCodeBatch) |
---|
55 | >>> from zope.interface.verify import verifyClass |
---|
56 | >>> verifyClass(IAccessCode, AccessCode) |
---|
57 | True |
---|
58 | |
---|
59 | >>> verifyClass(IAccessCodeBatch, AccessCodeBatch) |
---|
60 | True |
---|
61 | |
---|
62 | Access codes without that are not part of a batch, will give strange |
---|
63 | representations: |
---|
64 | |
---|
65 | >>> ac = AccessCode(None, '9999999999', 12.12) |
---|
66 | >>> ac.representation |
---|
67 | '--<10-DIGITS>' |
---|
68 | |
---|
69 | Access code plugin |
---|
70 | ================== |
---|
71 | |
---|
72 | .. class:: AccessCodePlugin |
---|
73 | |
---|
74 | .. attribute:: grok.implements(IWAeUPSIRPPluggable) |
---|
75 | .. attribute:: grok.name('accesscodes') |
---|
76 | |
---|
77 | .. method:: setup(site, name, logger) |
---|
78 | |
---|
79 | Create an accesscodebatch container in ``site``. Any events are |
---|
80 | logged to ``logger``. |
---|
81 | |
---|
82 | .. method:: update(site, name, logger) |
---|
83 | |
---|
84 | Check if ``site`` contains an accesscodebatch container and add |
---|
85 | it if missing. Any events are logged to ``logger``. |
---|
86 | |
---|
87 | The AccessCodePlugin is available as a global named utility for the |
---|
88 | IWAeUPSIRPPluggable interface named ``accesscodes``. |
---|
89 | |
---|
90 | It is looked up by a university instance when created. |
---|
91 | |
---|
92 | >>> from zope.component import getUtility |
---|
93 | >>> from waeup.sirp.interfaces import IWAeUPSIRPPluggable |
---|
94 | >>> plugin = getUtility(IWAeUPSIRPPluggable, name='accesscodes') |
---|
95 | >>> plugin |
---|
96 | <waeup.sirp.accesscodes.accesscodes.AccessCodePlugin object at 0x...> |
---|
97 | |
---|
98 | It provides a `setup()` and an `update()` method. Both have to be |
---|
99 | fed with a site object (the `IUniversity` instance to modify), a |
---|
100 | logger and a name. |
---|
101 | |
---|
102 | We create a faked site and a logger: |
---|
103 | |
---|
104 | >>> import logging |
---|
105 | >>> faked_site = dict() |
---|
106 | >>> logger = logging.getLogger('ac_test') |
---|
107 | >>> logger.setLevel(logging.DEBUG) |
---|
108 | >>> ch = logging.FileHandler('ac_tests.log', 'w') |
---|
109 | >>> ch.setLevel(logging.DEBUG) |
---|
110 | >>> logger.addHandler(ch) |
---|
111 | |
---|
112 | Now we can install our stuff in the faked site: |
---|
113 | |
---|
114 | >>> plugin.setup(faked_site, 'blah', logger) |
---|
115 | |
---|
116 | The faked site now has an access code container: |
---|
117 | |
---|
118 | >>> faked_site.keys() |
---|
119 | ['accesscodes'] |
---|
120 | |
---|
121 | The action is described in the log: |
---|
122 | |
---|
123 | >>> print open('ac_tests.log', 'r').read() |
---|
124 | Installed container for access code batches. |
---|
125 | |
---|
126 | We can also update an existing site, by calling `update()`: |
---|
127 | |
---|
128 | >>> plugin.update(faked_site, 'blah', logger) |
---|
129 | |
---|
130 | There was nothing to do for the updater: |
---|
131 | |
---|
132 | >>> print open('ac_tests.log', 'r').read() |
---|
133 | Installed container for access code batches. |
---|
134 | AccessCodePlugin: Updating site at {'accesscodes'...: Nothing to do. |
---|
135 | |
---|
136 | But if we remove the created batch container and call the updater, it |
---|
137 | will create a new one: |
---|
138 | |
---|
139 | >>> del faked_site['accesscodes'] |
---|
140 | >>> plugin.update(faked_site, 'blah', logger) |
---|
141 | >>> print open('ac_tests.log', 'r').read() |
---|
142 | Installed container for access code batches. |
---|
143 | AccessCodePlugin: Updating site at {'accesscodes'...: Nothing to do. |
---|
144 | Updating site at {}. Installing access codes. |
---|
145 | Installed container for access code batches. |
---|
146 | |
---|
147 | Clean up: |
---|
148 | |
---|
149 | >>> import os |
---|
150 | >>> os.unlink('ac_tests.log') |
---|