def read(self, service_url, timeout=config_loader(dataset="WMS_request_timeout")): """Get and parse a WMS capabilities document, returning an elementtree instance service_url is the base url, to which is appended the service, version, and request parameters """ getcaprequest = self.capabilities_url(service_url) # Don't specify a version if it is to be determined getcaprequest = getcaprequest.replace("&version=None", "").replace("?version=None", "") proxies = config_loader(dataset="proxies") # now split it up again to use the generic openURL function... spliturl = getcaprequest.split('?') u = openURL(spliturl[0], spliturl[1], method='Get', auth=self.auth, proxies=proxies) # (mss) Store capabilities document. self.capabilities_document = strip_bom(u.read()) return etree.fromstring(self.capabilities_document)
def openTool(self, index): """ Slot that handles requests to open control windows. """ index = self.controlToBeCreated(index) if index >= 0: if index == WMS: # Create a new WMSDockWidget. title = "Web Map Service (Top View)" widget = wc.HSecWMSControlWidget( default_WMS=config_loader(dataset="default_WMS"), view=self.mpl.canvas, wms_cache=config_loader(dataset="wms_cache")) widget.signal_disable_cbs.connect(self.disable_cbs) widget.signal_enable_cbs.connect(self.enable_cbs) elif index == SATELLITE: title = "Satellite Track Prediction" widget = sat.SatelliteControlWidget(parent=self, view=self.mpl.canvas) elif index == REMOTESENSING: title = "Remote Sensing Tools" widget = rs.RemoteSensingControlWidget(parent=self, view=self.mpl.canvas) elif index == KMLOVERLAY: title = "KML Overlay" widget = kml.KMLOverlayControlWidget(parent=self, view=self.mpl.canvas) else: raise IndexError("invalid control index") # Create the actual dock widget containing <widget>. self.createDockWidget(index, title, widget)
def get_pickertype(tag, typ): default = config_loader(dataset="filepicker_default") if typ is None: if tag is None: typ = default else: typ = config_loader(dataset=tag) return typ
def test_default_config_dataset(self): data = utils.config_loader(dataset="num_labels") assert data == 10 # defined value and not a default one data = utils.config_loader(dataset="num_labels", default=5) assert data == 10 # default for non existing entry data = utils.config_loader(dataset="foobar", default=5) assert data == 5
def add_plugins(self): picker_default = config_loader( dataset="filepicker_default") self._imported_plugins = config_loader(dataset="import_plugins") for name in self._imported_plugins: extension, module, function = self._imported_plugins[name][:3] picker_type = picker_default if len(self._imported_plugins[name]) == 4: picker_type = self._imported_plugins[name][3] try: imported_module = importlib.import_module(module) # wildcard exception to be resilient against error introduced by user code except Exception as ex: logging.error("Error on import: %s: %s", type(ex), ex) QtWidgets.QMessageBox.critical( self, self.tr("file io plugin error import plugins"), self.tr("ERROR: Configuration\n\n{}\n\nthrows {} error:\n{}".format( self._imported_plugins, type(ex), ex))) continue try: self.add_import_filter(name, extension, getattr(imported_module, function), pickertype=picker_type) # wildcard exception to be resilient against error introduced by user code except Exception as ex: logging.error("Error on installing plugin: %s: %s", type(ex), ex) QtWidgets.QMessageBox.critical( self, self.tr("file io plugin error import plugins"), self.tr("ERROR: Configuration\n\n{}\n\nthrows {} error:\n{}".format( self._imported_plugins, type(ex), ex))) continue self._exported_plugins = config_loader(dataset="export_plugins") for name in self._exported_plugins: extension, module, function = self._exported_plugins[name][:3] picker_type = picker_default if len(self._exported_plugins[name]) == 4: picker_type = self._exported_plugins[name][3] try: imported_module = importlib.import_module(module) # wildcard exception to be resilient against error introduced by user code except Exception as ex: logging.error("Error on import: %s: %s", type(ex), ex) QtWidgets.QMessageBox.critical( self, self.tr("file io plugin error import plugins"), self.tr("ERROR: Configuration\n\n{}\n\nthrows {} error:\n{}".format( self._exported_plugins, type(ex), ex))) continue try: self.add_export_filter(name, extension, getattr(imported_module, function), pickertype=picker_type) # wildcard exception to be resilient against error introduced by user code except Exception as ex: logging.error("Error on installing plugin: %s: %s", type(ex), ex) QtWidgets.QMessageBox.critical( self, self.tr("file io plugin error"), self.tr("ERROR: Configuration for export {} plugins\n\n{}\n\nthrows error:\n{}".format( self._exported_plugins, type(ex), ex))) continue
def test_sample_config_file(self): utils_path = os.path.dirname(os.path.abspath(utils.__file__)) config_file = os.path.join(utils_path, '../', 'docs', 'samples', 'config', 'mss', 'mss_settings.json.sample') data = utils.config_loader(config_file=config_file, dataset="new_flighttrack_flightlevel") assert data == 250 with pytest.raises(KeyError): utils.config_loader(config_file=config_file, dataset="UNDEFINED") with pytest.raises(KeyError): assert utils.config_loader(config_file=config_file, dataset="UNDEFINED") with pytest.raises(utils.FatalUserError): config_file = os.path.join(utils_path, '../', 'docs', 'samples', 'config', 'mss', 'not_existing_mss_settings.json.sample') _ = utils.config_loader(config_file=config_file)
def connect_handler(self): try: url = str(self.url.currentText()) r = requests.get(url_join(url, 'status')) if r.text == "Mscolab server": # delete mscolab http_auth settings for the url if url not in self.settings["recent_mscolab_urls"]: self.settings["recent_mscolab_urls"].append(url) if self.mscolab_server_url in self.settings["auth"].keys(): del self.settings["auth"][self.mscolab_server_url] # assign new url to self.mscolab_server_url self.mscolab_server_url = url self.status.setText("Status: connected") # enable and disable right buttons self.loginButton.setEnabled(False) self.addUser.setEnabled(True) self.emailid.setEnabled(True) self.password.setEnabled(True) # activate login button after email and password are entered self.emailid.textChanged[str].connect(self.text_changed) self.password.textChanged[str].connect(self.text_changed) # toggle to disconnect button self.toggleConnectionBtn.setText('Disconnect') self.toggleConnectionBtn.clicked.connect(self.disconnect_handler) self.url.setEnabled(False) if self.mscolab_server_url not in self.settings["server_settings"].keys(): self.settings["server_settings"].update({self.mscolab_server_url: {}}) save_settings_qsettings('mscolab', self.settings) self.emailid.setEnabled(True) self.password.setEnabled(True) self.emailid.setText(config_loader(dataset="MSCOLAB_mailid")) self.password.setText(config_loader(dataset="MSCOLAB_password")) else: show_popup(self, "Error", "Some unexpected error occurred. Please try again.") except requests.exceptions.ConnectionError: logging.debug("MSColab server isn't active") show_popup(self, "Error", "MSColab server isn't active") except requests.exceptions.InvalidSchema: logging.debug("invalid schema of url") show_popup(self, "Error", "Invalid Url Scheme!") except requests.exceptions.InvalidURL: logging.debug("invalid url") show_popup(self, "Error", "Invalid URL") except requests.exceptions.SSLError: logging.debug("Certificate Verification Failed") show_popup(self, "Error", "Certificate Verification Failed") except Exception as e: logging.debug("Error %s", str(e)) show_popup(self, "Error", "Some unexpected error occurred. Please try again.")
def save_figure(self, *args): picker_default = config_loader(dataset="filepicker_default", default=mss_default.filepicker_default) picker_type = config_loader(dataset="filepicker_matplotlib", default=picker_default) if picker_type in ["default", "qt"]: save_figure_original(self, *args) elif picker_type == "fs": filetypes = self.canvas.get_supported_filetypes_grouped() sorted_filetypes = sorted(six.iteritems(filetypes)) startpath = matplotlib.rcParams.get('savefig.directory', LAST_SAVE_DIRECTORY) startpath = os.path.expanduser(startpath) start = os.path.join(startpath, self.canvas.get_default_filename()) filters = [] for name, exts in sorted_filetypes: exts_list = " ".join(['*.%s' % ext for ext in exts]) filter = '%s (%s)' % (name, exts_list) filters.append(filter) fname, filter = _getSaveFileName(self.parent, title="Choose a filename to save to", filename=start, filters=filters) if fname is not None: if not fname.endswith(filter[1:]): fname = filter.replace('*', fname) if startpath == '': # explicitly missing key or empty str signals to use cwd matplotlib.rcParams['savefig.directory'] = startpath else: # save dir for next time savefig_dir = os.path.dirname(six.text_type(fname)) matplotlib.rcParams['savefig.directory'] = savefig_dir try: _dirname, _name = os.path.split(fname) _fs = open_fs(_dirname) with _fs.open(_name, 'wb') as source: self.canvas.print_figure(source, format=filter.replace('*.', '')) except Exception as e: QtWidgets.QMessageBox.critical(self, "Error saving file", six.text_type(e), QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.NoButton) else: raise FatalUserError( "Unknown file picker type '{}'".format(picker_type))
def authorize(self): for key, value in config_loader(dataset="MSC_login").items(): if key not in constants.MSC_LOGIN_CACHE: constants.MSC_LOGIN_CACHE[key] = value auth = constants.MSC_LOGIN_CACHE.get(self.mscolab_server_url, (None, None)) # get mscolab /token http auth credentials from cache emailid = self.emailid.text() password = self.password.text() data = { "email": emailid, "password": password } s = requests.Session() s.auth = (auth[0], auth[1]) s.headers.update({'x-test': 'true'}) url = self.mscolab_server_url + '/token' r = s.post(url, data=data) if r.status_code == 401: r = self.authenticate(data, r, url) if r.status_code == 200 and not r.text == "False": constants.MSC_LOGIN_CACHE[self.mscolab_server_url] = (auth[0], auth[1]) else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Oh no, server authentication were incorrect.') if r.text == "False": # popup that has wrong credentials self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Oh no, your credentials were incorrect.') else: # remove the login modal and put text there self.after_authorize(emailid, r)
def add_user(self): for key, value in config_loader(dataset="MSC_login").items(): if key not in constants.MSC_LOGIN_CACHE: constants.MSC_LOGIN_CACHE[key] = value auth = constants.MSC_LOGIN_CACHE.get(self.mscolab_server_url, (None, None)) emailid = self.add_user_dialog.emailid.text() password = self.add_user_dialog.password.text() re_password = self.add_user_dialog.rePassword.text() username = self.add_user_dialog.username.text() if password == re_password: data = { "email": emailid, "password": password, "username": username } s = requests.Session() s.auth = (auth[0], auth[1]) s.headers.update({'x-test': 'true'}) url = f'{self.mscolab_server_url}/register' r = s.post(url, data=data) if r.status_code == 401: r = self.authenticate(data, r, url) if r.status_code == 201: constants.MSC_LOGIN_CACHE[self.mscolab_server_url] = (username, password) if r.status_code == 201: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('You are registered, you can now log in.') else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage(r.json()["message"]) else: self.error_dialog = QtWidgets.QErrorMessage() self.error_dialog.showMessage('Oh no, your passwords don\'t match')
def __init__(self, token, p_id, user, project_name, conn, parent=None, mscolab_server_url=config_loader(dataset="default_MSCOLAB", default=mss_default.default_MSCOLAB)): """ token: access_token p_id: project id user: logged in user project_name: name of project, conn: socket connection parent: parent of widget mscolab_server_url: server url of mscolab """ super(MSColabVersionHistory, self).__init__(parent) self.setupUi(self) # Initialise Variables self.token = token self.p_id = p_id self.user = user self.project_name = project_name self.conn = conn self.mscolab_server_url = mscolab_server_url # Event handlers self.refreshBtn.clicked.connect(self.handle_refresh) self.checkoutBtn.clicked.connect(self.handle_undo) self.nameVersionBtn.clicked.connect(self.handle_named_version) self.deleteVersionNameBtn.clicked.connect(self.handle_delete_version_name) self.versionFilterCB.currentIndexChanged.connect(lambda: self.load_all_changes()) self.changes.currentItemChanged.connect(self.preview_change) # Setup UI self.deleteVersionNameBtn.setVisible(False) self.set_label_text() self.set_change_list_style() self.toggle_version_buttons(False) self.load_current_waypoints() self.load_all_changes()
def __init__(self, token, p_id, user, project_name, access_level, conn, parent=None, mscolab_server_url=config_loader(dataset="default_MSCOLAB")): """ token: access_token p_id: project id user: logged in user project_name: active project name, access_level: access level of user logged in conn: to send messages, recv messages, if a direct slot-signal can't be setup to be connected at parents' parent: widget parent mscolab_server_url: server url for mscolab """ super(MSColabProjectWindow, self).__init__(parent) self.setupUi(self) self.mscolab_server_url = mscolab_server_url self.token = token self.user = user self.p_id = p_id self.project_name = project_name self.conn = conn self.access_level = access_level self.text = "" self.attachment = None self.attachment_type = None self.active_edit_id = None self.active_message_reply = None self.current_search_index = None self.markdown = Markdown(extensions=['nl2br', 'sane_lists', DeregisterSyntax()]) self.messageText = MessageTextEdit(self.centralwidget) self.setup_message_text() # Signals self.searchMessageLineEdit.textChanged.connect(self.handle_search_text_changed) self.searchPrevBtn.clicked.connect(self.handle_prev_message_search) self.searchNextBtn.clicked.connect(self.handle_next_message_search) self.previewBtn.clicked.connect(self.toggle_preview) self.sendMessageBtn.clicked.connect(self.send_message) self.uploadBtn.clicked.connect(self.handle_upload) self.editMessageBtn.clicked.connect(self.edit_message) self.cancelBtn.clicked.connect(self.send_message_state) # Socket Connection handlers self.conn.signal_project_permissions_updated.connect(self.handle_permissions_updated) self.conn.signal_message_receive.connect(self.handle_incoming_message) self.conn.signal_message_reply_receive.connect(self.handle_incoming_message_reply) self.conn.signal_message_edited.connect(self.handle_message_edited) self.conn.signal_message_deleted.connect(self.handle_deleted_message) # Set Label text self.set_label_text() # Hide Edit Message section self.send_message_state() # load all users self.load_users() # load messages self.load_all_messages() if access_level == "viewer": self.messageText.setEnabled(False) self.previewBtn.setEnabled(False) self.uploadBtn.setEnabled(False) self.sendMessageBtn.setEnabled(False)
def load_performance(self): """ Gets a filename for a JSON file specifying aircraft performance and initializes an SimpleAircraft model. """ filename = get_open_filename(self, "Open Aircraft Performance JSON File", constants.MSS_CONFIG_PATH, "Performance File (*.json)", pickertag="filepicker_default") if filename is not None: try: performance = config_loader(config_file=filename) self.aircraft = aircrafts.SimpleAircraft(performance) self.lbAircraftName.setText(self.aircraft.name) self.dsbTakeoffWeight.setValue(self.aircraft.takeoff_weight) self.dsbFuel.setValue(self.aircraft.fuel) except KeyError as ex: QtWidgets.QMessageBox.critical( self, self.tr("Performance JSON Load"), self.tr("JSON File missing '{}' entry".format(ex))) except (FatalUserError, ValueError) as ex: QtWidgets.QMessageBox.critical( self, self.tr("Performance JSON Load"), self.tr("JSON File has Syntax Problems:\n{}".format(ex)))
def _add_hexagon(self): table_view = self.view.tableWayPoints waypoints_model = self.view.waypoints_model params = self._get_parameters() if params["radius"] < 0.01: QtWidgets.QMessageBox.warning( self, "Add hexagon", "You cannot create a hexagon with zero radius!") return points = create_hexagon(params["center_lat"], params["center_lon"], params["radius"], params["angle"]) index = table_view.currentIndex() if not index.isValid(): row = 0 flightlevel = config_loader(dataset="new_flighttrack_flightlevel", default=mss_default.new_flighttrack_flightlevel) else: row = index.row() + 1 flightlevel = waypoints_model.waypoint_data(row - 1).flightlevel waypoints = [] for i, point in enumerate(points): waypoints.append( ft.Waypoint(lon=float(point[1]), lat=float(point[0]), flightlevel=float(flightlevel), comments="Hexagon {:d}".format(i + 1))) waypoints_model.insertRows(row, rows=len(waypoints), waypoints=waypoints) index = waypoints_model.index(row, 0) table_view.setCurrentIndex(index) table_view.resizeRowsToContents()
def createEditor(self, parent, option, index): """Create a combobox listing predefined locations in the LOCATION column. """ if index.column() == LOCATION: combobox = QtWidgets.QComboBox(parent) locations = config_loader(dataset='locations', default=mss_default.locations) adds = list(locations.keys()) if self.parent() is not None: for loc in [ wp.location for wp in self.parent().waypoints_model.all_waypoint_data() if wp.location != "" ]: if loc not in adds: adds.append(loc) combobox.addItems(sorted(adds)) combobox.setEditable(True) return combobox else: # All other columns get the standard editor. return QtWidgets.QItemDelegate.createEditor( self, parent, option, index)
def __init__(self, lat=0, lon=0, flightlevel=0, location="", comments=""): self.location = location locations = config_loader(dataset='locations', default=mss_default.locations) if location in locations: self.lat, self.lon = locations[location] else: self.lat = lat self.lon = lon self.flightlevel = flightlevel self.pressure = thermolib.flightlevel2pressure(flightlevel) self.distance_to_prev = 0. self.distance_total = 0. self.comments = comments # Performance fields (for values read from the flight performance # service). self.leg_time = None # time from previous waypoint self.cum_time = None # total time of flight self.utc_time = None # time in UTC since given takeoff time self.leg_fuel = None # fuel consumption since previous waypoint self.rem_fuel = None # total fuel consumption self.weight = None # aircraft gross weight self.ceiling_alt = None # aircraft ceiling altitude self.ascent_rate = None # aircraft ascent rate self.wpnumber_major = None self.wpnumber_minor = None
def create_new_view(self): """Method called when the user selects a new view to be opened. Creates a new instance of the view and adds a QActiveViewsListWidgetItem to the list of open views (self.listViews). """ layout = config_loader(dataset="layout") view_window = None if self.sender() == self.actionTopView: # Top view. view_window = topview.MSSTopViewWindow(model=self.active_flight_track) view_window.mpl.resize(layout['topview'][0], layout['topview'][1]) if layout["immutable"]: view_window.mpl.setFixedSize(layout['topview'][0], layout['topview'][1]) elif self.sender() == self.actionSideView: # Side view. view_window = sideview.MSSSideViewWindow(model=self.active_flight_track) view_window.mpl.resize(layout['sideview'][0], layout['sideview'][1]) if layout["immutable"]: view_window.mpl.setFixedSize(layout['sideview'][0], layout['sideview'][1]) elif self.sender() == self.actionTableView: # Table view. view_window = tableview.MSSTableViewWindow(model=self.active_flight_track) view_window.centralwidget.resize(layout['tableview'][0], layout['tableview'][1]) if view_window is not None: # Make sure view window will be deleted after being closed, not # just hidden (cf. Chapter 5 in PyQt4). view_window.setAttribute(QtCore.Qt.WA_DeleteOnClose) # Open as a non-modal window. view_window.show() # Add an entry referencing the new view to the list of views. listitem = QActiveViewsListWidgetItem(view_window, self.listViews, self.viewsChanged) view_window.viewCloses.connect(listitem.view_destroyed) self.listViews.setCurrentItem(listitem) self.viewsChanged.emit()
def setModelData(self, editor, model, index): """For the LOCATION column: If the user selects a location from the combobox, get the corresponding coordinates. """ if index.column() == LOCATION: loc = editor.currentText() locations = config_loader(dataset='locations', default=mss_default.locations) if loc in locations: lat, lon = locations[loc] # Don't update distances and flight performance twice, hence # set update=False for LAT. model.setData(index.sibling(index.row(), LAT), QtCore.QVariant(lat), update=False) model.setData(index.sibling(index.row(), LON), QtCore.QVariant(lon)) else: for wp in self.parent().waypoints_model.all_waypoint_data(): if loc == wp.location: lat, lon = wp.lat, wp.lon # Don't update distances and flight performance twice, hence # set update=False for LAT. model.setData(index.sibling(index.row(), LAT), QtCore.QVariant(lat), update=False) model.setData(index.sibling(index.row(), LON), QtCore.QVariant(lon)) model.setData(index, QtCore.QVariant(editor.currentText())) else: QtWidgets.QItemDelegate.setModelData(self, editor, model, index)
def preload_wms(urls): """ This method accesses a list of WMS servers and load their capability documents. :param urls: List of URLs """ pdlg = QtWidgets.QProgressDialog("Preloading WMS servers...", "Cancel", 0, len(urls)) pdlg.reset() pdlg.setValue(0) pdlg.setModal(True) pdlg.show() QtWidgets.QApplication.processEvents() for i, base_url in enumerate(urls): pdlg.setValue(i) QtWidgets.QApplication.processEvents() # initialize login cache from config file, but do not overwrite existing keys for key, value in config_loader(dataset="WMS_login").items(): if key not in constants.WMS_LOGIN_CACHE: constants.WMS_LOGIN_CACHE[key] = value username, password = constants.WMS_LOGIN_CACHE.get(base_url, (None, None)) try: request = requests.get(base_url) if pdlg.wasCanceled(): break wms = wms_control.MSSWebMapService(request.url, version='1.1.1', username=username, password=password) wms_control.WMS_SERVICE_CACHE[wms.url] = wms logging.info("Stored WMS info for '%s'", wms.url) except Exception as ex: logging.error("Error in preloading '%s': '%s'", type(ex), ex) if pdlg.wasCanceled(): break logging.debug("Contents of WMS_SERVICE_CACHE: %s", wms_control.WMS_SERVICE_CACHE.keys()) pdlg.close()
def changeMapSection(self, index=0, only_kwargs=False): """ Change the current map section to one of the predefined regions. """ # Get the initial projection parameters from the tables in mss_settings. current_map_key = self.cbChangeMapSection.currentText() predefined_map_sections = config_loader( dataset="predefined_map_sections") current_map = predefined_map_sections.get( current_map_key, {"CRS": current_map_key, "map": {}}) proj_params = get_projection_params(current_map["CRS"]) # Create a keyword arguments dictionary for basemap that contains # the projection parameters. kwargs = current_map["map"] kwargs.update({"CRS": current_map["CRS"], "BBOX_UNITS": proj_params["bbox"], "PROJECT_NAME": self.waypoints_model.name}) kwargs.update(proj_params["basemap"]) if only_kwargs: # Return kwargs dictionary and do NOT redraw the map. return kwargs logging.debug("switching to map section '%s' - '%s'", current_map_key, kwargs) self.mpl.canvas.redraw_map(kwargs) self.mpl.navbar.clear_history()
def load_performance(self): """ Gets a filename for a JSON file specifying aircraft performance and initializes an SimpleAircraft model. """ filename = get_open_filename(self, "Open Aircraft Performance JSON File", constants.MSS_CONFIG_PATH, "Performance File (*.json)", pickertag="filepicker_default") if filename is not None: try: performance = config_loader(config_file=filename) self.aircraft = aircrafts.SimpleAircraft(performance) self.lbAircraftName.setText(self.aircraft.name) self.dsbTakeoffWeight.setValue(self.aircraft.takeoff_weight) if not any( hasattr(self.aircraft, _x) for _x in ("fuel", "empty_weight")): raise KeyError("empty_weight") if hasattr(self.aircraft, "empty_weight"): self.dsbEmptyWeight.setValue(self.aircraft.empty_weight) else: self.dsbEmptyWeight.setValue(self.aircraft.takeoff_weight - self.aircraft.fuel) self.update_parent_performance() except KeyError as ex: QtWidgets.QMessageBox.critical( self, self.tr("Performance JSON Load"), self.tr(f"JSON File missing '{ex}' entry")) except (FatalUserError, ValueError) as ex: QtWidgets.QMessageBox.critical( self, self.tr("Performance JSON Load"), self.tr(f"JSON File has Syntax Problems:\n{ex}"))
def __init__(self, url, version=None, xml=None, username=None, password=None, parse_remote_metadata=False, headers=None, timeout=config_loader(dataset="WMS_request_timeout"), auth=None): """Initialize.""" if auth: if username: auth.username = username if password: auth.password = password self.url = url self.version = version self.timeout = timeout self.headers = headers self._capabilities = None self.auth = auth or Authentication(username, password) # Authentication handled by Reader reader = WMSCapabilitiesReader(self.version, url=self.url, headers=headers, auth=self.auth) if xml: # read from stored xml self._capabilities = reader.readString(xml) else: # read from server self._capabilities = reader.read(self.url, timeout=self.timeout) self.request = reader.request if not self.version: self.version = self._capabilities.attrib["version"] if self.version not in ["1.1.1", "1.3.0"]: self.version = "1.1.1" reader.version = self.version self.WMS_NAMESPACE = "{http://www.opengis.net/wms}" if self.version == "1.3.0" else "" self.OGC_NAMESPACE = "{http://www.opengis.net/ogc}" if self.version == "1.3.0" else "" # avoid building capabilities metadata if the # response is a ServiceExceptionReport se = self._capabilities.find('ServiceException') if se is not None: err_message = str(se.text).strip() raise ServiceException(err_message) # (mss) Store capabilities document. self.capabilities_document = reader.capabilities_document # (mss) # build metadata objects self._buildMetadata(parse_remote_metadata)
def update_predefined_maps(self, extra=None): self.cbChangeMapSection.clear() predefined_map_sections = config_loader( dataset="predefined_map_sections") self.cbChangeMapSection.addItems(sorted(predefined_map_sections.keys())) if extra is not None and len(extra) > 0: self.cbChangeMapSection.insertSeparator(self.cbChangeMapSection.count()) self.cbChangeMapSection.addItems(sorted(extra))
def __init__(self, token, p_id, user, project_name, projects, conn, parent=None, mscolab_server_url=config_loader(dataset="default_MSCOLAB")): """ token: access token p_id: project id conn: connection to send/receive socket messages """ super(MSColabAdminWindow, self).__init__(parent) self.setupUi(self) self.mscolab_server_url = mscolab_server_url self.token = token self.p_id = p_id self.user = user self.project_name = project_name self.projects = projects self.conn = conn self.addUsers = [] self.modifyUsers = [] # Button click handlers self.addUsersBtn.clicked.connect(self.add_selected_users) self.modifyUsersBtn.clicked.connect(self.modify_selected_users) self.deleteUsersBtn.clicked.connect(self.delete_selected_users) self.importPermissionsBtn.clicked.connect(self.import_permissions) self.selectAllAddBtn.clicked.connect( lambda: self.select_all(self.addUsersTable)) self.deselectAllAddBtn.clicked.connect( lambda: self.deselect_all(self.addUsersTable)) self.selectAllModifyBtn.clicked.connect( lambda: self.select_all(self.modifyUsersTable)) self.deselectAllModifyBtn.clicked.connect( lambda: self.deselect_all(self.modifyUsersTable)) # Search filter self.addUsersSearch.textChanged.connect( lambda text: self.search_user_filter(text, self.addUsersTable)) self.modifyUsersSearch.textChanged.connect( lambda text: self.search_user_filter(text, self.modifyUsersTable)) self.modifyUsersPermissionFilter.currentTextChanged.connect( self.apply_permission_filter) # Setting handlers for connection manager self.conn.signal_project_permissions_updated.connect( self.handle_permissions_updated) self.set_label_text() self.load_users_without_permission() self.load_users_with_permission() self.populate_import_permission_cb()
def test_existing_config_file_different_parameters(self): """ on a user defined mss_settings_json without a defined num_labels this test should return its default value """ create_mss_settings_file('{"num_interpolation_points": 20 }') if not fs.open_fs(MSS_CONFIG_PATH).exists("mss_settings.json"): pytest.skip('undefined test mss_settings.json') with fs.open_fs(MSS_CONFIG_PATH) as file_dir: file_content = file_dir.readtext("mss_settings.json") assert "num_labels" not in file_content config_file = fs.path.combine(MSS_CONFIG_PATH, "mss_settings.json") data = utils.config_loader(config_file=config_file) assert data["num_labels"] == 10 num_labels = utils.config_loader(config_file=config_file, dataset="num_labels") assert num_labels == 10 num_interpolation_points = utils.config_loader( config_file=config_file, dataset="num_interpolation_points") assert num_interpolation_points == 20 data = utils.config_loader(config_file=config_file) assert data["num_interpolation_points"] == 20 with pytest.raises(KeyError): utils.config_loader(config_file=config_file, dataset="UNDEFINED") with pytest.raises(KeyError): assert utils.config_loader(config_file=config_file, dataset="UNDEFINED")
def create_new_flight_track(self, template=None, filename=None): """Creates a new flight track model from a template. Adds a new entry to the list of flight tracks. Called when the user selects the 'new/open flight track' menu entries. Arguments: template -- copy the specified template to the new flight track (so that it is not empty). filename -- if not None, load the flight track in the specified file. """ if template is None: template = [] waypoints = config_loader(dataset="new_flighttrack_template") default_flightlevel = config_loader( dataset="new_flighttrack_flightlevel") for wp in waypoints: template.append( ft.Waypoint(flightlevel=default_flightlevel, location=wp)) if len(template) < 2: QtWidgets.QMessageBox.critical( self, self.tr("flighttrack template"), self. tr("ERROR:Flighttrack template in configuration is too short. " "Please add at least two valid locations.")) if filename is not None: waypoints_model = ft.WaypointsTableModel(filename=filename) else: # Create a new flight track from the waypoints template. self.new_flight_track_counter += 1 waypoints_model = ft.WaypointsTableModel( name=f"new flight track ({self.new_flight_track_counter:d})") # Make a copy of the template. Otherwise all new flight tracks would # use the same data structure in memory. template_copy = copy.deepcopy(template) waypoints_model.insertRows(0, rows=len(template_copy), waypoints=template_copy) # Create a new list entry for the flight track. Make the item name # editable. listitem = QFlightTrackListWidgetItem(waypoints_model, self.listFlightTracks) listitem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.activate_flight_track(listitem)
def openTool(self, index): """Slot that handles requests to open tool windows. """ index = self.controlToBeCreated(index) if index >= 0: if index == WMS: # Open a WMS control widget. title = "Web Service Plot Control" widget = wms.VSecWMSControlWidget( default_WMS=config_loader(dataset="default_VSEC_WMS"), waypoints_model=self.waypoints_model, view=self.mpl.canvas, wms_cache=config_loader(dataset="wms_cache")) self.mpl.canvas.waypoints_interactor.signal_get_vsec.connect(widget.call_get_vsec) else: raise IndexError("invalid control index") # Create the actual dock widget containing <widget>. self.createDockWidget(index, title, widget)
def test_existing_empty_config_file(self): """ on a user defined empty mss_settings_json this test should return the default value for num_labels """ create_mss_settings_file('{ }') if not fs.open_fs(MSS_CONFIG_PATH).exists("mss_settings.json"): pytest.skip('undefined test mss_settings.json') with fs.open_fs(MSS_CONFIG_PATH) as file_dir: file_content = file_dir.readtext("mss_settings.json") assert ":" not in file_content config_file = fs.path.combine(MSS_CONFIG_PATH, "mss_settings.json") data = utils.config_loader(config_file=config_file) assert data["num_labels"] == 10 num_labels = utils.config_loader(config_file=config_file, dataset="num_labels") assert num_labels == 10 # this overwrites the builtin default value num_labels = utils.config_loader(config_file=config_file, dataset="num_labels") assert num_labels == 10 with pytest.raises(KeyError): utils.config_loader(config_file=config_file, dataset="UNDEFINED") with pytest.raises(KeyError): assert utils.config_loader(config_file=config_file, dataset="UNDEFINED")
def __init__(self, model=None, settings=None, numlabels=None): """ Arguments: model -- WaypointsTableModel defining the vertical section. """ if numlabels is None: numlabels = config_loader(dataset='num_labels', default=mss_default.num_labels) super(MplSideViewCanvas, self).__init__() # Default settings. self.settings_dict = { "vertical_extent": (1050, 180), "vertical_axis": "pressure", "flightlevels": [], "draw_flightlevels": True, "draw_flighttrack": True, "fill_flighttrack": True, "label_flighttrack": True, "draw_ceiling": True, "colour_ft_vertices": (0, 0, 1, 1), "colour_ft_waypoints": (1, 0, 0, 1), "colour_ft_fill": (0, 0, 1, 0.15), "colour_ceiling": (0, 0, 1, 0.15) } if settings is not None: self.settings_dict.update(settings) # Setup the plot. self.p_bot = self.settings_dict["vertical_extent"][0] * 100 self.p_top = self.settings_dict["vertical_extent"][1] * 100 self.numlabels = numlabels self.setup_side_view() # Draw a number of flight level lines. self.flightlevels = [] self.fl_label_list = [] self.draw_flight_levels() self.imgax = None self.image = None self.ceiling_alt = [] # If a waypoints model has been passed, create an interactor on it. self.waypoints_interactor = None self.waypoints_model = None self.basename = "sideview" if model: self.set_waypoints_model(model) self.set_settings(self.settings_dict)
def set_waypoints_model(self, model): """Set the WaypointsTableModel defining the vertical section. If no model had been set before, create a new interactor object on the model to let the user interactively move the altitude of the waypoints. """ self.waypoints_model = model if self.waypoints_interactor: self.waypoints_interactor.set_waypoints_model(model) else: # Create a path interactor object. The interactor object connects # itself to the change() signals of the flight track data model. self.waypoints_interactor = mpl_pi.VPathInteractor( self.ax, self.waypoints_model, numintpoints=config_loader(dataset="num_interpolation_points"), redraw_xaxis=self.redraw_xaxis, clear_figure=self.clear_figure )