Пример #1
0
    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)
Пример #2
0
    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)
Пример #3
0
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
Пример #4
0
 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
Пример #5
0
    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
Пример #6
0
 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)
Пример #7
0
 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.")
Пример #8
0
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))
Пример #9
0
 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)
Пример #10
0
    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')
Пример #11
0
    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()
Пример #12
0
    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)
Пример #13
0
    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)))
Пример #14
0
    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()
Пример #15
0
    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)
Пример #16
0
    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
Пример #17
0
 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()
Пример #18
0
    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)
Пример #19
0
    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()
Пример #20
0
    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()
Пример #21
0
    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}"))
Пример #22
0
    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)
Пример #23
0
 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))
Пример #24
0
    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()
Пример #25
0
 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")
Пример #26
0
    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)
Пример #27
0
 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)
Пример #28
0
 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")
Пример #29
0
    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)
Пример #30
0
 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
         )