def saveSlot(self): """ Saves the currently displayed data type. """ self._dataTypeModel.myPropertyList = self._dataTypeView.myPropertyList try: self._dataTypeModel.saveDataType() except ConfigurationError, error: getDefaultLogger().error(error.message)
def saveSlot(self): """ Saves the currently displayed relation type. """ self._relationTypeView.close() try: self._relationTypeModel.saveRelationType() except ConfigurationError, error: getDefaultLogger().error(error.message)
class CreateConfigurationController(object): """ Controller component of the create configuration dialog. """ _logger = logger.getDefaultLogger() def __init__(self, repositoryManager): """ Constructor. """ self.__errorMessage = None self.__view = CreateConfigurationView(self) self.__model = CreateConfigurationModel(repositoryManager) self.__view.show() def createConfiguration(self, hostUri, username, password, configurationPath, dataPath): """ Delegates the call to the model. """ self.__errorMessage = None self.__view.createPushButton.setEnabled(False) thread = threading.Thread(target=self.__prepare, args=(hostUri, configurationPath, dataPath, username, password)) thread.start() while thread.isAlive(): qApp.processEvents() self.__view.createPushButton.setEnabled(True) if not self.__errorMessage is None: self._logger.error(self.__errorMessage) self.__view.showErrorMessage(self.__errorMessage) else: createConfiguration = True if self.__model.exists: createConfiguration = self.__view.showQuestion( "The configuration path does already exist. Overwrite it?") self.__view.createPushButton.setEnabled(False) thread = threading.Thread( target=self.__performConfigurationCreation, args=(createConfiguration, )) thread.start() while thread.isAlive(): qApp.processEvents() if not self.__errorMessage is None: self._logger.error(self.__errorMessage) self.__view.showErrorMessage(self.__errorMessage) self.__view.createPushButton.setEnabled(True) def __prepare(self, hostUri, configurationPath, dataPath, username, password): """ Performs basic checks in thread. """ try: self.__model.prepareConfiguration(hostUri, configurationPath, dataPath, username, password) except ConfigurationError, error: self.__errorMessage = error.message
class IconHandler(object): """ Implements icon management for a specific repository. """ __logger = getDefaultLogger() def __init__(self, iconRegistry, sourceFileStorer, targetFileStorer): """ Constructor. @param iconRegistry: Global registry for icons. @type iconRegistry: L{IconRegistry<datafinder.core.configuration.icons.registry.IconRegistry>} @param sourceFileStorer: Represents the source directory containing icon files. @type sourceFileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} @param targetFileStorer: Represents the target directory for the icon files. @type targetFileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} """ self._iconRegistry = iconRegistry self._location = targetFileStorer.identifier self._sourceFileStorer = sourceFileStorer self._targetFileStorer = targetFileStorer @property def allIcons(self): """ Getter for all defined icons. """ return self._iconRegistry.icons @property def icons(self): """ Getter for handler-specific icons. """ return self._iconRegistry.getIcons(self._location) @property def localIconFilePath(self): """ Getter for the local icon file path. """ return self._location def load(self): """ Stores the icons in the target directory and register corresponding icons. @raise ConfigurationError: Indicating problems. """ self.__logger.info("Loading icons...") try: if not self._targetFileStorer.exists(): self._targetFileStorer.createCollection(True) except PersistenceError, error: raise ConfigurationError("Cannot prepare target icon location.\nReason: '%s'" % error.message) else:
class ScriptHandler(object): """ Handles scripts of a specific repository. """ __logger = getDefaultLogger() def __init__(self, scriptRegistry, sourceFileStorer, targetFileStorer): """ Constructor. @param scriptRegistry: Global registry for scripts. @type scriptRegistry: L{ScriptRegistry<datafinder.core.configuration.scripts.registry.ScriptRegistry>} @param sourceFileStorer: Represents the source directory containing scripts. @type sourceFileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} @param targetFileStorer: Represents the target directory of the scripts. @type targetFileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} """ self._scriptRegistry = scriptRegistry self._location = targetFileStorer.identifier self._sourceFileStorer = sourceFileStorer self._targetFileStorer = targetFileStorer @property def allScripts(self): """ Getter for all defined scripts. """ return self._scriptRegistry.scripts @property def scripts(self): """ Getter for handler-specific scripts. """ return self._scriptRegistry.getScripts(self._location) def load(self): """ Loads the scripts in the target directory and registers corresponding scripts. @raise ConfigurationError: Indicating problems. """ self.__logger.info("Loading scripts...") try: if not self._targetFileStorer.exists(): self._targetFileStorer.createCollection(True) except PersistenceError, error: raise ConfigurationError("Cannot access target location of repository-specific " \ + "script extensions.\nReason: '%s'" % error.message) else:
class ScriptRegistry(object): """ Global registry for script extensions. """ _logger = getDefaultLogger() def __init__(self, preferences): """ Constructor. @param preferences: Global preferences object. @type preferences: L{PreferencesHandler<datafinder.core.configuration.preferences.PreferencesHandler>} """ self._preferences = preferences self._registeredScripts = dict() @property def scripts(self): """ Getter for all existing scripts. """ result = list() for locationScripts in self._registeredScripts.values(): for script in locationScripts.values(): result.append(copy(script)) return result def load(self): """ Loads local script extensions. @raise ConfigurationError: Indicating problems on initialization. """ scripts = list() for scriptUri in self._preferences.scriptUris: try: fileStorer = createFileStorer(scriptUri) except PersistenceError, error: self._logger.debug("Cannot access script '%s'. Reason '%s'" % (scriptUri, error.message)) else: try: script = createScript(fileStorer) except ConfigurationError, error: self._logger.debug(error.message) else:
def __init__(self, parameter, startUrl, debug): """ Constructor. @param parameter: Parameter of the application. @type parameter: C{list} @param startUrl: The URL used for connection. @type startUrl: C{unicode} @param debug: Activates debug messages when set to C{True}. @type debug: C{bool} """ QtGui.QApplication.__init__(self, parameter) pixmap = QtGui.QPixmap(":/images/images/splash_datafinder_user.png") splash = QtGui.QSplashScreen(pixmap, QtCore.Qt.WindowStaysOnTopHint) splash.show() self.processEvents() #Initializing of the translator. self.__translator = Translator() self.installTranslator(self.__translator) #Initializing of the logging mechanism. rootLoggerHandler = LoggerHandler(constants.LOGGER_ROOT) rootLoggingModel = LoggingModel(rootLoggerHandler, parent=self) rootLogger = logging.getLogger(constants.LOGGER_ROOT) if debug: rootLogger.setLevel(logging.DEBUG) rootLogger.addHandler(rootLoggerHandler) logger.getDefaultLogger().addHandler(rootLoggerHandler) scriptLoggerHandler = LoggerHandler(constants.LOGGER_SCRIPT) scriptLoggingModel = LoggingModel(scriptLoggerHandler, parent=self) scriptLogger = logging.getLogger(constants.LOGGER_SCRIPT) scriptLogger.setLevel(logging.DEBUG) scriptLogger.addHandler(scriptLoggerHandler) #Model initialization. repositoryManager = repositoryManagerInstance repositoryManager.load() if repositoryManager.preferences.getConnection(startUrl) is None: repositoryManager.preferences.addConnection(startUrl) #controller initialization. self.__mainWindow = MainWindow() self.__unmanagedRepositoryController = UnmanagedRepositoryController( self.__mainWindow, repositoryManager) self.__managedRepositoryController = ManagedRepositoryController( self.__mainWindow, repositoryManager) self.__scriptController = ScriptController( repositoryManager.scriptRegistry, self.__unmanagedRepositoryController.model, self.__mainWindow) self.__unmanagedRepositoryController.load( self.__managedRepositoryController, self.__scriptController) self.__managedRepositoryController.load( self.__unmanagedRepositoryController, self.__scriptController) self.__outputView = OutputFacadeController( self.__mainWindow, SearchFilter(self.__managedRepositoryController.model), self.__managedRepositoryController.itemActionController) self.__outputView.myRootLogView.model = LoggingSortFilterModel( rootLoggingModel) self.__outputView.myScriptLogView.model = LoggingSortFilterModel( scriptLoggingModel) # Display the GUI self.__mainWindow.show() splash.finish(self.__mainWindow) # initialize script API and scripts scriptApiContext = _ScriptApiContext() scriptApiContext.mainWidget = self.__mainWindow scriptApiContext.repositoryManager = repositoryManager scriptApiContext.managedRepositoryController = self.__managedRepositoryController scriptApiContext.unmanagedRepositoryController = self.__unmanagedRepositoryController scriptApiContext.scriptController = self.__scriptController script_api._context = scriptApiContext self.__scriptController.load() # Register clean up stuff atexit.register(repositoryManager.savePreferences) #Log message that everything is fine... rootLogger.info("DataFinder successful started.")
#OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ Implements the model component of the create configuration dialog. """ __version__ = "$Revision-Id:$" from datafinder.common import logger from datafinder.core.error import ConfigurationError _logger = logger.getDefaultLogger() class CreateConfigurationModel(object): """ Implements the model component of the create configuration dialog. """ def __init__(self, repositoryManager): """ Constructor. """ self._repositoryManager = repositoryManager self._preferences = repositoryManager.preferences self._configurationUri = None self._dataPath = None self._repositoryConfiguration = None self._exists = None self._username = None
class ScriptCollection(object): """ Class representing a script collection. """ _logger = getDefaultLogger() def __init__(self, fileStorer): """ Constructor. @param fileStorer: Allowing access to the script data. @type fileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} """ self._fileStorer = fileStorer self.uri = self._fileStorer.uri self.name = self._fileStorer.name self._tmpdir = tempfile.mkdtemp() sys.path.append(self._tmpdir) self.title = self._fileStorer.name[:-4] sys.path.append(self._tmpdir) self._baseDirFileStorer = createFileStorer("file:///" + self._tmpdir + "/" + self.title) atexit.register(self._cleanup) self.scripts = list() self.hasPreferences = False self.location = None self._extract() self._parse() def _extract(self): """ Extract the script collection. """ dataStream = self._fileStorer.readData() tar = tarfile.open(fileobj=dataStream) for member in tar.getmembers(): tar.extract(member, self._tmpdir) tar.close() dataStream.close() def _parse(self): """ Parse all scripts. """ configFileStorer = self._baseDirFileStorer.getChild( constants.SCRIPT_DEFINITION_FILE_NAME) data = configFileStorer.readData() for line in data.readlines(): fileStorer = self._baseDirFileStorer.getChild(line.strip()) self.scripts.append(Script(fileStorer)) data.close() if self._baseDirFileStorer.getChild( constants.PREFERENCES_PAGE_MODULE_NAME).exists(): self.hasPreferences = True def _cleanup(self): """ Cleanup the temporary directory. """ if self._tmpdir in sys.path: sys.path.remove(self._tmpdir) try: fileStorer = createFileStorer("file:///" + self._tmpdir) if fileStorer.exists(): fileStorer.delete() except PersistenceError, error: self._logger.debug(error.message)
class SelectScriptDialog(SelectScriptDialogForm): """ Dialog to select a "script". (see L{datafinder.application.ScriptingHandler.ScriptingHandler}) """ __logger = getDefaultLogger() def __init__(self, *args): """ Constructor. """ SelectScriptDialogForm.__init__(self, *args) self.connect(self, PYSIGNAL("quit"), SLOT("reject()")) self.okay = 0 def setScripts(self, scripts): """ Set items of script-listview. Invoke this method before using getScript(). @param scripts: list of scripts @type scripts: C{list} of C{dictionaries} (keys: name, description, file, version, datatypes, icon) """ self.scriptListView.clear() for script in scripts: if isinstance(script, Script): item = QListViewItem(self.scriptListView, script.title or "", script.description or "", script.version or "", ",".join(script.datatypes), script.iconName or "") else: item = QListViewItem(self.scriptListView, script.title or "", "", "", "", "") item.script = script self.scriptListView.clearSelection() self.adjustSize() def getScriptToRemove(self): """ Show and handle dialog, returns name of selected script. @return: name of selected script (OK) or None (Cancel) @rtype: C{unicode} (or C{None}) """ self.setCaption(self.tr("Select Script")) self.taskTextLabel.setText(self.tr("Select Script to Remove:")) self.okButton.setText(self.tr("Remove")) self.cancelButton.setDefault(True) self.exec_loop() result = list() if self.okay: item = self.scriptListView.firstChild() while not item is None: if item.isSelected(): result.append(item.script) item = item.nextSibling() return result def cancelPushButtonSlot(self): """ Slot for Cancel-button. """ self.okay = 0 # false self.emit(PYSIGNAL("quit"), ()) def okPushButtonSlot(self): """ Slot for OK-button. """ self.okay = 1 # true self.emit(PYSIGNAL("quit"), ())
class Importer( ItemTreeWalkerBase, object ): # inherit from object to make pylint happy, but this is a pylint issue """ This class uses the L{ItemTreeWalkerBase<datafinder.core.item.visitor.base.ItemTreeWalkerBase>} protocol to implement a recursive copy algorithm between two repositories. It is assumed (but NOT checked) that the repository configurations are compatible. """ _log = logger.getDefaultLogger() def __init__(self, stopTraversalStates=None, stopProcessStates=None): """ @param stopTraversalStates: List of states that are used to prevent traversal of specific collections. Default: C{None} @type stopTraversalStates: C{list} of C{unicode} @param stopProcessStates: List of states that are used to prevent processing a specific items. Default: C{None} @type stopProcessStates: C{list} of C{unicode} """ super(Importer, self).__init__(-1, stopTraversalStates, stopProcessStates) self._pwd = None self._deferredLinks = None self._destinationRootPath = None self._itemFactory = None self._newSourceName = None self._defaultProperties = None self._source = None self._copyData = True self._ignoreLinks = False self._determinePropertiesCallback = None self.importedLeafs = None def performImport(self, source, targetCollection, newSourceName=None, defaultProperties=None, copyData=True, ignoreLinks=False, determinePropertiesCallback=None): """ This method initiates the copy process and starts walking the source creating a new node in the destination tree for each item it passes. @param source: The item that should be imported. @type source: L{ItemBase<datafinder.core.item.base.ItemBase>} @param targetCollection: The collection that should afterwards contain the copy. @type targetCollection: L{ItemCollection<datafinder.core.item.collection.ItemCollection>} @param newSourceName: Optional new name of the source item. Default: C{None} @type newSourceName: C{unicode} @param defaultProperties: Optional list of properties which are set for every item. Default: C{None} @type defaultProperties: C{list} of L{Property<datafinder.core.item.property.Property>} @param copyData: Flag indicating whether data has to be copied or not. @type copyData: C{bool} @param ignoreLinks: Flag indicating the links are ignored during import. Default: C{False} @type ignoreLinks: C{bool} @param determinePropertiesCallback: Function determining properties used when importing a specific item. @type: determinePropertiesCallback: C{callable} using an item description as input and returns a dictionary describing the properties. @raise ItemError: Indicating errors during import. """ self._pwd = targetCollection self._deferredLinks = list() self._destinationRootPath = targetCollection.path self._itemFactory = targetCollection.itemFactory self._newSourceName = newSourceName self._defaultProperties = defaultProperties self._source = source self._copyData = copyData self.importedLeafs = list() self._ignoreLinks = ignoreLinks self._determinePropertiesCallback = determinePropertiesCallback self.walk(source) missingDefferedLinkPaths = list() for source, importName, destinationParent in self._deferredLinks: try: self._copyLink(source, importName, destinationParent) except ItemError: missingDefferedLinkPaths.append(source.path) if len(missingDefferedLinkPaths) > 0: errorMessage = "The following links could not be imported:" for linkPath in missingDefferedLinkPaths: errorMessage += "\n" + linkPath raise ItemError(errorMessage) def walk(self, node): """ @see: L{walk<datafinder.core.item.visitor.base.ItemTreeWalkerBase.walk>} method to add further post-processing. """ super(Importer, self).walk(node) if node.isCollection: if not node.state in self._stopTraversalStates: self._pwd = self._pwd.parent def _copyLink(self, source, importName, destinationParent): """ Copies a link item. """ baseDestinationPath = self._destinationRootPath if not baseDestinationPath.endswith("/"): baseDestinationPath += "/" baseDestinationPath += (self._newSourceName or self._source.name) destinationLinkTargetPath = baseDestinationPath + source.linkTarget.path[ len(self._source.path):] destinationLinkTarget = self._itemFactory.create( destinationLinkTargetPath) link = self._itemFactory.createLink(importName, destinationLinkTarget, destinationParent) properties = source.properties.values()[:] if not self._determinePropertiesCallback is None: properties.extend(self._determinePropertiesCallback(source)) if not self._defaultProperties is None: properties.extend(self._defaultProperties) try: link.create(properties) except CoreError, error: link.invalidate() raise error
class SearchDialog(QtGui.QDialog, Ui_searchDialog): """ This class implements the search dialog. """ _logger = getDefaultLogger() def __init__(self, repositoryModel, parentWidget, itemActionController): """ Constructor. @param repositoryModel: Reference on the repository model. @type repositoryModel: L{RepositoryModel<datafinder.gui.user.models.repository.repository.RepositoryModel>} @param parentWidget: Parent widget of this dialog. @type parentWidget: L{QWidget<PyQt4.QtGui.QWidget>} """ QtGui.QDialog.__init__(self, parentWidget) Ui_searchDialog.__init__(self) self.setupUi(self) self._collectionSearchDialog = None self._parser = search_restriction.SearchRestrictionParser() self.__model = repositoryModel self._worker = None self._initialSearchQuery = "" self.__searchQueryAnalyzer = SearchQueryAnalyzer(self._parser, self._preparePropertyDefinitionToolTips()) self._initSearchQueryEditor() self.__highlighter = SearchSyntaxHighlighter(self.__searchQueryAnalyzer, self.restrictionTextEdit) self.__searchResultController = SearchResultController(self.resultsTableView, parentWidget, self, itemActionController) self.__searchResultController.model = SearchFilter(self.__model) self.__storedSearchesController = _SearchStorerController(self.searchesListView, self) self.__storedSearchesController.model = _ServerSearchStoreModel(repositoryModel.preferences) self._keywordSearchQueryConverter = KeywordSearchQueryConverter(self.__model.repository.configuration.registeredPropertyDefinitions) self.storedSearchesPushButton.setChecked(True) self._activateExpertMode() self.expertModePushButton.setEnabled(False) self._connectSlots() def show(self): """ @see: L{QDialog<PyQt4.QtGui.QDialog>}""" self.startLineEdit.setText(self.__model.activePath or "/") QtGui.QDialog.show(self) def _initSearchQueryEditor(self): """ Initializes the search query editor. """ self.restrictionTextEdit.searchQueryAnalyzer = self.__searchQueryAnalyzer propertyNameCompleter = Completer(self._preparePropertyDefinitionToolTips(), True) self.restrictionTextEdit.registerCompleter(propertyNameCompleter, SearchQueryAnalyzer.PROPERTY_TYPE) comparisionOperatorCompleter = QtGui.QCompleter(self._parser.comparisonTokens) comparisionOperatorCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.restrictionTextEdit.registerCompleter(comparisionOperatorCompleter, SearchQueryAnalyzer.COMPARISON_TYPE) conjunctionOperatorCompleter = QtGui.QCompleter(self._parser.conjunctionTokens) conjunctionOperatorCompleter.setCaseSensitivity(QtCore.Qt.CaseInsensitive) self.restrictionTextEdit.registerCompleter(conjunctionOperatorCompleter, SearchQueryAnalyzer.CONJUNCTION_TYPE) completions = {u"''": u"Empty Value.", u"'DD.MM.YYYY'": u"Date Format Value.", u"'DD.MM.YYYY HH:MM:SS'": u"Date Time Format Value."} valueStateCompleter = Completer(completions) self.restrictionTextEdit.registerCompleter(valueStateCompleter, SearchQueryAnalyzer.LITERAL_TYPE) self.restrictionTextEdit.state = SearchQueryAnalyzer.PROPERTY_TYPE def _preparePropertyDefinitionToolTips(self): """ Prepares a dictionary containing the tool tips of existing property definitions. """ result = dict() for propDef in self.__model.repository.configuration.registeredPropertyDefinitions.values(): result[propDef.identifier] = util.determinePropertyDefinitionToolTip(propDef) return result def _connectSlots(self): """ Connects signals and slots. """ self.connect(self.startSelectionButton, QtCore.SIGNAL("clicked()"), self._showSelectionClickedSlot) self.connect(self.closeButton, QtCore.SIGNAL("clicked()"), self._closeClickedSlot) self.connect(self.searchesListView, QtCore.SIGNAL("doubleClicked(QModelIndex)"), self._storedSearchClickedSlot) self.connect(self.expertModePushButton, QtCore.SIGNAL("clicked(bool)"), self._searchModeChanged) self.connect(self.storedSearchesPushButton, QtCore.SIGNAL("clicked(bool)"), self._storedSearchesModeChanged) self.connect(self.saveSearchButton, QtCore.SIGNAL("clicked()"), self._handleSearchStored) def _handleSearchStored(self): """ Reacts on when saving a search. """ self._initialSearchQuery = self.restrictionTextEdit.toPlainText() def _showSelectionClickedSlot(self): """ Slot is called when the start selection button was clicked. """ leafFilterModel = LeafFilter(self.__model) self._collectionSearchDialog = ItemSelectionDialog(leafFilterModel, self) self._collectionSearchDialog.selectedIndex = self.__model.indexFromPath(unicode(self.startLineEdit.text())) if self._collectionSearchDialog.exec_() == QtGui.QDialog.Accepted: item = self.__model.nodeFromIndex(self._collectionSearchDialog.selectedIndex) self.startLineEdit.setText(item.path or "/") def _closeClickedSlot(self): """ Slot is called when the close button was clicked. """ if self._proceedWithUnsavedChanges(): self.__storedSearchesController.model.save() self.close() def _expertSearchClickedSlot(self): """ Slot is called when the search button was clicked and the dialog is in the expert mode. """ self.resultsGroupBox.show() self.setEnabled(False) path = unicode(self.startLineEdit.text()) query = unicode(self.restrictionTextEdit.toPlainText()) self._worker = util.startNewQtThread(self.__model.search, self._searchFinishedSlot, self.__model.indexFromPath(path), query) def _searchFinishedSlot(self): """ Slot is called when the search thread finished its work and the dialog is in expert mode. """ if not self._worker.error is None: QtGui.QMessageBox.critical(self, "Search Error", self._worker.error.message) self.setEnabled(True) def _simpleSearchClickedSlot(self): """ Slot is called when the search button was clicked and the dialog is in the simple search mode. """ self.splitter_2.show() self.resultsGroupBox.show() self.setEnabled(False) text = unicode(self.keywordLineEdit.text()) path = unicode(self.startLineEdit.text()) query = self._keywordSearchQueryConverter.convert(text) self._worker = util.startNewQtThread(self.__model.search, self._searchFinishedSlot, self.__model.indexFromPath(path), query) def _storedSearchClickedSlot(self, index): """ Slot is called when a search was selected from the stored searches. """ if self._proceedWithUnsavedChanges(): self.__storedSearchesController.searchSelectedSlot(index) restriction = self.__storedSearchesController.model.restrictionFromIndex(index) self._initialSearchQuery = restriction self.restrictionTextEdit.setText(restriction) else: self.searchesListView.clearSelection() def _searchModeChanged(self, expertMode): """ Slot is called when the state of the expertModePushButton changed. """ if expertMode: self._activateExpertMode() else: if self._proceedWithUnsavedChanges(): self._activateSimpleMode() else: self.expertModePushButton.setChecked(True) def _proceedWithUnsavedChanges(self): """ Checks for unsaved changes of the search restrictions and asks the user how to proceed. """ continue_ = True if self._initialSearchQuery != self.restrictionTextEdit.toPlainText(): answer = QtGui.QMessageBox.question(self, "Unsaved Changes", "Some changes of the search restrictions "\ + "have not yet been saved and may be lost when you proceed."\ + "\nDo you want to continue?", QtGui.QMessageBox.Yes | QtGui.QMessageBox.No, QtGui.QMessageBox.No) if answer == QtGui.QMessageBox.No: continue_ = False return continue_ def _storedSearchesModeChanged(self, storedSearches): """ Slot is called when the state of the storedSearchesPushButton changed. """ self.storedSearchGroupBox.setVisible(bool(storedSearches)) def _activateSimpleMode(self): """ Activates the simple mode. It hides all expert mode's widgets and sets all simple mode's widgets visible. It also manages the signal slot connections. """ self.disconnect(self.__searchQueryAnalyzer, QtCore.SIGNAL(SearchQueryAnalyzer.VALIDATION_SIGNAL), self.searchButton.setEnabled) self.disconnect(self.__searchQueryAnalyzer, QtCore.SIGNAL(SearchQueryAnalyzer.VALIDATION_SIGNAL), self.__storedSearchesController.validationSlot) self.disconnect(self.searchButton, QtCore.SIGNAL("clicked()"), self._expertSearchClickedSlot) self.connect(self.keywordLineEdit, QtCore.SIGNAL("textChanged(const QString &)"), self._handleKeywordLineEditTextChanged) self.connect(self.searchButton, QtCore.SIGNAL("clicked()"), self._simpleSearchClickedSlot) self.splitter_2.hide() self.resultsGroupBox.hide() self.optionsGroupBox.hide() self.storedSearchGroupBox.hide() self.simpleSearchGroupBox.show() self.searchButton.show() self.storedSearchesPushButton.hide() self.resize(self.minimumSize().width(), self.sizeHint().height()) self._handleKeywordLineEditTextChanged(self.keywordLineEdit.text()) def _handleKeywordLineEditTextChanged(self, newText): """ Handles changes of the keyword line editor. """ isEmpty = len(unicode(newText).strip()) == 0 self.searchButton.setEnabled(not isEmpty) def _activateExpertMode(self): """ Activates the expert mode. It hides all simple mode's widgets and sets all expert mode's widgets visible. It also manages the signal slot connections. """ self.disconnect(self.searchButton, QtCore.SIGNAL("clicked()"), self._simpleSearchClickedSlot) self.disconnect(self.keywordLineEdit, QtCore.SIGNAL("textChanged(const QString &)"), self._handleKeywordLineEditTextChanged) self.optionsGroupBox.show() self.storedSearchGroupBox.setVisible(self.storedSearchesPushButton.isChecked()) self.connect(self.searchButton, QtCore.SIGNAL("clicked()"), self._expertSearchClickedSlot) self.connect(self.__searchQueryAnalyzer, QtCore.SIGNAL(SearchQueryAnalyzer.VALIDATION_SIGNAL), self.searchButton.setEnabled) self.connect(self.__searchQueryAnalyzer, QtCore.SIGNAL(SearchQueryAnalyzer.VALIDATION_SIGNAL), self.__storedSearchesController.validationSlot) self.startLabel.hide() self.startSelectionButton.hide() self.splitter_2.show() self.simpleSearchGroupBox.hide() self.storedSearchesPushButton.show() query = self._keywordSearchQueryConverter.convert(unicode(self.keywordLineEdit.text())) self._initialSearchQuery = query self.restrictionTextEdit.setText(query)
class AdminMain(AdminWindow): """ Implements the administration client functionality. """ __tabDataTypesTitle = "Data Types" __tabRelationTypesTitle = "Relation Types" __tabDataStoresTitle = "Data Stores" __baseCaption = "DataFinder Administration Client - Server: " __errorMessageCaption = "DataFinder Administration Client: Error" __informationMessageCaption = "DataFinder Administration Client: Information" __logger = getDefaultLogger() def __init__(self, repositoryManager): """ Constructor. """ # Init GUI AdminWindow.__init__(self) # set icon in window-title: self.setIcon(QPixmap.fromMimeSource("DF_Logo_24x24.png")) iconSet = QIconSet(QPixmap.fromMimeSource("dataType16.png")) self.dataNavigator.setTabIconSet(self.dataTypes, iconSet) iconSet = QIconSet(QPixmap.fromMimeSource("relationType16.png")) self.dataNavigator.setTabIconSet(self.relationTypes, iconSet) iconSet = QIconSet(QPixmap.fromMimeSource("dataStore16.png")) self.dataNavigator.setTabIconSet(self.dataStores, iconSet) logger_handler.installGuiLoggingHandler(self.__logger, self.logList) self.myStatusBar = self.statusBar() self.statusLabel1 = QLabel("DataFinder", self.myStatusBar) self.statusLabel2 = QLabel("OK", self.myStatusBar) self.myStatusBar.addWidget(self.statusLabel1, 80) self.myStatusBar.addWidget(self.statusLabel2, 20) self.statusLabel1.show() self.statusLabel2.show() self.myStatusBar.show() # prepare "About"-dialog: self.dfAboutDialog = about_dialog.AboutDialog() self.dfAboutDialog.setPixmap( QPixmap.fromMimeSource("about_datafinder_admin.png")) # Login-dialog: self.dfLoginDialog = login_dialog.LoginDialog( repositoryManager.preferences, parent=self, showurl=True) # IconView: propertyPanelLayout = QGridLayout(self.propertyPanel, 1, 1, 2, 6, "propertyPanelLayout") self.iconView = canvas_view.CanvasView(self.propertyPanel, self, "iconView", 0) propertyPanelLayout.addWidget(self.iconView, 0, 0) self.iconViewCanvas = self.iconView.canvas() self.connect(self.dfLoginDialog.okPushButton, PYSIGNAL("updateWebdavServerView"), self.updateWebdavServerSlot) self.connect(self.dataTypeBrowser, SIGNAL("doubleClicked(QListViewItem*)"), self.__addDataTypeIconSlot) self.connect(self.relationTypeBrowser, SIGNAL("doubleClicked(QListViewItem*)"), self.__addRelationTypeIconSlot) self.connect(self.dataStoreBrowser, SIGNAL("clicked(QListViewItem*)"), self.iconView.updateCanvasView) self.connect(self.dataStoreBrowser, SIGNAL("doubleClicked(QListViewItem*)"), self.editSlot) # Init model self._repositoryManager = repositoryManager self.repositoryConfiguration = None self._preferences = self._repositoryManager.preferences self._lastUploadDirectory = os.path.expanduser("~") self._dataTypes = list() self._relationTypes = list() self._dataStores = list() self.__setConnectionState(False) def __setConnectionState(self, isConnected): """ Sets the enabled state of the actions in accordance to successful or unsuccessful connection. """ self.iconView.clear() self.__setActionEnabledState(isConnected) if isConnected: self.setCaption(self.__baseCaption + unicode( self.repositoryConfiguration.repositoryConfigurationUri)) iconPath = self.repositoryConfiguration.localIconFilePath if sys.platform == "win32" and iconPath.startswith("/"): iconPath = iconPath[1:] utils.addQtImagePath(iconPath) else: self.repositoryConfiguration = None enableActions = [ self.fileConnectAction, self.fileExitAction, self.fileCreateConfigurationAction, self.editPreferencesAction, self.helpAboutAction ] for action in enableActions: action.setEnabled(True) self.setCaption(self.__baseCaption + "<not connected>") self.updateDataTypes() self.updateRelationTypes() self.updateDataStores() def __setActionEnabledState(self, isEnabled): """ Sets the enabled state of all actions. """ self.datamodelExportAction.setEnabled(isEnabled) self.datamodelImportAction.setEnabled(isEnabled) self.datamodelNewDataTypeAction.setEnabled(isEnabled) self.datamodelNewRelationTypeAction.setEnabled(isEnabled) self.deleteAction.setEnabled(isEnabled) self.editAction.setEnabled(isEnabled) self.editPreferencesAction.setEnabled(isEnabled) self.fileConnectAction.setEnabled(isEnabled) self.fileCreateConfigurationAction.setEnabled(isEnabled) self.fileDeleteConfigurationAction.setEnabled(isEnabled) self.fileExitAction.setEnabled(isEnabled) self.helpAboutAction.setEnabled(isEnabled) self.reloadConfigurationAction.setEnabled(isEnabled) self.storeExportAction.setEnabled(isEnabled) self.storeImportAction.setEnabled(isEnabled) self.storeNewAction.setEnabled(isEnabled) self.utilDeleteIconAction.setEnabled(isEnabled) self.utilDeleteScriptAction.setEnabled(isEnabled) self.utilUploadIconAction.setEnabled(isEnabled) self.utilUploadScriptAction.setEnabled(isEnabled) def __configureDatastore(self, datastore=None): """ Shows the Data Store configuration wizard to add a new Data Store. """ DataStoreConfigurationWizardController( self, self.repositoryConfiguration.dataStoreHandler, self.repositoryConfiguration.iconHandler, datastore) def changeIconPixmap(self, icon, oldLabel, newLabel): """ Changes the icon (node) pixmap. """ changedTitle = oldLabel if not oldLabel == newLabel and not self._getIconFromLabel( newLabel) == None: result = self.__showQuestion("DataFinder: Confirm Overwrite", "A Node of the same name \"" + unicode(newLabel) + \ "\" already exists.\nBefore renaming, please close that node.") return changedTitle if not oldLabel == newLabel and self._isTypeExisting(newLabel): result = self.__showQuestion( "DataFinder: Confirm Overwrite", "Overwrite existing \"" + unicode(newLabel) + "\"?") if result: return changedTitle iconItem = self._getIconFromLabel(oldLabel) if not iconItem is None: if icon is None: iconItem.setIconLabel(newLabel) else: iconItem.setIconLabel(newLabel) iconItem.setIconPixmap(icon.pixmap()) changedTitle = newLabel self.iconView.updateCanvasView() def _isNodeExisting(self, title): """ Check if the node with title does already exist. @param title: Title of the node. @type title: C{string} """ returnValue = True if self._getIconFromLabel(title) is None: returnValue = False return returnValue def _isTypeExisting(self, newName): """ Checks if the type exists. """ returnValue = False if not self.repositoryConfiguration.getDataType(newName) is None: returnValue = True elif not self.repositoryConfiguration.getRelation(newName) is None: returnValue = True return returnValue def _getIconFromLabel(self, searchLabel): """ Returns the icon specified by searchLabel. @param searchLabel: the label of the icon. @type searchLabel: C{String} @rtype: L{PrototypeIcon} """ return self.iconView.getIcon(searchLabel) def updateWebdavServerSlot(self, url, username, password): """ Reconnect to WebDAV server. """ # update preferences if self.dfLoginDialog.savePasswordCheckBox.isChecked(): self._preferences.addConnection(url, username, password) else: self._preferences.addConnection(url, username, None) self._preferences.store() try: if not self.repositoryConfiguration is None: self.repositoryConfiguration.release() repositoryConfiguration = None repositoryConfiguration = self._repositoryManager.getRepositoryConfiguration( url, username, password) repositoryConfiguration.load() except ConfigurationError, error: if not repositoryConfiguration is None: repositoryConfiguration.release() self.__showErrorMessage("Cannot connect to specified server. Reason: '%s'" % error.message \ + "Please try again or create a new configuration.") self.__setConnectionState(False) else:
self._setNodeIcon() self._dataTypeView.setButtonsState(False) def saveSlot(self): """ Saves the currently displayed data type. """ self._dataTypeModel.myPropertyList = self._dataTypeView.myPropertyList try: self._dataTypeModel.saveDataType() except ConfigurationError, error: getDefaultLogger().error(error.message) else: self._dataTypeView.close() self._parentFrame.updateDataTypes() getDefaultLogger().info("Data Type " + self._dataTypeModel.myTitle + " was successfully saved.") def __getattr__(self, name): """ Delegates calls to the generated PyQt class. """ return getattr(self._dataTypeView, name) class DataTypeModel(QObject): """ This is the data model of the add/edit data type dialog that contains the current data type or none and the list of available data types. """ def __init__(self, title, dataModelHandler, propertyDefinitionFactory, iconHandler):
self._dataTypeView.updateDataType(self._dataTypeModel.myTitle, self._dataTypeModel.myIconName, self._dataTypeModel.myPropertyList) self._setNodeIcon() self._dataTypeView.setButtonsState(False) def saveSlot(self): """ Saves the currently displayed data type. """ self._dataTypeModel.myPropertyList = self._dataTypeView.myPropertyList try: self._dataTypeModel.saveDataType() except ConfigurationError, error: getDefaultLogger().error(error.message) else: self._dataTypeView.close() self._parentFrame.updateDataTypes() getDefaultLogger().info("Data Type " + self._dataTypeModel.myTitle + " was successfully saved.") def __getattr__(self, name): """ Delegates calls to the generated PyQt class. """ return getattr(self._dataTypeView, name) class DataTypeModel(QObject): """ This is the data model of the add/edit data type dialog that contains the current data type or none and the list of available data types. """ def __init__(self, title, dataModelHandler, propertyDefinitionFactory, iconHandler): """
def __init__(self, repositoryModel): """ Constructor. """ self._repositoryModel = repositoryModel self._workerThreads = dict() self._logger = getDefaultLogger()
class DataStoreConfigurationWizardController(object): """ Controls the DataStoreWizardView. Delegates the control of the specific from to the according subclass of AbstractoptionComntroller. """ _logger = getDefaultLogger() def __init__(self, parentFrame, dataStoreHandler, iconHandler, datastore=None): """ Constructor. """ self.parent = parentFrame self._dataStoreHandler = dataStoreHandler # create main view self.wizardView = view.DataStoreConfigurationWizardView(parentFrame) # init model if not datastore is None: self.datastore = datastore else: self.datastore = self._dataStoreHandler.createDataStore() # add control logic of the displayed forms self.lastPageTitle = standardOptionsPage self.currentFormHandler = default.base_option_controller.BaseOptionController( self.wizardView, self, standardOptionsPage, dataStoreHandler, iconHandler) self.formControllerDict = { standardOptionsPage: { _defaultForAllDataStores: self.currentFormHandler }, storageOptionsPage: { datastores.OFFLINE_STORE: offline.storage_option_controller.StorageOptionController( self.wizardView, self, storageOptionsPage), datastores.TSM_CONNECTOR_STORE: tsm.storage_option_controller.StorageOptionController( self.wizardView, self, storageOptionsPage), _defaultForAllDataStores: default.storage_option_controller.StorageOptionController( self.wizardView, self, storageOptionsPage) }, securityOptionsPage: { datastores.GRIDFTP_STORE: gridftp.security_option_controller.SecurityOptionController( self.wizardView, self, securityOptionsPage), }, authenticationOptionsPage: { datastores.FTP_STORE: ftp.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage), datastores.WEBDAV_STORE: webdav.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage), datastores.TSM_CONNECTOR_STORE: tsm.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage), datastores.S3_STORE: s3.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage), datastores.SUBVERSION_STORE: webdav.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage), _defaultForAllDataStores: default.authentication_option_controller. AuthenticationOptionController(self.wizardView, self, authenticationOptionsPage) }, performanceOptionsPage: { datastores.GRIDFTP_STORE: gridftp.performance_option_controller. PerformanceOptionController(self.wizardView, self, performanceOptionsPage) } } # show wizard self.wizardView.setCaption( wizardCaptionTemplate % (self.datastore.storeType, self.datastore.name)) self.wizardView.show() self.wizardView.adjustSize() self.currentFormHandler.showModelPart() self.setPageSequence() # connect slots self.wizardView.connect(self.wizardView, SIGNAL("selected(const QString&)"), self._wizardPageChangedSlot) self.wizardView.connect(self.wizardView.finishButton(), SIGNAL("clicked()"), self._finishedSlot) def _finishedSlot(self): """ Method to overwrite standard behavior of the QWizard class if the button "finished" is used. This method validates the user input, saves the DataStore object and continues closes the wizard. """ self._dataStoreHandler.addDataStore(self.datastore) try: self._dataStoreHandler.store() except ConfigurationError, error: self._logger.error(error.message) else:
def __init__(self, parameter, startUrl, debug): """ Constructor. @param parameter: Parameter of the application. @type parameter: C{list} @param startUrl: The URL used for connection. @type startUrl: C{unicode} @param debug: Activates debug messages when set to C{True}. @type debug: C{bool} """ QtGui.QApplication.__init__(self, parameter) pixmap = QtGui.QPixmap(":/images/images/splash_datafinder_user.png") splash = QtGui.QSplashScreen(pixmap, QtCore.Qt.WindowStaysOnTopHint) splash.show() self.processEvents() #Initializing of the translator. self.__translator = Translator() self.installTranslator(self.__translator) #Initializing of the logging mechanism. rootLoggerHandler = LoggerHandler(constants.LOGGER_ROOT) rootLoggingModel = LoggingModel(rootLoggerHandler, parent=self) rootLogger = logging.getLogger(constants.LOGGER_ROOT) if debug: rootLogger.setLevel(logging.DEBUG) rootLogger.addHandler(rootLoggerHandler) logger.getDefaultLogger().addHandler(rootLoggerHandler) scriptLoggerHandler = LoggerHandler(constants.LOGGER_SCRIPT) scriptLoggingModel = LoggingModel(scriptLoggerHandler, parent=self) scriptLogger = logging.getLogger(constants.LOGGER_SCRIPT) scriptLogger.setLevel(logging.DEBUG) scriptLogger.addHandler(scriptLoggerHandler) #Model initialization. repositoryManager = repositoryManagerInstance repositoryManager.load() if repositoryManager.preferences.getConnection(startUrl) is None: repositoryManager.preferences.addConnection(startUrl) #controller initialization. self.__mainWindow = MainWindow() self.__unmanagedRepositoryController = UnmanagedRepositoryController(self.__mainWindow, repositoryManager) self.__managedRepositoryController = ManagedRepositoryController(self.__mainWindow, repositoryManager) self.__scriptController = ScriptController(repositoryManager.scriptRegistry, self.__unmanagedRepositoryController.model, self.__mainWindow) self.__unmanagedRepositoryController.load(self.__managedRepositoryController, self.__scriptController) self.__managedRepositoryController.load(self.__unmanagedRepositoryController, self.__scriptController) self.__outputView = OutputFacadeController(self.__mainWindow, SearchFilter(self.__managedRepositoryController.model), self.__managedRepositoryController.itemActionController) self.__outputView.myRootLogView.model = LoggingSortFilterModel(rootLoggingModel) self.__outputView.myScriptLogView.model = LoggingSortFilterModel(scriptLoggingModel) # Display the GUI self.__mainWindow.show() splash.finish(self.__mainWindow) # initialize script API and scripts scriptApiContext = _ScriptApiContext() scriptApiContext.mainWidget = self.__mainWindow scriptApiContext.repositoryManager = repositoryManager scriptApiContext.managedRepositoryController = self.__managedRepositoryController scriptApiContext.unmanagedRepositoryController = self.__unmanagedRepositoryController scriptApiContext.scriptController = self.__scriptController script_api._context = scriptApiContext self.__scriptController.load() # Register clean up stuff atexit.register(repositoryManager.savePreferences) #Log message that everything is fine... rootLogger.info("DataFinder successful started.")
self._relationTypeModel.initRelationType() self._setNodeIcon() self._relationTypeView.setButtonsState(False) def saveSlot(self): """ Saves the currently displayed relation type. """ self._relationTypeView.close() try: self._relationTypeModel.saveRelationType() except ConfigurationError, error: getDefaultLogger().error(error.message) else: self._parentFrame.updateRelationTypes() getDefaultLogger().info("Relation Type " + self._relationTypeModel.myTitle + " was successfully saved.") def __getattr__(self, name): """ Delegates calls to the generated PyQt class. """ return getattr(self._relationTypeView, name) class RelationTypeModel(QObject): """ This is the data model of the add/edit relation type dialog that contains the current relation type or none and the list of available data types """ def __init__(self, title, dataModelHandler, iconHandler): """
class Script(object): """ Represents a single script extension. """ _logger = getDefaultLogger() def __init__(self, fileStorer): """ Initialize a new script. @param fileStorer: Allowing access to the script data. @type fileStorer: L{FileStorer<datafinder.persistence.factory.FileStorer>} """ self._fileStorer = fileStorer self.uri = self._fileStorer.uri self.name = self._fileStorer.name self.location = None # Script options self.title = None self.description = None self.datatypes = list() self.dataformats = list() self.iconName = None self.version = None self.automatic = False self._parseScript() if self.iconName is None: self.iconName = "lightning_bolt" if self.title is None: self.title = fileStorer.name def _parseScript(self): """ Parse the script and extract the meta data. """ dataStream = self._fileStorer.readData() try: try: line = dataStream.readline() while line: line = line.strip() self._parse(line) line = dataStream.readline() finally: dataStream.close() except IOError: raise ConfigurationError("Cannot read script data.") def _parse(self, line): """ Evaluates the line and sets the corresponding script attribute. """ if line.startswith(_COMMENT_CHARACTER): if constants.TITLE_KEYWORD in line: self.title = line.split(constants.TITLE_KEYWORD)[1].strip() elif constants.DATATYPES_KEYWORD in line: datatypes = line.split( constants.DATATYPES_KEYWORD)[1].split(_LIST_SEPARATOR) for datatype in datatypes: datatype = datatype.strip() if len(datatype) > 0: self.datatypes.append(datatype) elif constants.DATAFORMATS_KEYWORD in line: dataformats = line.split( constants.DATAFORMATS_KEYWORD)[1].split(_LIST_SEPARATOR) for dataformat in dataformats: dataformat = dataformat.strip() if len(dataformat) > 0: self.dataformats.append(dataformat) elif constants.ICON_KEYWORD in line: self.iconName = line.split(constants.ICON_KEYWORD)[1].strip() elif constants.VERSION_KEYWORD in line: self.version = line.split(constants.VERSION_KEYWORD)[1].strip() elif constants.DESCRIPTION_KEYWORD in line: self.description = line.split( constants.DESCRIPTION_KEYWORD)[1].strip() elif constants.AUTOMATIC_EXECUTE_KEYWORD in line: self.automatic = True def execute(self): """ Execute the script. @param scriptOut: Object to write the script output to. @type scriptOut: Object with write() method. @raise ConfigurationError: Raised if execution of script caused an exception or script terminated with a negative return code. """ try: fileObject = self._fileStorer.readData() except PersistenceError, error: raise ConfigurationError("Cannot access script.\nReason: '%s'" % error.message) else:
#SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT #LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, #DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY #THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT #(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE #OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. """ Implements the model component of the create configuration dialog. """ __version__ = "$Revision-Id:$" from datafinder.common import logger from datafinder.core.error import ConfigurationError _logger = logger.getDefaultLogger() class CreateConfigurationModel(object): """ Implements the model component of the create configuration dialog. """ def __init__(self, repositoryManager): """ Constructor. """ self._repositoryManager = repositoryManager self._preferences = repositoryManager.preferences self._configurationUri = None self._dataPath = None self._repositoryConfiguration = None self._exists = None self._username = None self._password = None