def _build_permission_table(self, access_rights): table = {} all_permissions = Permission.all_permissions() for p in all_permissions: table[p] = {} for a in access_rights: columns, groupdefs = xtuple(a[0]), a[1:] for p in all_permissions: table_p = table[p] for c in columns: if c not in table_p: table_p[c] = () if True not in table_p: table_p[True] = () for gd in groupdefs: groups, permissions = xtuple(gd[0]), gd[1:] if Permission.ALL in permissions: permissions = all_permissions for p in permissions: table_p = table[p] for c in columns: if None in groups: table_p[c] = (None,) table_p[True] = (None,) elif c in table_p: table_p[c] = table_p[c] + groups table_p[True] = table_p[True] + groups else: table_p[c] = groups table_p[True] = table_p.get(True, ()) + groups return table
def _build_permission_table(self, access_rights): table = {} all_permissions = Permission.all_permissions() for p in all_permissions: table[p] = {} for a in access_rights: columns, groupdefs = xtuple(a[0]), a[1:] for p in all_permissions: table_p = table[p] for c in columns: if c not in table_p: table_p[c] = () if True not in table_p: table_p[True] = () for gd in groupdefs: groups, permissions = xtuple(gd[0]), gd[1:] if Permission.ALL in permissions: permissions = all_permissions for p in permissions: table_p = table[p] for c in columns: if None in groups: table_p[c] = (None, ) table_p[True] = (None, ) elif c in table_p: table_p[c] = table_p[c] + groups table_p[True] = table_p[True] + groups else: table_p[c] = groups table_p[True] = table_p.get(True, ()) + groups return table
def permitted(self, permission, groups, column=None): """Return true iff any of 'groups' has got 'permission'. Arguments: permission -- required permission, one of the 'Permission' class constants except of 'Permission.ALL' groups -- sequence of group names (as strings); permission is valid if at least one of the listed groups has got the permission column -- name of the column (as a string) to test the permission against, or 'None' in which case implicit rights are tested, or 'True' to check that any of the columns has the permission """ assert isinstance(column, basestring) or column in ( None, True, False, ), column key = (permission, xtuple(groups), column) try: result = self._query_cache[key] except KeyError: result = self._query_cache[key] = self._permitted( permission, groups, column) return result
def PopupCB(spec, name, column, returned_column, selected=None, condition=None, sort=(), **attrs): """Generuje popup list na základě hodnot z číselníku. Argumenty: spec -- název specifikace name -- jméno pro HTML widget label -- popis pro HTML widget column -- název sloupce číselníku, jehož hodnoty se budou zobrazovat returned_column -- název sloupce číselníku, jehož hodnoty se budou vracet selected -- None nebo seznam hodnot, které budou mít v HTML hodnotu selected sort -- řazení odpovídající argumentu volání pytis.data.select() condition -- podmínka odpovídající argumentu volání pytis.data.select() Vrací instanci HyperText.Select nebo None v případě neúspěchu. """ dbrows = dbselect(spec, condition=condition, sort=sort) if len(dbrows) == 0: return None options = [(r[column].value(), r[returned_column].value()) for r in dbrows] if selected: if isinstance(selected, basestring): selected = xtuple(selected) if len(selected) > 1: attrs['multiple'] = 1 else: selected = [] return Select(options, selected=selected, name=name, **attrs)
def _pdf(self): start_time = pytis.data.DateTime.now() T = pytis.data.DBTransactionDefault transaction = T(connection_data=config.dbconnection, isolation=T.REPEATABLE_READ) template_nodes = [] if self._form is not None and self._row_template is not None: i = 1 row_template = self._row_template for row in self._form.presented_rows(): row_lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, current_row=row, parameters=self._parameters) id_ = 'pytissubdoc%d' % (i,) row_template_lcg = row_template.lcg() parameters = self._template_parameters(row_template) document = lcg.ContentNode(id=id_, title=' ', # let's avoid printing the id content=row_template_lcg, globals=row_lcg_globals, **parameters) template_nodes.append(document) i += 1 lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, parameters=self._parameters) lcg_globals['app'] = self._application_variables def margin(key): size = self._page_layout.get(key) if size is None: size = UMm(10) return size presentation = lcg.Presentation( font_name='DejaVu', font_family=lcg.FontFamily.FIXED_WIDTH, top_margin=margin(PAGE_TOP_MARGIN), bottom_margin=margin(PAGE_BOTTOM_MARGIN), left_margin=margin(PAGE_LEFT_MARGIN), right_margin=margin(PAGE_RIGHT_MARGIN), page_width=self._page_layout.get(PAGE_WIDTH), page_height=self._page_layout.get(PAGE_HEIGHT), landscape=self._page_layout.get(PAGE_LANDSCAPE_MODE), ) start_time_export = pytis.data.DateTime.now() exporter = lcg.pdf.PDFExporter(translations=self._translations) body = xtuple(self._body) if self._body else () body_nodes = [doc.lcg_document(globals=lcg_globals) for doc in body] root_node = lcg.ContentNode(id='__dummy', content=lcg.Content(), children=body_nodes + template_nodes, **self._body_parameters) context = exporter.context(root_node, self._language, presentation=lcg.PresentationSet(self._style or [])) try: pdf = exporter.export(context, global_presentation=presentation) except lcg.SubstitutionIterator.IteratorError, e: message = _("Invalid use of iterator.\n" "Maybe you refer to an non-existent or inaccessible object in the table?") message += "\n" + unicode(e) pytis.form.run_dialog(pytis.form.Error, message) return ''
def _resolve(self, template_id, element, default=''): result = default for resolver in xtuple(self._output_resolvers): try: result = resolver.get(template_id, element, parameters=self._parameters) except ResolverError: continue break else: resolver = None return result, resolver
def _resolve(self, template_id, element, default=''): for resolver in xtuple(self._output_resolvers): try: return resolver.get(template_id, element, parameters=self._parameters, **self._spec_kwargs) except ResolverError: continue break return default
def is_in_groups(groups): if isinstance(groups, basestring): groups = xtuple(groups) def conn_spec(): return pytis.config.dbconnection dbgroups = pd.default_access_groups(conn_spec) if set(groups) & set(dbgroups) == set([]): return False else: return True
def is_in_groups(access_groups): """Return true iff the current user is a member of any of the groups. Arguments: 'access_groups' -- sequence of group names (as strings) to test the user against, or 'None'; if it is 'None' then true is returned unconditionally. """ from pytis.data import default_access_groups groups = default_access_groups(pytis.config.dbconnection) if ((groups is None or access_groups is None or any(g in groups for g in xtuple(access_groups)))): return True else: return False
def is_in_groups(access_groups): """Return true iff the current user is a member of any of the groups. Arguments: 'access_groups' -- sequence of group names (as strings) to test the user against, or 'None'; if it is 'None' then true is returned unconditionally. """ import config from pytis.data import default_access_groups groups = default_access_groups(config.dbconnection) if ((groups is None or access_groups is None or some(lambda g: g in groups, xtuple(access_groups)))): return True else: return False
def test_hidden(self): row, fields = self._fields(( pp.Field('numeric', type=pd.Integer()), pp.Field('string', type=pd.String()), pp.Field('multiline', type=pd.String(), height=4), pp.Field('date', type=pd.Date()), pp.Field('datetime', type=pd.DateTime()), pp.Field('boolean', type=pd.Boolean()), pp.Field('checklist', type=pd.Array(inner_type=pd.Integer()), enumerator=pd.FixedEnumerator(range(10)), selection_type=pp.SelectionType.CHECKLIST), pp.Field('choice', type=pd.Integer(), enumerator=pd.FixedEnumerator(range(10)), selection_type=pp.SelectionType.CHOICE), pp.Field('radio', type=pd.Integer(), enumerator=pd.FixedEnumerator(range(10)), selection_type=pp.SelectionType.RADIO), )) context = self._export_context('cs') for fid, value, exported in ( ('numeric', 5, '5'), ('string', 'x', 'x'), ('multiline', 'xxx\nxxx', 'xxx\nxxx'), ('date', datetime.date(2016, 8, 30), '30.08.2016'), ('datetime', datetime.datetime(2016, 8, 30, 12, 40, tzinfo=context.timezone()), '30.08.2016 12:40:00'), ('boolean', True, 'T'), ('boolean', False, 'F'), ('checklist', (pd.ival(1), pd.ival(4)), ('1', '4')), ('choice', 5, '5'), ('radio', 5, '5'), ): field = pu.find(fid, fields, key=lambda f: f.id) row[fid] = pd.Value(row.type(fid), value) self.assertEqual(context.localize(field.hidden(context)), ''.join('<input type="hidden" name="%s" value=%s/>' % (fid, saxutils.quoteattr(v)) for v in pu.xtuple(exported))) error = field.validate(self.Request(params={fid: exported}), context.locale_data()) self.assertIs(error, None, "%s: %s" % (error and error.message(), exported)) self.assertEqual(row[fid].value(), value)
def permitted(self, permission, groups, column=None): """Return true iff any of 'groups' has got 'permission'. Arguments: permission -- required permission, one of the 'Permission' class constants except of 'Permission.ALL' groups -- sequence of group names (as strings); permission is valid if at least one of the listed groups has got the permission column -- name of the column (as a string) to test the permission against, or 'None' in which case implicit rights are tested, or 'True' to check that any of the columns has the permission """ assert isinstance(column, basestring) or column in (None, True, False,), column key = (permission, xtuple(groups), column) try: result = self._query_cache[key] except KeyError: result = self._query_cache[key] = self._permitted(permission, groups, column) return result
def __init__(self, resolver, output_resolvers, template_id, form=None, form_bindings=None, parameters={}, language=None, translations=(), spec_kwargs=None): """Arguments: resolver -- form specification resolver output_resolvers -- resolver of template names and data objects; may also be a non-empty sequence of resolvers, in such a case the first resolver not throwing 'ResolverError' when accessing the template will be used template_id -- id of the output template, string form -- current form; 'Form' instance or 'None' form_bindings -- bindings of the current form (if it is the main form of a dual form) as a sequence of 'Binding' instances; or 'None' parameters -- dictionary of form parameters language -- language code to pass to the exporter context translations -- translations to pass to PDFExporter spec_kwargs -- dictionary of keyword arguments to pass to the print specification constructor """ self._resolver = resolver self._output_resolvers = xtuple(output_resolvers) self._template_id = template_id self._parameters = HashableDict(parameters) self._language = language self._translations = translations self._spec_kwargs = spec_kwargs or {} if not self._resolve(template_id, 'init'): raise AbortOutput() self._doc_header, __ = self._resolve(template_id, 'doc_header') self._doc_footer, __ = self._resolve(template_id, 'doc_footer') self._page_header, __ = self._resolve(template_id, 'page_header', default=None) self._first_page_header, __ = self._resolve(template_id, 'first_page_header', default=self._page_header) page_number = pytis.output.Center('Strana ', pytis.output.PageNumber()) self._page_footer, __ = self._resolve(template_id, 'page_footer', default=page_number) self._page_background, __ = self._resolve(template_id, 'background', default=None) self._page_layout, __ = self._resolve(template_id, 'page_layout', default={}) style, __ = self._resolve(template_id, 'style', default=None) if style: style_parser = lcg.StyleFile() style_parser.read(StringIO.StringIO(style)) # doesn't work with cStringIO self._style = style_parser.presentations() else: self._style = None body, __ = self._resolve(template_id, 'body') if body is None: # In order to apply style parameters correctly temp_body = pytis.output.StructuredText('') else: temp_body = body parameters = copy.copy(self._template_parameters(temp_body)) for p, a in (('page_header', self._page_header,), ('page_footer', self._page_footer,), ('first_page_header', self._first_page_header,), ('page_background', self._page_background,), ): if p not in parameters: if a is None: value = None elif isinstance(a, list): # presentation style value = a elif isinstance(a, lcg.Content): value = a else: value = a.lcg() parameters[p] = value self._body_parameters = parameters if ((not isinstance(body, pytis.output.Document) and body and not (isinstance(body, (tuple, list,)) and body and isinstance(body[0], pytis.output.Document)))): body.lcg() # to generate parameters body = pytis.output.Document(body, **parameters) else: # It's unclear how to interpret this situation. In the Lout # formatter the parameters were apparently taken from # specifications and applied globally, but they could also be given # in the Document's (and ignored there?), with the exception of # background. So let's them add to Document's if they are not # present there yet. if isinstance(body, pytis.output.Document): body_list = [body] else: body_list = body if isinstance(body_list, (tuple, list,)): for document in body_list: for k, v in parameters.items(): name = 'arg_' + k if getattr(document, name) is None: setattr(document, name, v) self._body = body self._form = form self._form_bindings = form_bindings self._row_template, __ = self._resolve(template_id, 'row', default=None) self._application_variables, __ = self._resolve(template_id, 'variables', default={}) if form is None: self._codebooks = None else: self._codebooks = self._retrieve_codebooks(form.view_spec(), resolver=self._resolver)
def __init__(self, resolver, output_resolvers, template_id, form=None, form_bindings=None, parameters={}, language=None, translations=()): """Arguments: resolver -- form specification resolver output_resolvers -- resolver of template names and data objects; may also be a non-empty sequence of resolvers, in such a case the first resolver not throwing 'ResolverError' when accessing the template will be used template_id -- id of the output template, string form -- current form; 'Form' instance or 'None' form_bindings -- bindings of the current form (if it is the main form of a dual form) as a sequence of 'Binding' instances; or 'None' parameters -- dictionary of form parameters language -- language code to pass to the exporter context translations -- translations to pass to PDFExporter """ self._resolver = resolver self._output_resolvers = xtuple(output_resolvers) self._template_id = template_id self._parameters = HashableDict(parameters) self._language = language self._translations = translations if not self._resolve(template_id, 'init'): raise AbortOutput() self._doc_header, __ = self._resolve(template_id, 'doc_header') self._doc_footer, __ = self._resolve(template_id, 'doc_footer') self._page_header, __ = self._resolve(template_id, 'page_header', default=None) self._first_page_header, __ = self._resolve(template_id, 'first_page_header', default=self._page_header) page_number = pytis.output.Center('Strana ', pytis.output.PageNumber()) self._page_footer, __ = self._resolve(template_id, 'page_footer', default=page_number) self._page_background, __ = self._resolve(template_id, 'background', default=None) self._page_layout, __ = self._resolve(template_id, 'page_layout', default={}) style, __ = self._resolve(template_id, 'style', default=None) if style: style_parser = lcg.StyleFile() style_parser.read(StringIO.StringIO(style)) # doesn't work with cStringIO self._style = style_parser.presentations() else: self._style = None body, __ = self._resolve(template_id, 'body') if body is None: # In order to apply style parameters correctly temp_body = pytis.output.StructuredText('') else: temp_body = body parameters = copy.copy(self._template_parameters(temp_body)) for p, a in (('page_header', self._page_header,), ('page_footer', self._page_footer,), ('first_page_header', self._first_page_header,), ('page_background', self._page_background,), ): if p not in parameters: if a is None: value = None elif isinstance(a, list): # presentation style value = a elif isinstance(a, lcg.Content): value = a else: value = a.lcg() parameters[p] = value self._body_parameters = parameters if ((not isinstance(body, pytis.output.Document) and body and not (isinstance(body, (tuple, list,)) and body and isinstance(body[0], pytis.output.Document)))): body.lcg() # to generate parameters body = pytis.output.Document(body, **parameters) else: # It's unclear how to interpret this situation. In the Lout # formatter the parameters were apparently taken from # specifications and applied globally, but they could also be given # in the Document's (and ignored there?), with the exception of # background. So let's them add to Document's if they are not # present there yet. if isinstance(body, pytis.output.Document): body_list = [body] else: body_list = body if isinstance(body_list, (tuple, list,)): for document in body_list: for k, v in parameters.items(): name = 'arg_' + k if getattr(document, name) is None: setattr(document, name, v) self._body = body self._form = form self._form_bindings = form_bindings self._row_template, __ = self._resolve(template_id, 'row', default=None) self._application_variables, __ = self._resolve(template_id, 'variables', default={}) if form is None: self._codebooks = None else: self._codebooks = self._retrieve_codebooks(form.view_spec(), resolver=self._resolver)
def _pdf(self): start_time = pytis.data.DateTime.now() T = pytis.data.DBTransactionDefault transaction = T(connection_data=pytis.config.dbconnection, isolation=T.REPEATABLE_READ) template_nodes = [] if self._form is not None and self._row_template is not None: i = 1 row_template = self._row_template for row in self._form.presented_rows(): row_lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, current_row=row, parameters=self._parameters) id_ = 'pytissubdoc%d' % (i, ) row_template_lcg = row_template.lcg() parameters = self._template_parameters(row_template) document = lcg.ContentNode( id=id_, title=' ', # let's avoid printing the id content=row_template_lcg, globals=row_lcg_globals, **parameters) template_nodes.append(document) i += 1 lcg_globals = self._LCGGlobals(self._resolver, self._form, self._form_bindings, self._codebooks, transaction, parameters=self._parameters) lcg_globals['app'] = self._application_variables def margin(key): size = self._page_layout.get(key) if size is None: size = UMm(10) return size presentation = lcg.Presentation( font_name='DejaVu', font_family=lcg.FontFamily.FIXED_WIDTH, top_margin=margin(PAGE_TOP_MARGIN), bottom_margin=margin(PAGE_BOTTOM_MARGIN), left_margin=margin(PAGE_LEFT_MARGIN), right_margin=margin(PAGE_RIGHT_MARGIN), page_width=self._page_layout.get(PAGE_WIDTH), page_height=self._page_layout.get(PAGE_HEIGHT), landscape=self._page_layout.get(PAGE_LANDSCAPE_MODE), ) start_time_export = pytis.data.DateTime.now() exporter = lcg.pdf.PDFExporter(translations=self._translations) body = xtuple(self._body) if self._body else () body_nodes = [doc.lcg_document(globals=lcg_globals) for doc in body] root_node = lcg.ContentNode(id='__dummy', content=lcg.Content(), children=body_nodes + template_nodes, **self._body_parameters) context = exporter.context(root_node, self._language, presentation=lcg.PresentationSet(self._style or [])) try: pdf = exporter.export(context, global_presentation=presentation) except lcg.SubstitutionIterator.IteratorError as e: message = _( "Invalid use of iterator.\n" "Maybe you refer to an non-existent or inaccessible object in the table?" ) message += "\n" + unistr(e) pytis.form.run_dialog(pytis.form.Error, message) return '' show_time = pytis.data.DateTime.now() log(EVENT, ('Output formatting took %.3fs (PDF export %.3fs)' % ( pytis.data.DateTime.diff_seconds(start_time, show_time), pytis.data.DateTime.diff_seconds(start_time_export, show_time), ))) try: transaction.commit() except pytis.data.DBSystemException: pass return pdf