예제 #1
0
 def _update(self, data, key, **kwargs):
     row = self._row(data, **key)
     rowdata = self._values(data, changed=False, removed=False, **kwargs)
     if row is None:
         data.insert(pd.Row(self._values(data, **key) + rowdata))
     elif not row['changed'].value() and any([row[k].value() != v.value() for k, v in rowdata]):
         data.update((row[0],), pd.Row(rowdata))
예제 #2
0
파일: dbutils.py 프로젝트: cerha/pytis
def dbinsert(spec, row, transaction=None):
    """Provede insert do tabulky dané specifikací.

    Argumenty:

      spec -- název specifikace datového objektu nad kterým má být proveden
        insert.
      row -- sekvence dvouprvkových sekvencí (id, value) nebo instance
        pd.Row
      transaction -- instance pd.DBTransactionDefault

    Vrací počet vložených řádků.

    """
    assert isinstance(row, (pd.Row, tuple, list)), row
    import pytis.form
    if isinstance(row, (tuple, list)):
        for item in row:
            if not isinstance(item, (tuple, list)) or len(item) != 2:
                errmsg = 'Column definition must be (ID, VALUE) pair.'
                raise ProgramError(errmsg)
            k, v = item
            if not isinstance(k, basestring):
                errmsg = 'Invalid column id %s' % k
                raise ProgramError(errmsg)
            if not isinstance(v, pd.Value):
                errmsg = 'Invalid column value %s' % v
                raise ProgramError(errmsg)
        row = pd.Row(row)
    data = pytis.util.data_object(spec)
    success, result = pytis.form.db_operation(data.insert, row, transaction=transaction)
    return result
예제 #3
0
파일: _test.py 프로젝트: nicLucian/pytis
 def test_display(self):
     C = pd.ColumnSpec
     S = pd.String
     V = pd.Value
     rows = [
         pd.Row((('x', V(S(), x)), ('y', V(S(), y))))
         for x, y in (('1', 'FIRST'), ('2', 'SECOND'), ('3', 'THIRD'))
     ]
     edata = pd.DataFactory(pd.MemData, (C('x', S()), C('y', S())),
                            data=rows)
     enum = pd.DataEnumerator(edata)
     key = C('a', pd.Integer())
     columns = (key, C('b', S(enumerator=enum)), C('c', S(enumerator=enum)),
                C('d', S(enumerator=enum)))
     data = pd.Data(columns, key)
     fields = (
         Field('a'),
         Field('b', display='y'),
         Field('c', display=lambda x: '-' + x + '-'),
         Field('d', display=lambda row: row['y'].value().lower()),
     )
     row = pp.PresentedRow(fields,
                           data,
                           None,
                           prefill={
                               'b': '2',
                               'c': '3',
                               'd': '1'
                           })
     self.assertEqual(row.display('a'), '')
     self.assertEqual(row.display('b'), 'SECOND')
     self.assertEqual(row.display('c'), '-3-')
     self.assertEqual(row.display('d'), 'first')
예제 #4
0
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()
예제 #5
0
파일: test.py 프로젝트: cerha/pytis
 def test_original_row(self):
     r = pd.Row([(k, pd.Value(pd.Integer(), v))
                 for k, v in dict(a=None, b=6, c=None, d=3).items()])
     row = self._mega_row(new=True, row=r, b=22, c=33, d=44)
     r1 = row.original_row()
     self._check_values(r1, a=None, b=22, c=33, d=44)
     r2 = row.original_row(initialized=False)
     self._check_values(r2, a=None, b=6, c=None, d=3)
예제 #6
0
파일: web.py 프로젝트: cerha/pytis
 def __getitem__(self, key):
     if self._row is None:
         # Perform the database access only when needed.
         rows = self._data.get_rows(limit=1, **self._kwargs)
         if rows:
             self._row = rows[0]
         else:
             self._row = pd.Row(())
     return self._row[key].export()
예제 #7
0
파일: test.py 프로젝트: cerha/pytis
 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
예제 #8
0
파일: misc.py 프로젝트: cerha/pytis
def mark_products(product_id=None, mark=True):
    """Mark/unmark all products."""
    assert isinstance(mark, bool)
    assert product_id is None or isinstance(product_id, (int, tuple, list))
    row = pd.Row((('marked', pd.bval(mark)),))
    if product_id is None:
        condition = pd.EQ('marked', pd.bval(not mark))
    elif isinstance(product_id, (list, tuple)):
        condition = pd.OR(*[pd.EQ('product_id', pd.ival(x)) for x in product_id])
    else:
        condition = pd.EQ('product_id', pd.ival(product_id))
    import pytis.extensions
    return pytis.extensions.dbupdate_many('misc.Products', condition=condition, update_row=row)
예제 #9
0
파일: dbutils.py 프로젝트: cerha/pytis
def dbfunction(name, *args, **kwargs):
    """Deprecated.  Use pytis.data.dbfunction instead.

    Nová funkce pytis.data.dbfunction má oproti této původní funkci několik
    odlišností, které je potřeba zohlednit při přepisu starého kódu na použití
    nové funkce.

    1. Tato (původní) funkce vrací None pokud je hodnota některého z argumentů
    None aniž by došlo ke skutečnému vyvolání DB funkce (čemuž lze zabránit
    argumentem proceed_with_empty_values=False).  Nová funkce toto nedělá a
    argument proceed_with_empty_values nemá.

    2. Argumenty nové funkce se předávají vnitřní hodnotou a nikoliv jako
    sekvence dvouprvkových tuplů, ale přímo jako argumenty funkce.

    3. Funkci je možné předat jako DB specifikaci.  V tom případě je prováděna
    typová kontrola argumentů a výsledek může být jak množina řádků (tabulkové
    funkce), tak jednoduchá hodnota dle atributu multirow ve specifikaci.

    4. pd.dbfunction nepoužívá obalení pomocí pf.db_operation(), takže to je
    potřeba případně přidat explicitně, kde je to potřeba (většinou by to
    potřeba být nemělo.).

    """
    # TODO PY3: define keyword arguments in function definition.
    import pytis.form
    proceed_with_empty_values = kwargs.pop('proceed_with_empty_values', False)
    transaction = kwargs.pop('transaction', None)
    assert not kwargs
    if not proceed_with_empty_values and args and any(v.value() in (None, '') for k, v in args):
        return None

    def conn_spec():
        return pytis.config.dbconnection
    success, function = pytis.form.db_operation(pd.DBFunctionDefault, name, conn_spec)
    success, result = pytis.form.db_operation(function.call, pd.Row(args),
                                              transaction=transaction)
    if not success:
        return None
    if len(result) == 1 and len(result[0]) == 1:
        return result[0][0].value()
    return result
예제 #10
0
 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)))
예제 #11
0
파일: test.py 프로젝트: cerha/pytis
 def _data_row(self, row, **values):
     return pd.Row([(f.id(), pd.Value(f.type(), values.get(f.id())))
                    for f in row.fields() if not f.virtual()])
예제 #12
0
    def _reload_actions(self, record):
        import wiking

        def action_descr(module, action):
            if issubclass(module, wiking.PytisModule):
                for a in module.Spec.actions:
                    if a.name() == action:
                        return a.descr() or a.title()
            try:
                return dict(self._DEFAULT_ACTIONS)[action]
            except KeyError:
                method = getattr(module, 'action_' + action)
                docstring = method.__doc__
                return docstring and docstring.splitlines()[0] or _(
                    "Neuvedeno")

        module = self._module(record['modname'].value())
        if module:
            from pytis.form import run_dialog, CheckListDialog, create_data_object
            data = create_data_object(self._spec_name('Actions'))
            data.select(condition=pd.EQ('mod_id', record['mod_id']))
            existing_actions = {}
            while True:
                row = data.fetchone()
                if row is None:
                    break
                else:
                    existing_actions[row['name'].value()] = row['action_id']
            data.close()
            actions = [
                attr[7:] for attr in dir(module) if attr.startswith('action_')
                and isinstance(getattr(module, attr), collections.Callable)
            ]
            default_actions = [a[0] for a in self._DEFAULT_ACTIONS]
            # Order default actions first and in the order of self._DEFAULT_ACTIONS.
            order = lambda a: a in default_actions and (default_actions.index(
                a) + 1) or a
            actions.sort(lambda a, b: cmp(order(a), order(b)))
            descriptions = [action_descr(module, action) for action in actions]
            result = run_dialog(
                CheckListDialog,
                title=_("Nalezené akce"),
                message=_("Zaškrtněte akce, které chcete zpřístupnit webovým "
                          "uživatelům:"),
                items=zip([a in existing_actions for a in actions], actions,
                          descriptions),
                columns=(_("Action"), _("Description")))
            if result is not None:
                # TODO: Use a transaction.  Respect existing actions.
                for i, action in enumerate(actions):
                    if result[i]:
                        description_value = pd.Value(pd.String(),
                                                     descriptions[i] or None)
                        try:
                            key = existing_actions[action]
                        except KeyError:
                            rowdata = [('mod_id', record['mod_id']),
                                       ('name', pd.Value(pd.String(), action)),
                                       ('description', description_value)]
                            data.insert(pd.Row(rowdata))
                        else:
                            data.update(
                                (key, ),
                                pd.Row((('description', description_value), )))
예제 #13
0
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
    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('cms_page_attachments',
                              ('attachment_id', 'filename', 'width', 'height',
                               'image', 'image_width', 'image_height', 'thumbnail',
                               'thumbnail_size', 'thumbnail_width', 'thumbnail_height'),
                              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
    image_screen_size = wiking.cms.cfg.image_screen_size
    image_thumbnail_sizes = wiking.cms.cfg.image_thumbnail_sizes
    transaction = pd.transaction()
    data.select(transaction=transaction)
    try:
        while True:
            row = data.fetchone()
            if row is None:
                break
            ext = os.path.splitext(row['filename'].value())[1].lower()
            path = os.path.join(wiking.cms.cfg.storage, pytis.config.dbname, 'attachments',
                                row['attachment_id'].export() + (ext or '.'))
            attachment = open(path, 'rb')
            try:
                image = PIL.Image.open(attachment)
            except IOError as e:
                continue
            sys.stderr.write("Resizing %s (%dx%d): " %
                             (row['filename'].value(), image.size[0], image.size[1]))
            thumbnail_size = row['thumbnail_size'].value()
            if thumbnail_size is None:
                thumbnail_value, real_thumbnail_size = None, (None, None)
            else:
                if thumbnail_size == 'small':
                    size = image_thumbnail_sizes[0]
                elif thumbnail_size == 'medium':
                    size = image_thumbnail_sizes[1]
                else:
                    size = image_thumbnail_sizes[2]
                thumbnail_value, real_thumbnail_size = resize(image, (size, size))
                sys.stderr.write("%dx%d, " % real_thumbnail_size)
            resized_image_value, resized_image_size = resize(image, image_screen_size)
            sys.stderr.write("%dx%d\n" % resized_image_size)
            values = dict(
                width=image.size[0],
                height=image.size[1],
                thumbnail=thumbnail_value,
                thumbnail_width=real_thumbnail_size[0],
                thumbnail_height=real_thumbnail_size[1],
                image=resized_image_value,
                image_width=resized_image_size[0],
                image_height=resized_image_size[1],
            )
            r = pd.Row([(key, pd.Value(row[key].type(), value)) for key, value in values.items()])
            data.update(row['attachment_id'], r, transaction=transaction)
    except Exception:
        try:
            transaction.rollback()
        except Exception:
            pass
        sys.stderr.write("Transaction rolled back.\n")
        raise
    else:
        sys.stderr.write("Transaction commited.\n")
        transaction.commit()
    transaction.close()
예제 #14
0
파일: _test.py 프로젝트: nicLucian/pytis
 def _data_row(self, **values):
     return pd.Row([(c.id(), pd.Value(c.type(), values.get(c.id())))
                    for c in self._columns])