def __init__(self):
        super().__init__()

        dial = ConnectDialog(self)
        dial.exec()

        # tmp!!!!! TODO:
        try:
            self.channel = Channel('192.168.1.11',
                                   8000 + int(dial.port_field.text()), '69420')
        except ValueError as _:
            self.channel = Channel('192.168.1.11', 8000, '69420')

        # self.channel = Channel(dial.host_field.text(), dial.port_field.text(), dial.password_field.text())

        self.move_buttons = dict()
        self.light_buttons = dict()
        self.distance_label = None
        self.speed_label = None
        self.line_label = None

        self.place_move_buttons()
        self.place_light_buttons()
        self.place_labels()

        self.widget_update_signal.connect(self.update_widgets)
        self.lock = Lock()
        self.update_active = True

        Thread(target=self.supervise_update).start()
Exemple #2
0
    def connection_dialog(self):
        if self._connection_dialog is None:
            self._connection_dialog = ConnectDialog(self)
            self._connection_dialog.set_known_connections(
                self.known_session_params)

        return self._connection_dialog
Exemple #3
0
 def action_connect(self):
     if not self.client.is_connected:
         confirm = ConnectDialog(self.client)
         confirm.exec_()
         self.prompt_login()
Exemple #4
0
class PostgresMainWindow(PlugableMainWindow):
    '''
    A main window with functions to connect to postgres
    '''
    _central_widget = None
    _preferences_dialog = None
    _connection_dialog = None

    CONN_CLASS = OpenmolarDatabase

    #: True if more than one pg session is allowed (False for client)
    ALLOW_MULTIPLE_SESSIONS = True

    def __init__(self, parent=None):
        PlugableMainWindow.__init__(self, parent)
        self.setMinimumSize(600, 400)

        self.setWindowTitle(_("Postgres Application"))

        ## Main Menu

        ## "file"

        icon = QtGui.QIcon(":icons/postgresql_elephant.svg")
        self.action_connect = QtGui.QAction(icon, _("Begin Session"), self)
        self.action_connect.setToolTip(_("Start a PostgreSQL session"))

        icon = QtGui.QIcon(":icons/no_postgresql_elephant.svg")
        self.action_disconnect = QtGui.QAction(icon, _("End Session(s)"), self)
        self.action_disconnect.setToolTip(_("End all PostgreSQL sessions"))

        insertpoint = self.action_quit
        self.menu_file.insertAction(insertpoint, self.action_connect)
        self.menu_file.insertAction(insertpoint, self.action_disconnect)
        self.menu_file.insertSeparator(insertpoint)

        #:
        self.main_toolbar.insertAction(insertpoint, self.action_connect)
        self.main_toolbar.insertAction(insertpoint, self.action_disconnect)
        #self.addToolBar(self.session_toolbar)

        ####       now load stored settings                                ####
        self.loadSettings()

        self.action_connect.triggered.connect(self.new_pg_session)
        self.action_disconnect.triggered.connect(self.end_pg_sessions)

        QtCore.QTimer.singleShot(100, self.setBriefMessageLocation)

        self.session_widgets = []

        self.setCentralWidget(self.central_widget)

        self.update_session_status()

    @property
    def central_widget(self):
        '''
        should be Overwritten
        the central widget should have functions frequently associated with
        a tab widget.
        namely addTab etc..
        '''
        if self._central_widget is None:
            LOGGER.debug("PostgresMainWindow.. creating central widget")
            self._central_widget = QtGui.QTabWidget()
            self._central_widget.add = self._central_widget.addTab
            self._central_widget.remove = self._central_widget.removeTab
        return self._central_widget

    @property
    def new_session_widget(self):
        '''
        return a widget (of type :doc:`PostgresSessionWidget` )
        single-session widgets should return the existing session widget.
        multi-session clients should return a new widget
        (and keep a reference to it)
        '''
        return PostgresSessionWidget()

    def add_session(self, session):
        '''
        get self.new_session_widget give it the session and to the ui.

        .. note::
            returns whatever self.new_session_widget created so that calling
            functions have a reference to it.

        '''
        widg = self.new_session_widget
        widg.set_session(session)
        self.session_widgets.append(widg)
        self.central_widget.add(widg, widg.pg_session.description)
        return widg

    @property
    def known_session_params(self):
        '''
        parse the allowed locations for connections.
        returns a list of :doc:`ConnectionData`
        '''
        def parse_conf(filepath):
            try:
                LOGGER.debug("checking %s for config" % filepath)

                conn_data = ConnectionData()
                conn_data.get_password = self.get_password
                conn_data.from_conf_file(filepath)

                LOGGER.info("loaded connection %s" % conn_data)
                known_session_params.append(conn_data)

            except Exception as exc:
                LOGGER.exception("error loading %s" % filepath)
                message = "%s '%s'<pre>%s</pre>" % (_("Bad Config file"),
                                                    filepath, exc.message)
                self.advise(message, 2)

        known_session_params = []
        for conf_dir in SETTINGS.CONNECTION_CONFDIRS:
            LOGGER.debug("checking %s for connection config files" % conf_dir)
            for root, dir_, files in os.walk(conf_dir):
                for file_ in sorted(files):
                    parse_conf(os.path.join(root, file_))

        LOGGER.info("%s connections found" % len(known_session_params))

        return known_session_params

    def get_password(self, conn_data):
        '''
        raise a dialog to get a password
        '''
        password, result = QtGui.QInputDialog.getText(
            self, _("password required"), u"%s '%s'" %
            (_("Please enter the postgres login password for user"),
             conn_data.user), QtGui.QLineEdit.Password)
        if not result:
            LOGGER.WARNING("password dialog cancelled by user")
        return unicode(password)

    @property
    def connection_dialog(self):
        if self._connection_dialog is None:
            self._connection_dialog = ConnectDialog(self)
            self._connection_dialog.set_known_connections(
                self.known_session_params)

        return self._connection_dialog

    def new_pg_session(self):
        '''
        connect a new postgres session
        '''
        if self.ALLOW_MULTIPLE_SESSIONS or not self.has_pg_connection:
            LOGGER.debug("%s.new_pg_session" % __file__)
            dl = self.connection_dialog
            while True:
                if not dl.exec_():
                    return
                if not self.ALLOW_MULTIPLE_SESSIONS:
                    self.end_pg_sessions()
                conn_data = dl.chosen_connection

                session = self.CONN_CLASS(conn_data)
                try:
                    if self._attempt_connection(session):
                        self.add_session(session)
                except session.SchemaVersionError as error:
                    self.handle_schema_version_error(session, error)
                    LOGGER.exception("Schema Version Error")
                finally:
                    break
        self.update_session_status()

    def handle_schema_version_error(self, session, error):
        '''
        If, on connection to a database, the schema version is found to be
        unsupported by the application, this function is called.
        '''
        self.advise(
            u"%s<hr /><pre>%s</pre>" % (_("Schema is out of date"), error), 2)

    def _attempt_connection(self, session):
        '''
        attempt to open session (ie call :doc:`OpenmolarDatabase` .connect() )
        '''
        LOGGER.info(
            u"%s '%s'" %
            (_("Attempting connection using data"), session.connection_data))

        try:
            session.connect()
            self.connect(QtGui.QApplication.instance(),
                         QtCore.SIGNAL("Query Error"), self.advise_dl)
            return True
        except ConnectionError as error:
            self.advise(
                u"%s<hr /><pre>%s</pre>" % (_("Connection Error"), error), 2)
            LOGGER.exception("Connection Error")

        return False

    def end_pg_sessions(self):
        '''
        disconnect from postgres server
        (if not connected - pass quietly).
        '''
        for widg in self.session_widgets:
            i = self.central_widget.indexOf(widg)
            if widg.is_connected:
                widg.pg_session.close()
                LOGGER.info("DISCONNECTED session %s" % widg.pg_session)
            if i != -1:
                #widg has already been removed?
                self.central_widget.removeTab(i)
        self.session_widgets = []
        self.update_session_status()

    def update_session_status(self):
        '''
        toggles the connect buttons/menu actions,
        updates the sessions displayed.
        '''
        for session_widg in self.session_widgets:
            session_widg.update_status()
        self.action_connect.setEnabled(self.ALLOW_MULTIPLE_SESSIONS
                                       or not self.has_pg_connection)
        self.action_disconnect.setEnabled(self.session_widgets != [])

    @property
    def has_pg_connection(self):
        '''
        returns a bool which states if an active connection exists.
        '''
        return self.session_widgets != []

    def get_user_pass(self, dbname):
        '''
        return a tuple of (result, user, password)
        '''
        LOGGER.debug("%s.get_user_pass %s" % (__file__, dbname))
        dl = UserPasswordDialog(self)
        return dl.exec_(), dl.name, dl.password

    def closeEvent(self, event=None):
        '''
        re-implement the close event of QtGui.QMainWindow, and check the user
        really meant to do this.
        '''
        self.saveSettings()
        self.end_pg_sessions()

    def preferences_dialog(self):
        if self._preferences_dialog is None:
            dl = PlugableMainWindow.preferences_dialog(self)

            connections_pref = Preference(_("Database Connections"))

            m_d_widg = ManageDatabasesWidget(self)
            m_d_widg.set_connections(self.known_session_params)
            connections_pref.setWidget(m_d_widg)
            dl.insert_preference_dialog(0, connections_pref)

            self._preferences_dialog = dl

        return self._preferences_dialog
class PostgresMainWindow(PlugableMainWindow):
    """
    A main window with functions to connect to postgres
    """

    _central_widget = None
    _preferences_dialog = None
    _connection_dialog = None

    CONN_CLASS = OpenmolarDatabase

    #: True if more than one pg session is allowed (False for client)
    ALLOW_MULTIPLE_SESSIONS = True

    def __init__(self, parent=None):
        PlugableMainWindow.__init__(self, parent)
        self.setMinimumSize(600, 400)

        self.setWindowTitle(_("Postgres Application"))

        ## Main Menu

        ## "file"

        icon = QtGui.QIcon(":icons/postgresql_elephant.svg")
        self.action_connect = QtGui.QAction(icon, _("Begin Session"), self)
        self.action_connect.setToolTip(_("Start a PostgreSQL session"))

        icon = QtGui.QIcon(":icons/no_postgresql_elephant.svg")
        self.action_disconnect = QtGui.QAction(icon, _("End Session(s)"), self)
        self.action_disconnect.setToolTip(_("End all PostgreSQL sessions"))

        insertpoint = self.action_quit
        self.menu_file.insertAction(insertpoint, self.action_connect)
        self.menu_file.insertAction(insertpoint, self.action_disconnect)
        self.menu_file.insertSeparator(insertpoint)

        #:
        self.main_toolbar.insertAction(insertpoint, self.action_connect)
        self.main_toolbar.insertAction(insertpoint, self.action_disconnect)
        # self.addToolBar(self.session_toolbar)

        ####       now load stored settings                                ####
        self.loadSettings()

        self.action_connect.triggered.connect(self.new_pg_session)
        self.action_disconnect.triggered.connect(self.end_pg_sessions)

        QtCore.QTimer.singleShot(100, self.setBriefMessageLocation)

        self.session_widgets = []

        self.setCentralWidget(self.central_widget)

        self.update_session_status()

    @property
    def central_widget(self):
        """
        should be Overwritten
        the central widget should have functions frequently associated with
        a tab widget.
        namely addTab etc..
        """
        if self._central_widget is None:
            LOGGER.debug("PostgresMainWindow.. creating central widget")
            self._central_widget = QtGui.QTabWidget()
            self._central_widget.add = self._central_widget.addTab
            self._central_widget.remove = self._central_widget.removeTab
        return self._central_widget

    @property
    def new_session_widget(self):
        """
        return a widget (of type :doc:`PostgresSessionWidget` )
        single-session widgets should return the existing session widget.
        multi-session clients should return a new widget
        (and keep a reference to it)
        """
        return PostgresSessionWidget()

    def add_session(self, session):
        """
        get self.new_session_widget give it the session and to the ui.

        .. note::
            returns whatever self.new_session_widget created so that calling
            functions have a reference to it.

        """
        widg = self.new_session_widget
        widg.set_session(session)
        self.session_widgets.append(widg)
        self.central_widget.add(widg, widg.pg_session.description)
        return widg

    @property
    def known_session_params(self):
        """
        parse the allowed locations for connections.
        returns a list of :doc:`ConnectionData`
        """

        def parse_conf(filepath):
            try:
                LOGGER.debug("checking %s for config" % filepath)

                conn_data = ConnectionData()
                conn_data.get_password = self.get_password
                conn_data.from_conf_file(filepath)

                LOGGER.info("loaded connection %s" % conn_data)
                known_session_params.append(conn_data)

            except Exception as exc:
                LOGGER.exception("error loading %s" % filepath)
                message = "%s '%s'<pre>%s</pre>" % (_("Bad Config file"), filepath, exc.message)
                self.advise(message, 2)

        known_session_params = []
        for conf_dir in SETTINGS.CONNECTION_CONFDIRS:
            LOGGER.debug("checking %s for connection config files" % conf_dir)
            for root, dir_, files in os.walk(conf_dir):
                for file_ in sorted(files):
                    parse_conf(os.path.join(root, file_))

        LOGGER.info("%s connections found" % len(known_session_params))

        return known_session_params

    def get_password(self, conn_data):
        """
        raise a dialog to get a password
        """
        password, result = QtGui.QInputDialog.getText(
            self,
            _("password required"),
            u"%s '%s'" % (_("Please enter the postgres login password for user"), conn_data.user),
            QtGui.QLineEdit.Password,
        )
        if not result:
            LOGGER.WARNING("password dialog cancelled by user")
        return unicode(password)

    @property
    def connection_dialog(self):
        if self._connection_dialog is None:
            self._connection_dialog = ConnectDialog(self)
            self._connection_dialog.set_known_connections(self.known_session_params)

        return self._connection_dialog

    def new_pg_session(self):
        """
        connect a new postgres session
        """
        if self.ALLOW_MULTIPLE_SESSIONS or not self.has_pg_connection:
            LOGGER.debug("%s.new_pg_session" % __file__)
            dl = self.connection_dialog
            while True:
                if not dl.exec_():
                    return
                if not self.ALLOW_MULTIPLE_SESSIONS:
                    self.end_pg_sessions()
                conn_data = dl.chosen_connection

                session = self.CONN_CLASS(conn_data)
                try:
                    if self._attempt_connection(session):
                        self.add_session(session)
                except session.SchemaVersionError as error:
                    self.handle_schema_version_error(session, error)
                    LOGGER.exception("Schema Version Error")
                finally:
                    break
        self.update_session_status()

    def handle_schema_version_error(self, session, error):
        """
        If, on connection to a database, the schema version is found to be
        unsupported by the application, this function is called.
        """
        self.advise(u"%s<hr /><pre>%s</pre>" % (_("Schema is out of date"), error), 2)

    def _attempt_connection(self, session):
        """
        attempt to open session (ie call :doc:`OpenmolarDatabase` .connect() )
        """
        LOGGER.info(u"%s '%s'" % (_("Attempting connection using data"), session.connection_data))

        try:
            session.connect()
            self.connect(QtGui.QApplication.instance(), QtCore.SIGNAL("Query Error"), self.advise_dl)
            return True
        except ConnectionError as error:
            self.advise(u"%s<hr /><pre>%s</pre>" % (_("Connection Error"), error), 2)
            LOGGER.exception("Connection Error")

        return False

    def end_pg_sessions(self):
        """
        disconnect from postgres server
        (if not connected - pass quietly).
        """
        for widg in self.session_widgets:
            i = self.central_widget.indexOf(widg)
            if widg.is_connected:
                widg.pg_session.close()
                LOGGER.info("DISCONNECTED session %s" % widg.pg_session)
            if i != -1:
                # widg has already been removed?
                self.central_widget.removeTab(i)
        self.session_widgets = []
        self.update_session_status()

    def update_session_status(self):
        """
        toggles the connect buttons/menu actions,
        updates the sessions displayed.
        """
        for session_widg in self.session_widgets:
            session_widg.update_status()
        self.action_connect.setEnabled(self.ALLOW_MULTIPLE_SESSIONS or not self.has_pg_connection)
        self.action_disconnect.setEnabled(self.session_widgets != [])

    @property
    def has_pg_connection(self):
        """
        returns a bool which states if an active connection exists.
        """
        return self.session_widgets != []

    def get_user_pass(self, dbname):
        """
        return a tuple of (result, user, password)
        """
        LOGGER.debug("%s.get_user_pass %s" % (__file__, dbname))
        dl = UserPasswordDialog(self)
        return dl.exec_(), dl.name, dl.password

    def closeEvent(self, event=None):
        """
        re-implement the close event of QtGui.QMainWindow, and check the user
        really meant to do this.
        """
        self.saveSettings()
        self.end_pg_sessions()

    def preferences_dialog(self):
        if self._preferences_dialog is None:
            dl = PlugableMainWindow.preferences_dialog(self)

            connections_pref = Preference(_("Database Connections"))

            m_d_widg = ManageDatabasesWidget(self)
            m_d_widg.set_connections(self.known_session_params)
            connections_pref.setWidget(m_d_widg)
            dl.insert_preference_dialog(0, connections_pref)

            self._preferences_dialog = dl

        return self._preferences_dialog
    def connection_dialog(self):
        if self._connection_dialog is None:
            self._connection_dialog = ConnectDialog(self)
            self._connection_dialog.set_known_connections(self.known_session_params)

        return self._connection_dialog