def __init__(self, downloader): QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) self.indicator_lbl = QLabel('Select Indicators') self.indicator_multiselect = MultiSelectComboBox(self) self.scroll_area_contents.layout().addWidget(self.indicator_lbl) self.scroll_area_contents.layout().addWidget( self.indicator_multiselect) self.country_lbl = QLabel('Select Countries') self.country_multiselect = MultiSelectComboBox(self) self.scroll_area_contents.layout().addWidget(self.country_lbl) self.scroll_area_contents.layout().addWidget(self.country_multiselect) self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.set_ok_button() # login to platform, to be able to retrieve sv indices self.sv_downloader = downloader self.indicators_info_dict = {} with WaitCursorManager('Filling list of indicators...'): self.fill_names() with WaitCursorManager('Filling list of themes...'): self.fill_themes() with WaitCursorManager('Filling list of countries...'): self.fill_countries() self.indicator_multiselect.item_was_clicked.connect( self.update_indicator_info) self.indicator_multiselect.selection_changed.connect( self.set_ok_button) self.country_multiselect.selection_changed.connect(self.set_ok_button)
def accept(self): with WaitCursorManager( 'Extracting custom site ids...', message_bar=self.iface.messageBar()): log_msg('Extracting custom site ids', level='I', print_to_stdout=True) sitecol = extract_npz( self.session, self.hostname, self.calc_id, 'sitecol', message_bar=self.iface.messageBar()) try: custom_site_ids = sitecol['array']['custom_site_id'] except ValueError: custom_site_ids = sitecol['array']['sids'] msg = ('Missing field "custom_site_id", needed by some ' 'OQ-GeoViewer projects. Using "sids" instead.') log_msg(msg, level='W', print_to_stdout=True, message_bar=self.iface.messageBar()) with WaitCursorManager( 'Creating disaggregation layer', self.iface.messageBar()): log_msg('Creating disagg_layer', level='I', print_to_stdout=True) log_msg('Getting disagg array', level='I', print_to_stdout=True) disagg_array = self.disagg['array'] lons = disagg_array['lon'] lats = disagg_array['lat'] self.layer = self.build_layer( self.disagg, disagg_array, lons, lats, custom_site_ids) if custom_site_ids is not None: self.build_custom_site_ids_layer(lons, lats, custom_site_ids) self.style_curves()
def run_calc(self, calc_id=None, file_names=None, directory=None): """ Run a calculation. If `calc_id` is given, it means we want to run a calculation re-using the output of the given calculation """ text = self.tr('Select the files needed to run the calculation,' ' or the zip archive containing those files.') if directory is None: default_dir = QSettings().value('irmt/run_oqengine_calc_dir', QDir.homePath()) else: default_dir = directory if not file_names: file_names = QFileDialog.getOpenFileNames(self, text, default_dir) if not file_names: return if directory is None: selected_dir = QFileInfo(file_names[0]).dir().path() QSettings().setValue('irmt/run_oqengine_calc_dir', selected_dir) else: file_names = [os.path.join(directory, os.path.basename(file_name)) for file_name in file_names] if len(file_names) == 1: file_full_path = file_names[0] _, file_ext = os.path.splitext(file_full_path) if file_ext == '.zip': zipped_file_name = file_full_path else: # NOTE: an alternative solution could be to check if the single # file is .ini, to look for all the files specified in the .ini # and to build a zip archive with all them msg = "Please select all the files needed, or a zip archive" log_msg(msg, level='C', message_bar=self.message_bar) return else: _, zipped_file_name = tempfile.mkstemp() with zipfile.ZipFile(zipped_file_name, 'w') as zipped_file: for file_name in file_names: zipped_file.write(file_name) run_calc_url = "%s/v1/calc/run" % self.hostname with WaitCursorManager('Starting calculation...', self.message_bar): if calc_id is not None: # FIXME: currently the web api is expecting a hazard_job_id # although it could be any kind of job_id. This will have to be # changed as soon as the web api is updated. data = {'hazard_job_id': calc_id} else: data = {} files = {'archive': open(zipped_file_name, 'rb')} try: resp = self.session.post( run_calc_url, files=files, data=data, timeout=20) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if resp.ok: self.refresh_calc_list() return resp.json() else: log_msg(resp.text, level='C', message_bar=self.message_bar)
def download_output(self, output_id, outtype, dest_folder=None): if not dest_folder: dest_folder = ask_for_download_destination_folder(self) if not dest_folder: return output_download_url = ( "%s/v1/calc/result/%s?export_type=%s&dload=true" % (self.hostname, output_id, outtype)) with WaitCursorManager('Downloading output...', self.message_bar): try: # FIXME: enable the user to set verify=True resp = self.session.get(output_download_url, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if not resp.ok: err_msg = ( 'Unable to download the output.\n%s: %s.\n%s' % (resp.status_code, resp.reason, resp.text)) log_msg(err_msg, level='C', message_bar=self.message_bar) return filename = resp.headers['content-disposition'].split( 'filename=')[1] filepath = os.path.join(dest_folder, filename) open(filepath, "wb").write(resp.content) return filepath
def __init__(self, downloader): QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) self.indicator_multiselect = ListMultiSelectWidget( title='Select Indicators') self.vertical_layout.insertWidget(4, self.indicator_multiselect) self.country_multiselect = ListMultiSelectWidget( title='Select Countries') self.vertical_layout.insertWidget(7, self.country_multiselect) self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.set_ok_button() # login to platform, to be able to retrieve sv indices self.sv_downloader = downloader self.indicators_info_dict = {} with WaitCursorManager(): self.fill_themes() self.fill_countries() self.indicator_multiselect.unselected_widget.itemClicked.connect( self.update_indicator_info) self.indicator_multiselect.selected_widget.itemClicked.connect( self.update_indicator_info) self.indicator_multiselect.selection_changed.connect( self.set_ok_button) self.country_multiselect.selection_changed.connect(self.set_ok_button)
def load_from_npz(self): boundaries = gzip.decompress(self.npz_file['boundaries']).split(b'\n') row_wkt_geom_types = { row_idx: QgsGeometry.fromWkt(boundary.decode('utf8')).wkbType() for row_idx, boundary in enumerate(boundaries)} wkt_geom_types = set(row_wkt_geom_types.values()) if len(wkt_geom_types) > 1: root = QgsProject.instance().layerTreeRoot() rup_group = root.insertGroup(0, "Earthquake Ruptures") else: rup_group = None for wkt_geom_type in wkt_geom_types: if wkt_geom_type == QgsWkbTypes.Point: layer_geom_type = "point" elif wkt_geom_type == QgsWkbTypes.LineString: layer_geom_type = "linestring" elif wkt_geom_type == QgsWkbTypes.Polygon: layer_geom_type = "polygon" elif wkt_geom_type == QgsWkbTypes.MultiPoint: layer_geom_type = "multipoint" elif wkt_geom_type == QgsWkbTypes.MultiLineString: layer_geom_type = "multilinestring" elif wkt_geom_type == QgsWkbTypes.MultiPolygon: layer_geom_type = "multipolygon" else: raise ValueError( 'Unexpected geometry type: %s' % wkt_geom_type) with WaitCursorManager( 'Creating layer for "%s" ruptures...' % layer_geom_type, self.iface.messageBar()): # NOTE: adding to map in this method self.layer = self.build_layer( boundaries=boundaries, geometry_type=layer_geom_type, wkt_geom_type=wkt_geom_type, row_wkt_geom_types=row_wkt_geom_types, add_to_group=rup_group, add_to_map=False) style_by = self.style_by_cbx.itemData( self.style_by_cbx.currentIndex()) if style_by == 'mag': self.style_maps(self.layer, style_by, self.iface, self.output_type) else: # 'trt' self.style_categorized(layer=self.layer, style_by=style_by) if rup_group: tree_node = rup_group else: tree_node = QgsProject.instance().layerTreeRoot() QgsProject.instance().addMapLayer(self.layer, False) tree_node.insertLayer(0, self.layer) self.iface.setActiveLayer(self.layer) log_msg('Layer %s was loaded successfully' % self.layer.name(), level='S', message_bar=self.iface.messageBar()) if rup_group: zoom_to_group(rup_group) else: self.iface.zoomToActiveLayer()
def load_from_npz(self): for poe in self.poes: if (self.load_selected_only_ckb.isChecked() and poe != self.poe_cbx.currentText()): continue with WaitCursorManager('Creating layer for poe "%s"...' % poe, self.iface.messageBar()): self.build_layer(poe=poe) self.style_curves()
def load_from_npz(self): # NOTE: selecting only 1 event, we have only 1 gsim rlz = self.rlz_or_stat_cbx.currentData() gsim = self.rlz_or_stat_cbx.currentText() with WaitCursorManager('Creating layer for "%s"...' % gsim, self.iface.messageBar()): self.layer = self.build_layer(rlz_or_stat=rlz, gsim=gsim) self.style_maps(self.layer, self.default_field_name, self.iface, self.output_type)
def load_from_npz(self): for rlz, gsim in zip(self.rlzs_or_stats, self.gsims): if (self.load_selected_only_ckb.isChecked() and gsim != self.rlz_or_stat_cbx.currentText()): continue with WaitCursorManager('Creating layer for "%s"...' % gsim, self.iface.messageBar()): self.build_layer(rlz_or_stat=rlz, gsim=gsim) self.style_maps() if self.npz_file is not None: self.npz_file.close()
def get_calc_status(self, calc_id): calc_status_url = "%s/v1/calc/%s/status" % (self.hostname, calc_id) with WaitCursorManager(): try: # FIXME: enable the user to set verify=True resp = self.session.get( calc_status_url, timeout=10, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return calc_status = json.loads(resp.text) return calc_status
def get_output_list(self, calc_id): output_list_url = "%s/v1/calc/%s/results" % (self.hostname, calc_id) with WaitCursorManager(): try: # FIXME: enable the user to set verify=True resp = self.session.get(output_list_url, timeout=10, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if resp.ok: output_list = json.loads(resp.text) self.current_calc_id = calc_id return output_list else: return []
def extract_realizations(self): with WaitCursorManager('Extracting...', message_bar=self.iface.messageBar()): self.rlzs_npz = extract_npz(self.session, self.hostname, self.calc_id, 'realizations', message_bar=self.iface.messageBar(), params=None) self.rlzs_or_stats = [ rlz_id for rlz_id in self.rlzs_npz['array']['rlz_id'] ] self.gsims = [ branch_path.decode('utf8').strip("\"") for branch_path in self.rlzs_npz['array']['branch_path'] ]
def get_calc_log(self, calc_id): if calc_id not in self.calc_log_line: self.calc_log_line[calc_id] = 0 start = self.calc_log_line[calc_id] stop = '' # get until the end calc_log_url = "%s/v1/calc/%s/log/%s:%s" % ( self.hostname, calc_id, start, stop) with WaitCursorManager(): try: # FIXME: enable the user to set verify=True resp = self.session.get(calc_log_url, timeout=10, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return calc_log = json.loads(resp.text) self.calc_log_line[calc_id] = start + len(calc_log) return '\n'.join([','.join(row) for row in calc_log])
def on_asset_risk_downloaded(self, extracted_npz): self.npz_file = extracted_npz self.dataset = self.npz_file['array'] with WaitCursorManager('Creating layer...', self.iface.messageBar()): self.layer = self.build_layer() self.style_maps( self.layer, self.default_field_name, self.iface, self.output_type, perils=self.perils, render_higher_on_top=self.higher_on_top_chk.isChecked()) if (self.zonal_layer_cbx.currentText() and self.zonal_layer_gbx.isChecked()): self.aggregate_by_zone() else: self.loading_completed.emit(self) QDialog.accept(self)
def login(self): self.session = Session() self.hostname, username, password = get_credentials('engine') # try without authentication (if authentication is disabled server # side) # NOTE: check_is_lockdown() can raise exceptions, # to be caught from outside is_lockdown = check_is_lockdown(self.hostname, self.session) if not is_lockdown: self.is_logged_in = True return with WaitCursorManager('Logging in...', self.message_bar): # it can raise exceptions, caught by self.attempt_login engine_login(self.hostname, username, password, self.session) # if no exception occurred self.is_logged_in = True return self.is_logged_in = False
def on_show_calc_params_btn_clicked(self): self.params_dlg = ShowParamsDialog() self.params_dlg.setWindowTitle( 'Parameters of calculation %s' % self.current_calc_id) get_calc_params_url = "%s/v1/calc/%s/oqparam" % ( self.hostname, self.current_calc_id) with WaitCursorManager('Getting calculation parameters...', self.message_bar): try: # FIXME: enable the user to set verify=True resp = self.session.get(get_calc_params_url, timeout=10, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return json_params = json.loads(resp.text) indented_params = json.dumps(json_params, indent=4) self.params_dlg.text_browser.setText(indented_params) self.params_dlg.show()
def __init__(self, iface, suppl_info, file_stem): QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.ok_button.setEnabled(False) self.iface = iface self.vertices_count = None self.file_stem = file_stem self.xml_file = file_stem + '.xml' self.suppl_info = suppl_info self.selected_idx = self.suppl_info['selected_project_definition_idx'] self.project_definition = self.suppl_info['project_definitions'][ self.selected_idx] if 'title' in self.project_definition: self.title_le.setText(self.project_definition['title']) else: self.title_le.setText(DEFAULTS['ISO19115_TITLE']) if 'description' in self.project_definition: self.description_te.setPlainText(self.project_definition[ 'description']) # if no field is selected, we should not allow uploading self.zone_label_field_is_specified = False reload_attrib_cbx( self.zone_label_field_cbx, iface.activeLayer(), True) self.set_zone_label_field() self.set_license() self.exists_on_platform = 'platform_layer_id' in self.suppl_info self.do_update = False self.update_radio.setEnabled(self.exists_on_platform) self.update_radio.setChecked(self.exists_on_platform) self.set_labels() with WaitCursorManager("Counting layer's vertices", iface.messageBar()): self.vertices_count = ProcessLayer( iface.activeLayer()).count_vertices()
def __init__(self, iface, downloader): QDialog.__init__(self) # Set up the user interface from Designer. self.setupUi(self) self.iface = iface # login to platform, to be able to retrieve sv indices self.sv_downloader = downloader self.ok_button = self.buttonBox.button(QDialogButtonBox.Ok) self.layer_lbl.setText('Project definition') self.layer_id = None # needed after ok is pressed self.downloaded_layer_id = None # the id of the layer created self.extra_infos = {} self.set_ok_button() with WaitCursorManager(): self.get_capabilities()
def get_engine_version(self): engine_version_url = "%s/v1/engine_version" % self.hostname with WaitCursorManager(): try: # FIXME: enable the user to set verify=True resp = self.session.get( engine_version_url, timeout=10, verify=False, allow_redirects=False) if resp.status_code == 302: raise RedirectionError( "Error %s loading %s: please check the url" % ( resp.status_code, resp.url)) if not resp.ok: raise ServerError( "Error %s loading %s: %s" % ( resp.status_code, resp.url, resp.reason)) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return return resp.text
def on_download_datastore_btn_clicked(self): dest_folder = ask_for_download_destination_folder(self) if not dest_folder: return datastore_url = "%s/v1/calc/%s/datastore" % ( self.hostname, self.current_calc_id) with WaitCursorManager('Getting HDF5 datastore...', self.message_bar): try: # FIXME: enable the user to set verify=True resp = self.session.get(datastore_url, timeout=10, verify=False) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return filename = resp.headers['content-disposition'].split( 'filename=')[1] filepath = os.path.join(dest_folder, os.path.basename(filename)) open(filepath, "wb").write(resp.content) log_msg('The datastore has been saved as %s' % filepath, level='I', message_bar=self.message_bar)
def accept(self): if self.integrate_svi_check.isChecked(): self.zone_field_name = self.zone_field_name_cbx.currentText() (point_attrs_dict, self.dmg_by_asset_layer, self.zone_field_name) = add_zone_id_to_points( self.iface, self.dmg_by_asset_layer, self.svi_layer, self.zone_field_name) else: # the layer containing points was not modified by the zonal # aggregation, so the field names remained as the original ones point_attrs_dict = {field.name(): field.name() for field in self.dmg_by_asset_layer.fields()} with WaitCursorManager('Generating recovery curves...', self.iface.messageBar()): self.calculate_community_level_recovery_curve( point_attrs_dict, self.integrate_svi_check.isChecked()) msg = 'Recovery curves have been saved to [%s]' % self.output_data_dir log_msg(msg, level='I', message_bar=self.iface.messageBar()) self.save_state() super(RecoveryModelingDialog, self).accept()
def finalize_init(self, extracted_npz): self.npz_file = extracted_npz # NOTE: still running this synchronously, because it's small stuff with WaitCursorManager('Loading loss types...', self.iface.messageBar()): self.loss_types = get_loss_types(self.session, self.hostname, self.calc_id, self.iface.messageBar()) self.populate_out_dep_widgets() if self.zonal_layer_path: zonal_layer = self.load_zonal_layer(self.zonal_layer_path) self.populate_zonal_layer_cbx(zonal_layer) else: self.pre_populate_zonal_layer_cbx() self.adjustSize() self.set_ok_button() self.show() self.init_done.emit(self)
def remove_calc(self, calc_id): calc_remove_url = "%s/v1/calc/%s/remove" % (self.hostname, calc_id) with WaitCursorManager('Removing calculation...', self.message_bar): try: resp = self.session.post(calc_remove_url, timeout=10) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return if resp.ok: msg = 'Calculation %s successfully removed' % calc_id log_msg(msg, level='I', message_bar=self.message_bar) if self.current_calc_id == calc_id: self.current_calc_id = None self.clear_output_list() if self.pointed_calc_id == calc_id: self.pointed_calc_id = None self.clear_output_list() self.refresh_calc_list() else: msg = 'Unable to remove calculation %s' % calc_id log_msg(msg, level='C', message_bar=self.message_bar) return
def get_loggedin_downloader(message_bar): """ Attempt to login to the OpenQuake Platform :param message_bar: needed to display messages :returns: a :class:`svir.utilities.SvDownloader` instance """ hostname, username, password = get_credentials('platform') sv_downloader = SvDownloader(hostname) try: msg = ("Connecting to the OpenQuake Platform...") with WaitCursorManager(msg, message_bar): sv_downloader.login(username, password) return sv_downloader except (SvNetworkError, ConnectionError, InvalidSchema, MissingSchema, ReadTimeout) as e: err_msg = str(e) if isinstance(e, InvalidSchema): err_msg += ' (you could try prepending http:// or https://)' log_msg(err_msg, level='C', message_bar=message_bar) return None
def load_from_npz(self): for rlz_or_stat in self.rlzs_or_stats: if (self.load_selected_only_ckb.isChecked() and rlz_or_stat != self.rlz_or_stat_cbx.currentText()): continue for taxonomy in self.taxonomies: if (self.load_selected_only_ckb.isChecked() and taxonomy != self.taxonomy_cbx.currentText()): continue for loss_type in self.loss_types: if (self.load_selected_only_ckb.isChecked() and loss_type != self.loss_type_cbx.currentText()): continue with WaitCursorManager( 'Creating layer for "%s", ' ' taxonomy "%s" and loss type "%s"...' % (rlz_or_stat, taxonomy, loss_type), self.iface.messageBar()): self.layer = self.build_layer(rlz_or_stat, taxonomy=taxonomy, loss_type=loss_type) self.style_maps(self.layer, self.default_field_name, self.iface, self.output_type)
def on_filter_btn_clicked(self): with WaitCursorManager(): self.fill_names()
def on_theme_cbx_currentIndexChanged(self): theme = self.theme_cbx.currentText() with WaitCursorManager(): self.fill_subthemes(theme)
def on_eng_test_btn_clicked(self): server = 'engine' profile_name = self.engine_profile_cbx.currentText() with WaitCursorManager('Logging in...', self.message_bar): self._attempt_login(server, profile_name)
def refresh_calc_list(self): # returns True if the list is correctly retrieved calc_list_url = "%s/v1/calc/list?relevant=true" % self.hostname with WaitCursorManager(): try: # FIXME: enable the user to set verify=True resp = self.session.get( calc_list_url, timeout=10, verify=False, allow_redirects=False) if resp.status_code == 302: raise RedirectionError( "Error %s loading %s: please check the url" % ( resp.status_code, resp.url)) if not resp.ok: raise ServerError( "Error %s loading %s: %s" % ( resp.status_code, resp.url, resp.reason)) except HANDLED_EXCEPTIONS as exc: self._handle_exception(exc) return False calc_list = json.loads(resp.text) selected_keys = [ 'description', 'id', 'calculation_mode', 'owner', 'status'] col_names = [ 'Description', 'Job ID', 'Calculation Mode', 'Owner', 'Status'] col_widths = [340, 60, 135, 70, 80] if not calc_list: if self.calc_list_tbl.rowCount() > 0: self.calc_list_tbl.clearContents() self.calc_list_tbl.setRowCount(0) else: self.calc_list_tbl.setRowCount(0) self.calc_list_tbl.setColumnCount(len(col_names)) self.calc_list_tbl.setHorizontalHeaderLabels(col_names) self.calc_list_tbl.horizontalHeader().setStyleSheet( "font-weight: bold;") self.set_calc_list_widths(col_widths) return False actions = [ {'label': 'Console', 'bg_color': '#3cb3c5', 'txt_color': 'white'}, {'label': 'Remove', 'bg_color': '#d9534f', 'txt_color': 'white'}, {'label': 'Outputs', 'bg_color': '#3cb3c5', 'txt_color': 'white'}, {'label': 'Continue', 'bg_color': 'white', 'txt_color': 'black'} ] self.calc_list_tbl.clearContents() self.calc_list_tbl.setRowCount(len(calc_list)) self.calc_list_tbl.setColumnCount(len(selected_keys) + len(actions)) for row, calc in enumerate(calc_list): for col, key in enumerate(selected_keys): item = QTableWidgetItem() try: value = calc_list[row][key] except KeyError: # from engine2.5 to engine2.6, job_type was changed into # calculation_mode. This check prevents the plugin to break # wnen using an old version of the engine. if key == 'calculation_mode': value = 'unknown' else: # if any other unexpected keys are used, it is safer to # raise a KeyError raise item.setData(Qt.DisplayRole, value) # set default colors row_bg_color = Qt.white row_txt_color = Qt.black if calc['status'] == 'failed': row_bg_color = QColor('#f2dede') elif calc['status'] == 'complete': row_bg_color = QColor('#dff0d8') item.setBackgroundColor(row_bg_color) item.setTextColor(row_txt_color) self.calc_list_tbl.setItem(row, col, item) for col, action in enumerate(actions, len(selected_keys)): # display the Continue and Output buttons only if the # computation is completed if (calc['status'] != 'complete' and action['label'] in ('Continue', 'Outputs')): continue button = QPushButton() button.setText(action['label']) style = 'background-color: %s; color: %s' % ( action['bg_color'], action['txt_color']) button.setStyleSheet(style) QObject.connect( button, SIGNAL("clicked()"), lambda calc_id=calc['id'], action=action['label']: ( self.on_calc_action_btn_clicked(calc_id, action))) self.calc_list_tbl.setCellWidget(row, col, button) self.calc_list_tbl.setColumnWidth(col, BUTTON_WIDTH) empty_col_names = [''] * len(actions) headers = col_names + empty_col_names self.calc_list_tbl.setHorizontalHeaderLabels(headers) self.calc_list_tbl.horizontalHeader().setStyleSheet( "font-weight: bold;") self.set_calc_list_widths(col_widths) if self.pointed_calc_id: self.highlight_and_scroll_to_calc_id(self.pointed_calc_id) # if a running calculation is selected, the corresponding outputs will # be displayed (once) automatically at completion if (self.pointed_calc_id and self.output_list_tbl.rowCount() == 0): self.update_output_list(self.pointed_calc_id) return True
def accept(self): self.suppl_info['title'] = self.title_le.text() if 'title' not in self.project_definition: self.project_definition['title'] = self.suppl_info['title'] self.suppl_info['abstract'] = self.description_te.toPlainText() if 'description' not in self.project_definition: self.project_definition['description'] = self.suppl_info[ 'abstract'] zone_label_field = self.zone_label_field_cbx.currentText() self.suppl_info['zone_label_field'] = zone_label_field license_name = self.license_cbx.currentText() license_idx = self.license_cbx.currentIndex() license_url = self.license_cbx.itemData(license_idx) license_txt = '%s (%s)' % (license_name, license_url) self.suppl_info['license'] = license_txt self.suppl_info['irmt_plugin_version'] = IRMT_PLUGIN_VERSION self.suppl_info['supplemental_information_version'] = \ SUPPLEMENTAL_INFORMATION_VERSION self.suppl_info['vertices_count'] = self.vertices_count self.suppl_info['project_definitions'][self.selected_idx] = \ self.project_definition active_layer_id = self.iface.activeLayer().id() write_layer_suppl_info_to_qgs(active_layer_id, self.suppl_info) if self.do_update: with WaitCursorManager( 'Updating project on the OpenQuake Platform', self.iface.messageBar()): hostname, username, password = get_credentials('platform') session = Session() try: platform_login(hostname, username, password, session) except SvNetworkError as e: error_msg = ( 'Unable to login to the platform: ' + e.message) log_msg(error_msg, level='C', message_bar=self.iface.messageBar(), exception=e) return if 'platform_layer_id' not in self.suppl_info: error_msg = ('Unable to retrieve the id of' 'the layer on the Platform') log_msg(error_msg, level='C', message_bar=self.iface.messageBar()) return response = update_platform_project( hostname, session, self.project_definition, self.suppl_info['platform_layer_id']) if response.ok: log_msg(tr(response.text), level='S', message_bar=self.iface.messageBar()) else: error_msg = response.text # example of response text: # "The title 'No incomplete data' was already assigned to # another project definition. Please provide a new unique # one." # NOTE: if the api response message changes, this might # not work properly if 'Please provide a new unique' in response.text: error_msg += (' Please consider using the "Manage' ' project definitions" functionality' ' to save the current project definition' ' as a new one having a unique title.') log_msg(error_msg, level='C', message_bar=self.iface.messageBar()) else: if DEBUG: log_msg('xml_file: %s' % self.xml_file) # do not upload the selected_project_definition_idx self.suppl_info.pop('selected_project_definition_idx', None) write_iso_metadata_file(self.xml_file, self.suppl_info) metadata_dialog = UploadDialog( self.iface, self.file_stem) metadata_dialog.upload_successful.connect( lambda layer_url: insert_platform_layer_id( layer_url, active_layer_id, self.suppl_info)) if metadata_dialog.exec_(): QDesktopServices.openUrl(QUrl(metadata_dialog.layer_url)) elif DEBUG: log_msg("metadata_dialog cancelled") super(UploadSettingsDialog, self).accept()