Source code for lib_openmolar.common.qt4.postgres.postgres_mainwindow

#! /usr/bin/env python
# -*- coding: utf-8 -*-

###############################################################################
##                                                                           ##
##  Copyright 2010, Neil Wallace <rowinggolfer@googlemail.com>               ##
##                                                                           ##
##  This program is free software: you can redistribute it and/or modify     ##
##  it under the terms of the GNU General Public License as published by     ##
##  the Free Software Foundation, either version 3 of the License, or        ##
##  (at your option) any later version.                                      ##
##                                                                           ##
##  This program is distributed in the hope that it will be useful,          ##
##  but WITHOUT ANY WARRANTY; without even the implied warranty of           ##
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            ##
##  GNU General Public License for more details.                             ##
##                                                                           ##
##  You should have received a copy of the GNU General Public License        ##
##  along with this program.  If not, see <http://www.gnu.org/licenses/>.    ##
##                                                                           ##
###############################################################################

import re
import os
import sys
from PyQt4 import QtGui, QtCore

from lib_openmolar.common import SETTINGS
from lib_openmolar.common.datatypes import ConnectionData

from lib_openmolar.common.qt4.widgets import (
    RestorableApplication,
    PluggableMainWindow,
    Preference
    )

from connect_dialog import ConnectDialog
from postgres_database import ConnectionError, PostgresDatabase
from manage_databases_widget import ManageDatabasesWidget
from postgres_session_widget import PostgresSessionWidget

from lib_openmolar.common.qt4.dialogs import UserPasswordDialog

[docs]class PostgresMainWindow(PluggableMainWindow): ''' A main window with functions to connect to postgres ''' _central_widget = None _preferences_dialog = None _connection_dialog = None _known_session_params = None CONN_CLASS = PostgresDatabase #: True if more than one pg session is allowed (False for client) ALLOW_MULTIPLE_SESSIONS = True
[docs] def __init__(self, parent=None): PluggableMainWindow.__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
[docs] 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
[docs] 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()
[docs] 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
[docs] def known_session_params(self): ''' parse the allowed locations for connections. returns a list of :doc:`ConnectionData` ''' if self._known_session_params is None: self._known_session_params = [] try: conf_dir = str( QtCore.QSettings().value("connection_conf_dir").toString()) LOGGER.debug( "checking %s for connection config files"% conf_dir) for root, dir_, files in os.walk(conf_dir): for file_ in sorted(files): filepath = os.path.join(root, file_) 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) self._known_session_params.append(conn_data) except Exception: LOGGER.exception("error getting known_session_params") return self._known_session_params
[docs] def get_password(self, prompt): ''' raise a dialog to get a password ''' password, result = QtGui.QInputDialog.getText(self, _("password required"), prompt, QtGui.QLineEdit.Password) if result is None: logging.WARNING("password dialog cancelled by user") return unicode(password)
@property
[docs] 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
[docs] 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) if self._attempt_connection(session): self.add_session(session) break self.update_session_status()
def _attempt_connection(self, session): ''' attempt to open session (ie call :doc:`PostgresDatabase` .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
[docs] 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()
[docs] 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
[docs] def has_pg_connection(self): ''' returns a bool which states if an active connection exists. ''' return self.session_widgets != []
[docs] def get_user_pass(self, dbname): ''' return a tuple of (result, user, password) ''' LOGGER.debug("%s.get_user_pass %s"% (__file__, dbname)) if dbname == "openmolar_demo": return (True, "om_demo", "password") dl = UserPasswordDialog(self) return dl.exec_(), dl.name, dl.password
[docs] 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()
[docs] def preferences_dialog(self): if self._preferences_dialog is None: dl = PluggableMainWindow.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 _test(): import __builtin__ import gettext import os gettext.install("") class MockSettings(object): plugins = [] PLUGIN_DIRS = ["/home/neil/openmolar/hg_openmolar/plugins/client",] __builtin__.SETTINGS = MockSettings() app = RestorableApplication("openmolar-test-suite") settings = QtCore.QSettings() settings.setValue("connection_conf_dir", "/etc/openmolar/client/connections") mw = PostgresMainWindow() mw.show() app.exec_() if __name__ == "__main__": import logging LOGGER = logging.getLogger() _test()