api = VkApi() if api.isLogedIn(): self.track_list = VkAudio.parse(api.audio_get(api.current_user_id, api.audio_get_count(api.current_user_id))) for track in self.track_list: btn = QPushButton() btn.setText(track.artist + track.title) btn.clicked.connect(partial(self.on_track_click, track.url)) self.ui.track_list.add_widget_item(btn) self.show() def on_track_click(self, item_id): if self.track_list: for track in self.track_list: if track.url == item_id: self.ui.player_widget.prepare_playback(track) if __name__ == '__main__': app = QApplication(sys.argv) app.setStyle("Fusion") login = LoginDialog() if not login.exec_(): sys.exit(-1) ex = ZebraApplication() sys.exit(app.exec_())
class PSSOptimisation(object): def __init__(self): QtCore.QCoreApplication.setApplicationName("PSSOptimisation") QtCore.QCoreApplication.setApplicationVersion(str(VERSION)) QtCore.QCoreApplication.setOrganizationName("Hubert Grzeskowiak") self.settings = QtCore.QSettings() self.main_window = MainWindow(True) self.grades_model = GradesModel(self.main_window) self.proxy_model = GradesModelProxy() self.proxy_model.setSourceModel(self.grades_model) self.initUI() # tray = QtGui.QSystemTrayIcon(self.main_window) # tray.setIcon(QtGui.QIcon("icons/Accessories-calculator.svg")) # tray.connect(tray, # SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), # self.trayClicked) # tray.show() # self.tray = tray # def trayClicked(self, reason): # print reason # if reason == QtGui.QSystemTrayIcon.DoubleClick: # self.main_window.setVisible(not self.main_window.isVisible()) def initUI(self): self.connectUI() self.main_window.show() def __columnsChanged(self): """This should be called whenever the columns filter is changed. It's a workaround for a bug in the headerview not updating the columns properly on filter change. """ header = self.main_window.grades_table.horizontalHeader() header.resizeSections(QtGui.QHeaderView.ResizeToContents) header.resizeSection(0, header.sectionSize(0) - 1) header.resizeSection(0, header.sectionSize(0) + 1) def connectUI(self): self.main_window.grades_table.setModel(self.proxy_model) delegate = CheckBoxDelegate() self.main_window.grades_table.setItemDelegate(delegate) self.main_window.connect(self.main_window.action_download, SIGNAL("triggered()"), self.openLoginDialog) self.main_window.connect(self.main_window.action_donate, SIGNAL("triggered()"), self.openDonationDialog) self.main_window.connect(self.main_window.action_open, SIGNAL("triggered()"), self.openFileDialog) self.main_window.connect(self.grades_model, SIGNAL("dataChanged()"), self.updateStats) self.main_window.connect( self.grades_model, SIGNAL("dataChanged()"), self.main_window.grades_table.resizeColumnsToContents) self.main_window.connect(self.grades_model, SIGNAL("modelReset()"), self.updateStats) self.main_window.connect( self.grades_model, SIGNAL("modelReset()"), self.main_window.grades_table.resizeColumnsToContents) # workaround for buggy headerview self.main_window.connect(self.proxy_model, SIGNAL("columnsVisibilityChanged()"), self.__columnsChanged) # create actions for toggling table columns header = self.main_window.grades_table.horizontalHeader() self.header_actions = QtGui.QActionGroup(header) self.header_actions.setExclusive(False) for nr, (name, visible) in enumerate( zip(self.grades_model.header_data, self.proxy_model.col_visibility)): action = self.header_actions.addAction(name) action.setCheckable(True) action.setChecked(visible) action.connect(action, SIGNAL("triggered()"), lambda nr=nr: self.proxy_model.toggleColumn(nr)) # add that menu as context menu for the header header.addActions(self.header_actions.actions()) header.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu) # and put it into the main window's menus self.main_window.menu_table_columns.clear() for action in self.header_actions.actions(): self.main_window.menu_table_columns.addAction(action) # automatically download new grades (depends on settings) if self.settings.value("updateOnStart", False).toBool(): QtCore.QTimer.singleShot(200, self.tryAutoDownloadFromPSSO) def openLoginDialog(self): self.login_dialog = LoginDialog(self.main_window) self.login_dialog.exec_() if self.login_dialog.result(): username = str(self.login_dialog.username_line.text()) password = str(self.login_dialog.password_line.text()) if username and password: remember = self.login_dialog.remember_checkbox.isChecked() self.handleLoginData(username, password, remember) def handleLoginData(self, username, password, remember=False): """Try to load the grades by using the provided login credentials. On failure, an error popup is displayed. On success a loading progress bar and after that a table is shown. If "remember" is True, then the login data is saved. """ self.main_window.setDisabled(True) QtGui.QApplication.processEvents() QtGui.QApplication.processEvents() progress = 0 try: iterator = self.grades_model.getFromPSSOIterator( username, password) for step in iterator: self.main_window.showProgress(progress, step) # getFromPSSOIterator defines 8 steps, but 1st is at 0 progress += 100.0 / 7 QtGui.QApplication.processEvents() except (ConnectionError, ServiceUnavailableError, ParsingError) as e: QtGui.QMessageBox.critical(self.main_window, e.title, e.message) return except LoginError as e: self.clearLoginData(username) QtGui.QMessageBox.critical(self.main_window, e.title, e.message) return finally: self.main_window.setEnabled(True) self.main_window.showProgress(-1) self.main_window.showTable() self.main_window.setEnabled(True) if remember: self.saveLoginData(username, password) def saveLoginData(self, username, password): assert username and password self.settings.setValue("username", username) keyring.set_password("PSSO", username, password) def getLoginData(self): """Try to retrieve previously saved username and password. Returns a tuple of two empty strings on failure. """ username = str(self.settings.value("username").toString() or "") try: password = keyring.get_password("PSSO", username) or "" except IOError: return "", "" return username, password def clearLoginData(self, username=None): """Remove username and password settings. If a username is given, its password will be removed. If there is a saved username, it will also get removed alongside with the corresponding password. """ username2 = str(self.settings.value("username").toString() or "") try: keyring.delete_password("PSSO", username) except: pass try: keyring.delete_password("PSSO", username2) except: pass self.settings.remove("username") def tryAutoDownloadFromPSSO(self): u, p = self.getLoginData() if u and p: self.handleLoginData(u, p) def openFileDialog(self): ofd = OpenFileDialog(self.main_window) accepted = ofd.exec_() if accepted and ofd.html_file: try: html = codecs.open(ofd.html_file, encoding='utf-8') except IOError: QtGui.QMessageBox.warning( self.main_window, "File not found", "Sorry, but there seems to be no file called {}.".format( ofd.html_file)) return self.grades_model.getFromHTML(html) self.main_window.showTable() def openDonationDialog(self): dp = DonationDialog(self.main_window) dp.exec_() def updateStats(self): self.main_window.num_of_grades.setText( str(self.grades_model.getNumOfGrades())) self.main_window.num_of_credits.setText( str(self.grades_model.getNumOfCredits())) self.main_window.average_grade.setText( str(self.grades_model.getAverageGrade()))
class PSSOptimisation(object): def __init__(self): QtCore.QCoreApplication.setApplicationName("PSSOptimisation") QtCore.QCoreApplication.setApplicationVersion(str(VERSION)) QtCore.QCoreApplication.setOrganizationName("Hubert Grzeskowiak") self.settings = QtCore.QSettings() self.main_window = MainWindow(True) self.grades_model = GradesModel(self.main_window) self.proxy_model = GradesModelProxy() self.proxy_model.setSourceModel(self.grades_model) self.initUI() # tray = QtGui.QSystemTrayIcon(self.main_window) # tray.setIcon(QtGui.QIcon("icons/Accessories-calculator.svg")) # tray.connect(tray, # SIGNAL("activated(QSystemTrayIcon::ActivationReason)"), # self.trayClicked) # tray.show() # self.tray = tray # def trayClicked(self, reason): # print reason # if reason == QtGui.QSystemTrayIcon.DoubleClick: # self.main_window.setVisible(not self.main_window.isVisible()) def initUI(self): self.connectUI() self.main_window.show() def __columnsChanged(self): """This should be called whenever the columns filter is changed. It's a workaround for a bug in the headerview not updating the columns properly on filter change. """ header = self.main_window.grades_table.horizontalHeader() header.resizeSections(QtGui.QHeaderView.ResizeToContents) header.resizeSection(0, header.sectionSize(0)-1) header.resizeSection(0, header.sectionSize(0)+1) def connectUI(self): self.main_window.grades_table.setModel(self.proxy_model) delegate = CheckBoxDelegate() self.main_window.grades_table.setItemDelegate(delegate) self.main_window.connect(self.main_window.action_download, SIGNAL("triggered()"), self.openLoginDialog) self.main_window.connect(self.main_window.action_donate, SIGNAL("triggered()"), self.openDonationDialog) self.main_window.connect(self.main_window.action_open, SIGNAL("triggered()"), self.openFileDialog) self.main_window.connect(self.grades_model, SIGNAL("dataChanged()"), self.updateStats) self.main_window.connect(self.grades_model, SIGNAL("dataChanged()"), self.main_window.grades_table.resizeColumnsToContents) self.main_window.connect(self.grades_model, SIGNAL("modelReset()"), self.updateStats) self.main_window.connect(self.grades_model, SIGNAL("modelReset()"), self.main_window.grades_table.resizeColumnsToContents) # workaround for buggy headerview self.main_window.connect(self.proxy_model, SIGNAL("columnsVisibilityChanged()"), self.__columnsChanged) # create actions for toggling table columns header = self.main_window.grades_table.horizontalHeader() self.header_actions = QtGui.QActionGroup(header) self.header_actions.setExclusive(False) for nr, (name, visible) in enumerate(zip( self.grades_model.header_data, self.proxy_model.col_visibility)): action = self.header_actions.addAction(name) action.setCheckable(True) action.setChecked(visible) action.connect(action, SIGNAL("triggered()"), lambda nr=nr: self.proxy_model.toggleColumn(nr)) # add that menu as context menu for the header header.addActions(self.header_actions.actions()) header.setContextMenuPolicy( QtCore.Qt.ActionsContextMenu) # and put it into the main window's menus self.main_window.menu_table_columns.clear() for action in self.header_actions.actions(): self.main_window.menu_table_columns.addAction(action) # automatically download new grades (depends on settings) if self.settings.value("updateOnStart", False).toBool(): QtCore.QTimer.singleShot(200, self.tryAutoDownloadFromPSSO) def openLoginDialog(self): self.login_dialog = LoginDialog(self.main_window) self.login_dialog.exec_() if self.login_dialog.result(): username = str(self.login_dialog.username_line.text()) password = str(self.login_dialog.password_line.text()) if username and password: remember = self.login_dialog.remember_checkbox.isChecked() self.handleLoginData(username, password, remember) def handleLoginData(self, username, password, remember=False): """Try to load the grades by using the provided login credentials. On failure, an error popup is displayed. On success a loading progress bar and after that a table is shown. If "remember" is True, then the login data is saved. """ self.main_window.setDisabled(True) QtGui.QApplication.processEvents() QtGui.QApplication.processEvents() progress = 0 try: iterator = self.grades_model.getFromPSSOIterator(username, password) for step in iterator: self.main_window.showProgress(progress, step) # getFromPSSOIterator defines 8 steps, but 1st is at 0 progress += 100.0/7 QtGui.QApplication.processEvents() except (ConnectionError, ServiceUnavailableError, ParsingError) as e: QtGui.QMessageBox.critical(self.main_window, e.title, e.message) return except LoginError as e: self.clearLoginData(username) QtGui.QMessageBox.critical(self.main_window, e.title, e.message) return finally: self.main_window.setEnabled(True) self.main_window.showProgress(-1) self.main_window.showTable() self.main_window.setEnabled(True) if remember: self.saveLoginData(username, password) def saveLoginData(self, username, password): assert username and password self.settings.setValue("username", username) keyring.set_password("PSSO", username, password) def getLoginData(self): """Try to retrieve previously saved username and password. Returns a tuple of two empty strings on failure. """ username = str(self.settings.value("username").toString() or "") try: password = keyring.get_password("PSSO", username) or "" except IOError: return "", "" return username, password def clearLoginData(self, username=None): """Remove username and password settings. If a username is given, its password will be removed. If there is a saved username, it will also get removed alongside with the corresponding password. """ username2 = str(self.settings.value("username").toString() or "") try: keyring.delete_password("PSSO", username) except: pass try: keyring.delete_password("PSSO", username2) except: pass self.settings.remove("username") def tryAutoDownloadFromPSSO(self): u, p = self.getLoginData() if u and p: self.handleLoginData(u, p) def openFileDialog(self): ofd = OpenFileDialog(self.main_window) accepted = ofd.exec_() if accepted and ofd.html_file: try: html = codecs.open(ofd.html_file, encoding='utf-8') except IOError: QtGui.QMessageBox.warning(self.main_window, "File not found", "Sorry, but there seems to be no file called {}.".format( ofd.html_file)) return self.grades_model.getFromHTML(html) self.main_window.showTable() def openDonationDialog(self): dp = DonationDialog(self.main_window) dp.exec_() def updateStats(self): self.main_window.num_of_grades.setText(str( self.grades_model.getNumOfGrades())) self.main_window.num_of_credits.setText(str( self.grades_model.getNumOfCredits())) self.main_window.average_grade.setText(str( self.grades_model.getAverageGrade()))
from PyQt5.QtWidgets import QApplication from login_dialog import LoginDialog from main_window import MainWindow import sip import sys sip.setapi("QString", 1) if __name__ == "__main__": a = QApplication(sys.argv) a.setStyle("fusion") loginDialog = LoginDialog() isAuth = False result = -1 # while not isAuth: loginDialog.exec_() # if result == loginDialog.Success or result == loginDialog.Rejected: # isAuth = True # else: # isAuth = False isAuth = loginDialog.Success if isAuth == True: w = MainWindow() w.show() a.exec_() # exit(0)
class LizardDownloader: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'LizardDownloader_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.login_dialog = LoginDialog() self.import_dialog = LizardDownloaderDialog() self.upload_points_dialog = UploadPointsDialog() # Declare instance attributes self.actions = [] self.menu = self.tr(u'&GGMN lizard integration') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'LizardDownloader') self.toolbar.setObjectName(u'LizardDownloader') # Stored username/password, will be set by the login dialog. self.username = None self.password = None self.organisations = [] # Will be filled after logging in. self.selected_organisation = None self.start_date = datetime.date(1930, 1, 1) self.end_date = datetime.date.today() self.filename = None self.custom_filename = None self.custom_layer = None self.already_uploaded = [] # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('LizardDownloader', message) def add_action(self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/LizardDownloader/icon.png' self.add_action( icon_path, text=self.tr(u'Log into Lizard'), callback=self.run_login, add_to_toolbar=False, parent=self.iface.mainWindow()) self.add_action( icon_path, text=self.tr(u'Download from Lizard'), callback=self.run_import, add_to_toolbar=False, parent=self.iface.mainWindow()) self.download_custom_points_action = self.add_action( icon_path, text=self.tr(u'Download custom points from Lizard'), callback=self.run_custom_import, enabled_flag=False, add_to_toolbar=False, parent=self.iface.mainWindow()) self.upload_custom_points_action = self.add_action( icon_path, text=self.tr(u'Upload custom points to Lizard'), callback=self.run_upload, add_to_toolbar=False, enabled_flag=False, parent=self.iface.mainWindow()) self.upload_raster_action = self.add_action( icon_path, text=self.tr(u'Upload interpolation raster to Lizard'), callback=self.run_raster_upload, enabled_flag=False, add_to_toolbar=False, parent=self.iface.mainWindow()) def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&GGMN lizard integration'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def determine_organisations(self): if not (self.username and self.password): raise RuntimeError("Not logged in") single_user_api = SingleUserInfo() single_user_api.username = self.username single_user_api.password = self.password organisations_url = single_user_api.organisations_url() organisations_url = organisations_url.rstrip('/') organisations_api = Organisations() organisations_api.username = self.username organisations_api.password = self.password organisations_api.base_url = organisations_url return organisations_api.for_dialog() def run_login(self): """Show login dialog if the user isn't logged in yet.""" # show the dialog self.login_dialog.show() ok_pressed = self.login_dialog.exec_() if ok_pressed: self.username = self.login_dialog.username.text() self.password = self.login_dialog.password.text() self.organisations = self.determine_organisations() return ok_pressed def run_import(self): """Run method that performs all the real work""" if not (self.username and self.password): ok_pressed = self.run_login() if not ok_pressed: # Then we don't want to do anything either! return # Set up the dialog. (Should perhaps be moved to the dialog class.) self.import_dialog.organisationComboBox.clear() for organisation in self.organisations: self.import_dialog.organisationComboBox.addItem( organisation['name'], organisation['unique_id']) if self.selected_organisation: self.import_dialog.organisationComboBox.setCurrentIndex( self.import_dialog.organisationComboBox.findData( self.selected_organisation)) self.import_dialog.startDate.setDate( QDate(self.start_date.year, self.start_date.month, self.start_date.day)) self.import_dialog.endDate.setDate( QDate(self.end_date.year, self.end_date.month, self.end_date.day)) # show the dialog self.import_dialog.show() # Run the dialog event loop result = self.import_dialog.exec_() # See if OK was pressed if result: index = self.import_dialog.organisationComboBox.currentIndex() self.selected_organisation = self.organisations[index]['unique_id'] # print("Selected org: %s" % self.selected_organisation) self.start_date = self.import_dialog.startDate.date().toPyDate() self.end_date = self.import_dialog.endDate.date().toPyDate() start = self.start_date.strftime('%Y-%m-%dT00:00:00Z') end = self.end_date.strftime('%Y-%m-%dT00:00:00Z') gw_info = QGisLizardImporter(username=self.username, password=self.password, organisation_id=self.selected_organisation) self.iface.messageBar().pushMessage( "Lizard", "Downloading data (can take up to a minute)...") gw_info.download( start=start, end=end, groundwater_type=GROUNDWATER_TYPE) if gw_info.data: if not self.filename: # Take homedir as starting point self.filename = os.path.expanduser('~') self.filename = QFileDialog.getSaveFileName( self.iface.mainWindow(), self.tr("New shapefile to save downloaded data in"), self.filename, self.tr("Shape files (*.shp)")) gw_info.data_to_shape(filename=self.filename, overwrite=True) gw_info.load_shape(self.filename) self.download_custom_points_action.setDisabled(False) self.upload_raster_action.setDisabled(False) else: def _split_url(url): return '\n&'.join(url.split('&')) msg = """ No data found for period and extent. Technical debug info follows: Username: {username} Organisation ID: {organisation_id} Start date: {start} End date: {end} Locations url: {locations_url} len(locations): {locations_len} Timeseries url: {timeseries_url} len(timeseries): {timeseries_len} """.format(username=self.username, organisation_id=self.selected_organisation, start=start, end=end, locations_url=_split_url(gw_info.groundwater.locs.url), timeseries_url=_split_url(gw_info.groundwater.ts.url), locations_len=len(gw_info.groundwater.locs.results), timeseries_len=len(gw_info.groundwater.ts.results)) pop_up_info(msg=msg, title='No data found') return def run_custom_import(self): start = self.start_date.strftime('%Y-%m-%dT00:00:00Z') end = self.end_date.strftime('%Y-%m-%dT00:00:00Z') gw_info = QGisLizardCustomImporter(username=self.username, password=self.password, organisation_id=self.selected_organisation) gw_info.download( start=start, end=end, groundwater_type=CUSTOM_GROUNDWATER_TYPE) # It is fine to have no data. We'll just create an empty shapefile, # then. if not self.custom_filename: # Take homedir as starting point self.filename = os.path.expanduser('~') self.custom_filename = QFileDialog.getSaveFileName( self.iface.mainWindow(), self.tr("New shapefile to save downloaded CUSTOM data in"), self.filename, self.tr("Shape files (*.shp)")) gw_info.data_to_custom_shape(filename=self.custom_filename, overwrite=True) self.custom_layer = gw_info.load_custom_shape(self.custom_filename) self.custom_layer.featureDeleted.connect(self._record_deleted_point) self.custom_layer.featureAdded.connect(self._record_added_point) self.custom_layer.attributeValueChanged.connect(self._record_changed_point) self.upload_custom_points_action.setDisabled(False) def _record_deleted_point(self, id): # print("Point %s has been deleted" % id) pass def _record_added_point(self, id): # print("Point %s has been added" % id) pass def _record_changed_point(self, id, index, dont_care): # QgsFeatureId fid, int idx, const QVariant & # print("Point %s has been changed" % id) pass def run_upload(self): to_upload = [] for feature in self.custom_layer.getFeatures(): attrs = feature.attributes() value = attrs[0] downloaded = bool(attrs[1] == DOWNLOADED_MARKER) if downloaded: # We only upload new stuff continue wkt = feature.geometry().asPoint().wellKnownText() # ^^^ Hope that this is in the right coordinate system. if wkt in self.already_uploaded: # We already uploaded it earlier. continue to_upload.append({'feature': feature, 'wkt': wkt, 'value': value}) self.upload_points_dialog.number.setText(str(len(to_upload))) self.upload_points_dialog.show() # Run the dialog event loop result = self.upload_points_dialog.exec_() # See if OK was pressed if result: num_succeeded = 0 num_failed = 0 loc_api = Locations() loc_api.username = self.username loc_api.password = self.password loc_api.organisation_id = self.selected_organisation for point in to_upload: values = { 'name': GGMN_CUSTOM, 'organisation': self.selected_organisation, 'organisation_code': datetime.datetime.now().isoformat(), 'ddsc_show_on_map': 'false', 'access_modifier': 0, 'geometry': point['wkt']} try: location_uuid = loc_api.add_new_one(values) except Exception as e: # print(e) num_failed += 1 continue # print("Created location with uuid %s" % location_uuid) ts_api = TimeSeries() ts_api.username = self.username ts_api.password = self.password ts_api.organisation_id = self.selected_organisation values = {'name': GGMN_CUSTOM, 'location': location_uuid, 'supplier_code': datetime.datetime.now().isoformat(), 'organisation_code': datetime.datetime.now().isoformat(), 'access_modifier': 0, 'value_type': 1, # 1 = float 'parameter_referenced_unit': CUSTOM_GROUNDWATER_TYPE, } try: ts_id = ts_api.add_new_one(values) except Exception as e: # print(e) num_failed += 1 continue # print("Created timeserie id=%s" % ts_id) try: ts_api.add_value(ts_id, value=point['value']) except Exception as e: # print(e) num_failed += 1 continue self.already_uploaded.append(point['wkt']) num_succeeded += 1 pop_up_info("%s succesfully uploaded, %s failed" % (num_succeeded, num_failed)) def run_raster_upload(self): # The selected layer should be a raster layer. layer = self.iface.activeLayer() if not isinstance(layer, QgsRasterLayer): pop_up_info("Error: you must select the raster layer") return fd, tiff_filename = tempfile.mkstemp(suffix='.tiff') os.close(fd) # ^^^ We just want the filename, not the opened file descriptor. provider = layer.dataProvider() pipe = QgsRasterPipe() pipe.set(provider.clone()) file_writer = QgsRasterFileWriter(tiff_filename) file_writer.writeRaster(pipe, provider.xSize(), provider.ySize(), provider.extent(), provider.crs()) # http://build-failed.blogspot.nl/2014/12/splitting-vector-and-raster-files-in.html # print(tiff_filename) # Optionally TODO: grab title from dialog. title = "Uploaded by the qgis plugin on %s" % ( datetime.datetime.now().isoformat()) form = urllib2_upload.MultiPartForm() form.add_field('title', title) form.add_field('organisation_id', str(self.selected_organisation)) filename = os.path.basename(tiff_filename) form.add_file('raster_file', filename, fileHandle=open(tiff_filename, 'rb')) request = urllib2.Request('https://ggmn.un-igrac.org/upload_raster/') request.add_header('User-agent', 'qgis ggmn uploader') request.add_header('username', self.username) request.add_header('password', self.password) body = str(form) request.add_header('Content-type', form.get_content_type()) request.add_header('Content-length', len(body)) # print("content-length: %s" % len(body)) request.add_data(body) fd2, logfile = tempfile.mkstemp(prefix="uploadlog", suffix=".txt") open(logfile, 'w').write(request.get_data()) # print("Printed what we'll send to %s" % logfile) answer = urllib2.urlopen(request).read() # print(answer) # print("Uploaded geotiff to the server") pop_up_info("Uploaded geotiff to the server")
class SLTRPlugin: """QGIS Plugin Implementation.""" def __init__(self, iface): """Constructor. :param iface: An interface instance that will be passed to this class which provides the hook by which you can manipulate the QGIS application at run time. :type iface: QgsInterface """ # Save reference to the QGIS interface self.iface = iface # initialize plugin directory self.plugin_dir = os.path.dirname(__file__) if not sys.path.__contains__(self.plugin_dir): sys.path.append(self.plugin_dir) # initialize locale locale = QSettings().value('locale/userLocale')[0:2] locale_path = os.path.join( self.plugin_dir, 'i18n', 'SLTRPlugin_{}.qm'.format(locale)) if os.path.exists(locale_path): self.translator = QTranslator() self.translator.load(locale_path) if qVersion() > '4.3.3': QCoreApplication.installTranslator(self.translator) # Create the dialog (after translation) and keep reference self.dlg = LoginDialog() self.dlg2 = SolaPluginDialog() self.dlg3 = CreateFormDialog() # Declare instance attributes self.actions = [] self.fid_array = [] self.user = '' self.fid = 0 self.parcel_id = '' self.transactionId = '' configParser = ConfigParser.RawConfigParser() configfilepath = self.plugin_dir+os.path.sep+'config.ini' configParser.read(configfilepath) self.db_hostName = configParser.get('settings', 'Hostname') # '192.168.0.1' self.db_databaseName = configParser.get('settings', 'DatabaseName') # 'sltrportal' self.db_UserName = configParser.get('settings', 'Username') # 'postgres' self.db_password = configParser.get('settings', 'Password') # 'sola450' self.db_Port = int(configParser.get('settings', 'Port')) # 5432 self.url = configParser.get('settings', 'Url') # 'url=http://192.168.0.1:8080/geoserver/SLTR/wms?service=WMS&version=1.1.0&request=GetMap&layers=kano&styles=&crs=EPSG:26332&format=image/jpeg' print self.db_hostName print self.db_databaseName print self.db_UserName print self.db_password print self.url self.menu = self.tr(u'&SLTRPlugin') # TODO: We are going to let the user set this up in a future iteration self.toolbar = self.iface.addToolBar(u'SLTRPlugin') self.toolbar.setObjectName(u'SLTRPlugin') # noinspection PyMethodMayBeStatic def tr(self, message): """Get the translation for a string using Qt translation API. We implement this ourselves since we do not inherit QObject. :param message: String for translation. :type message: str, QString :returns: Translated version of message. :rtype: QString """ # noinspection PyTypeChecker,PyArgumentList,PyCallByClass return QCoreApplication.translate('SLTRPlugin', message) def add_action( self, icon_path, text, callback, enabled_flag=True, add_to_menu=True, add_to_toolbar=True, status_tip=None, whats_this=None, parent=None): """Add a toolbar icon to the toolbar. :param icon_path: Path to the icon for this action. Can be a resource path (e.g. ':/plugins/foo/bar.png') or a normal file system path. :type icon_path: str :param text: Text that should be shown in menu items for this action. :type text: str :param callback: Function to be called when the action is triggered. :type callback: function :param enabled_flag: A flag indicating if the action should be enabled by default. Defaults to True. :type enabled_flag: bool :param add_to_menu: Flag indicating whether the action should also be added to the menu. Defaults to True. :type add_to_menu: bool :param add_to_toolbar: Flag indicating whether the action should also be added to the toolbar. Defaults to True. :type add_to_toolbar: bool :param status_tip: Optional text to show in a popup when mouse pointer hovers over the action. :type status_tip: str :param parent: Parent widget for the new action. Defaults None. :type parent: QWidget :param whats_this: Optional text to show in the status bar when the mouse pointer hovers over the action. :returns: The action that was created. Note that the action is also added to self.actions list. :rtype: QAction """ icon = QIcon(icon_path) action = QAction(icon, text, parent) action.triggered.connect(callback) action.setEnabled(enabled_flag) if status_tip is not None: action.setStatusTip(status_tip) if whats_this is not None: action.setWhatsThis(whats_this) if add_to_toolbar: self.toolbar.addAction(action) if add_to_menu: self.iface.addPluginToMenu( self.menu, action) self.actions.append(action) return action def initGui(self): """Create the menu entries and toolbar icons inside the QGIS GUI.""" icon_path = ':/plugins/SLTRPlugin/icon.png' self.add_action( icon_path, text=self.tr(u'SLTR'), callback=self.run, parent=self.iface.mainWindow()) # self.toolbar = self.iface.addToolBar("SLTRToolBar") # Create actions def unload(self): """Removes the plugin menu item and icon from QGIS GUI.""" for action in self.actions: self.iface.removePluginMenu( self.tr(u'&SLTRPlugin'), action) self.iface.removeToolBarIcon(action) # remove the toolbar del self.toolbar def run(self): """Run method that performs all the real work""" # show the dialog self.dlg.show() # Run the dialog event loop result = self.dlg.exec_() # See if OK was pressed if result: # Do something useful here - delete the line containing pass and # substitute with your code. # Capture Login Details print self.dlg.userNameBox.text() print self.dlg.pswdBox.text() # Check User namer and password username = self.dlg.userNameBox.text() password = self.dlg.pswdBox.text() if self.authUser(username, password) == True: self.user = username self.iface.messageBar().pushMessage("Success", "Login Successful! Welcome " + self.dlg.userNameBox.text(), level=QgsMessageBar.INFO, duration=3) self.transactionId = self.getTransactionId() self.createRasterLayer() self.createLGALayer() self.createWardLayer() self.createSectionLayer() self.createBlockLayer() self.createParcelLayer() layer = self.iface.activeLayer() canvas = self.iface.mapCanvas() extent = layer.extent() canvas.setExtent(extent) self.dlg.close() else: self.iface.messageBar().pushMessage("Error", "Your Login attempt was unsuccessful. Please try again", level=QgsMessageBar.CRITICAL, duration=5) self.run() # tryout # END TRY''' def captureFeatures(self, fid): print 'Feature Added' print fid if fid in self.fid_array: print "in Capture Features: I saw it there!!" pass else: self.fid = fid self.fid_array.append(fid) self.initDialog('') def startEdit(self): print 'Edit started' def finishEdit(self): print 'Finished Editing!' # self.initDialog() layer = self.iface.activeLayer() self.initDialog('') def initDialog(self, error): if error != '': self.dlg2.error_label.setText(error) self.dlg2.show() result = self.dlg2.exec_() layer = self.iface.activeLayer() if result: if self.checkParcelNumberExists(self.dlg2.parcel_id.text()): self.parcel_id = self.dlg2.parcel_id.text() if self.dlg2.absentee.isChecked() == True: self.statuscode = 'absentee' print 'Absentee Claimant' else: self.statuscode = 'pending' print 'Present Claimant so pending' if self.dlg2.existing_title.isChecked() == True: self.existing_title = 'existing_title' print 'Existing Title' else: self.existing_title = self.parcel_id print 'No Existin Title for ' + self.parcel_id print ' just captured parcel' + self.parcel_id if self.checkParcelExistsAlready(self.parcel_id) == False: # self.dlg2.parcel_id.setText('') layer.featureAdded.disconnect(self.captureFeatures) print 'About to saveEdit' + self.parcel_id self.saveEdit(self.parcel_id, self.statuscode, self.existing_title) layer.featureAdded.connect(self.captureFeatures) else: # layer.deleteFeature(fid) # self.resetFid() # layer.commitChanges() # layer.startEditing() self.initDialog('Parcel Number already exists! Please check and try again') else: # self.resetFid() # layer.commitChanges() # layer.startEditing() self.initDialog('The Parcel Number doesn''t exist for the generated forms. Please try again') else: layer.deleteFeature(self.fid) layer.commitChanges() layer.startEditing() self.dlg2.parcel_id.setText('') def createParcelLayer(self): uri = QgsDataSourceURI() uri.setConnection(self.db_hostName, str(self.db_Port), self.db_databaseName, self.db_UserName, self.db_password) uri.setDataSource("cadastre", "cadastre_object", "geom_polygon") uri.uri() print uri.uri() rlayer = self.iface.addVectorLayer(uri.uri(), "Parcels", "postgres") self.iface.setActiveLayer(rlayer) rlayer.loadNamedStyle(self.plugin_dir + '/parcel.qml') #rlayer.layerModified.connect(self.captureFeatures) rlayer.featureAdded.connect(self.captureFeatures) rlayer.setEditForm(self.plugin_dir + os.sep + 'createForm.ui') #rlayer.setEditFormInit('.CreateFormDialog.formOpen') rlayer.startEditing() def createWardLayer(self): uri = QgsDataSourceURI() uri.setConnection(self.db_hostName, str(self.db_Port), self.db_databaseName, self.db_UserName, self.db_password) uri.setDataSource("cadastre", "spatial_unit_group", "geom", "hierarchy_level=3") uri.uri() print uri.uri() rlayer = self.iface.addVectorLayer(uri.uri(), "Ward", "postgres") rlayer.loadNamedStyle(self.plugin_dir + '/ward.qml') def createLGALayer(self): uri = QgsDataSourceURI() uri.setConnection(self.db_hostName, str(self.db_Port), self.db_databaseName, self.db_UserName, self.db_password) uri.setDataSource("cadastre", "spatial_unit_group", "geom", "hierarchy_level=2") uri.uri() print uri.uri() rlayer = self.iface.addVectorLayer(uri.uri(), "LGA", "postgres") rlayer.loadNamedStyle(self.plugin_dir + '/lga.qml') def createRasterLayer(self): # http://192.168.0.1:8080/geoserver/SLTR/wms urlWithParams = self.url rlayer = QgsRasterLayer(urlWithParams, 'Orthophoto', 'wms') QgsMapLayerRegistry.instance().addMapLayer(rlayer) # urlWithParams = 'url=http://localhost:8085/geoserver/calabar/wms?service=WMS&version=1.1.0&request=GetMap&layers=Calabar_20Dec2013_50cm_Colr2&styles=&srs=EPSG:4326&format=image/jpeg' # rlayer = QgsRasterLayer(urlWithParams, 'Orthophoto', 'wms') # QgsMapLayerRegistry.instance().addMapLayer(rlayer) # urlWithParams = 'url=http://localhost:8085/geoserver/lokoja/wms?service=WMS&version=1.1.0&request=GetMap&layers=Lokoja_Mos_Nov2011_50cm_Color&styles=&crs=EPSG:32632&format=image/png' # rlayer = QgsRasterLayer(urlWithParams, 'Orthophoto', 'wms') # QgsMapLayerRegistry.instance().addMapLayer(rlayer) def createSectionLayer(self): uri = QgsDataSourceURI() uri.setConnection(self.db_hostName, str(self.db_Port), self.db_databaseName, self.db_UserName, self.db_password) uri.setDataSource("cadastre", "spatial_unit_group", "geom", "hierarchy_level=4") uri.uri() print uri.uri() rlayer = self.iface.addVectorLayer(uri.uri(), "Section", "postgres") rlayer.loadNamedStyle(self.plugin_dir + '/lga.qml') def createBlockLayer(self): uri = QgsDataSourceURI() uri.setConnection(self.db_hostName, str(self.db_Port), self.db_databaseName, self.db_UserName, self.db_password) uri.setDataSource("cadastre", "spatial_unit_group", "geom", "hierarchy_level=5") uri.uri() print uri.uri() rlayer = self.iface.addVectorLayer(uri.uri(), "Blocks", "postgres") rlayer.loadNamedStyle(self.plugin_dir + '/lga.qml') def authUser(self, username, password): db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): # assume you have a table called 'appuser' query = db.exec_("select * from public.user where username='******' AND qpass = '******'") # No password implementations yet # iterate over the rows if query.size() == 1: return True else: return False pass def saveEdit(self, parcel_id, statuscode, existing_title): layer = self.iface.activeLayer() fid = self.fid print 'current featureID' + parcel_id print 'in saving of edits A as: ' + parcel_id # print feature.id() # print feature.geometry() # dataProvider=layer.dataProvider() # absentee or pending for status caps = layer.dataProvider().capabilities() # if caps & QgsVectorDataProvider.AddAttributes: feature = layer.getFeatures(QgsFeatureRequest(fid)).next() # transaction_id=self.getTransactionId() # check that the specified parcel number exists print 'current Transaction ID ' + self.transactionId print 'in saving of edits B' + parcel_id if self.checkParcelExistsAlready(parcel_id) == False: name_lastpart=self.getNameLastPart(feature.geometry().exportToWkt()) layer.changeAttributeValue(fid, feature.fieldNameIndex('id'), self.getUUID()) layer.changeAttributeValue(fid, feature.fieldNameIndex('type_code'), 'parcel') layer.changeAttributeValue(fid, feature.fieldNameIndex('source_reference'), existing_title) layer.changeAttributeValue(fid, feature.fieldNameIndex('name_firstpart'), parcel_id) layer.changeAttributeValue(fid, feature.fieldNameIndex('name_lastpart'), name_lastpart) layer.changeAttributeValue(fid, feature.fieldNameIndex('status_code'), statuscode) layer.changeAttributeValue(fid, feature.fieldNameIndex('change_action'), 'i') layer.changeAttributeValue(fid, feature.fieldNameIndex('change_user'), self.user) layer.changeAttributeValue(fid, feature.fieldNameIndex('transaction_id'), self.transactionId) layer.changeAttributeValue(fid, feature.fieldNameIndex('land_use_code'), 'residential') layer.changeAttributeValue(fid, feature.fieldNameIndex('view_id'), 1) #self.fid_array.append(fid) # feat.setGeometry() (res, outFeat) = layer.dataProvider().addFeatures([feature]) layer.commitChanges() layer.startEditing() print 'finished saveEdit' else: self.initDialog('An error has occurred. Duplicate Parcel Number. Please check and try again') pass def checkParcelNumberExists(self, parcelNumber): # Check the forms table to verify the existence of the parcel number in the form table db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): # assume you have a table called 'appuser' query = db.exec_("select nr from public.form where nr='" + parcelNumber + "'") print 'in checkParcelNumberExists' # iterate over the rows to see if there is only one record and it exists if query.size() == 1: return True else: return False pass # Implementation to standardize db calls def checkParcelExistsAlready(self, parcelNumber): db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): query = db.exec_( "select name_firstpart from cadastre.cadastre_object where name_firstpart='" + parcelNumber + "'") print 'in checkParcelExistsAlready' # iterate over the rows to see if there is only one record and it exists if query.size() == 1: print query.size() return True else: return False pass def getTransactionId(self): # return '010656ad-1725-41e6-b172-064e9b89b323' # Essentially create a transaction ID in code, insert the transaction entry and store in the session variable did = str(self.getUUID()) db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): # assume you have a table called 'appuser' query = db.exec_("insert into transaction.transaction(id,change_action,change_user) VALUES('" + did + "','i','" + self.user + "')") # iterate over the rows if query.size() == 1: #self.transactionId = did print "in getTransactionId success" + did print did return did # else: # self.iface.messageBar().pushMessage("Error", # "An error has occurred. Please notify the administrator", # level=QgsMessageBar.CRITICAL, duration=5) def getUUID(self): db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): # assume you have a table called 'appuser' query = db.exec_("select uuid_generate_v1()") print "in getUUID" # iterate over the rows if query.size() == 1: query.next() return str(query.value(0)) else: return False pass def getNameLastPart(self, geom): db = QSqlDatabase('QPSQL') if db.isValid(): db.setHostName(self.db_hostName) # string db.setDatabaseName(self.db_databaseName) # string db.setUserName(self.db_UserName) # string db.setPassword(self.db_password) # integer e.g. 5432 db.setPort(self.db_Port) if db.open(): print str(geom) query=db.exec_("select cadastre.get_new_cadastre_object_identifier_last_part((SELECT ST_PolygonFromText(('"+str(geom)+"'),32632)),'value')") print "in getNameLastPart" if query.size()==1: query.next() print str(query.value(0)) return str(query.value(0)) else: return '' pass pass def checkOverlaps(self): pass def resetFid(self): self.fid = 0