def argument_provider(self, query_fields, **kwargs): if query_fields: date_from = query_fields['date_from'] date_to = query_fields['date_to'] username_ = query_fields['username_'] tablename_ = query_fields['tablename_'] key_value_ = query_fields['key_value_'] detail_ = query_fields['detail_'] search_path_ = query_fields['search_path_'] else: date_from = pd.dval(None) date_to = pd.dval(None) username_ = pd.sval(None) tablename_ = pd.sval(None) key_value_ = pd.sval(None) detail_ = pd.sval(None) search_path_ = pd.sval(None) return { 'date_from': date_from, 'date_to': date_to, 'username_': username_, 'tablename_': tablename_, 'key_value_': key_value_, 'detail_': detail_, 'search_path_': search_path_ }
def argument_provider(self, query_fields, **kwargs): if query_fields: date_from = query_fields['date_from'] date_to = query_fields['date_to'] username_ = query_fields['username_'] tablename_ = query_fields['tablename_'] key_value_ = query_fields['key_value_'] detail_ = query_fields['detail_'] search_path_ = query_fields['search_path_'] else: date_from = pd.dval(None) date_to = pd.dval(None) username_ = pd.sval(None) tablename_ = pd.sval(None) key_value_ = pd.sval(None) detail_ = pd.sval(None) search_path_ = pd.sval(None) return { 'date_from': date_from, 'date_to': date_to, 'username_': username_, 'tablename_': tablename_, 'key_value_': key_value_, 'detail_': detail_, 'search_path_': search_path_}
def show_changes_in_row(key_value, tablename=None): CHANGE_LOG_SPEC = 'logging.ChangesLog' arguments = {"date_from": pd.dval(datetime.date(year=2000, month=1, day=1)), "date_to": pd.dval(datetime.date(year=2100, month=1, day=1)), "key_value_": pd.sval(key_value.export()), "search_path_": pd.sval(config.dbschemas)} if tablename is not None: arguments["tablename_"] = pd.sval(tablename) return run_form(BrowseForm, CHANGE_LOG_SPEC, arguments=arguments)
def show_changes_in_row(key_value, tablename=None): CHANGE_LOG_SPEC = 'logging.ChangesLog' arguments = { "date_from": pd.dval(datetime.date(year=2000, month=1, day=1)), "date_to": pd.dval(datetime.date(year=2100, month=1, day=1)), "key_value_": pd.sval(key_value.export()), "search_path_": pd.sval(config.dbschemas) } if tablename is not None: arguments["tablename_"] = pd.sval(tablename) return run_form(BrowseForm, CHANGE_LOG_SPEC, arguments=arguments)
def test_validation_cache(self): # This test reproduces a previously existing bug in validation result caching. enumerator = self._enumerator(('id', 'title'), data=(('1', 'First'), ('2', 'Second'))) row = self._row((pp.Field('a', type=pd.String(not_null=True, enumerator=enumerator)), )) assert not row.validate('a', '3') is None data = enumerator._data # There is currently no need to make this public elsewhere. data.insert(pd.Row( (('id', pd.sval('3')), ('title', pd.sval('Third'))))) assert row.validate('a', '3') == None
def _authorize(self, req): uri = req.server_uri(current=True) + '/' + '/'.join(req.path[:2]) username = req.header('X-Pytis-Attachment-Storage-Username') key = req.header('X-Pytis-Attachment-Storage-Key') if username and key: data = self._data data.select(condition=pd.AND(pd.EQ('uri', pd.sval(uri)), pd.EQ('username', pd.sval(username)))) row = data.fetchone() data.close() if row and row['key'].value() == key: req.set_param('authorized_readonly', row['readonly'].value()) return raise wiking.AuthorizationError()
def test_completer(self): completer = self._enumerator( ('x', ), data=(('Apple', ), ('Bananas', ), ('Basil', ), ('Bacardi', ), ('Cinamon', )), ) fields = ( pp.Field('a', type=pd.Integer(not_null=True)), pp.Field('x0', type=pd.String(enumerator=pd.FixedEnumerator(('a', 'b', 'c')))), pp.Field('x1', type=pd.String(), completer=('yes', 'no', 'maybe')), pp.Field('x2', type=pd.String(), completer=completer, runtime_filter=pp.computer(lambda r, a: pd.NE( 'x', pd.sval('Bacardi')) if a == 1 else None)), ) row = self._row(fields, new=True) assert not row.has_completer('a') assert row.has_completer('x0') assert row.has_completer('x1', static=True) assert row.has_completer('x2') assert not row.has_completer('x2', static=True) assert row.completions('a') == [] assert row.completions('x0') == ['a', 'b', 'c'] assert row.completions('x1') == ['maybe', 'no', 'yes'] assert row.completions('x1', prefix='y') == ['yes'] assert row.completions('x2') == ('Apple', 'Bananas', 'Basil', 'Bacardi', 'Cinamon') assert row.completions('x2', prefix='ba') == ('Bananas', 'Basil', 'Bacardi') row['a'] = 1 assert row.completions('x2', prefix='ba') == ('Bananas', 'Basil')
def run(): if '--help' in sys.argv: usage() try: pytis.config.add_command_line_options(sys.argv) if len(sys.argv) > 1: usage() except getopt.GetoptError as e: usage(e.msg) wiking.cfg.user_config_file = pytis.config.config_file wiking.cms.cfg.user_config_file = pytis.config.config_file pytis.config.dblisten = False pytis.config.log_exclude = [pytis.util.ACTION, pytis.util.EVENT, pytis.util.DEBUG, pytis.util.OPERATIONAL] while True: try: data = pd.dbtable('users', ('uid', 'login', 'password'), pytis.config.dbconnection) except pd.DBLoginException as e: if pytis.config.dbconnection.password() is None: import getpass login = pytis.config.dbuser password = getpass.getpass("Enter database password for %s: " % login) pytis.config.dbconnection.update_login_data(user=login, password=password) else: break storage = wiking.Pbkdf2PasswordStorage() transaction = pd.transaction() data.select(transaction=transaction) n = 0 plain = 0 try: while True: row = data.fetchone() if row is None: break orig_prefix, orig_password = row['password'].value().split(':', 1) if orig_prefix == 'md5u': prefix = 'pbkdf2/md5' elif orig_prefix == 'plain': prefix = 'pbkdf2' plain += 1 else: continue password = prefix + ':' + storage.stored_password(orig_password) data.update(row['uid'], pd.Row([('password', pd.sval(password))]), transaction=transaction) n += 1 except Exception: try: transaction.rollback() except Exception: pass sys.stderr.write("Transaction rolled back.\n") raise else: print("Total %d passwords updated (%d from plain text, %d from md5)." % \ (n, plain, n - plain)) transaction.commit() transaction.close()
def test_binary_computer(self): a = '\x04\x00\x00\x05\x00\x19\x00' b = '\x00\x05\x04\xa4\xbb\x10\x00' row = self._row(( pp.Field('x', type=pd.String()), pp.Field( 'data', type=pd.Binary(not_null=True), computer=pp.computer( lambda r, x: x == 'a' and a or x == 'b' and b or None)), )) assert row['data'].value() is None row['x'] = pd.sval('a') assert row['data'].value() == a assert isinstance(row['data'].value(), pd.Binary.Data) row['x'] = pd.sval('b') assert row['data'].value() == b
def run(): if "--help" in sys.argv: usage() try: config.add_command_line_options(sys.argv) if len(sys.argv) > 1: usage() except getopt.GetoptError as e: usage(e.msg) wiking.cfg.user_config_file = config.config_file wiking.cms.cfg.user_config_file = config.config_file config.dblisten = False config.log_exclude = [pytis.util.ACTION, pytis.util.EVENT, pytis.util.DEBUG, pytis.util.OPERATIONAL] while True: try: data = pd.dbtable("users", ("uid", "login", "password"), config.dbconnection) except pd.DBLoginException as e: if config.dbconnection.password() is None: import getpass login = config.dbuser password = getpass.getpass("Enter database password for %s: " % login) config.dbconnection.update_login_data(user=login, password=password) else: break storage = wiking.Pbkdf2PasswordStorage() transaction = pd.DBTransactionDefault(config.dbconnection) data.select(transaction=transaction) n = 0 plain = 0 try: while True: row = data.fetchone() if row is None: break orig_prefix, orig_password = row["password"].value().split(":", 1) if orig_prefix == "md5u": prefix = "pbkdf2/md5" elif orig_prefix == "plain": prefix = "pbkdf2" plain += 1 else: continue password = prefix + ":" + storage.stored_password(orig_password) data.update(row["uid"], pd.Row([("password", pd.sval(password))]), transaction=transaction) n += 1 except: try: transaction.rollback() except: pass sys.stderr.write("Transaction rolled back.\n") raise else: print "Total %d passwords updated (%d from plain text, %d from md5)." % (n, plain, n - plain) transaction.commit() transaction.close()
def _update_spec_help(self, spec_name): if self._done.get(spec_name): return self._done[spec_name] = True resolver = pytis.util.resolver() try: view_spec = resolver.get(spec_name, 'view_spec') except pytis.util.ResolverError as e: print e return description = view_spec.description() help_text = (view_spec.help() or '').strip() or None self._update(self._spec_help_data, dict(spec_name=spec_name), description=description, help=help_text) data = self._spec_help_items_data for kind, items in (('field', view_spec.fields()), ('profile', view_spec.profiles().unnest()), ('binding', view_spec.bindings()), ('action', view_spec.actions(unnest=True))): for item in items: self._update(data, dict(spec_name=spec_name, kind=kind, identifier=item.id()), content=item.descr()) # Items which were modified (content changed by hand) are kept with # the 'removed' flag set, since the texts may be reused for other # items in case of identifier change or other rearrangements. It # will also automatically resurrect texts for items which are # removed temporarily (eg. commented out) which is quite common # during development. Items which were not ever modified or have # no content may be safely deleted (they contain no hand-edited # data). conds = [pd.EQ('spec_name', pd.sval(spec_name)), pd.EQ('kind', pd.sval(kind)), pd.NOT(pd.ANY_OF('identifier', *[pd.sval(item.id()) for item in items])), ] data.delete_many(pd.AND(*(conds + [pd.OR(pd.EQ('changed', pd.bval(False)), pd.EQ('content', pd.sval(None)))]))) data.update_many(pd.AND(*(conds + [pd.EQ('removed', pd.bval(False))])), pd.Row(self._values(data, removed=True)))
def _update_spec_help(self, spec_name): if self._done.get(spec_name): return self._done[spec_name] = True resolver = pytis.util.resolver() try: view_spec = resolver.get(spec_name, 'view_spec') except pytis.util.ResolverError as e: print(e) return description = view_spec.description() help_text = (view_spec.help() or '').strip() or None self._update(self._spec_help_data, dict(spec_name=spec_name), description=description, help=help_text) data = self._spec_help_items_data for kind, items in (('field', view_spec.fields()), ('profile', view_spec.profiles().unnest()), ('binding', view_spec.bindings()), ('action', view_spec.actions(unnest=True))): for item in items: self._update(data, dict(spec_name=spec_name, kind=kind, identifier=item.id()), content=item.descr()) # Items which were modified (content changed by hand) are kept with # the 'removed' flag set, since the texts may be reused for other # items in case of identifier change or other rearrangements. It # will also automatically resurrect texts for items which are # removed temporarily (eg. commented out) which is quite common # during development. Items which were not ever modified or have # no content may be safely deleted (they contain no hand-edited # data). conds = [pd.EQ('spec_name', pd.sval(spec_name)), pd.EQ('kind', pd.sval(kind)), pd.NOT(pd.ANY_OF('identifier', *[pd.sval(item.id()) for item in items])), ] data.delete_many(pd.AND(*(conds + [pd.OR(pd.EQ('changed', pd.bval(False)), pd.EQ('content', pd.sval(None)))]))) data.update_many(pd.AND(*(conds + [pd.EQ('removed', pd.bval(False))])), pd.Row(self._values(data, removed=True)))
def __init__(self): try: data = pytis.data.dbtable('ev_pytis_user_help', ('help_id', 'fullname', 'spec_name', 'page_id', 'position', 'title', 'description', 'menu_help', 'content',)) except pd.DBException: log(OPERATIONAL, "Not using DMP help: DMP help tables not found in database.") raise self.NotAvailable() count = data.select(condition=pd.NE('help_id', pd.sval('menu/'))) data.close() if count == 0: log(OPERATIONAL, "Not using DMP help: DMP help tables are empty.") raise self.NotAvailable() self._data = data self._cached_descriptions = {} super(DmpHelpGenerator, self).__init__()
def test_setitem(self): row = self._mega_row() self._check_values(row, a=None, b=None, c=None, d=None) row['a'] = 5 self._check_values(row, a=5, b=None, c=None, d=None) row['b'] = 10 self._check_values(row, a=5, b=10, c=None, d=None) row['c'] = 20 self._check_values(row, a=5, b=10, c=20, d=40, total=30) row['d'] = 30 self._check_values(row, a=5, b=10, c=20, d=30, total=30) row['total'] = 3 self._check_values(row, a=5, b=10, c=20, d=30, total=3) row['array'] = ('apl', 'str') assert [v.value() for v in row['array'].value()] == ['apl', 'str'] with pytest.raises(TypeError): row['c'] = 'x' with pytest.raises(TypeError): row['c'] = pd.sval('x') with pytest.raises(TypeError): row['array'] = (1, 2)
def _application_help_page_content(self, node, uri): self._data.select(condition=pd.EQ('help_id', pd.sval(uri[5:]))) row = self._data.fetchone() self._data.close() if row: if row['page_id'].value(): storage = pytis.presentation.DbAttachmentStorage( 'e_pytis_help_pages_attachments', 'page_id', row['page_id'].value(), ) return lcg.Container(lcg.Parser().parse(row['content'].value() or ''), resources=storage.resources()) if row['menu_help'].value(): return lcg.Parser().parse(row['menu_help'].value()) else: spec_name = row['spec_name'].value() # TODO: Use the default descriptions from HelpUpdater. if spec_name: content = self._spec_help_content(spec_name)[1] if content: return content return lcg.Content()
class Continents(Specification): """Codebook of continents and their codes. Codebook is a regular view. Any view can be used as a codebook. It is, however, possible to define several properties of a view, which influence its use in the codebook context. They are all covered by the 'CodebookSpec' instance passed as the 'cb' argument of the specification. See the 'CodebookSpec' documentation for more information about the available options. Using a view as a codebook for a particular field is than done by passing its name as the 'codebook' argument in the field specification. See the specification of 'Countries' below for an example. """ public = True title = _("Continents") table = dbdefs.Continents fields = ( Field('id', width=3, column_width=6, fixed=True, filter=TextFilter.ALPHANUMERIC, post_process=PostProcess.UPPER), Field('name', width=40), Field('smallest', codebook='cb.Countries'), ) cb = CodebookSpec(display='name') bindings = ( Binding('all-countries', _("All Countries"), 'cb.Countries', 'continent', search=lambda r: r['id'].value() == 'EU' and pd.sval('CZ') or None), Binding('islands', _("Islands"), 'cb.Countries', 'continent', condition=lambda r: pd.WM( 'name', pd.WMValue(pd.String(), '*island*'))), Binding('disabled-countries', _("Disabled Countries"), 'cb.DisabledCountries', 'continent'), Binding('random-numbers', _("Random numbers"), 'misc.RandomNumbers', arguments=lambda r: {}), ) prints = ( (_("Default"), 'output/None'), # This spec doen't exist, so defaults are used. (_("Countries of the current continent"), 'cb.PrintContinentCountries'), PrintAction('p_countries_continents', _("Countries of the current continent as specification"), 'cb.PrintContinentCountries'), PrintAction('p_overflow', _("PDF LayoutError"), 'cb.PrintOverflow'), (_("Template based"), 'output/Continents'), (_("Database template"), 'ContinentsDB'), (_("Iterated table"), 'IteratedContinents'), )
def params(self): return ( # Don't bother creating a separate table for testing shared params. # Simply use any existing table... SharedParams('country', 'cb.Countries', pd.EQ('id', pd.sval('CZ'))), )
def condition(self): return pd.EQ('kind', pd.sval(self._ITEM_KIND))
class FormProfiles(Specification): public = True table = 'ev_pytis_form_profiles' title = _("Profily formulářů") fields = ( Field('id', _("Identifier"), width=25, editable=Editable.NEVER), Field('title', _("Title"), width=25, editable=Editable.NEVER), Field('username', _("User"), not_null=True, codebook='statistics.FormUserList', value_column='login', editable=Editable.NEVER), Field('fullname', _("Fullname"), not_null=True, codebook='menu.ApplicationMenuM', width=80, column_width=30, editable=Editable.NEVER), Field('spec_name', _("Specification Name"), width=50, column_width=30, editable=Editable.NEVER), Field('form_name', _("Form Class"), width=50, column_width=30, editable=Editable.NEVER), Field('profile_id', _("Id profilu"), width=25, editable=Editable.NEVER), Field('pickled_filter', editable=Editable.NEVER), Field('pickled_params', editable=Editable.NEVER), Field('dump', _("Content"), width=80, height=8, editable=Editable.NEVER), Field('errors', _("Chyby"), width=80, height=8, editable=Editable.NEVER), Field('invalid', _("Neplatný"), type=pd.Boolean, virtual=True, width=1, computer=computer(lambda r, errors: errors is not None), editable=Editable.NEVER), ) cb = CodebookSpec(display='title') columns = ('title', 'profile_id', 'username', 'spec_name', 'form_name', 'invalid') layout = HGroup(('title', 'profile_id', 'username'), ('spec_name', 'form_name', 'dump', 'errors')) profiles = ( Profile('invalid-profiles', _("Neplatné profily"), filter=pd.NE('errors', pd.sval(None))), Profile('user-profiles', _("Uživatelské profily"), filter=pd.WM('profile_id', pd.WMValue(pd.String(), '_user_profile_*'))), Profile('system-profiles', _("Systémové profily"), filter=pd.NW('profile_id', pd.WMValue(pd.String(), '_user_profile_*'))), )