Ejemplo n.º 1
0
def read_x2go_info_file(rename=False, use_defaults=True):
    pytis_x2go_file = pytis_x2go_info_file()
    if os.path.exists(pytis_x2go_file):
        for i in range(3):
            try:
                access_data = parse_x2go_info_file(pytis_x2go_file)
            except X2GoInfoSoftException as e:
                log(OPERATIONAL, *e.args)
                time.sleep(1)
                continue
            except X2GoInfoHardException as e:
                log(OPERATIONAL, *e.args)
                return None
            if rename:
                try:
                    os.rename(pytis_x2go_file, pytis_x2go_info_file(x2go_session_id(fake=True)))
                except Exception as e:
                    return
            else:
                os.remove(pytis_x2go_file)
            break
    elif use_defaults:
        access_data = dict(port=config.rpc_local_port, password=None)
    else:
        access_data = None
    return access_data
Ejemplo n.º 2
0
def read_x2go_info_file(rename=False, use_defaults=True):
    pytis_x2go_file = pytis_x2go_info_file()
    if os.path.exists(pytis_x2go_file):
        for i in range(3):
            try:
                access_data = parse_x2go_info_file(pytis_x2go_file)
            except X2GoInfoSoftException as e:
                log(OPERATIONAL, *e.args)
                time.sleep(1)
                continue
            except X2GoInfoHardException as e:
                log(OPERATIONAL, *e.args)
                return None
            if rename:
                try:
                    os.rename(pytis_x2go_file, pytis_x2go_info_file(x2go_session_id(fake=True)))
                except Exception as e:
                    return
            else:
                os.remove(pytis_x2go_file)
            break
    elif use_defaults:
        access_data = dict(port=config.rpc_local_port, password=None)
    else:
        access_data = None
    return access_data
Ejemplo n.º 3
0
 def _pytis_help_nodes(self):
     def clone(node, id):
         return self.ContentNode(
             id=id,
             title=node.title(),
             descr=node.descr(),
             content=node.content(),
             hidden=node.hidden(),
             children=[clone(n, 'help:pytis/' + n.id()) for n in node.children()],
             resource_provider=self._resource_provider,
             foldable=True,
         )
     directory = os.path.join(pytis.config.help_dir, 'src')
     reader = lcg.reader(directory, 'pytis', ext='txt',
                         resource_provider=self._resource_provider)
     try:
         node = reader.build()
     except IOError as e:
         log(OPERATIONAL, "Unable to read Pytis help files from '%s':" % directory, e)
         node = self.ContentNode('help:pytis', title=_("Pytis User Guide"),
                                 content=lcg.p(_("Help files not found!")),
                                 hidden=True, resource_provider=self._resource_provider)
     else:
         node = clone(node, 'help:pytis')
     return node
Ejemplo n.º 4
0
    def __init__(self, message, exception=None, *args):
        """Inicializuj výjimku a zaloguj informace o ní.

        Argumenty:

          message -- lidsky čitelné oznámení o chybě, string; může být též
            'None', v kterémžto případě se doplní standardní zpráva
            o databázové chybě, to je však vhodné používat pouze v případě, kdy
            nemá smysl uživateli sdělovat bližší popis chyby
          exception -- výjimka, která tuto výjimku způsobila, instance třídy
            'Exception'; nebo 'None' (neznamená nutně, že chyba nebyla
            způsobena výjimkou, tato výjimka pouze nemusí být podstatná)
          args -- libovolné další argumenty, které mají být spolu s 'message' a
            'exception' předány konstruktoru nadtřídy

        """
        if message is None:
            message = _(u"Database error")
        super_(DBException).__init__(self, message, exception, *args)
        log(OPERATIONAL, 'Database exception', (message, ) + args)
        if exception:
            log(OPERATIONAL, 'Wrapped database exception',
                (exception, ) + exception.args)
        self._message = message
        self._exception = exception
Ejemplo n.º 5
0
Archivo: defs.py Proyecto: cerha/pytis
def _get_default_select(spec):
    import pytis.form

    def init_select(view, data):
        sorting = view.sorting()
        if sorting is None:
            sorting = tuple([(k.id(), pd.DESCENDANT) for k in data.key()
                             if view.field(k.id()) is not None])
        success, select_count = pytis.form.db_operation(data.select,
                                                        sort=sorting,
                                                        reuse=False)
        if not success:
            log(EVENT, 'Selhání databázové operace')
            return None
        return select_count

    resolver = pytis.config.resolver
    try:
        view = resolver.get(spec, 'view_spec')
    except Exception:
        log(OPERATIONAL, "Nepodařilo se vytvořit view_spec")
        return None
    try:
        data = pytis.util.data_object(spec)
    except Exception:
        log(OPERATIONAL, "Nepodařilo se vytvořit datový objekt")
        return None
    data = pytis.util.data_object(spec)
    select_count = init_select(view, data)
    if select_count:
        print("Default select pro specifikaci %s vrací %s řádků" % (
            spec,
            select_count,
        ))
        data.fetchone()
Ejemplo n.º 6
0
Archivo: grid.py Proyecto: cerha/pytis
    def _retrieve_row(self, row):
        def fetch(row):
            attempt = 1
            while True:
                try:
                    return self._data.fetch(row)
                except pytis.data.DBRetryException:
                    if attempt <= 10:
                        attempt += 1
                        continue
                    else:
                        raise

        current = self._current_row
        if not current or current.row != row:
            success, data_row = db_operation(fetch, row)
            if not success:
                self._panic()
            if data_row:
                self._presented_row.set_row(data_row)
                current = self._current_row = self._CurrentRow(
                    row, copy.copy(self._presented_row))
            else:
                if 0 <= row < self.number_of_rows(min_value=(row + 1)):
                    log(DEBUG, "Missing grid row:", row)
                return None
        return current.the_row
Ejemplo n.º 7
0
 def _pytis_help(self, resource_dirs):
     image_dir = os.path.join(config.help_dir, 'img')
     resource_provider = lcg.ResourceProvider(dirs=[image_dir] + resource_dirs)
     def clone(node, node_id):
         # Clone the content node, but force `id' to help URI and `foldable' to True.
         return lcg.ContentNode(node_id, title=node.title(), descr=node.descr(),
                                content=node.content(), hidden=node.hidden(),
                                children=[clone(n, 'help:pytis/'+n.id()) for n in node.children()],
                                resource_provider=resource_provider,
                                foldable=True)
     try:
         node = self._pytis_help_root_node
     except AttributeError:
         directory = os.path.join(config.help_dir, 'src')
         reader = lcg.reader(directory, 'pytis', ext='txt', resource_provider=resource_provider)
         try:
             node = self._pytis_help_root_node = reader.build()
         except IOError as e:
             log(OPERATIONAL, "Unable to read Pytis help files from '%s':" % directory, e)
             node = lcg.ContentNode('pytis:', title=_("Pytis User Guide"),
                                    content=lcg.p(_("Help files not found!")),
                                    hidden=True, resource_provider=resource_provider)
     # We need to clone on every request because set_parent() is called on
     # the result when added to the help tree and set_parent may not be
     # called multiple times.
     return clone(node, 'help:pytis')
Ejemplo n.º 8
0
Archivo: event.py Proyecto: cerha/pytis
def top_level_exception(einfo=None):
    """Zpracuj aktuálně vyvolanou výjimku aplikace."""
    global _in_top_level_exception
    if not _in_top_level_exception:
        _in_top_level_exception = True
        try:
            if not einfo:
                einfo = sys.exc_info()
            if issubclass(einfo[0], SystemExit):
                sys.exit()
            tbstring = format_traceback()
            import cgitb
            try:
                tbstring = cgitb.text(einfo)
            except Exception:
                import traceback
                tbstring = "\n".join(traceback.format_exception(*einfo))
            log(OPERATIONAL, 'Top-level exception caught', tbstring)
            if pytis.form.run_dialog(pytis.form.BugReport, einfo):
                sys.exit()
            if pytis.config.debug_on_error:
                import pdb
                pdb.post_mortem(sys.exc_info()[2])
        finally:
            _in_top_level_exception = False
Ejemplo n.º 9
0
 def __init__(self, connection_creator, connection_closer):
     if __debug__:
         log(DEBUG, 'Creating a new pool')
     self._lock = thread.allocate_lock()
     self._pool = {}
     self._connection_creator = connection_creator
     self._connection_closer = connection_closer
     self._allocated_connections = {}
Ejemplo n.º 10
0
 def __init__(self, connection_creator, connection_closer):
     if __debug__:
         log(DEBUG, 'Creating a new pool')
     self._lock = _thread.allocate_lock()
     self._pool = {}
     self._connection_creator = connection_creator
     self._connection_closer = connection_closer
     self._allocated_connections = {}
Ejemplo n.º 11
0
def client_available():
    """Return true, iff remote client is available."""
    if not config.rpc_communication_enabled or client_ip() is None:
        level = OPERATIONAL if config.rpc_communication_enabled else DEBUG
        log(level, "RPC unavailable")
        return False
    try:
        return _request('echo', 'hello') == 'hello'
    except Exception, e:
        log(OPERATIONAL, "RPC exception:", e)
        return False
Ejemplo n.º 12
0
def client_available():
    """Return true, iff remote client is available."""
    if not config.rpc_communication_enabled or client_ip() is None:
        level = OPERATIONAL if config.rpc_communication_enabled else DEBUG
        log(level, "RPC unavailable")
        return False
    try:
        return _request('echo', 'hello') == 'hello'
    except Exception, e:
        log(OPERATIONAL, "RPC exception:", e)
        return False
Ejemplo n.º 13
0
 def value(self):
     # Temporary hack: Automatically upgrade the legacy values 'plain' and 'md5'
     # to the new UniversalPasswordStorage instance.  This instance is compatible
     # with existing passwords when upgrade.72.sql was applied.
     value = super(CMSConfiguration._Option_password_storage, self).value()
     if value in ('plain', 'md5'):
         from pytis.util import OPERATIONAL, log
         log(OPERATIONAL,
             ("Value '%s' of configuration option 'password_storage' is not valid anymore. "
              "Using 'wiking.UniversalPasswordStorage() instead.") % value)
         value = wiking.UniversalPasswordStorage()
     return value
Ejemplo n.º 14
0
Archivo: defs.py Proyecto: cerha/pytis
 def init_select(view, data):
     sorting = view.sorting()
     if sorting is None:
         sorting = tuple([(k.id(), pd.DESCENDANT) for k in data.key()
                          if view.field(k.id()) is not None])
     success, select_count = pytis.form.db_operation(data.select,
                                                     sort=sorting,
                                                     reuse=False)
     if not success:
         log(EVENT, 'Selhání databázové operace')
         return None
     return select_count
Ejemplo n.º 15
0
 def put_back(self, connection_spec, connection):
     pool = self._pool
     spec_id = self._connection_spec_id(connection_spec)
     with Locked(self._lock):
         try:
             connections = pool[spec_id]
         except KeyError:
             pool[spec_id] = connections = []
         if ((pytis.config.max_pool_connections is None
              or len(connections) < pytis.config.max_pool_connections)):
             connections.append(connection)
     if __debug__:
         log(DEBUG, 'Connection returned to pool:', connection)
Ejemplo n.º 16
0
 def value(self):
     # Temporary hack: Automatically upgrade the legacy values 'plain' and 'md5'
     # to the new UniversalPasswordStorage instance.  This instance is compatible
     # with existing passwords when upgrade.72.sql was applied.
     value = super(CMSConfiguration._Option_password_storage,
                   self).value()
     if value in ('plain', 'md5'):
         from pytis.util import OPERATIONAL, log
         log(OPERATIONAL, (
             "Value '%s' of configuration option 'password_storage' is not valid anymore. "
             "Using 'wiking.UniversalPasswordStorage() instead.") %
             value)
         value = wiking.UniversalPasswordStorage()
     return value
Ejemplo n.º 17
0
 def put_back(self, connection_spec, connection):
     pool = self._pool
     spec_id = self._connection_spec_id(connection_spec)
     def lfunction():
         try:
             connections = pool[spec_id]
         except KeyError:
             pool[spec_id] = connections = []
         import config
         if ((config.max_pool_connections is None or
              len(connections) < config.max_pool_connections)):
             connections.append(connection)
     with_lock(self._lock, lfunction)
     if __debug__:
         log(DEBUG, 'Connection returned to pool:', connection)
Ejemplo n.º 18
0
 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__()
Ejemplo n.º 19
0
    def __init__(self, permission, table=None, column=None):
        """
        Arguments:

          permission -- the missing permission, one of the 'Permission' class
            constants
          table -- name of the table which couldn't be accessed, string or
            'None'
          column -- name of the column which couldn't be accessed, string or
            'None'

        """
        log(EVENT, 'Access violation attempt',
            (pytis.config.dbconnection.user(), permission, table, column))
        Exception.__init__(self, _(u"Access denied"), permission, table,
                           column)
Ejemplo n.º 20
0
    def __init__(self, permission, table=None, column=None):
        """
        Arguments:

          permission -- the missing permission, one of the 'Permission' class
            constants
          table -- name of the table which couldn't be accessed, string or
            'None'
          column -- name of the column which couldn't be accessed, string or
            'None'

        """
        import config
        log(EVENT, 'Access violation attempt',
            (config.dbconnection.user(), permission, table, column))
        Exception.__init__(self, _(u"Access denied"), permission, table, column)
Ejemplo n.º 21
0
 def _notif_listen_loop(self):
     while True:
         while self._pgnotif_connection is None:
             time.sleep(10)
             try:
                 self._notif_init_connection()
                 for notification in self._registered_notifications:
                     self._notif_do_registration(notification)
             except Exception as e:
                 self._pgnotif_connection = None
         connection_ = self._pgnotif_connection
         connection = connection_.connection()
         if __debug__:
             log(DEBUG, 'Listening for notifications:', connection)
         def lfunction():
             cursor = connection.cursor()
             try:
                 fileno = connection.fileno()
             except AttributeError: # older psycogp2 versions
                 fileno = cursor.fileno()
             return cursor, fileno
         cursor, fileno = with_lock(self._pg_query_lock, lfunction)
         try:
             select.select([fileno], [], [], None)
         except Exception as e:
             if __debug__:
                 log(DEBUG, 'Socket error', e.args)
             break
         if __debug__:
             log(DEBUG, 'Input received')
         def lfunction():
             notifications = []
             try:
                 connection.poll()
                 ready = True
             except AttributeError: # older psycopg2 versions
                 try:
                     ready = cursor.isready()
                 except dbapi.OperationalError:
                     self._pg_notif_connection = None
                     return notifications
             if ready:
                 notifies = connection.notifies
                 if notifies:
                     if __debug__:
                         log(DEBUG, 'Data change registered')
                     notifications = []
                     while notifies:
                         notifications.append(notifies.pop()[1])
             return notifications
         notifications = with_locks((self._notif_connection_lock,
                                     self._pg_query_lock,),
                                    lfunction)
         if __debug__:
             log(DEBUG, 'Notifications received:', notifications)
         self._notif_invoke_callbacks(notifications)
Ejemplo n.º 22
0
 def SetValue(self, row, col, value):
     # Tato metoda neodpovídá specifikaci gridu, ale to nevadí, protože
     # políčka editujeme výhradně přes naše editory.
     assert isinstance(value, pytis.data.Value), ('Value not a value', value)
     edited = self._edited_row
     if edited is None:
         # K této situaci dochází, když se kliknutím myši opouští
         # rozeditované políčko řádku, jemuž ještě nebyla změněna žádná
         # hodnota.  V takovém případě naše metody editaci nakrásno
         # ukončí a wxWindows po provedené změně řádku vesele zavolá
         # SetValue ...
         return
     # Nastav hodnotu editovanému sloupci
     cid = self._columns[col].id
     edited.update(cid, value)
     log(EVENT, 'Nastavena hodnota editovaného políčka:',
         (row, col, value))
Ejemplo n.º 23
0
 def SetValue(self, row, col, value):
     # Tato metoda neodpovídá specifikaci gridu, ale to nevadí, protože
     # políčka editujeme výhradně přes naše editory.
     assert isinstance(value,
                       pytis.data.Value), ('Value not a value', value)
     edited = self._edited_row
     if edited is None:
         # K této situaci dochází, když se kliknutím myši opouští
         # rozeditované políčko řádku, jemuž ještě nebyla změněna žádná
         # hodnota.  V takovém případě naše metody editaci nakrásno
         # ukončí a wxWindows po provedené změně řádku vesele zavolá
         # SetValue ...
         return
     # Nastav hodnotu editovanému sloupci
     cid = self._columns[col].id
     edited.update(cid, value)
     log(EVENT, 'Nastavena hodnota editovaného políčka:', (row, col, value))
Ejemplo n.º 24
0
 def get(self, connection_spec):
     pool = self._pool
     spec_id = self._connection_spec_id(connection_spec)
     with Locked(self._lock):
         try:
             connections = pool[spec_id]
         except KeyError:
             pool[spec_id] = connections = []
         try:
             allocated_connections = self._allocated_connections[spec_id]
         except KeyError:
             allocated_connections = self._allocated_connections[spec_id] \
                 = weakref.WeakKeyDictionary()
         c = None
         broken_connections_present = False
         while connections:
             c_candidate = connections.pop()
             if c_candidate.connection_info('broken'):
                 broken_connections_present = True
             else:
                 c = c_candidate
                 if __debug__:
                     log(DEBUG, 'Available connections:', connections)
                 break
         if c is None or broken_connections_present:
             gc.collect()
         if c is None:
             if ((pytis.config.connection_limit is not None
                  and len(allocated_connections) >=
                  pytis.config.connection_limit)):
                 if __debug__:
                     log(EVENT, "Connections summary:")
                     for c in allocated_connections.keys():
                         log(EVENT, "Connection:",
                             c.connection_info('last_access'))
                 raise DBSystemException(
                     _(u"Too many database connections"))
             else:
                 c = self._connection_creator(connection_spec)
                 if __debug__:
                     log(DEBUG, 'New connection created:', c)
                 allocated_connections[c] = True
     if __debug__:
         log(DEBUG, 'Passing connection:', c)
     return c
Ejemplo n.º 25
0
 def get(self, connection_spec):
     import config
     pool = self._pool
     spec_id = self._connection_spec_id(connection_spec)
     def lfunction():
         try:
             connections = pool[spec_id]
         except KeyError:
             pool[spec_id] = connections = []
         try:
             allocated_connections = self._allocated_connections[spec_id]
         except KeyError:
             allocated_connections = self._allocated_connections[spec_id] \
                 = weakref.WeakKeyDictionary()
         c = None
         broken_connections_present = False
         while connections:
             c_candidate = connections.pop()
             if c_candidate.connection_info('broken'):
                 broken_connections_present = True
             else:
                 c = c_candidate
                 if __debug__:
                     log(DEBUG, 'Available connections:', connections)
                 break
         if c is None or broken_connections_present:
             gc.collect()
         if c is None:
             if ((config.connection_limit is not None and
                  len(allocated_connections) >= config.connection_limit)):
                 if __debug__:
                     log(EVENT, "Connections summary:")
                     for c in allocated_connections.keys():
                         log(EVENT, "Connection:", c.connection_info('last_access'))
                 raise DBSystemException(_(u"Too many database connections"))
             else:
                 c = self._connection_creator(connection_spec)
                 if __debug__:
                     log(DEBUG, 'New connection created:', c)
                 allocated_connections[c] = True
         return c
     c = with_lock(self._lock, lfunction)
     if __debug__:
         log(DEBUG, 'Passing connection:', c)
     return c
Ejemplo n.º 26
0
    def sleep(self):
        """Uvolni systémové zdroje využívané instancí a umožni její zrušení.

        Pokud instance využívá některé nedostatkové systémové zdroje jako
        například spojení do databáze nebo procesy, tato metoda by je měla
        uvolnit.  Druhou funkcí metody je uvolnit prostředky (například hlídací
        procesy), které znemožňují zrušení instance.

        Tato metoda by měla být volána vždy, když je trvale nebo na delší dobu
        ukončeno používání instance.

        Zavoláním této metody se neznemožňuje další použití instance, lze
        nadále využívat všechny její veřejné metody.  Je-li pak ovšem třeba
        opět uvolnit zdroje, je nutno tuto metodu zavolat znovu.

        """
        if __debug__:
            log(DEBUG, 'Sleep')
        self.close()
Ejemplo n.º 27
0
    def sleep(self):
        """Uvolni systémové zdroje využívané instancí a umožni její zrušení.

        Pokud instance využívá některé nedostatkové systémové zdroje jako
        například spojení do databáze nebo procesy, tato metoda by je měla
        uvolnit.  Druhou funkcí metody je uvolnit prostředky (například hlídací
        procesy), které znemožňují zrušení instance.

        Tato metoda by měla být volána vždy, když je trvale nebo na delší dobu
        ukončeno používání instance.

        Zavoláním této metody se neznemožňuje další použití instance, lze
        nadále využívat všechny její veřejné metody.  Je-li pak ovšem třeba
        opět uvolnit zdroje, je nutno tuto metodu zavolat znovu.

        """
        if __debug__:
            log(DEBUG, 'Sleep')
        self.close()
Ejemplo n.º 28
0
Archivo: dbapi.py Proyecto: cerha/pytis
 def _notif_listen_loop(self):
     while True:
         while self._pgnotif_connection is None:
             time.sleep(10)
             try:
                 self._notif_init_connection()
                 for notification in self._registered_notifications:
                     self._notif_do_registration(notification)
             except Exception as e:
                 self._pgnotif_connection = None
         connection_ = self._pgnotif_connection
         connection = connection_.connection()
         if __debug__:
             log(DEBUG, 'Listening for notifications:', connection)
         with Locked(self._pg_query_lock):
             fileno = connection.fileno()
         try:
             select.select([fileno], [], [], None)
         except Exception as e:
             if __debug__:
                 log(DEBUG, 'Socket error', e.args)
             break
         if __debug__:
             log(DEBUG, 'Input received')
         with Locked(self._notif_connection_lock), Locked(
                 self._pg_query_lock):
             notifications = []
             try:
                 connection.poll()
                 ready = True
             except dbapi.OperationalError:
                 self._pg_notif_connection = None
                 ready = False
             if ready:
                 notifies = connection.notifies
                 if notifies:
                     if __debug__:
                         log(DEBUG, 'Data change registered')
                     while notifies:
                         notifications.append(notifies.pop()[1])
         if __debug__:
             log(DEBUG, 'Notifications received:', notifications)
         self._notif_invoke_callbacks(notifications)
Ejemplo n.º 29
0
 def fetch(row, direction=pytis.data.FORWARD):
     result = self._data.fetchone(direction=direction)
     if result is None:
         # In theory this shouldn't happen but it actually happens so we
         # have to attempt some workaround here.
         data.rewind()
         if row > 0:
             data.skip(row - 1, direction=pytis.data.FORWARD)
         result = data.fetchone(direction=pytis.data.FORWARD)
         if result is None:
             # This shouldn't happen at all but it still happens.
             log(DEBUG, "Missing grid row")
             if require:
                 raise Exception('Missing row', row)
             return None
         else:
             log(DEBUG, "Grid data synchronization error")
     self._presented_row.set_row(result)
     the_row = copy.copy(self._presented_row)
     self._current_row = self._CurrentRow(row, the_row)
Ejemplo n.º 30
0
 def lfunction():
     notifications = []
     try:
         connection.poll()
         ready = True
     except AttributeError:  # older psycopg2 versions
         try:
             ready = cursor.isready()
         except dbapi.OperationalError:
             self._pg_notif_connection = None
             return notifications
     if ready:
         notifies = connection.notifies
         if notifies:
             if __debug__:
                 log(DEBUG, 'Data change registered')
             notifications = []
             while notifies:
                 notifications.append(notifies.pop()[1])
     return notifications
Ejemplo n.º 31
0
 def fetch(row, direction=pytis.data.FORWARD):
     result = self._data.fetchone(direction=direction)
     if result is None:
         # In theory this shouldn't happen but it actually happens so we
         # have to attempt some workaround here.
         data.rewind()
         if row > 0:
             data.skip(row - 1, direction=pytis.data.FORWARD)
         result = data.fetchone(direction=pytis.data.FORWARD)
         if result is None:
             # This shouldn't happen at all but it still happens.
             log(DEBUG, "Missing grid row")
             if require:
                 raise Exception('Missing row', row)
             return None
         else:
             log(DEBUG, "Grid data synchronization error")
     self._presented_row.set_row(result)
     the_row = copy.copy(self._presented_row)
     self._current_row = self._CurrentRow(row, the_row)
Ejemplo n.º 32
0
 def lfunction():
     notifications = []
     try:
         connection.poll()
         ready = True
     except AttributeError: # older psycopg2 versions
         try:
             ready = cursor.isready()
         except dbapi.OperationalError:
             self._pg_notif_connection = None
             return notifications
     if ready:
         notifies = connection.notifies
         if notifies:
             if __debug__:
                 log(DEBUG, 'Data change registered')
             notifications = []
             while notifies:
                 notifications.append(notifies.pop()[1])
     return notifications
Ejemplo n.º 33
0
 def _reverse_forward_tunnel(self, transport):
     forward_host = self._forward_host
     forward_port = self._forward_port
     port = self._ssh_forward_port
     if not port:
         port = self._DEFAULT_SSH_FORWARD_PORT
     n_attempts = 1 if self._strict_forward_port else self._MAX_SSH_FORWARD_ATTEMPTS
     port_limit = port + n_attempts
     for p in range(port, port_limit):
         try:
             transport.request_port_forward('', p)
             break
         except paramiko.SSHException as e:
             log(EVENT, "Couldn't connect to port %s: %s" % (p, e,))
     else:
         message = "No free port found in the range %s-%s" % (port, port_limit - 1,)
         log(OPERATIONAL, message)
         raise paramiko.SSHException(message)
     if self._actual_ssh_forward_port is not None:
         self._actual_ssh_forward_port.set(p)
     log(EVENT, 'Remote port %d forwarded to %s:%d' % (p, forward_host, forward_port,))
     while True:
         chan = transport.accept(1000)
         if chan is None:
             continue
         gevent.spawn(self._handler, chan, forward_host, forward_port)
Ejemplo n.º 34
0
 def _handler(self, chan, host, port):
     sock = socket.socket()
     try:
         sock.connect((host, port))
     except Exception as e:
         log(OPERATIONAL,
             'Forwarding request to %s:%d failed: %r' % (host, port, e))
         return
     log(
         EVENT, 'Tunnel open %r -> %r -> %r' %
         (chan.origin_addr, chan.getpeername(), (host, port)))
     while True:
         r, w, x = select.select([sock, chan], [], [])
         if sock in r:
             data = sock.recv(1024)
             if len(data) == 0:
                 break
             chan.send(data)
         if chan in r:
             data = chan.recv(1024)
             if len(data) == 0:
                 break
             sock.send(data)
     chan.close()
     sock.close()
     log(EVENT, 'Tunnel closed from %r' % (chan.origin_addr, ))
Ejemplo n.º 35
0
 def run(self):
     self._actual_ssh_port = None
     # Get parameters
     ssh_host = self._ssh_host
     ssh_port = self._ssh_port
     forward_host = self._forward_host
     forward_port = self._forward_port
     user = self._ssh_user or getpass.getuser()
     password = self._ssh_password
     key_filename = self._key_filename
     if key_filename is None and not os.getenv('SSH_AGENT_PID'):
         key_filename = os.path.expanduser('~/.ssh/id_rsa')
         if not os.path.exists(key_filename):
             key_filename = None
     # Create client
     client = paramiko.SSHClient()
     client.load_system_host_keys()
     client.set_missing_host_key_policy(paramiko.WarningPolicy())
     # Connect to the ssh host
     log(EVENT, 'Connecting to ssh host %s:%d' % (ssh_host, ssh_port,))
     try:
         client.connect(hostname=ssh_host, port=ssh_port, username=user,
                        key_filename=key_filename, password=password, gss_auth=self._gss_auth)
     except Exception as e:
         log(OPERATIONAL, 'Failed to connect to %s@%s:%d: %r' % (user, ssh_host, ssh_port, e,))
         return
     # Forward
     log(EVENT, 'Forwarding remote port %d+ to %s:%d' %
         (self._ssh_forward_port or self._DEFAULT_SSH_FORWARD_PORT, forward_host, forward_port,))
     self._reverse_forward_tunnel(client.get_transport())
Ejemplo n.º 36
0
    def __init__(self, message, exception=None, *args):
        """Inicializuj výjimku a zaloguj informace o ní.

        Argumenty:

          message -- lidsky čitelné oznámení o chybě, string; může být též
            'None', v kterémžto případě se doplní standardní zpráva
            o databázové chybě, to je však vhodné používat pouze v případě, kdy
            nemá smysl uživateli sdělovat bližší popis chyby
          exception -- výjimka, která tuto výjimku způsobila, instance třídy
            'Exception'; nebo 'None' (neznamená nutně, že chyba nebyla
            způsobena výjimkou, tato výjimka pouze nemusí být podstatná)
          args -- libovolné další argumenty, které mají být spolu s 'message' a
            'exception' předány konstruktoru nadtřídy

        """
        if message is None:
            message = _(u"Database error")
        super_(DBException).__init__(self, message, exception, *args)
        log(OPERATIONAL, 'Database exception', (message,) + args)
        if exception:
            log(OPERATIONAL, 'Wrapped database exception', (exception,) + exception.args)
        self._message = message
        self._exception = exception
Ejemplo n.º 37
0
def parse_x2go_info_file(filename):
    try:
        f = open(filename)
    except Exception as e:
        log(OPERATIONAL, "Can't read pytis X2Go file", e)
        return None
    data = ''
    while True:
        d = f.read()
        if not d:
            break
        data += d
    items = data.split(':')
    if len(items) != 4:
        raise X2GoInfoSoftException("Incomplete or invalid X2Go file")
    if items[0] != '0':
        raise X2GoInfoHardException("Unknown pytis X2Go format")
    access_data = {}
    try:
        access_data['port'] = int(items[1])
    except ValueError:
        raise X2GoInfoHardException("Invalid port number in X2Go file", items[1])
    access_data['password'] = items[2]
    return access_data
Ejemplo n.º 38
0
def parse_x2go_info_file(filename):
    try:
        f = open(filename)
    except Exception as e:
        log(OPERATIONAL, "Can't read pytis X2Go file", e)
        return None
    data = ''
    while True:
        d = f.read()
        if not d:
            break
        data += d
    items = data.split(':')
    if len(items) != 4:
        raise X2GoInfoSoftException("Incomplete or invalid X2Go file")
    if items[0] != '0':
        raise X2GoInfoHardException("Unknown pytis X2Go format")
    access_data = {}
    try:
        access_data['port'] = int(items[1])
    except ValueError:
        raise X2GoInfoHardException("Invalid port number in X2Go file", items[1])
    access_data['password'] = items[2]
    return access_data
Ejemplo n.º 39
0
 def run(self):
     self._actual_ssh_port = None
     # Get parameters
     ssh_host = self._ssh_host
     ssh_port = self._ssh_port
     forward_host = self._forward_host
     forward_port = self._forward_port
     user = self._ssh_user or getpass.getuser()
     password = self._ssh_password
     key_filename = self._key_filename
     if key_filename is None and not os.getenv('SSH_AGENT_PID'):
         key_filename = os.path.expanduser('~/.ssh/id_rsa')
         if not os.path.exists(key_filename):
             key_filename = None
     # Create client
     client = paramiko.SSHClient()
     client.load_system_host_keys()
     client.set_missing_host_key_policy(paramiko.WarningPolicy())
     # Connect to the ssh host
     log(EVENT, 'Connecting to ssh host %s:%d' % (
         ssh_host,
         ssh_port,
     ))
     try:
         client.connect(hostname=ssh_host,
                        port=ssh_port,
                        username=user,
                        key_filename=key_filename,
                        password=password,
                        gss_auth=self._gss_auth)
     except Exception as e:
         log(
             OPERATIONAL, 'Failed to connect to %s@%s:%d: %r' % (
                 user,
                 ssh_host,
                 ssh_port,
                 e,
             ))
         return
     # Forward
     log(
         EVENT, 'Forwarding remote port %d+ to %s:%d' % (
             self._ssh_forward_port or self._DEFAULT_SSH_FORWARD_PORT,
             forward_host,
             forward_port,
         ))
     self._reverse_forward_tunnel(client.get_transport())
Ejemplo n.º 40
0
 def _reverse_forward_tunnel(self, transport):
     forward_host = self._forward_host
     forward_port = self._forward_port
     port = self._ssh_forward_port
     if not port:
         port = self._DEFAULT_SSH_FORWARD_PORT
     n_attempts = 1 if self._strict_forward_port else self._MAX_SSH_FORWARD_ATTEMPTS
     port_limit = port + n_attempts
     for p in range(port, port_limit):
         try:
             transport.request_port_forward('', p)
             break
         except paramiko.SSHException as e:
             log(EVENT, "Couldn't connect to port %s: %s" % (
                 p,
                 e,
             ))
     else:
         message = "No free port found in the range %s-%s" % (
             port,
             port_limit - 1,
         )
         log(OPERATIONAL, message)
         raise paramiko.SSHException(message)
     if self._actual_ssh_forward_port is not None:
         self._actual_ssh_forward_port.set(p)
     log(
         EVENT, 'Remote port %d forwarded to %s:%d' % (
             p,
             forward_host,
             forward_port,
         ))
     while True:
         chan = transport.accept(1000)
         if chan is None:
             continue
         gevent.spawn(self._handler, chan, forward_host, forward_port)
Ejemplo n.º 41
0
 def _handler(self, chan, host, port):
     sock = socket.socket()
     try:
         sock.connect((host, port))
     except Exception as e:
         log(OPERATIONAL, 'Forwarding request to %s:%d failed: %r' % (host, port, e))
         return
     log(EVENT, 'Tunnel open %r -> %r -> %r' % (chan.origin_addr, chan.getpeername(),
                                               (host, port)))
     while True:
         r, w, x = select.select([sock, chan], [], [])
         if sock in r:
             data = sock.recv(1024)
             if len(data) == 0:
                 break
             chan.send(data)
         if chan in r:
             data = chan.recv(1024)
             if len(data) == 0:
                 break
             sock.send(data)
     chan.close()
     sock.close()
     log(EVENT, 'Tunnel closed from %r' % (chan.origin_addr,))
Ejemplo n.º 42
0
    def __init__(self, req):
        """Initialize the global wiking handler instance.
        
        The argument 'req' is the initial request which triggered the Handler
        creation, however the handler will normally exist much longer than for
        this single request and its method 'handle()' will be called to handle
        also other requests (including this one).  The constructor only needs
        the request instance to gather some global information to be able to
        initialize the configuration etc.
        
        """
        # Initialize the global configuration stored in 'wiking.cfg'.
        config_file = req.option("config_file")
        if config_file:
            # Read the configuration file first, so that the request options have a higher priority.
            wiking.cfg.user_config_file = config_file
        for option in wiking.cfg.options():
            name = option.name()
            value = req.option(name)
            if value and name != "config_file":
                if name in ("translation_path", "resource_path", "modules"):
                    separator = value.find(":") != -1 and ":" or ","
                    value = tuple([d.strip() for d in value.split(separator)])
                    if name == "translation_path":
                        value = tuple(wiking.cfg.translation_path) + value
                    elif name == "resource_path":
                        value += tuple(wiking.cfg.resource_path)
                elif isinstance(option, wiking.cfg.NumericOption):
                    if value.isdigit():
                        value = int(value)
                    else:
                        log(OPERATIONAL, "Invalid numeric value for '%s':" % name, value)
                        continue
                elif isinstance(option, wiking.cfg.BooleanOption):
                    if value.lower() in ("yes", "true", "on"):
                        value = True
                    elif value.lower() in ("no", "false", "off"):
                        value = False
                    else:
                        log(OPERATIONAL, "Invalid boolean value for '%s':" % name, value)
                        continue
                elif not isinstance(option, wiking.cfg.StringOption):
                    log(OPERATIONAL, "Unable to set '%s' through request options." % name)
                    continue
                setattr(wiking.cfg, name, value)
        # Apply default values which depend on the request.
        server_hostname = wiking.cfg.server_hostname
        if server_hostname is None:
            # TODO: The name returned by req.server_hostname() works for simple
            # cases where there are no server aliases, but we can not guarantee
            # that it is really unique.  Thus might be safer to raise an error
            # when req.primary_server_hostname() returns None and require
            # configuring server_hostname explicitly.
            server_hostname = req.primary_server_hostname() or req.server_hostname()
            wiking.cfg.server_hostname = server_hostname
        domain = server_hostname
        if domain.startswith("www."):
            domain = domain[4:]
        if wiking.cfg.webmaster_address is None:
            wiking.cfg.webmaster_address = "webmaster@" + domain
        if wiking.cfg.default_sender_address is None:
            wiking.cfg.default_sender_address = "wiking@" + domain
        if wiking.cfg.dbname is None:
            wiking.cfg.dbname = server_hostname
        if wiking.cfg.resolver is None:
            wiking.cfg.resolver = wiking.WikingResolver(wiking.cfg.modules)
        # Modify pytis configuration.
        import pytis.util
        import config

        config.dblisten = False
        config.log_exclude = [pytis.util.ACTION, pytis.util.EVENT, pytis.util.DEBUG]
        for option in ("dbname", "dbhost", "dbport", "dbuser", "dbpass", "dbsslm", "dbschemas"):
            setattr(config, option, getattr(wiking.cfg, option))
        config.dbconnections = wiking.cfg.connections
        config.dbconnection = config.option("dbconnection").default()
        config.resolver = wiking.cfg.resolver
        del config
        self._application = application = wiking.module.Application
        self._exporter = wiking.cfg.exporter(translations=wiking.cfg.translation_path)
        application.initialize(req)
        # Save the current handler instance for profiling purposes.
        Handler._instance = self
Ejemplo n.º 43
0
def top_level_exception(message=None):
    """Zpracuj aktuálně vyvolanou výjimku aplikace."""
    global _in_top_level_exception
    if _in_top_level_exception:
        return
    _in_top_level_exception = True
    einfo = sys.exc_info()
    if issubclass(einfo[0], SystemExit):
        sys.exit()
    tbstring = format_traceback()
    import cgitb
    try:
        tbstring = cgitb.text(einfo)
    except:
        import traceback
        tbstring = "\n".join(traceback.format_exception(*einfo))
    log(OPERATIONAL, 'Top-level exception caught', tbstring)
    text = pytis.form.run_dialog(pytis.form.BugReport, einfo, message=message)
    if text is None:
        sys.exit()
    elif text:
        to = config.bug_report_address
        if not to:
            pytis.form.run_dialog(
                pytis.form.Message,
                _("Destination address not known. The configuration option "
                  "`bug_report_address' must be set."))
        else:
            tb = einfo[2]
            while tb.tb_next is not None:
                tb = tb.tb_next
            filename = os.path.split(tb.tb_frame.f_code.co_filename)[-1]
            buginfo = "%s at %s line %d" % (einfo[0].__name__, filename,
                                            tb.tb_lineno)
            address = config.sender_address
            if not address:
                import commands
                status, domain = commands.getstatusoutput('hostname -f')
                username = config.dbconnection.user()
                if status:
                    address = username
                else:
                    address = '%s@%s' % (username, domain)
                while True:
                    address = pytis.form.run_dialog(
                        pytis.form.InputDialog,
                        prompt=_("Your e-mail address") + ': ',
                        value=address,
                        input_width=30,
                        message=(_('Set your address in form "%s" '
                                   'to avoid being '
                                   'asked next time.') %
                                 (_("User interface settings"), )))
                    if address is None or address and address.strip() != '':
                        break
            if address:
                import email.Header
                import email.Message
                import email.Utils
                import smtplib

                def header(value):
                    if isinstance(value, basestring):
                        try:
                            unicode(value, 'us-ascii')
                        except:
                            pass
                        else:
                            return value
                    return email.Header.Header(value, 'utf-8')

                msg = email.Message.Message()
                msg['From'] = header(address)
                msg['To'] = header(to)
                msg['Subject'] = header('%s: %s' %
                                        (config.bug_report_subject, buginfo))
                msg['Date'] = email.Utils.formatdate()
                msg.set_payload(text)
                try:
                    try:
                        server = smtplib.SMTP(config.smtp_server)
                        server.sendmail(address, to, msg.as_string())
                    finally:
                        try:
                            server.quit()
                        except:
                            pass
                except Exception as e:
                    pytis.form.run_dialog(
                        pytis.form.Error,
                        _("Failed sending error report:") + "\n" + unicode(e))
                else:
                    pytis.form.run_dialog(pytis.form.Message,
                                          _("Error report sent."))
    if config.debug_on_error:
        import pdb
        pdb.post_mortem(sys.exc_info()[2])
    _in_top_level_exception = False
Ejemplo n.º 44
0
    def __init__(self, bindings, ordering=None, distinct_on=(), arguments=None,
                 crypto_names=(), **kwargs):
        """Inicializuj tabulku s napojením do databáze.

        Argumenty:
        
          bindings -- sekvence instancí třídy 'DBBinding'
          ordering -- stejné jako v předkovi
          distinct_on -- sequence of column names to add as a DISTINCT TO part
            to SELECT commands
          arguments -- sequence of 'DBBinding' instances defining table
            arguments, when the table is actually a row returning function.
            Otherwise it must be 'None'.
          crypto_names -- sequence of additional crypto names (strings)
            required by the object but not defined in bindings
          kwargs -- k předání předkovi

        Sloupce datové tabulky se určí automaticky na základě 'bindings'.
        Jejich typy jsou určeny typy odpovídajících dat v databázi(přesné
        mapování závisí na potomcích třídy a není zde specifikováno).  Klíčovým
        sloupcem tabulky je první sloupec z 'bindings', který je klíčovým
        sloupcem v databázi.

        Žádné dva prvky 'bindings' by neměly mít shodné id, s výjimkou skrytých
        bindings, která mají jako id prázdný řetězec.
        
        """
        assert is_sequence(bindings), ('Invalid binding type', bindings)
        self._bindings = tuple(bindings)
        assert not filter(lambda b: not isinstance(b, DBBinding),
                          bindings), \
            ('Invalid binding type', bindings)
        assert arguments is None or is_sequence(arguments), ('Invalid binding type', arguments)
        if arguments is None:
            self._arguments = None
        else:
            self._arguments = tuple(arguments)
            assert not filter(lambda b: not isinstance(b, DBBinding),
                              arguments), \
                ('Invalid "argument" type', arguments)
        if __debug__:
            log(DEBUG, 'Database instance bindings:', self._bindings)
        columns, key = self._db_bindings_to_column_spec(self._bindings)
        if __debug__:
            log(DEBUG, 'Database instance columns:', columns)
        if __debug__:
            log(DEBUG, 'Database instance key:', key)
        self._distinct_on = distinct_on
        assert is_sequence(crypto_names), crypto_names
        if __debug__:
            assert all([isinstance(n, basestring) for n in crypto_names]), crypto_names
        crypto_names = list(crypto_names)
        for b in bindings:
            if isinstance(b, DBColumnBinding):
                n = b.crypto_name()
                if n is not None and n not in crypto_names:
                    crypto_names.append(n)
        self._crypto_names = crypto_names
        try:
            del kwargs['key']
        except:
            pass
        super(DBData, self).__init__(columns=columns, key=key, ordering=ordering, **kwargs)
Ejemplo n.º 45
0
 def _postgresql_query(self, connection, query, outside_transaction, _retry=True):
     result = None
     def transform_arg(arg):
         if isinstance(arg, Range.Range):
             lower = arg.lower()
             upper = arg.upper()
             test_value = upper if lower is None else lower
             if isinstance(test_value, (int, long, float,)):
                 c = psycopg2.extras.NumericRange
             elif isinstance(test_value, datetime.datetime):
                 if test_value.tzinfo is None:
                     c = psycopg2.extras.DateTimeRange
                 else:
                     c = psycopg2.extras.DateTimeTZRange
             elif isinstance(test_value, datetime.date):
                 c = psycopg2.extras.DateRange
             else:
                 raise Exception("Unsupported range type", arg)
             bounds = ('[' if arg.lower_inc() else '(') + (']' if arg.upper_inc() else ')')
             arg = c(lower, upper, bounds=bounds)
         return arg
     if isinstance(query, basestring):
         query_args = {}
     else:
         query, args = query.query()
         query_args = dict([(k, transform_arg(v)) for k, v in args.items()])
     def do_query(connection, query):
         raw_connection = connection.connection()
         standard_strings = connection.connection_info('standard_strings')
         if not standard_strings:
             query = query.replace('\\', '\\\\')
         cursor = raw_connection.cursor()
         callback = self._query_callback[0]
         # The hasattr test is a hack enforced by the fact that constructor
         # calls of pytis.data classes are in very strange state now.
         if hasattr(self, '_sql_logger') and self._sql_logger is not None:
             if query_args:
                 def escape(arg):
                     if isinstance(arg, basestring):
                         result = "'%s'" % (arg.replace('\x00', '\\0').replace("'", "''"),)
                         if not standard_strings:
                             result = result.replace('\\', '\\\\')
                     elif isinstance(arg, buffer):
                         result = '<binary_data>'
                     else:
                         result = arg
                     return result
                 escaped_args = dict([(k, escape(v)) for k, v in query_args.items()])
                 query_string = query % escaped_args
             else:
                 query_string = query
             self._sql_logger.write(query_string + '\n')
         if callback is not None:
             start_time = time.time()
         # query_args shouldn't be used when empty to prevent mistaken
         # '%' processing in `query'
         try:
             if query_args:
                 cursor.execute(query, query_args)
             else:
                 cursor.execute(query)
             connection.connection_info('transaction_commands').append(query)
         finally:
             if outside_transaction:
                 raw_connection.commit()
                 self._postgresql_reset_connection_info(connection, ['commit'])
         if callback is not None:
             callback(query, start_time, time.time())
         return cursor
     def retry(message, exception):
         connection.set_connection_info('broken', True)
         if _retry:
             if not outside_transaction:
                 raise DBRetryException(message, exception, exception.args, query)
             cdata = connection.connection_data()
             search_path = connection.connection_info('search_path')
             new_connection = self._postgresql_new_connection(cdata)
             try:
                 if search_path:
                     do_query(new_connection, 'set search_path to ' + search_path)
                 result = do_query(new_connection, query)
             except Exception as e:
                 raise DBSystemException(message, e, e.args, query)
         else:
             raise DBSystemException(message, exception, exception.args, query)
         return result, new_connection
     try:
         result = do_query(connection, query)
         if query == 'commit':
             self._postgresql_commit_transaction(connection)
         elif query == 'rollback':
             self._postgresql_rollback_transaction(connection)
     except dbapi.InterfaceError as e:
         if e.args and e.args[0].find('connection already closed') != -1:
             # We believe this shouldn't happen as a program error and it
             # may occur as a result of database engine connection crash.
             log(OPERATIONAL, "Access to closed database connection")
             result, connection = retry(_(u"Database interface error"), e)
         else:
             raise DBUserException(None, e, e.args, query)
     except dbapi.NotSupportedError as e:
         if e.args and e.args[0].find('cannot perform INSERT RETURNING') != -1:
             # This is handled once again below since older dbapi versions report it as
             # ProgrammingError and newer versions as NotSupportedError.
             raise DBInsertException()
         raise DBUserException(None, e, e.args, query)
     except dbapi.ProgrammingError as e:
         if e.args:
             position = e.args[0].find
             if position('could not obtain lock') != -1:
                 raise DBLockException()
             elif position('cannot perform INSERT RETURNING') != -1:
                 raise DBInsertException()
             elif (position('error: Connection timed out') != -1 or
                   position('timeout expired') != -1):
                 
                 raise DBSystemException(_(u"Database connection timeout"), e, e.args, query)
             elif position('server closed the connection unexpectedly') != -1:
                 result, connection = retry(_(u"Database connection error"), e)
             else:
                 log(OPERATIONAL, "Transaction commands:",
                     connection.connection_info('transaction_commands'))
                 data = '%s [search_path=%s]' % (query,
                                                 connection.connection_info('search_path'),)
                 raise DBUserException(None, e, e.args, data)
         else:
             raise DBUserException(None, e, e.args, query)
     except dbapi.DataError as e:
         raise DBUserException(None, e, e.args, query)
     except dbapi.OperationalError as e:
         if e.args and e.args[0].find('could not obtain lock') != -1:
             raise DBLockException()
         result, connection = retry(_(u"Database operational error"), e)
     except dbapi.InternalError as e:
         raise DBException(None, e, query)
     except dbapi.IntegrityError as e:
         raise DBUserException(_(u"Database integrity violation"),
                               e, e.args, query)
     now = time.time()
     connection.set_connection_info('last_query_time', now)
     connection.set_connection_info('last_activity', now)
     if connection.connection_info('transaction_start_time') is None:
         connection.set_connection_info('transaction_start_time', now)
         if __debug__:
             if query not in ('commit', 'rollback',):
                 connection.set_connection_info('transaction_start_stack',
                                                inspect.currentframe())
     if __debug__:
         if query.startswith('fetch') or query.startswith('skip'):
             extra_info = (query,)
         else:
             self._last_informative_query = query
             extra_info = ()
         info = (time.ctime(now), self._last_informative_query,) + extra_info
         connection.set_connection_info('last_access', info)
     return self._postgresql_Result(result), connection
Ejemplo n.º 46
0
 def select_row(self, *args, **kwargs):
     if hasattr(self._main_form, 'select_row'):
         return self._main_form.select_row(*args, **kwargs)
     else:
         log(EVENT, "Main form doesn't support `select_row()'!")
Ejemplo n.º 47
0
 def _panic(self):
     if __debug__:
         log(DEBUG, 'Zpanikaření gridové tabulky')
Ejemplo n.º 48
0
Archivo: event.py Proyecto: cerha/pytis
 def process_event(event, callback=callback):
     def system_callback():
         # Při zamykání atd. se využívá toho, že v existují jen dvě vlákna
         # zpracovávající události a že v rámci jednoho vlákna dochází pouze
         # k sekvenčnímu nebo cibulovitému řazení událostí.
         STATE_CURRENT = 'STATE_CURRENT'
         STATE_FREE = 'STATE_FREE'
         STATE_BLOCKED = 'STATE_BLOCKED'
         global _system_callback_thread_ident, _system_callback_lock
         _system_callback_access_lock.acquire()
         try:
             ident = _thread.get_ident()
             if _system_callback_thread_ident == ident:
                 # Jsme uvnitř vlastní slupky, jsme v pohodě
                 state = STATE_CURRENT
             elif (_system_callback_thread_ident is None and
                   _system_callback_lock is None):
                 # Nikdo jiný nemá zájem, uzmeme to
                 _system_callback_thread_ident = ident
                 state = STATE_FREE
             else:
                 # Máme konkurenci -- vytvoříme si synchronizační zámek pro
                 # oznámení uvolnění cesty
                 _system_callback_lock = lock = _thread.allocate_lock()
                 _system_callback_lock.acquire()
                 state = STATE_BLOCKED
         finally:
             _system_callback_access_lock.release()
         if state == STATE_BLOCKED:
             # Čekáme na uvolnění cesty
             lock.acquire()
             lock.release()
             _system_callback_access_lock.acquire()
             try:
                 # Ještě stále je to náš synchronizační zámek?  Uvolni jej!
                 if _system_callback_lock is lock:
                     _system_callback_lock = None
                 # Teď jsme na koni my
                 _system_callback_thread_ident = ident
                 state = STATE_FREE
             finally:
                 _system_callback_access_lock.release()
         try:
             # To hlavní...
             result = callback(event)
         finally:
             _system_callback_access_lock.acquire()
             try:
                 # Jako první usurpátoři musíme uvolnit informace o své
                 # cibuli ...
                 if state == STATE_FREE:
                     _system_callback_thread_ident = None
                     if _system_callback_lock is not None:
                         while True:
                             try:
                                 # ... a poslat signál případnému čekateli
                                 _system_callback_lock.release()
                                 break
                             except _thread.error:
                                 # To je případ, kdy čekatel ještě nestačil
                                 # na svůj zámek zavolat acquire
                                 pass
             finally:
                 _system_callback_access_lock.release()
         return result
     if isinstance(event, wx.IdleEvent) and idle_blocked():
         return
     global _current_event, _interrupted, _last_user_event, _last_user_event_time
     is_user = _is_user_event(event)
     if is_user:
         pytis.form.message('')
     if not isinstance(event, (wx.IdleEvent, wx.UpdateUIEvent)):
         if __debug__:
             log(DEBUG, 'Processing event:', (event, event.__class__))
     try:
         if _thread.get_ident() == _watcher_thread_ident or _current_event:
             # Událost během události
             if _wx_key and _wx_key.is_event_of_key(event, 'Ctrl-g'):  # TODO: ne natvr.
                 _interrupted = True
                 result = True
             elif is_user:
                 result = True
             else:
                 result = system_callback()
         elif is_user and pytis.form.modal(pytis.form.top_window()):
             # Událost vyvolaná uživatelským příkazem v modálním okně
             result = callback(event)
         elif is_user:
             # Událost vyvolaná uživatelským příkazem
             _interrupted = False
             _current_event = event
             try:
                 result = callback(event)
             finally:
                 _interrupted = False  # událost končí -> nebude co přerušit
                 _current_event = None
                 _last_user_event = event
         else:
             # Standardní "systémová" událost
             result = system_callback()
     except SystemExit:
         raise
     except Exception:
         top_level_exception()
         return
     finally:
         if is_user:
             _last_user_event_time = time.time()
     return result
Ejemplo n.º 49
0
    def __init__(self,
                 bindings,
                 ordering=None,
                 distinct_on=(),
                 arguments=None,
                 crypto_names=(),
                 **kwargs):
        """Inicializuj tabulku s napojením do databáze.

        Argumenty:

          bindings -- sekvence instancí třídy 'DBBinding'
          ordering -- stejné jako v předkovi
          distinct_on -- sequence of column names to add as a DISTINCT TO part
            to SELECT commands
          arguments -- sequence of 'DBBinding' instances defining table
            arguments, when the table is actually a row returning function.
            Otherwise it must be 'None'.
          crypto_names -- sequence of additional crypto names (strings)
            required by the object but not defined in bindings
          kwargs -- k předání předkovi

        Sloupce datové tabulky se určí automaticky na základě 'bindings'.
        Jejich typy jsou určeny typy odpovídajících dat v databázi(přesné
        mapování závisí na potomcích třídy a není zde specifikováno).  Klíčovým
        sloupcem tabulky je první sloupec z 'bindings', který je klíčovým
        sloupcem v databázi.

        Žádné dva prvky 'bindings' by neměly mít shodné id, s výjimkou skrytých
        bindings, která mají jako id prázdný řetězec.

        """
        assert all(isinstance(b, DBBinding) for b in bindings), bindings
        assert arguments is None or all(
            isinstance(b, DBBinding) for b in arguments), arguments
        assert all([isinstance(n, basestring)
                    for n in crypto_names]), crypto_names
        self._bindings = tuple(bindings)
        if arguments is None:
            self._arguments = None
        else:
            self._arguments = tuple(arguments)
        if __debug__:
            log(DEBUG, 'Database instance bindings:', self._bindings)
        columns, key = self._db_bindings_to_column_spec(self._bindings)
        if __debug__:
            log(DEBUG, 'Database instance columns:', columns)
        if __debug__:
            log(DEBUG, 'Database instance key:', key)
        self._distinct_on = distinct_on
        self._crypto_names = list(
            set(crypto_names).union(b.crypto_name() for b in bindings
                                    if isinstance(b, DBColumnBinding)
                                    and b.crypto_name() is not None))
        try:
            del kwargs['key']
        except Exception:
            pass
        super(DBData, self).__init__(columns=columns,
                                     key=key,
                                     ordering=ordering,
                                     **kwargs)
Ejemplo n.º 50
0
    def __init__(self, req):
        """Initialize the global wiking handler instance.

        The argument 'req' is the initial request which triggered the Handler
        creation, however the handler will normally exist much longer than for
        this single request and its method 'handle()' will be called to handle
        also other requests (including this one).  The constructor only needs
        the request instance to gather some global information to be able to
        initialize the configuration etc.

        """
        # Initialize the global configuration stored in 'wiking.cfg'.
        config_file = req.option('config_file')
        if config_file:
            # Read the configuration file first, so that the request options have a higher priority.
            wiking.cfg.user_config_file = config_file
        for option in wiking.cfg.options():
            name = option.name()
            value = req.option(name)
            if value and name != 'config_file':
                if name in ('translation_path', 'resource_path', 'modules'):
                    separator = value.find(':') != -1 and ':' or ','
                    value = tuple([d.strip() for d in value.split(separator)])
                    if name == 'translation_path':
                        value = tuple(wiking.cfg.translation_path) + value
                    elif name == 'resource_path':
                        value += tuple(wiking.cfg.resource_path)
                elif isinstance(option, wiking.cfg.NumericOption):
                    if value.isdigit():
                        value = int(value)
                    else:
                        log(OPERATIONAL, "Invalid numeric value for '%s':" % name, value)
                        continue
                elif isinstance(option, wiking.cfg.BooleanOption):
                    if value.lower() in ('yes', 'true', 'on'):
                        value = True
                    elif value.lower() in ('no', 'false', 'off'):
                        value = False
                    else:
                        log(OPERATIONAL, "Invalid boolean value for '%s':" % name, value)
                        continue
                elif not isinstance(option, wiking.cfg.StringOption):
                    log(OPERATIONAL, "Unable to set '%s' through request options." % name)
                    continue
                setattr(wiking.cfg, name, value)
        # Apply default values which depend on the request.
        server_hostname = wiking.cfg.server_hostname
        if server_hostname is None:
            # TODO: The name returned by req.server_hostname() works for simple
            # cases where there are no server aliases, but we can not guarantee
            # that it is really unique.  Thus might be safer to raise an error
            # when req.primary_server_hostname() returns None and require
            # configuring server_hostname explicitly.
            server_hostname = req.primary_server_hostname() or req.server_hostname()
            wiking.cfg.server_hostname = server_hostname
        domain = server_hostname
        if domain.startswith('www.'):
            domain = domain[4:]
        if wiking.cfg.webmaster_address is None:
            wiking.cfg.webmaster_address = 'webmaster@' + domain
        if wiking.cfg.default_sender_address is None:
            wiking.cfg.default_sender_address = 'wiking@' + domain
        if wiking.cfg.dbname is None:
            wiking.cfg.dbname = server_hostname
        if wiking.cfg.resolver is None:
            wiking.cfg.resolver = wiking.WikingResolver(wiking.cfg.modules)
        # Modify pytis configuration.
        pytis.config.dblisten = False
        pytis.config.log_exclude = [pytis.util.ACTION, pytis.util.EVENT, pytis.util.DEBUG]
        for option in ('dbname', 'dbhost', 'dbport', 'dbuser', 'dbpass', 'dbsslm', 'dbschemas',):
            setattr(pytis.config, option, getattr(wiking.cfg, option))
        pytis.config.dbconnections = wiking.cfg.dbconnections
        pytis.config.dbconnection = pytis.config.option('dbconnection').default()
        pytis.config.resolver = wiking.cfg.resolver
        self._application = application = wiking.module.Application
        self._exporter = wiking.cfg.exporter(translations=wiking.cfg.translation_path)
        application.initialize(req)
        # Save the current handler instance for profiling purposes.
        Handler._instance = self
Ejemplo n.º 51
0
    def _postgresql_query(self,
                          connection,
                          query,
                          outside_transaction,
                          _retry=True):
        result = None

        def transform_arg(arg):
            if isinstance(arg, Range.Range):
                lower = arg.lower()
                upper = arg.upper()
                test_value = upper if lower is None else lower
                if isinstance(test_value, (
                        int,
                        long,
                        float,
                )):
                    c = psycopg2.extras.NumericRange
                elif isinstance(test_value, datetime.datetime):
                    if test_value.tzinfo is None:
                        c = psycopg2.extras.DateTimeRange
                    else:
                        c = psycopg2.extras.DateTimeTZRange
                elif isinstance(test_value, datetime.date):
                    c = psycopg2.extras.DateRange
                else:
                    raise Exception("Unsupported range type", arg)
                bounds = ('[' if arg.lower_inc() else
                          '(') + (']' if arg.upper_inc() else ')')
                arg = c(lower, upper, bounds=bounds)
            return arg

        if isinstance(query, basestring):
            query_args = {}
        else:
            query, args = query.query()
            query_args = dict([(k, transform_arg(v)) for k, v in args.items()])

        def do_query(connection, query):
            raw_connection = connection.connection()
            standard_strings = connection.connection_info('standard_strings')
            if not standard_strings:
                query = query.replace('\\', '\\\\')
            cursor = raw_connection.cursor()
            callback = self._query_callback[0]
            # The hasattr test is a hack enforced by the fact that constructor
            # calls of pytis.data classes are in very strange state now.
            if hasattr(self, '_sql_logger') and self._sql_logger is not None:
                if query_args:

                    def escape(arg):
                        if isinstance(arg, basestring):
                            result = "'%s'" % (arg.replace(
                                '\x00', '\\0').replace("'", "''"), )
                            if not standard_strings:
                                result = result.replace('\\', '\\\\')
                        elif isinstance(arg, buffer):
                            result = '<binary_data>'
                        else:
                            result = arg
                        return result

                    escaped_args = dict([(k, escape(v))
                                         for k, v in query_args.items()])
                    query_string = query % escaped_args
                else:
                    query_string = query
                self._sql_logger.write(query_string + '\n')
            if callback is not None:
                start_time = time.time()
            # query_args shouldn't be used when empty to prevent mistaken
            # '%' processing in `query'
            try:
                if query_args:
                    cursor.execute(query, query_args)
                else:
                    cursor.execute(query)
                connection.connection_info('transaction_commands').append(
                    query)
            finally:
                if outside_transaction:
                    raw_connection.commit()
                    self._postgresql_reset_connection_info(
                        connection, ['commit'])
            if callback is not None:
                callback(query, start_time, time.time())
            return cursor

        def retry(message, exception):
            connection.set_connection_info('broken', True)
            if _retry:
                if not outside_transaction:
                    raise DBRetryException(message, exception, exception.args,
                                           query)
                cdata = connection.connection_data()
                search_path = connection.connection_info('search_path')
                new_connection = self._postgresql_new_connection(cdata)
                try:
                    if search_path:
                        do_query(new_connection,
                                 'set search_path to ' + search_path)
                    result = do_query(new_connection, query)
                except Exception as e:
                    raise DBSystemException(message, e, e.args, query)
            else:
                raise DBSystemException(message, exception, exception.args,
                                        query)
            return result, new_connection

        try:
            result = do_query(connection, query)
            if query == 'commit':
                self._postgresql_commit_transaction(connection)
            elif query == 'rollback':
                self._postgresql_rollback_transaction(connection)
        except dbapi.InterfaceError as e:
            if e.args and e.args[0].find('connection already closed') != -1:
                # We believe this shouldn't happen as a program error and it
                # may occur as a result of database engine connection crash.
                log(OPERATIONAL, "Access to closed database connection")
                result, connection = retry(_(u"Database interface error"), e)
            else:
                raise DBUserException(None, e, e.args, query)
        except dbapi.NotSupportedError as e:
            if e.args and e.args[0].find(
                    'cannot perform INSERT RETURNING') != -1:
                # This is handled once again below since older dbapi versions report it as
                # ProgrammingError and newer versions as NotSupportedError.
                raise DBInsertException()
            raise DBUserException(None, e, e.args, query)
        except dbapi.ProgrammingError as e:
            if e.args:
                position = e.args[0].find
                if position('could not obtain lock') != -1:
                    raise DBLockException()
                elif position('cannot perform INSERT RETURNING') != -1:
                    raise DBInsertException()
                elif (position('error: Connection timed out') != -1
                      or position('timeout expired') != -1):

                    raise DBSystemException(_(u"Database connection timeout"),
                                            e, e.args, query)
                elif position(
                        'server closed the connection unexpectedly') != -1:
                    result, connection = retry(_(u"Database connection error"),
                                               e)
                else:
                    log(OPERATIONAL, "Transaction commands:",
                        connection.connection_info('transaction_commands'))
                    data = '%s [search_path=%s]' % (
                        query,
                        connection.connection_info('search_path'),
                    )
                    raise DBUserException(None, e, e.args, data)
            else:
                raise DBUserException(None, e, e.args, query)
        except dbapi.DataError as e:
            raise DBUserException(None, e, e.args, query)
        except dbapi.OperationalError as e:
            if e.args and e.args[0].find('could not obtain lock') != -1:
                raise DBLockException()
            result, connection = retry(_(u"Database operational error"), e)
        except dbapi.InternalError as e:
            raise DBException(None, e, query)
        except dbapi.IntegrityError as e:
            raise DBUserException(_(u"Database integrity violation"), e,
                                  e.args, query)
        now = time.time()
        connection.set_connection_info('last_query_time', now)
        connection.set_connection_info('last_activity', now)
        if connection.connection_info('transaction_start_time') is None:
            connection.set_connection_info('transaction_start_time', now)
            if __debug__:
                if query not in (
                        'commit',
                        'rollback',
                ):
                    connection.set_connection_info('transaction_start_stack',
                                                   inspect.currentframe())
        if __debug__:
            if query.startswith('fetch') or query.startswith('skip'):
                extra_info = (query, )
            else:
                self._last_informative_query = query
                extra_info = ()
            info = (
                time.ctime(now),
                self._last_informative_query,
            ) + extra_info
            connection.set_connection_info('last_access', info)
        return self._postgresql_Result(result), connection
Ejemplo n.º 52
0
        def _notif_listen_loop(self):
            while True:
                while self._pgnotif_connection is None:
                    time.sleep(10)
                    try:
                        self._notif_init_connection()
                        for notification in self._registered_notifications:
                            self._notif_do_registration(notification)
                    except Exception as e:
                        self._pgnotif_connection = None
                connection_ = self._pgnotif_connection
                connection = connection_.connection()
                if __debug__:
                    log(DEBUG, 'Listening for notifications:', connection)

                def lfunction():
                    cursor = connection.cursor()
                    try:
                        fileno = connection.fileno()
                    except AttributeError:  # older psycogp2 versions
                        fileno = cursor.fileno()
                    return cursor, fileno

                cursor, fileno = with_lock(self._pg_query_lock, lfunction)
                try:
                    select.select([fileno], [], [], None)
                except Exception as e:
                    if __debug__:
                        log(DEBUG, 'Socket error', e.args)
                    break
                if __debug__:
                    log(DEBUG, 'Input received')

                def lfunction():
                    notifications = []
                    try:
                        connection.poll()
                        ready = True
                    except AttributeError:  # older psycopg2 versions
                        try:
                            ready = cursor.isready()
                        except dbapi.OperationalError:
                            self._pg_notif_connection = None
                            return notifications
                    if ready:
                        notifies = connection.notifies
                        if notifies:
                            if __debug__:
                                log(DEBUG, 'Data change registered')
                            notifications = []
                            while notifies:
                                notifications.append(notifies.pop()[1])
                    return notifications

                notifications = with_locks((
                    self._notif_connection_lock,
                    self._pg_query_lock,
                ), lfunction)
                if __debug__:
                    log(DEBUG, 'Notifications received:', notifications)
                self._notif_invoke_callbacks(notifications)
Ejemplo n.º 53
0
 def IsAcceptedKey(self, event):
     # TODO/wx: Z neznámých důvodů není voláno.
     if __debug__:
         log(DEBUG, 'Neuvěřitelné -- voláno IsAcceptedKey')
     return False
Ejemplo n.º 54
0
 def apply_profile(self, *args, **kwargs):
     if hasattr(self._main_form, 'apply_profile'):
         return self._main_form.apply_profile(*args, **kwargs)
     else:
         log(EVENT, "Main form doesn't support `apply_profile()'!")