def run(self, edited_command=None): proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc) ) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc) ) if not edited_command: ili2db_jar_arg = self._ili2db_jar_arg() if ili2db_jar_arg == self.ILI2DB_NOT_FOUND: return self.ILI2DB_NOT_FOUND args = self._args(False) java_path = get_java_path(self.configuration.base_configuration) proc.start(java_path, ili2db_jar_arg + args) else: proc.start(self.command_with_password(edited_command)) if not proc.waitForStarted(): proc = None if not proc: raise JavaNotFoundError() self.process_started.emit(self.command_without_password(edited_command)) self.__result = self.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result
def _get_sync(self, qurl: QUrl, timeout: int = 20000) -> Reply: ''' synchronous GET-request ''' request = QNetworkRequest(qurl) ## newer versions of QGIS (3.6+) support synchronous requests #if hasattr(self._manager, 'blockingGet'): #reply = self._manager.blockingGet(request, forceRefresh=True) ## use blocking event loop for older versions #else: loop = QEventLoop() timer = QTimer() timer.setSingleShot(True) # reply or timeout break event loop, whoever comes first timer.timeout.connect(loop.quit) reply = self._manager.get(request) reply.finished.connect(loop.quit) timer.start(timeout) # start blocking loop loop.exec() loop.deleteLater() if not timer.isActive(): reply.deleteLater() raise ConnectionError('Timeout') timer.stop() #if reply.error(): #self.error.emit(reply.errorString()) #raise ConnectionError(reply.errorString()) res = Reply(reply) self.finished.emit(res) return res
def testStoreMissingAuth(self): """ Test file storing with missing authentication """ f = self.getNewFile(b"New content") storedContent = self.storage.store(f.name, self.url + "/" + os.path.basename(f.name)) self.assertTrue(storedContent) self.assertEqual(storedContent.status(), Qgis.ContentStatus.NotStarted) spyStored = QSignalSpy(storedContent.stored) spyCanceled = QSignalSpy(storedContent.canceled) loop = QEventLoop() storedContent.errorOccurred.connect(loop.quit) QTimer.singleShot(1, lambda: storedContent.store()) loop.exec() self.assertEqual(storedContent.status(), Qgis.ContentStatus.Failed) self.assertTrue(storedContent.errorString()) self.assertFalse(storedContent.url()) QCoreApplication.processEvents() self.assertEqual(len(spyStored), 0) self.assertEqual(len(spyCanceled), 0)
def _run(self): loop = QEventLoop() for session_widget in self.session_widget_list: session_widget.on_done_or_skipped.connect(lambda: loop.quit()) # fall in a loop on fail untill the user skipped it or it has been successful if not session_widget.run(): loop.exec()
def run(self): ili2db_bin = get_ili2db_bin(self.tool_name, self.stdout, self.stderr, ili2db_tools) if not ili2db_bin: return ili2db_jar_arg = ["-jar", ili2db_bin] self.configuration.tool_name = self.tool_name args = self.configuration.to_ili2db_args() if self.configuration.base_configuration.java_path: # A java path is configured: respect it no mather what java_paths = [self.configuration.base_configuration.java_path] else: # By default try JAVA_HOME and PATH java_paths = [] if 'JAVA_HOME' in os.environ: paths = os.environ['JAVA_HOME'].split(";") for path in paths: java_paths += [ os.path.join( path.replace("\"", "").replace("'", ""), 'java') ] java_paths += ['java'] proc = None for java_path in java_paths: proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) proc.start(java_path, ili2db_jar_arg + args) if not proc.waitForStarted(): proc = None else: break if not proc: raise JavaNotFoundError() safe_args = ili2db_jar_arg + self.configuration.to_ili2db_args( hide_password=True) safe_command = java_path + ' ' + ' '.join(safe_args) self.process_started.emit(safe_command) self.__result = Exporter.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result
def update_referecedata_cache_model(self, filter_models, type): # updates the model and waits for the end loop = QEventLoop() self.ilireferencedatacache.model_refreshed.connect(lambda: loop.quit()) timer = QTimer() timer.setSingleShot(True) timer.timeout.connect(lambda: loop.quit()) timer.start(10000) self.refresh_referencedata_cache(filter_models, type) loop.exec() return self.ilireferencedatacache.model
def testStoreWithoutFileName(self): """ Test file storing and fetching """ f = self.getNewFile(b"New content") # store storedContent = self.storage.store(f.name, self.url + "/", self.auth_config.id()) self.assertTrue(storedContent) self.assertEqual(storedContent.status(), Qgis.ContentStatus.NotStarted) spyErrorOccurred = QSignalSpy(storedContent.errorOccurred) spyProgressChanged = QSignalSpy(storedContent.progressChanged) loop = QEventLoop() storedContent.stored.connect(loop.quit) storedContent.errorOccurred.connect(loop.quit) QTimer.singleShot(1, lambda: storedContent.store()) loop.exec() self.assertEqual(len(spyErrorOccurred), 0) self.assertFalse(storedContent.errorString()) self.assertEqual(storedContent.url(), self.url + "/" + os.path.basename(f.name)) self.assertEqual(storedContent.status(), Qgis.ContentStatus.Finished) self.assertTrue(len(spyProgressChanged) > 0) self.assertEqual(spyProgressChanged[-1][0], 100) # fetch fetchedContent = self.storage.fetch( self.url + "/" + os.path.basename(f.name), self.auth_config.id()) self.assertTrue(fetchedContent) self.assertEqual(fetchedContent.status(), Qgis.ContentStatus.NotStarted) spyErrorOccurred = QSignalSpy(fetchedContent.errorOccurred) loop = QEventLoop() fetchedContent.fetched.connect(loop.quit) fetchedContent.errorOccurred.connect(loop.quit) QTimer.singleShot(1, lambda: fetchedContent.fetch()) loop.exec() self.assertEqual(len(spyErrorOccurred), 0) self.assertEqual(fetchedContent.status(), Qgis.ContentStatus.Finished) self.assertFalse(fetchedContent.errorString()) self.assertTrue(fetchedContent.filePath()) self.checkContent(fetchedContent.filePath(), b"New content") self.assertEqual( os.path.splitext(fetchedContent.filePath())[1], '.txt')
def save_wms_image(filename, url, layer, extent): bbox = "%f,%f,%f,%f" % (extent.xMinimum(), extent.yMinimum(), extent.xMaximum(), extent.yMaximum()) h = int(extent.height() / extent.width() * WIDTH) url = ( "%s/wms?request=GetMap&service=WMS&version=1.1.1&srs=EPSG:4326&layers=visualtests:%s&" "styles=visualtests:%s&format=image/png&width=%i&height=%i&bbox=%s" % (url, layer.name(), layer.name(), WIDTH, h, bbox)) nam = QNetworkAccessManager() reply = nam.get(QNetworkRequest(QUrl(url))) loop = QEventLoop() reply.finished.connect(loop.quit) loop.exec() img = QImage() img.loadFromData(reply.readAll()) img.save(filename)
def decorated_function(*args, **kwargs): inst = args[0] if type( args[0]).__name__ == 'AsistenteLADMCOLPlugin' else args[0].ladmcol # Check if Invisible Layers and Groups is installed and active, install it if necessary if not inst.ilg_plugin.check_if_dependency_is_valid(): loop = QEventLoop() # Do the installation synchronously inst.ilg_plugin.download_dependency_completed.connect(loop.exit) inst.ilg_plugin.install() inst.logger.info( __name__, "Installing dependency ({} {})...".format( INVISIBLE_LAYERS_AND_GROUPS_PLUGIN_NAME, INVISIBLE_LAYERS_AND_GROUPS_MIN_REQUIRED_VERSION)) loop.exec() func_to_decorate(*args, **kwargs)
def run(self): ili2db_bin = get_ili2db_bin(self.tool, self.stdout, self.stderr) if not ili2db_bin: return ili2db_jar_arg = ["-jar", ili2db_bin] self.configuration.tool = self.tool db_simple_factory = DbSimpleFactory() db_factory = db_simple_factory.create_factory(self.tool) config_manager = db_factory.get_db_command_config_manager( self.configuration) args = config_manager.get_ili2db_args(False) args_hide_password = config_manager.get_ili2db_args(True) java_path = get_java_path(self.configuration.base_configuration) proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) proc.start(java_path, ili2db_jar_arg + args) if not proc.waitForStarted(): proc = None if not proc: raise JavaNotFoundError() safe_args = ili2db_jar_arg + args_hide_password safe_command = java_path + ' ' + ' '.join(safe_args) self.process_started.emit(safe_command) self.__result = Importer.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result
def _post_sync(self, qurl: QUrl, timeout: int = 20000, data: bytes = b'', content_type=None): ''' synchronous POST-request ''' request = QNetworkRequest(qurl) if content_type: request.setHeader(QNetworkRequest.ContentTypeHeader, content_type) # newer versions of QGIS (3.6+) support synchronous requests if hasattr(self._manager, 'blockingPost'): reply = self._manager.blockingPost(request, data, forceRefresh=True) # use blocking event loop for older versions else: loop = QEventLoop() timer = QTimer() timer.setSingleShot(True) # reply or timeout break event loop, whoever comes first timer.timeout.connect(loop.quit) reply = self._manager.post(request, data) reply.finished.connect(loop.quit) timer.start(timeout) # start blocking loop loop.exec() loop.deleteLater() if not timer.isActive(): reply.deleteLater() raise ConnectionError('Timeout') timer.stop() if reply.error(): self.error.emit(reply.errorString()) raise ConnectionError(reply.errorString()) res = Reply(reply) self.finished.emit(res) return res
def get_topping_file_model(self, id_list): topping_file_cache = IliToppingFileCache( self.import_schema_configuration.base_configuration, id_list) # we wait for the download or we timeout after 30 seconds and we apply what we have loop = QEventLoop() topping_file_cache.download_finished.connect(lambda: loop.quit()) timer = QTimer() timer.setSingleShot(True) timer.timeout.connect(lambda: loop.quit()) timer.start(30000) topping_file_cache.refresh() self.log_panel.print_info(self.tr("- - Downloading…"), LogColor.COLOR_TOPPING) if len(topping_file_cache.downloaded_files) != len(id_list): loop.exec() if len(topping_file_cache.downloaded_files) == len(id_list): self.log_panel.print_info( self.tr("- - All topping files successfully downloaded"), LogColor.COLOR_TOPPING, ) else: missing_file_ids = id_list for downloaded_file_id in topping_file_cache.downloaded_files: if downloaded_file_id in missing_file_ids: missing_file_ids.remove(downloaded_file_id) self.log_panel.print_info( self. tr("- - Some topping files where not successfully downloaded: {}" ).format(" ".join(missing_file_ids)), LogColor.COLOR_TOPPING, ) return topping_file_cache.model
def generate_report(self, db, report_type): # Check if mapfish and Jasper are installed, otherwise show where to # download them from and return base_path = os.path.join(os.path.expanduser('~'), 'Asistente-LADM_COL', 'impresion') bin_path = os.path.join(base_path, 'bin') if not os.path.exists(bin_path): self.qgis_utils.message_with_button_download_report_dependency_emitted.emit( QCoreApplication.translate( "ReportGenerator", "The dependency library to generate reports is not installed. Click on the button to download and install it." )) return # Check version required_version_found = True version_path = os.path.join(base_path, 'version') if not os.path.exists(version_path): required_version_found = False else: version_found = '' with open(version_path) as f: version_found = f.read() if version_found.strip() != REPORTS_REQUIRED_VERSION: required_version_found = False if not required_version_found: self.qgis_utils.message_with_button_remove_report_dependency_emitted.emit( QCoreApplication.translate( "ReportGenerator", "The dependency library to generate reports was found, but does not match with the version required. Click the button to remove the installed version and try again." )) return # Check if JAVA_HOME path is set, otherwise use path from QGIS Model Baker if os.name == 'nt': if 'JAVA_HOME' not in os.environ: self.msg = QMessageBox() self.msg.setIcon(QMessageBox.Information) self.msg.setText( QCoreApplication.translate( "ReportGenerator", "JAVA_HOME environment variable is not defined, please define it as an enviroment variable on Windows and restart QGIS before generating the annex 17." )) self.msg.setWindowTitle( QCoreApplication.translate("ReportGenerator", "JAVA_HOME not defined")) self.msg.setStandardButtons(QMessageBox.Close) self.msg.exec_() return plot_layer = self.qgis_utils.get_layer(db, PLOT_TABLE, QgsWkbTypes.PolygonGeometry, load=True) if plot_layer is None: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "Layer 'Plot' not found in DB! {}").format( db.get_description()), Qgis.Warning) return selected_plots = plot_layer.selectedFeatures() if not selected_plots: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "To generate reports, first select at least a plot!"), Qgis.Warning) return # Where to store the reports? previous_folder = QSettings().value( "Asistente-LADM_COL/reports/save_into_dir", ".") save_into_folder = QFileDialog.getExistingDirectory( None, QCoreApplication.translate( "ReportGenerator", "Select a folder to save the reports to be generated"), previous_folder) if not save_into_folder: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "You need to select a folder where to save the reports before continuing." ), Qgis.Warning) return QSettings().setValue("Asistente-LADM_COL/reports/save_into_dir", save_into_folder) config_path = os.path.join(base_path, report_type) json_spec_file = os.path.join(config_path, 'spec_json_file.json') script_name = '' if os.name == 'posix': script_name = 'print' elif os.name == 'nt': script_name = 'print.bat' script_path = os.path.join(bin_path, script_name) if not os.path.isfile(script_path): print("### SCRIPT FILE WASN'T FOUND") return self.enable_action_requested.emit(report_type, False) # Update config file yaml_config_path = self.update_yaml_config(db, config_path) print("CONFIG FILE:", yaml_config_path) total = len(selected_plots) step = 0 count = 0 tmp_dir = self.get_tmp_dir() # Progress bar setup progress = QProgressBar() if total == 1: progress.setRange(0, 0) else: progress.setRange(0, 100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.qgis_utils.create_progress_message_bar_emitted.emit( QCoreApplication.translate("ReportGenerator", "Generating {} report{}...").format( total, '' if total == 1 else 's'), progress) polygons_with_holes = [] multi_polygons = [] for selected_plot in selected_plots: plot_id = selected_plot[ID_FIELD] geometry = selected_plot.geometry() abstract_geometry = geometry.get() if abstract_geometry.ringCount() > 1: polygons_with_holes.append(str(plot_id)) self.log.logMessage( QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it has holes. The reporter module does not support such polygons." ).format(ID_FIELD, plot_id), PLUGIN_NAME, Qgis.Warning) continue if abstract_geometry.numGeometries() > 1: multi_polygons.append(str(plot_id)) self.log.logMessage( QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it is a multi-polygon. The reporter module does not support such polygons." ).format(ID_FIELD, plot_id), PLUGIN_NAME, Qgis.Warning) continue # Generate data file json_file = self.update_json_data(db, json_spec_file, plot_id, tmp_dir, report_type) print("JSON FILE:", json_file) # Run sh/bat passing config and data files proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) parcel_number = self.ladm_data.get_parcels_related_to_plot( db, plot_id, PARCEL_NUMBER_FIELD) or [''] file_name = '{}_{}_{}.pdf'.format(report_type, plot_id, parcel_number[0]) current_report_path = os.path.join(save_into_folder, file_name) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): # Grant execution permissions os.chmod( script_path, stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): proc = None print("### COULDN'T EXECUTE SCRIPT TO GENERATE REPORT...") else: loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() print(plot_id, ':', proc.exitCode()) if proc.exitCode() == 0: count += 1 step += 1 progress.setValue(step * 100 / total) os.remove(yaml_config_path) self.enable_action_requested.emit(report_type, True) self.qgis_utils.clear_message_bar_emitted.emit() if total == count: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report <a href='file:///{}'>{}</a> was successfully generated!" ).format(normalize_local_url(save_into_folder), file_name) else: msg = QCoreApplication.translate( "ReportGenerator", "All reports were successfully generated in folder <a href='file:///{path}'>{path}</a>!" ).format(path=normalize_local_url(save_into_folder)) self.qgis_utils.message_with_duration_emitted.emit( msg, Qgis.Success, 0) else: details_msg = '' if polygons_with_holes: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they have holes and are not supported: {}." ).format(", ".join(polygons_with_holes)) if multi_polygons: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they are multi-polygons and are not supported: {}." ).format(", ".join(multi_polygons)) if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report for plot {} couldn't be generated!{} See QGIS log (tab '{}') for details." ).format(plot_id, details_msg, self.LOG_TAB) else: if count == 0: msg = QCoreApplication.translate( "ReportGenerator", "No report could be generated!{} See QGIS log (tab '{}') for details." ).format(details_msg, self.LOG_TAB) else: msg = QCoreApplication.translate( "ReportGenerator", "At least one report couldn't be generated!{details_msg} See QGIS log (tab '{log_tab}') for details. Go to <a href='file:///{path}'>{path}</a> to see the reports that were generated." ).format(details_msg=details_msg, path=normalize_local_url(save_into_folder), log_tab=self.LOG_TAB) self.qgis_utils.message_with_duration_emitted.emit( msg, Qgis.Warning, 0)
def testStoreFetchFileImmediately(self): """ Test file storing and fetching (Immediately mode) """ f = self.getNewFile(b"New content") # store url = self.url + "/" + os.path.basename(f.name) storedContent = self.storage.store(f.name, url, self.auth_config.id(), Qgis.ActionStart.Immediate) self.assertTrue(storedContent) self.assertEqual(storedContent.status(), Qgis.ContentStatus.Running) spyErrorOccurred = QSignalSpy(storedContent.errorOccurred) spyProgressChanged = QSignalSpy(storedContent.progressChanged) loop = QEventLoop() storedContent.stored.connect(loop.quit) storedContent.errorOccurred.connect(loop.quit) loop.exec() self.assertEqual(len(spyErrorOccurred), 0) self.assertEqual(storedContent.url(), url) self.assertFalse(storedContent.errorString()) self.assertEqual(storedContent.status(), Qgis.ContentStatus.Finished) self.assertTrue(len(spyProgressChanged) > 0) self.assertEqual(spyProgressChanged[-1][0], 100) # fetch fetchedContent = self.storage.fetch(self.url + "/" + os.path.basename(f.name), self.auth_config.id(), Qgis.ActionStart.Immediate) self.assertTrue(fetchedContent) # Some external storage (SimpleCopy) doesn't actually need to retrieve the resource self.assertTrue(fetchedContent.status() == Qgis.ContentStatus.Finished or fetchedContent.status() == Qgis.ContentStatus.Running) if (fetchedContent.status() == Qgis.ContentStatus.Running): spyErrorOccurred = QSignalSpy(fetchedContent.errorOccurred) loop = QEventLoop() fetchedContent.fetched.connect(loop.quit) fetchedContent.errorOccurred.connect(loop.quit) loop.exec() self.assertEqual(len(spyErrorOccurred), 0) self.assertEqual(fetchedContent.status(), Qgis.ContentStatus.Finished) self.assertFalse(fetchedContent.errorString()) self.assertTrue(fetchedContent.filePath()) self.checkContent(fetchedContent.filePath(), b"New content") self.assertEqual(os.path.splitext(fetchedContent.filePath())[1], '.txt') # fetch again, should be cached fetchedContent = self.storage.fetch(self.url + "/" + os.path.basename(f.name), self.auth_config.id(), Qgis.ActionStart.Immediate) self.assertTrue(fetchedContent) self.assertEqual(fetchedContent.status(), Qgis.ContentStatus.Finished) self.assertTrue(not fetchedContent.errorString()) self.assertTrue(fetchedContent.filePath()) self.checkContent(fetchedContent.filePath(), b"New content") self.assertEqual(os.path.splitext(fetchedContent.filePath())[1], '.txt') # fetch bad url fetchedContent = self.storage.fetch(self.url + "/error", self.auth_config.id(), Qgis.ActionStart.Immediate) self.assertTrue(fetchedContent) # Some external storage (SimpleCopy) doesn't actually need to retrieve the resource self.assertTrue(fetchedContent.status() == Qgis.ContentStatus.Failed or fetchedContent.status() == Qgis.ContentStatus.Running) if (fetchedContent.status() == Qgis.ContentStatus.Running): spyErrorOccurred = QSignalSpy(fetchedContent.errorOccurred) loop = QEventLoop() fetchedContent.errorOccurred.connect(loop.quit) fetchedContent.fetched.connect(loop.quit) loop.exec() self.assertEqual(len(spyErrorOccurred), 1) self.assertEqual(fetchedContent.status(), Qgis.ContentStatus.Failed) self.assertTrue(fetchedContent.errorString()) self.assertFalse(fetchedContent.filePath())
def run(self): ili2db_bin = get_ili2db_bin(self.tool_name, self.stdout, self.stderr, ili2db_tools) if not ili2db_bin: return args = ["-jar", ili2db_bin] args += ["--schemaimport"] if self.tool_name == 'ili2pg': # PostgreSQL specific options args += ["--dbhost", self.configuration.host] if self.configuration.port: args += ["--dbport", self.configuration.port] args += ["--dbusr", self.configuration.user] if self.configuration.password: args += ["--dbpwd", self.configuration.password] args += ["--dbdatabase", self.configuration.database] args += [ "--dbschema", self.configuration.schema or self.configuration.database ] args += ["--setupPgExt"] elif self.tool_name == 'ili2gpkg': args += ["--dbfile", self.configuration.dbfile] args += ["--coalesceCatalogueRef"] args += ["--createEnumTabs"] args += ["--createNumChecks"] args += ["--coalesceMultiSurface"] args += ["--coalesceMultiLine"] args += ["--strokeArcs"] args += ["--beautifyEnumDispName"] #args += ["--createBasketCol"] args += ["--createUnique"] args += ["--createGeomIdx"] args += ["--createFk"] args += ["--createFkIdx"] args += ["--createMetaInfo"] if self.configuration.inheritance == 'smart1': args += ["--smart1Inheritance"] elif self.configuration.inheritance == 'smart2': args += ["--smart2Inheritance"] else: args += ["--noSmartMapping"] proxy = QgsNetworkAccessManager.instance().fallbackProxy() if proxy.type() == QNetworkProxy.HttpProxy: args += ["--proxy", proxy.hostName()] args += ["--proxyPort", str(proxy.port())] if self.configuration.epsg != 21781: args += ["--defaultSrsCode", "{}".format(self.configuration.epsg)] if self.configuration.ilimodels: args += ['--models', self.configuration.ilimodels] if self.configuration.ilifile: # Valid ili file, don't pass --modelDir (it can cause ili2db # errors) args += self.configuration.base_configuration.to_ili2db_args( export_modeldir=False) args += [self.configuration.ilifile] else: args += self.configuration.base_configuration.to_ili2db_args() if self.configuration.base_configuration.java_path: # A java path is configured: respect it no mather what java_paths = [self.configuration.base_configuration.java_path] else: # By default try JAVA_HOME and PATH java_paths = [] if 'JAVA_HOME' in os.environ: paths = os.environ['JAVA_HOME'].split(os.pathsep) for path in paths: java_paths += [ os.path.join( path.replace("\"", "").replace("'", ""), 'java') ] java_paths += ['java'] proc = None for java_path in java_paths: proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) proc.start(java_path, args) if not proc.waitForStarted(): proc = None else: break if not proc: raise JavaNotFoundError() command = java_path + ' ' + ' '.join(args) safe_command = command.replace( "--dbpwd {}".format(self.configuration.password), "--dbpwd ***") self.process_started.emit(safe_command) self.__result = Importer.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result
def run(self): ili2db_bin = get_ili2db_bin(self.tool_name, self.stdout, self.stderr, ili2db_tools) if not ili2db_bin: return args = ["-jar", ili2db_bin] args += ["--export"] if self.tool_name == 'ili2pg': # PostgreSQL specific options args += ["--dbhost", self.configuration.host] if self.configuration.port: args += ["--dbport", self.configuration.port] args += ["--dbusr", self.configuration.user] if self.configuration.password: args += ["--dbpwd", self.configuration.password] args += ["--dbdatabase", self.configuration.database] args += [ "--dbschema", self.configuration.schema or self.configuration.database ] elif self.tool_name == 'ili2gpkg': args += ["--dbfile", self.configuration.dbfile] args += self.configuration.base_configuration.to_ili2db_args(False) if self.configuration.ilimodels: args += ['--models', self.configuration.ilimodels] args += [self.configuration.xtffile] if self.configuration.base_configuration.java_path: # A java path is configured: respect it no mather what java_paths = [self.configuration.base_configuration.java_path] else: # By default try JAVA_HOME and PATH java_paths = [] if 'JAVA_HOME' in os.environ: paths = os.environ['JAVA_HOME'].split(";") for path in paths: java_paths += [ os.path.join( path.replace("\"", "").replace("'", ""), 'java') ] java_paths += ['java'] proc = None for java_path in java_paths: proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) proc.start(java_path, args) if not proc.waitForStarted(): proc = None else: break if not proc: raise JavaNotFoundError() self.process_started.emit(java_path + ' ' + ' '.join(args)) self.__result = Exporter.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result
def generate_report(self, db, report_type): # Check if mapfish and Jasper are installed, otherwise show where to # download them from and return if not self.report_dependency.check_if_dependency_is_valid(): self.report_dependency.download_dependency(URL_REPORTS_LIBRARIES) return java_home_set = self.java_dependency.set_java_home() if not java_home_set: self.java_dependency.get_java_on_demand() self.logger.info_msg( __name__, QCoreApplication.translate( "ReportGenerator", "Java is a prerequisite. Since it was not found, it is being configured..." )) return plot_layer = self.app.core.get_layer(db, db.names.LC_PLOT_T, load=True) if not plot_layer: return selected_plots = plot_layer.selectedFeatures() if not selected_plots: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "To generate reports, first select at least a plot!")) return # Where to store the reports? previous_folder = QSettings().value( "Asistente-LADM-COL/reports/save_into_dir", ".") save_into_folder = QFileDialog.getExistingDirectory( None, QCoreApplication.translate( "ReportGenerator", "Select a folder to save the reports to be generated"), previous_folder) if not save_into_folder: self.logger.warning_msg( __name__, QCoreApplication.translate( "ReportGenerator", "You need to select a folder where to save the reports before continuing." )) return QSettings().setValue("Asistente-LADM-COL/reports/save_into_dir", save_into_folder) config_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, report_type) json_spec_file = os.path.join(config_path, 'spec_json_file.json') script_name = '' if os.name == 'posix': script_name = 'print' elif os.name == 'nt': script_name = 'print.bat' script_path = os.path.join(DEPENDENCY_REPORTS_DIR_NAME, 'bin', script_name) if not os.path.isfile(script_path): self.logger.warning( __name__, "Script file for reports wasn't found! {}".format(script_path)) return self.enable_action_requested.emit(report_type, False) # Update config file yaml_config_path = self.update_yaml_config(db, config_path) self.logger.debug( __name__, "Config file for reports: {}".format(yaml_config_path)) total = len(selected_plots) step = 0 count = 0 tmp_dir = self.get_tmp_dir() # Progress bar setup progress = QProgressBar() if total == 1: progress.setRange(0, 0) else: progress.setRange(0, 100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.app.gui.create_progress_message_bar( QCoreApplication.translate("ReportGenerator", "Generating {} report{}...").format( total, '' if total == 1 else 's'), progress) polygons_with_holes = [] multi_polygons = [] for selected_plot in selected_plots: plot_id = selected_plot[db.names.T_ID_F] geometry = selected_plot.geometry() abstract_geometry = geometry.get() if abstract_geometry.ringCount() > 1: polygons_with_holes.append(str(plot_id)) self.logger.warning( __name__, QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it has holes. The reporter module does not support such polygons." ).format(db.names.T_ID_F, plot_id)) continue if abstract_geometry.numGeometries() > 1: multi_polygons.append(str(plot_id)) self.logger.warning( __name__, QCoreApplication.translate( "ReportGenerator", "Skipping Annex 17 for plot with {}={} because it is a multi-polygon. The reporter module does not support such polygons." ).format(db.names.T_ID_F, plot_id)) continue # Generate data file json_file = self.update_json_data(db, json_spec_file, plot_id, tmp_dir, report_type) self.logger.debug(__name__, "JSON file for reports: {}".format(json_file)) # Run sh/bat passing config and data files proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) parcel_number = self.ladm_data.get_parcels_related_to_plots( db, [plot_id], db.names.LC_PARCEL_T_PARCEL_NUMBER_F) or [''] file_name = '{}_{}_{}.pdf'.format(report_type, plot_id, parcel_number[0]) current_report_path = os.path.join(save_into_folder, file_name) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): # Grant execution permissions os.chmod( script_path, stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): proc = None self.logger.warning( __name__, "Couldn't execute script to generate report...") else: loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.logger.debug(__name__, "{}:{}".format(plot_id, proc.exitCode())) if proc.exitCode() == 0: count += 1 step += 1 progress.setValue(step * 100 / total) os.remove(yaml_config_path) self.enable_action_requested.emit(report_type, True) self.logger.clear_message_bar() if total == count: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report <a href='file:///{}'>{}</a> was successfully generated!" ).format(normalize_local_url(save_into_folder), file_name) else: msg = QCoreApplication.translate( "ReportGenerator", "All reports were successfully generated in folder <a href='file:///{path}'>{path}</a>!" ).format(path=normalize_local_url(save_into_folder)) self.logger.success_msg(__name__, msg) else: details_msg = '' if polygons_with_holes: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they have holes and are not supported: {}." ).format(", ".join(polygons_with_holes)) if multi_polygons: details_msg += QCoreApplication.translate( "ReportGenerator", " The following polygons were skipped because they are multi-polygons and are not supported: {}." ).format(", ".join(multi_polygons)) if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report for plot {} couldn't be generated!{} See QGIS log (tab '{}') for details." ).format(plot_id, details_msg, self.LOG_TAB) else: if count == 0: msg = QCoreApplication.translate( "ReportGenerator", "No report could be generated!{} See QGIS log (tab '{}') for details." ).format(details_msg, self.LOG_TAB) else: msg = QCoreApplication.translate( "ReportGenerator", "At least one report couldn't be generated!{details_msg} See QGIS log (tab '{log_tab}') for details. Go to <a href='file:///{path}'>{path}</a> to see the reports that were generated." ).format(details_msg=details_msg, path=normalize_local_url(save_into_folder), log_tab=self.LOG_TAB) self.logger.warning_msg(__name__, msg)
def generate_report(self, db, button): # Check if mapfish and Jasper are installed, otherwise show where to # download them from and return base_path = os.path.join(os.path.expanduser('~'), 'Asistente-LADM_COL', 'impresion') bin_path = os.path.join(base_path, 'bin') if not os.path.exists(bin_path): self.qgis_utils.message_with_button_download_report_dependency_emitted.emit( QCoreApplication.translate( "ReportGenerator", "The dependency library to generate reports is not installed. Click on the button to download and install it." )) return # Check version required_version_found = True version_path = os.path.join(base_path, 'version') if not os.path.exists(version_path): required_version_found = False else: version_found = '' with open(version_path) as f: version_found = f.read() if version_found != REPORTS_REQUIRED_VERSION: required_version_found = False if not required_version_found: self.qgis_utils.message_with_button_remove_report_dependency_emitted.emit( QCoreApplication.translate( "ReportGenerator", "The dependency library to generate reports was found, but does not match with the version required. Click the button to remove the installed version and try again." )) return # Check if JAVA_HOME path is set, otherwise use path from project Generator if os.name == 'nt': if 'JAVA_HOME' not in os.environ: java_path = self.get_java_path_from_project_generator() if not java_path: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "Please set JAVA_HOME path in Project Generator Settings or in Environmental Variables for your OS" ), Qgis.Warning) return else: os.environ["JAVA_HOME"] = java_path self.log.logMessage( "The JAVA_HOME path has been set using Project Generator Settings for reports.", PLUGIN_NAME, Qgis.Info) plot_layer = self.qgis_utils.get_layer(db, PLOT_TABLE, QgsWkbTypes.PolygonGeometry, load=True) if plot_layer is None: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "Layer 'Plot' not found in DB! {}").format( db.get_description()), Qgis.Warning) return selected_plots = plot_layer.selectedFeatures() if not selected_plots: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "To generate reports, first select at least a plot!"), Qgis.Warning) return # Where to store the reports? previous_folder = QSettings().value( "Asistente-LADM_COL/reports/save_into_dir", ".") save_into_folder = QFileDialog.getExistingDirectory( None, QCoreApplication.translate( "ReportGenerator", "Select a folder to save the reports to be generated"), previous_folder) if not save_into_folder: self.qgis_utils.message_emitted.emit( QCoreApplication.translate( "ReportGenerator", "You need to select a folder where to save the reports before continuing." ), Qgis.Warning) return QSettings().setValue("Asistente-LADM_COL/reports/save_into_dir", save_into_folder) config_path = os.path.join(base_path, 'ANT') json_spec_file = os.path.join(config_path, 'spec_json_file.json') script_name = '' if os.name == 'posix': script_name = 'print' elif os.name == 'nt': script_name = 'print.bat' script_path = os.path.join(bin_path, script_name) if not os.path.isfile(script_path): print("### SCRIPT FILE WASN'T FOUND") return button.setEnabled(False) # Update config file yaml_config_path = self.update_yaml_config(db, config_path) print("CONFIG FILE:", yaml_config_path) total = len(selected_plots) step = 0 count = 0 tmp_dir = self.get_tmp_dir() # Progress bar setup progress = QProgressBar() if total == 1: progress.setRange(0, 0) else: progress.setRange(0, 100) progress.setAlignment(Qt.AlignLeft | Qt.AlignVCenter) self.qgis_utils.create_progress_message_bar_emitted.emit( QCoreApplication.translate("ReportGenerator", "Generating {} report{}...").format( total, '' if total == 1 else 's'), progress) for selected_plot in selected_plots: plot_id = selected_plot[ID_FIELD] # Generate data file json_file = self.update_json_data(db, json_spec_file, plot_id, tmp_dir) print("JSON FILE:", json_file) # Run sh/bat passing config and data files proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) current_report_path = os.path.join( save_into_folder, 'anexo_17_{}.pdf'.format(plot_id)) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): # Grant execution permissions os.chmod( script_path, stat.S_IXOTH | stat.S_IXGRP | stat.S_IXUSR | stat.S_IRUSR | stat.S_IRGRP) proc.start(script_path, [ '-config', yaml_config_path, '-spec', json_file, '-output', current_report_path ]) if not proc.waitForStarted(): proc = None print("### COULDN'T EXECUTE SCRIPT TO GENERATE REPORT...") else: loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() print(plot_id, ':', proc.exitCode()) if proc.exitCode() == 0: count += 1 step += 1 progress.setValue(step * 100 / total) os.remove(yaml_config_path) button.setEnabled(True) self.qgis_utils.clear_message_bar_emitted.emit() if total == count: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report <a href='file://{}'>anexo_17_{}.pdf</a> was successfully generated!" ).format(save_into_folder, plot_id) else: msg = QCoreApplication.translate( "ReportGenerator", "All reports were successfully generated in folder <a href='file://{path}'>{path}</a>!" ).format(path=save_into_folder) self.qgis_utils.message_with_duration_emitted.emit( msg, Qgis.Success, 0) else: if total == 1: msg = QCoreApplication.translate( "ReportGenerator", "The report for plot {} couldn't be generated! See QGIS log (tab 'Anexo_17') for details." ).format(plot_id) else: if count == 0: msg = QCoreApplication.translate( "ReportGenerator", "No report could be generated! See QGIS log (tab 'Anexo_17') for details." ) else: msg = QCoreApplication.translate( "ReportGenerator", "At least one report couldn't be generated! See QGIS log (tab 'Anexo_17') for details. Go to <a href='file://{path}'>{path}</a> to see the reports that were generated." ).format(path=save_into_folder) self.qgis_utils.message_with_duration_emitted.emit( msg, Qgis.Warning, 0)
def run(self): ili2db_bin = get_ili2db_bin(self.tool_name, self.stdout, self.stderr, ili2db_tools) if not ili2db_bin: return args = ["-jar", ili2db_bin] args += ["--import"] if self.configuration.delete_data: args += ["--deleteData"] if self.tool_name == 'ili2pg': # PostgreSQL specific options args += ["--dbhost", self.configuration.host] if self.configuration.port: args += ["--dbport", self.configuration.port] args += ["--dbusr", self.configuration.user] if self.configuration.password: args += ["--dbpwd", self.configuration.password] args += ["--dbdatabase", self.configuration.database] args += [ "--dbschema", self.configuration.schema or self.configuration.database ] elif self.tool_name == 'ili2gpkg': args += ["--dbfile", self.configuration.dbfile] args += self.configuration.base_configuration.to_ili2db_args() if self.configuration.ilimodels: args += ['--models', self.configuration.ilimodels] # Use our default schema-import parameters and get others from QSettings. # They're used by ili2db in case the schema doesn't exist. If it exists, # this doesn't have any effect on the import. args += ["--createEnumTabs"] args += ["--createNumChecks"] args += ["--coalesceMultiSurface"] args += ["--createGeomIdx"] args += ["--createFk"] args += ["--createMetaInfo"] if self.tool_name == 'ili2pg': args += ["--setupPgExt"] proxy = QgsNetworkAccessManager.instance().fallbackProxy() if proxy.type() == QNetworkProxy.HttpProxy: args += ["--proxy", proxy.hostName()] args += ["--proxyPort", str(proxy.port())] settings = QSettings() epsg = settings.value('QgsProjectGenerator/ili2pg/epsg') if epsg: args += ["--defaultSrsCode", "{}".format(epsg)] inheritance = settings.value('QgsProjectGenerator/ili2pg/inheritance', 'smart2') if inheritance == 'smart1': args += ["--smart1Inheritance"] elif inheritance == 'smart2': args += ["--smart2Inheritance"] else: args += ["--noSmartMapping"] args += [self.configuration.xtffile] if self.configuration.base_configuration.java_path: # A java path is configured: respect it no mather what java_paths = [self.configuration.base_configuration.java_path] else: # By default try JAVA_HOME and PATH java_paths = [] if 'JAVA_HOME' in os.environ: paths = os.environ['JAVA_HOME'].split(";") for path in paths: java_paths += [ os.path.join( path.replace("\"", "").replace("'", ""), 'java') ] java_paths += ['java'] proc = None for java_path in java_paths: proc = QProcess() proc.readyReadStandardError.connect( functools.partial(self.stderr_ready, proc=proc)) proc.readyReadStandardOutput.connect( functools.partial(self.stdout_ready, proc=proc)) proc.start(java_path, args) if not proc.waitForStarted(): proc = None else: break if not proc: raise JavaNotFoundError() self.process_started.emit(java_path + ' ' + ' '.join(args)) self.__result = DataImporter.ERROR loop = QEventLoop() proc.finished.connect(loop.exit) loop.exec() self.process_finished.emit(proc.exitCode(), self.__result) return self.__result