accesscodes.accesscode – AC Components

Components to handle access codes.

Access codes (aka PINs) in waeup sites are organized in batches. That means a certain accesscode must be part of a batch. As a site (or university) can hold an arbitrary number of batches, we also provide a batch container. Each university has one batch container that holds all access code batches of which each one can hold several thousands of access codes.

class waeup.kofa.accesscodes.accesscode.AccessCode(batch_serial=None, random_num=None)[source]

Bases: grokcore.content.components.Model

An access code (aka PIN).

Implements waeup.kofa.accesscodes.interfaces.IAccessCode. AccessCode instances are normally part of an AccessCodeBatch so their representation (or code) is built with the containing batch involved.

batch_serial
the serial number of the new AccessCode inside its batch.
random_num
a 10-digit number representing the main part of the code.

AccessCode instances normally have a representation (or code) like

APP-XXX-YYYYYYYYYY

where APP is the prefix of the containing batch, XXX is the batch number and YYYYYYYYYY is the real code. The complete PIN is portal-wide unique.

Access code instances are far more than simple strings. They have a state, a history (so that all changes can be tracked) and a cost (given as a float number).

The state of an access code is something like ‘used’, ‘disabled’, etc. and determined by the workflow defined in waeup.kofa.accesscodes.workflow. This also means that instead of setting the status of an access code directly (you can’t do that easily, and yes, that’s intentionally), you have to trigger a transition (that might fail, if the transition is not allowed in terms of logic or permissions). See waeup.kofa.accesscodes.workflow for details.

__doc__ = "An access code (aka PIN).\n\n Implements\n :class:`waeup.kofa.accesscodes.interfaces.IAccessCode`. :class:`AccessCode`\n instances are normally part of an :class:`AccessCodeBatch` so\n their representation (or code) is built with the containing batch\n involved.\n\n `batch_serial`\n the serial number of the new :class:`AccessCode` inside its batch.\n\n `random_num`\n a 10-digit number representing the main part of the code.\n\n :class:`AccessCode` instances normally have a representation (or\n code) like\n\n ``APP-XXX-YYYYYYYYYY``\n\n where ``APP`` is the prefix of the containing batch, ``XXX`` is\n the batch number and ``YYYYYYYYYY`` is the real code. The complete\n PIN is portal-wide unique.\n\n Access code instances are far more than simple strings. They have\n a state, a history (so that all changes can be tracked) and a\n cost (given as a float number).\n\n The state of an access code is something like 'used', 'disabled',\n etc. and determined by the workflow defined in\n :mod:`waeup.kofa.accesscodes.workflow`. This also means that\n instead of setting the status of an access code directly (you\n can't do that easily, and yes, that's intentionally), you have to\n trigger a transition (that might fail, if the transition is not\n allowed in terms of logic or permissions). See\n :mod:`waeup.kofa.accesscodes.workflow` for details.\n\n "
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCode>
__init__(batch_serial=None, random_num=None)[source]
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
batch

The batch this AccessCode is contained.

batch_num

The number of the batch this AccessCode belongs to. A read-only attribute.

batch_prefix

The prefix of the batch this AccessCode belongs to.

history

A waeup.kofa.objecthistory.ObjectHistory instance.

representation

A string representation of the AccessCode.

It has format APP-XXX-YYYYYYYYYY as described above.

state

The workflow state. A read-only attribute.

translated_state

The translated workflow state. A read-only attribute.

class waeup.kofa.accesscodes.accesscode.AccessCodeBatch(creation_date=None, creator=None, batch_prefix=None, cost=None, entry_num=0, num=None)[source]

Bases: grokcore.content.components.Container

A batch of access codes.

__doc__ = 'A batch of access codes.\n '
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCodeBatch>
__init__(creation_date=None, creator=None, batch_prefix=None, cost=None, entry_num=0, num=None)[source]
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
_createEntries()[source]

Create the entries for this batch.

_getStoragePath()[source]

Get the directory, where we store all batch-related CSV files.

addAccessCode(num, pin, cost=0.0, owner=None)[source]

Add an access-code.

archive()[source]

Create a CSV file for archive.

createCSVLogFile()[source]

Create a CSV file with data in batch.

Data will not contain invalidation date nor student ids. File will be created in accesscodes subdir of data center storage path.

Returns name of created file.

getAccessCode(ac_id)[source]

Get the AccessCode with ID ac_id or KeyError.

getNewRandomNum(num=1)[source]

Create a set of num random numbers of 10 digits each.

The number is returned as string.

class waeup.kofa.accesscodes.accesscode.AccessCodeBatchContainer[source]

Bases: grokcore.content.components.Container, waeup.kofa.utils.logger.Logger

__doc__ = None
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCodeBatchContainer>
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
_getStoragePath()[source]

Get the directory, where batch import files are stored.

If the path does not exist yet, it is created. The path is normally accesscodes/imports below the datacenter storage path (see waeup.kofa.accesscodes.Datacenter.storage).

addBatch(batch)[source]

Add an already created batch.

addBatchByImport(batch, batch_id)[source]

Add an already created batch by import with defined id.

We want to create a batch without access codes. Since num_entry access codes are automatically added by handle_batch_added when the batch is added to the ZODB, we have to temporarily set entry_num to zero when adding the batch persistently.

createBatch(creation_date, creator, prefix, cost, entry_num)[source]

Create and add a batch.

disable(ac_id, comment=None)[source]

Disable the AC with ID ac_id.

user_id is the user ID of the user triggering the process. Already disabled ACs are left untouched.

enable(ac_id, comment=None)[source]

(Re-)enable the AC with ID ac_id.

This leaves the given AC in state unused. Already enabled ACs are left untouched.

getAccessCode(ac_id)[source]

Get the AccessCode with ID ac_id or KeyError.

getImportFiles()[source]

Return a generator with basenames of available import files.

getNum(prefix)[source]

Get next unused num for given prefix.

logger_filename = 'accesscodes.log'
logger_info(ob_class, comment=None)[source]

Get the logger’s info method.

logger_name = 'waeup.kofa.${sitename}.accesscodes'
reimport(filename, creator=u'UNKNOWN')[source]

Reimport a batch given in CSV file.

CSV file must be of format as generated by createCSVLogFile method.

class waeup.kofa.accesscodes.accesscode.AccessCodeBatchFactory[source]

Bases: grokcore.component.components.GlobalUtility

A factory for accesscodebatches.

We need this factory for the accesscodebatchprocessor.

__call__(*args, **kw)[source]
__doc__ = 'A factory for accesscodebatches.\n\n We need this factory for the accesscodebatchprocessor.\n '
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCodeBatchFactory>
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
description = u'This factory instantiates new accesscode batch instances.'
getInterfaces()[source]
title = (u'Create a new accesscode batch.',)
class waeup.kofa.accesscodes.accesscode.AccessCodeFactory[source]

Bases: grokcore.component.components.GlobalUtility

A factory for accesscodes.

We need this factory for the accesscodeprocessor.

__call__(*args, **kw)[source]
__doc__ = 'A factory for accesscodes.\n\n We need this factory for the accesscodeprocessor.\n '
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCodeFactory>
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
description = u'This factory instantiates new accesscode instances.'
getInterfaces()[source]
title = (u'Create a new accesscode.',)
class waeup.kofa.accesscodes.accesscode.AccessCodePlugin[source]

Bases: grokcore.component.components.GlobalUtility

__doc__ = None
__implemented__ = <implementedBy waeup.kofa.accesscodes.accesscode.AccessCodePlugin>
__module__ = 'waeup.kofa.accesscodes.accesscode'
__provides__

Special descriptor for class __provides__

The descriptor caches the implementedBy info, so that we can get declarations for objects without instance-specific interfaces a bit quicker.

For example:

>>> from zope.interface import Interface
>>> class IFooFactory(Interface):
...     pass
>>> class IFoo(Interface):
...     pass
>>> class C(object):
...     implements(IFoo)
...     classProvides(IFooFactory)
>>> [i.getName() for i in C.__provides__]
['IFooFactory']
>>> [i.getName() for i in C().__provides__]
['IFoo']
setup(site, name, logger)[source]
update(site, name, logger)[source]
waeup.kofa.accesscodes.accesscode.create_accesscode(batch_prefix, batch_num, cost, owner)[source]
waeup.kofa.accesscodes.accesscode.disable_accesscode(access_code, comment=None)[source]

Disable AccessCode denoted by string access_code.

Fires an appropriate transition to perform the task.

comment is a string that will appear in the access code history.

See fire_transition() for possible exceptions and their meanings.

waeup.kofa.accesscodes.accesscode.fire_transition(access_code, arg, toward=False, comment=None, owner=None)[source]

Fire workflow transition for access code.

The access code instance is looked up via access_code (a string like APP-1-12345678).

arg tells what kind of transition to trigger. This will be a transition id like 'use' or 'init', or some transition target like waeup.kofa.accesscodes.workflow.INITIALIZED.

If toward is False (the default) you have to pass a transition id as arg, otherwise you must give a transition target.

If comment is specified (default is None) the given string will be passed along as transition comment. It will appear in the history of the changed access code. You can use this to place remarks like for which object the access code was used or similar.

If owner is specified, the owner attribute of the access code is checked. If the access code has an owner but is different, fire_transition() fails and returns False.

fire_transition() might raise exceptions depending on the reason why the requested transition cannot be performed.

The following exceptions can occur during processing:

KeyError:
signals not existent access code, batch or site.
ValueError:
signals illegal format of access_code string. The regular format is APP-N-XXXXXXXX.
hurry.workflow.interfaces.InvalidTransitionError:
the transition requested cannot be performed because the workflow rules forbid it.
Unauthorized:
the current user is not allowed to perform the requested transition.
waeup.kofa.accesscodes.accesscode.get_access_code(access_code)[source]

Get an access code instance.

An access code here is a string like PUDE-1-1234567890.

Returns None if the given code cannot be found.

This is a convenicence function that is faster than looking up a batch container for the approriate access code.

waeup.kofa.accesscodes.accesscode.handle_batch_added(batch, event)[source]
waeup.kofa.accesscodes.accesscode.invalidate_accesscode(access_code, comment=None, owner=None)[source]

Invalidate AccessCode denoted by string access_code.

Fires an appropriate transition to perform the task.

comment is a string that will appear in the access code history.

See fire_transition() for possible exceptions and their meanings.

waeup.kofa.accesscodes.accesscode.reenable_accesscode(access_code, comment=None)[source]

Reenable AccessCode denoted by string access_code.

Fires an appropriate transition to perform the task.

comment is a string that will appear in the access code history.

See fire_transition() for possible exceptions and their meanings.