773 lines
24 KiB
Python
773 lines
24 KiB
Python
# w.c.s. - web application for online forms
|
|
# Copyright (C) 2005-2018 Entr'ouvert
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import warnings
|
|
|
|
from django.utils import six
|
|
from django.utils.encoding import force_text
|
|
from django.utils.functional import SimpleLazyObject
|
|
|
|
from quixote import get_publisher, get_request
|
|
|
|
from pyproj import Geod
|
|
|
|
from .qommon import misc, force_str
|
|
from .qommon.evalutils import make_datetime
|
|
from .qommon.templatetags.qommon import parse_datetime
|
|
from .qommon.storage import (Or, Equal, NotEqual)
|
|
|
|
|
|
class LazyFormDefObjectsManager(object):
|
|
def __init__(self, formdef, formdata=None, criterias=None, order_by=None):
|
|
self._formdef = formdef
|
|
self._formdata = formdata
|
|
if criterias is None:
|
|
criterias = [NotEqual('status', 'draft')]
|
|
# add custom marker to criteria so it can be found back and removed in
|
|
# drafts().
|
|
criterias[0].exclude_drafts = True
|
|
self._criterias = criterias
|
|
self._order_by = order_by
|
|
self._cached_resultset = None
|
|
|
|
@property # @property for backward compatibility
|
|
def count(self):
|
|
return self._formdef.data_class().count(clause=self._criterias)
|
|
|
|
def _clone(self, criterias, order_by=None):
|
|
return LazyFormDefObjectsManager(
|
|
self._formdef,
|
|
self._formdata,
|
|
criterias,
|
|
order_by=order_by or self._order_by)
|
|
|
|
def order_by(self, attribute):
|
|
return self._clone(self._criterias, order_by=attribute)
|
|
|
|
def all(self):
|
|
# (expose 'all' only to mimick django, it's not actually useful as this
|
|
# object serves as both manager and queryset)
|
|
return self._clone(None)
|
|
|
|
def pending(self):
|
|
status_filters = ['wf-%s' % x.id for x in
|
|
self._formdef.workflow.get_not_endpoint_status()]
|
|
criterias = [Or([Equal('status', x) for x in status_filters])]
|
|
return self._clone(self._criterias + criterias)
|
|
|
|
def current_user(self): # filter on current user
|
|
user = get_request().user
|
|
return self._clone(self._criterias + [Equal('user_id', str(user.id) if user else '-1')])
|
|
|
|
def drafts(self):
|
|
criterias = [x for x in self._criterias if not getattr(x, 'exclude_drafts', False)]
|
|
return self._clone(criterias + [Equal('status', 'draft')])
|
|
|
|
def done(self):
|
|
status_filters = ['wf-%s' % x.id for x in
|
|
self._formdef.workflow.get_endpoint_status()]
|
|
criterias = [Or([Equal('status', x) for x in status_filters])]
|
|
return self._clone(self._criterias + criterias)
|
|
|
|
def distance_filter(self, distance):
|
|
geod = Geod(ellps='WGS84')
|
|
center = self._formdata.get_auto_geoloc()
|
|
center_lon, center_lat = center['lon'], center['lat']
|
|
def distance_check(obj):
|
|
geoloc = obj.get_auto_geoloc()
|
|
if not geoloc:
|
|
return False
|
|
# keep computed distance in object
|
|
obj._distance = geod.inv(center_lon, center_lat, geoloc['lon'], geoloc['lat'])[2]
|
|
return bool(obj._distance < distance)
|
|
return self._clone(self._criterias + [distance_check])
|
|
|
|
def __getattr__(self, attribute):
|
|
# backward compatibility
|
|
if attribute.startswith('count_status_'):
|
|
status = attribute[len('count_status_'):]
|
|
return len(self._formdef.data_class().get_ids_with_indexed_value(
|
|
'status', 'wf-%s' % status))
|
|
if attribute == 'formdef':
|
|
warnings.warn('Deprecated access to formdef', DeprecationWarning)
|
|
return self._formdef
|
|
raise AttributeError('No such attribute %r' % attribute)
|
|
|
|
def __len__(self):
|
|
if self._cached_resultset:
|
|
return len(self._cached_resultset)
|
|
return self.count
|
|
|
|
def __getitem__(self, key):
|
|
try:
|
|
int(key)
|
|
except ValueError:
|
|
# A django template doing formdef.objects.drafts would start by
|
|
# doing ['drafts'], that would raise TypeError and then continue
|
|
# to accessing .drafts (this is done in _resolve_lookup).
|
|
# We need to abort earlier as we don't want to load all formdata
|
|
# in that situation.
|
|
raise TypeError
|
|
if self._cached_resultset is None:
|
|
self._cached_resultset = [LazyFormData(x) for x in
|
|
self._formdef.data_class().select(clause=self._criterias, order_by=self._order_by)]
|
|
return self._cached_resultset[key]
|
|
|
|
def __iter__(self):
|
|
if self._cached_resultset:
|
|
for lazy_formdata in self._cached_resultset:
|
|
yield lazy_formdata
|
|
data_class = self._formdef.data_class()
|
|
temp_cached_resultset = []
|
|
for formdata in self._formdef.data_class().select_iterator(
|
|
clause=self._criterias, order_by=self._order_by):
|
|
lazy_formdata = LazyFormData(formdata)
|
|
temp_cached_resultset.append(lazy_formdata)
|
|
yield lazy_formdata
|
|
self._cached_resultset = temp_cached_resultset
|
|
|
|
def __nonzero__(self):
|
|
return any(self)
|
|
|
|
|
|
class LazyFormDef(object):
|
|
def __init__(self, formdef):
|
|
self._formdef = formdef
|
|
|
|
@property
|
|
def name(self):
|
|
return self._formdef.name
|
|
|
|
@property
|
|
def slug(self):
|
|
return self._formdef.url_name
|
|
|
|
@property
|
|
def objects(self):
|
|
return LazyFormDefObjectsManager(self._formdef)
|
|
|
|
@property
|
|
def option(self):
|
|
return LazyFormDefOption(self._formdef)
|
|
|
|
|
|
class LazyFormDefOption(object):
|
|
def __init__(self, formdef):
|
|
self._formdef = formdef
|
|
|
|
_options = None
|
|
@property
|
|
def options(self):
|
|
if self._options is not None:
|
|
return self._options
|
|
self._options = {}
|
|
if not self._formdef.workflow.variables_formdef:
|
|
return self._options
|
|
if not self._formdef.workflow_options:
|
|
return self._options
|
|
for field in self._formdef.workflow.variables_formdef.fields:
|
|
if not field.varname:
|
|
continue
|
|
self._options[field.varname] = self._formdef.workflow_options.get(field.varname)
|
|
if field.store_display_value:
|
|
if '%s_display' % field.varname in self._formdef.workflow_options:
|
|
self._options[field.varname + '_raw'] = self._options[field.varname]
|
|
self._options[field.varname] = self._formdef.workflow_options[
|
|
'%s_display' % field.varname]
|
|
if field.store_structured_value:
|
|
if '%s_structured' % field.varname in self._formdef.workflow_options:
|
|
self._options[field.varname + '_structured'] = self._formdef.workflow_options.get(
|
|
'%s_structured' % field.varname)
|
|
return self._options
|
|
|
|
def __getitem__(self, key):
|
|
return self.options[key]
|
|
|
|
|
|
class LazyFormData(LazyFormDef):
|
|
def __init__(self, formdata):
|
|
super(LazyFormData, self).__init__(formdata.formdef)
|
|
self._formdata = formdata
|
|
|
|
@property
|
|
def objects(self):
|
|
return LazyFormDefObjectsManager(self._formdef, formdata=self._formdata)
|
|
|
|
@property
|
|
def formdef(self):
|
|
return LazyFormDef(self._formdata.formdef)
|
|
|
|
@property
|
|
def internal_id(self):
|
|
return self._formdata.id
|
|
|
|
@property
|
|
def receipt_date(self):
|
|
return misc.strftime(misc.date_format(), self._formdata.receipt_time)
|
|
|
|
@property
|
|
def receipt_time(self):
|
|
return misc.strftime('%H:%M', self._formdata.receipt_time)
|
|
|
|
@property
|
|
def number(self):
|
|
return self._formdata.get_display_id()
|
|
|
|
@property
|
|
def number_raw(self):
|
|
return str(self._formdata.id) if self._formdata.id else None
|
|
|
|
@property
|
|
def url(self):
|
|
return self._formdata.get_url()
|
|
|
|
@property
|
|
def url_backoffice(self):
|
|
return self._formdata.get_url(backoffice=True)
|
|
|
|
@property
|
|
def backoffice_url(self):
|
|
return self._formdata.get_url(backoffice=True)
|
|
|
|
@property
|
|
def api_url(self):
|
|
return self._formdata.get_api_url()
|
|
|
|
@property
|
|
def uri(self):
|
|
return '%s/%s/' % (self._formdef.url_name, self._formdata.id)
|
|
|
|
@property
|
|
def criticality_level(self):
|
|
return self._formdata.criticality_level
|
|
|
|
@property
|
|
def criticality_label(self):
|
|
try:
|
|
return self._formdata.get_criticality_level_object().name
|
|
except IndexError:
|
|
return None
|
|
|
|
@property
|
|
def digest(self):
|
|
return self._formdata.digest
|
|
|
|
@property
|
|
def display_name(self):
|
|
return self._formdata.get_display_name()
|
|
|
|
@property
|
|
def receipt_datetime(self):
|
|
return make_datetime(self._formdata.receipt_time) if self._formdata.receipt_time else None
|
|
|
|
@property
|
|
def status(self):
|
|
return self._formdata.get_status_label()
|
|
|
|
@property
|
|
def status_is_endpoint(self):
|
|
return self._formdata.is_at_endpoint_status()
|
|
|
|
@property
|
|
def tracking_code(self):
|
|
formdata = self._formdata
|
|
if not formdata.status and formdata.data:
|
|
if 'future_tracking_code' in formdata.data:
|
|
return formdata.data['future_tracking_code']
|
|
elif 'draft_formdata_id' in formdata.data:
|
|
formdata = formdata.formdef.data_class().get(formdata.data['draft_formdata_id'])
|
|
return formdata.tracking_code
|
|
|
|
@property
|
|
def submission_backoffice(self):
|
|
return self._formdata.backoffice_submission
|
|
|
|
@property
|
|
def submission_channel(self):
|
|
return self._formdata.submission_channel
|
|
|
|
@property
|
|
def submission_channel_label(self):
|
|
return self._formdata.get_submission_channel_label()
|
|
|
|
@property
|
|
def submission_context(self):
|
|
return self._formdata.submission_context
|
|
|
|
@property
|
|
def status_url(self):
|
|
return '%sstatus' % self._formdata.get_url()
|
|
|
|
@property
|
|
def details(self):
|
|
return self._formdef.get_detailed_email_form(self._formdata, self._formdata.get_url())
|
|
|
|
@property
|
|
def user(self):
|
|
user = self._formdata.get_user()
|
|
return LazyUser(user) if user else None
|
|
|
|
@property
|
|
def var(self):
|
|
return LazyFormDataVar(self._formdef.get_all_fields(), self._formdata.data, self._formdata)
|
|
|
|
@property
|
|
def field(self):
|
|
# no lazy dictionary here as it's legacy.
|
|
d = {}
|
|
for field in self._formdef.get_all_fields():
|
|
if not hasattr(field, 'get_view_value'):
|
|
continue
|
|
value = self._formdata.data.get(field.id)
|
|
if value is not None and field.convert_value_to_str:
|
|
value = field.convert_value_to_str(value)
|
|
elif value is None:
|
|
value = ''
|
|
identifier_name = misc.simplify(field.label, space='_')
|
|
d[identifier_name] = value
|
|
|
|
return d
|
|
|
|
@property
|
|
def role(self):
|
|
from wcs.roles import Role
|
|
workflow_roles = {}
|
|
if self._formdef.workflow_roles:
|
|
workflow_roles.update(self._formdef.workflow_roles)
|
|
if self._formdata.workflow_roles:
|
|
workflow_roles.update(self._formdata.workflow_roles)
|
|
|
|
d = {}
|
|
for role_type, role_id in workflow_roles.items():
|
|
prefix = '%s_' % role_type.replace('-', '_').strip('_')
|
|
try:
|
|
d.update(Role.get(role_id).get_substitution_variables(prefix))
|
|
except KeyError:
|
|
pass
|
|
return d
|
|
|
|
@property
|
|
def comment(self):
|
|
if self._formdata.evolution and self._formdata.evolution[-1].comment:
|
|
return self._formdata.evolution[-1].comment
|
|
return ''
|
|
|
|
@property
|
|
def page_no(self):
|
|
return int(self._formdata.page_no)
|
|
|
|
@property
|
|
def attachments(self):
|
|
from wcs.workflows import AttachmentsSubstitutionProxy
|
|
return AttachmentsSubstitutionProxy(self._formdata)
|
|
|
|
@property
|
|
def geoloc(self):
|
|
data = {}
|
|
if self._formdata.geolocations:
|
|
for k, v in self._formdata.geolocations.items():
|
|
data[k] = v
|
|
data[k + '_lat'] = v.get('lat')
|
|
data[k + '_lon'] = v.get('lon')
|
|
return data
|
|
|
|
@property
|
|
def distance(self):
|
|
return getattr(self._formdata, '_distance', None)
|
|
|
|
@property
|
|
def previous_status(self):
|
|
if self._formdata.evolution:
|
|
for evolution in reversed(self._formdata.evolution):
|
|
if evolution.status and evolution.status != self._formdata.status:
|
|
return self._formdata.get_status_label(evolution.status)
|
|
return ''
|
|
|
|
@property
|
|
def status_changed(self):
|
|
first_evolution_in_current_status = None
|
|
for evolution in reversed(self._formdata.evolution or []):
|
|
if evolution.status and evolution.status != self._formdata.status:
|
|
break
|
|
if evolution.status:
|
|
first_evolution_in_current_status = evolution
|
|
|
|
return bool(self.status != self.previous_status and
|
|
self._formdata.evolution and
|
|
self._formdata.evolution[-1].status and
|
|
first_evolution_in_current_status is self._formdata.evolution[-1] and
|
|
not self._formdata.evolution[-1].last_jump_datetime)
|
|
|
|
@property
|
|
def evolution(self):
|
|
return self._formdef.get_detailed_evolution(self._formdata)
|
|
|
|
def export_to_json(self, include_files=True):
|
|
# this gets used to generate an email attachment :/
|
|
return self._formdata.export_to_json(include_files=include_files)
|
|
|
|
def __getitem__(self, key):
|
|
try:
|
|
return getattr(self, key)
|
|
except AttributeError:
|
|
if key.startswith('f'):
|
|
for field in self._formdef.get_all_fields():
|
|
if str(field.id) == str(key[1:]):
|
|
return self._formdata.data.get(field.id)
|
|
raise
|
|
|
|
|
|
class LazyFormDataVar(object):
|
|
def __init__(self, fields, data, formdata=None):
|
|
self._fields = fields
|
|
self._data = data or {}
|
|
self._formdata = formdata
|
|
|
|
_varnames = None
|
|
@property
|
|
def varnames(self):
|
|
if self._varnames is not None:
|
|
return self._varnames
|
|
self._varnames = {}
|
|
for field in self._fields:
|
|
if not field.varname:
|
|
continue
|
|
self._varnames[field.varname] = field
|
|
return self._varnames
|
|
|
|
def __getitem__(self, key):
|
|
try:
|
|
field = self.varnames[key]
|
|
except KeyError:
|
|
# key was unknown but for some values we may still have to provide
|
|
# multiple keys (for example file fields will expect to have both
|
|
# form_var_foo and form_var_foo_raw set to None) and user
|
|
# conditions may use the "is" operator that cannot be overridden
|
|
# (this applies to None as well as boolean values).
|
|
#
|
|
# Therefore we catch unknown keys with known suffixes ("foo_raw")
|
|
# and remove the suffix to get the actual field. If the data is
|
|
# None or a boolean type, we return it as is.
|
|
if not (key.endswith('_raw') or key.endswith('_url')):
|
|
raise
|
|
maybe_varname = key.rsplit('_', 1)[0]
|
|
field = self.varnames[maybe_varname]
|
|
if self._data.get(field.id) in (None, True, False):
|
|
# valid suffix and data of the correct type
|
|
return self._data.get(field.id)
|
|
raise KeyError(key)
|
|
|
|
if self._data.get(field.id) is None:
|
|
return None
|
|
|
|
if str(field.id) not in self._data:
|
|
raise KeyError(key)
|
|
|
|
if field.key == 'date':
|
|
return LazyFieldVarDate(self._data, field, self._formdata)
|
|
if field.key == 'map':
|
|
return LazyFieldVarMap(self._data, field, self._formdata)
|
|
if field.key == 'password':
|
|
return LazyFieldVarPassword(self._data, field, self._formdata)
|
|
|
|
return LazyFieldVar(self._data, field, self._formdata)
|
|
|
|
def __getattr__(self, attr):
|
|
try:
|
|
return self.__getitem__(attr)
|
|
except KeyError:
|
|
raise AttributeError(attr)
|
|
|
|
|
|
class LazyFieldVar(object):
|
|
def __init__(self, data, field, formdata=None):
|
|
self._data = data
|
|
self._field = field
|
|
self._formdata = formdata
|
|
|
|
@property
|
|
def raw(self):
|
|
if self._field.store_display_value or self._field.key in ('file', 'date'):
|
|
return self._data.get(self._field.id)
|
|
raise KeyError('raw')
|
|
|
|
@property
|
|
def url(self):
|
|
if self._field.key != 'file' or not self._formdata:
|
|
raise KeyError('url')
|
|
return '%sdownload?f=%s' % (self._formdata.get_url(), self._field.id)
|
|
|
|
def get_value(self):
|
|
if self._field.store_display_value:
|
|
return self._data.get('%s_display' % self._field.id)
|
|
value = self._data.get(self._field.id)
|
|
if self._field.convert_value_to_str:
|
|
return self._field.convert_value_to_str(value)
|
|
if isinstance(value, str):
|
|
return force_text(value, get_publisher().site_charset)
|
|
return value
|
|
|
|
def __str__(self):
|
|
value = self.get_value()
|
|
if not isinstance(value, six.string_types):
|
|
value = str(value)
|
|
return force_str(value)
|
|
|
|
def __nonzero__(self):
|
|
if self._field.key == 'bool':
|
|
return bool(self._data.get(self._field.id))
|
|
return bool(self.get_value())
|
|
|
|
__bool__ = __nonzero__
|
|
|
|
def __contains__(self, value):
|
|
if self._field.key == 'items':
|
|
return misc.site_encode(value) in self._data.get(self._field.id)
|
|
return value in self.get_value()
|
|
|
|
def __unicode__(self):
|
|
return force_text(str(self), get_publisher().site_charset)
|
|
|
|
def __eq__(self, other):
|
|
return force_text(self) == force_text(other)
|
|
|
|
def __ne__(self, other):
|
|
return force_text(self) != force_text(other)
|
|
|
|
def __getitem__(self, key):
|
|
if isinstance(key, (int, slice)):
|
|
return self.get_value()[key]
|
|
try:
|
|
return getattr(self, key)
|
|
except AttributeError:
|
|
pass
|
|
structured_value = self._field.get_structured_value(self._data)
|
|
if not structured_value:
|
|
raise KeyError(key)
|
|
if isinstance(structured_value, dict):
|
|
return structured_value[key]
|
|
if isinstance(structured_value, list):
|
|
for i, struct_value in enumerate(structured_value):
|
|
if str(key) == str(i):
|
|
return struct_value
|
|
raise KeyError(key)
|
|
|
|
def __iter__(self):
|
|
return iter(self.get_value())
|
|
|
|
def __add__(self, other):
|
|
return self.get_value().__add__(other)
|
|
|
|
def __radd__(self, other):
|
|
return other + self.get_value()
|
|
|
|
def __mul__(self, other):
|
|
return self.get_value().__mul__(other)
|
|
|
|
def startswith(self, other):
|
|
return self.get_value().startswith(other)
|
|
|
|
def __getstate__(self):
|
|
raise AssertionError('lazy cannot be pickled')
|
|
|
|
|
|
class DateOperatorsMixin(object):
|
|
def __eq__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) == parse_datetime(other)
|
|
|
|
def __ne__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) != parse_datetime(other)
|
|
|
|
def __gt__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) > parse_datetime(other)
|
|
|
|
def __lt__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) < parse_datetime(other)
|
|
|
|
def __ge__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) >= parse_datetime(other)
|
|
|
|
def __le__(self, other):
|
|
if hasattr(other, 'timetuple'):
|
|
other = other.timetuple()
|
|
elif hasattr(other, 'get_value'):
|
|
other = other.get_value()
|
|
return parse_datetime(self.timetuple()) <= parse_datetime(other)
|
|
|
|
|
|
class LazyDateObject(DateOperatorsMixin, SimpleLazyObject):
|
|
pass
|
|
|
|
|
|
def lazy_date(value):
|
|
return LazyDateObject(lambda: value)
|
|
|
|
|
|
class LazyFieldVarDate(DateOperatorsMixin, LazyFieldVar):
|
|
def get_raw(self):
|
|
return self._data.get(self._field.id)
|
|
|
|
def timetuple(self):
|
|
return self.get_raw()
|
|
|
|
# for backward compatibility with sites using time.struct_time
|
|
# methods we still have to provide time.struct_time properties.
|
|
@property
|
|
def tm_year(self):
|
|
return self.get_raw().tm_year
|
|
|
|
@property
|
|
def tm_mon(self):
|
|
return self.get_raw().tm_mon
|
|
|
|
@property
|
|
def tm_mday(self):
|
|
return self.get_raw().tm_mday
|
|
|
|
@property
|
|
def tm_hour(self):
|
|
return self.get_raw().tm_hour
|
|
|
|
@property
|
|
def tm_min(self):
|
|
return self.get_raw().tm_min
|
|
|
|
@property
|
|
def tm_sec(self):
|
|
return self.get_raw().tm_sec
|
|
|
|
@property
|
|
def tm_wday(self):
|
|
return self.get_raw().tm_wday
|
|
|
|
@property
|
|
def tm_yday(self):
|
|
return self.get_raw().tm_yday
|
|
|
|
year = tm_year
|
|
month = tm_mon
|
|
day = tm_mday
|
|
|
|
|
|
class LazyFieldVarMap(LazyFieldVar):
|
|
def split(self, *args, **kwargs):
|
|
# Compatibility with usage of map variable as a string. It is
|
|
# recommended to use lat/lon properties instead.
|
|
return self._data.get(self._field.id).split(*args, **kwargs)
|
|
|
|
|
|
class LazyFieldVarPassword(LazyFieldVar):
|
|
def __getitem__(self, key):
|
|
# get subpart (cleartext, md5, sha1) if it exists
|
|
field_value = self._data.get(self._field.id)
|
|
if key in field_value:
|
|
return field_value[key]
|
|
return super(LazyFieldVarPassword, self)._getitem__(key)
|
|
|
|
|
|
class LazyUser(object):
|
|
def __init__(self, user):
|
|
self._user = user
|
|
|
|
@property
|
|
def display_name(self):
|
|
return self._user.display_name
|
|
|
|
@property
|
|
def email(self):
|
|
return self._user.email
|
|
|
|
@property
|
|
def var(self):
|
|
return LazyFormDataVar(self._user.get_formdef().fields, self._user.form_data)
|
|
|
|
@property
|
|
def admin_access(self):
|
|
return self._user.can_go_in_admin()
|
|
|
|
@property
|
|
def backoffice_access(self):
|
|
return self._user.can_go_in_backoffice()
|
|
|
|
@property
|
|
def name_identifier(self):
|
|
d = {}
|
|
for i, name_identifier in enumerate(self._user.name_identifiers):
|
|
d[str(i)] = name_identifier
|
|
return d
|
|
|
|
def __getitem__(self, key):
|
|
return getattr(self, key)
|
|
|
|
def __getattr__(self, attr):
|
|
try:
|
|
return super(LazyUser, self).__getattr__(attr)
|
|
except AttributeError:
|
|
return getattr(self._user, attr)
|
|
|
|
|
|
class LazyRequest(object):
|
|
def __init__(self, request):
|
|
self._request = request
|
|
|
|
@property
|
|
def quixote_request(self): # compatibility
|
|
return self._request
|
|
|
|
@property
|
|
def GET(self):
|
|
return self._request.django_request.GET
|
|
|
|
@property
|
|
def META(self):
|
|
return self._request.django_request.META
|
|
|
|
@property
|
|
def is_in_backoffice(self):
|
|
return self._request.is_in_backoffice()
|
|
|
|
@property
|
|
def method(self):
|
|
return self._request.method
|
|
|
|
@property
|
|
def user(self):
|
|
return self._request.user
|
|
|
|
@property
|
|
def view_name(self):
|
|
return getattr(self._request, 'view_name', None)
|