Esempio n. 1
0
    def __init__(self, parent=None, first_run=False):
        wx.Dialog.__init__(self,
                           parent,
                           title="Settings",
                           style=wx.DEFAULT_DIALOG_STYLE)
        self._first_run = first_run
        self._sizer = wx.BoxSizer(wx.VERTICAL)
        self._defaults = {}

        self._sizer.Add(URLEntryPanel(
            self, default_url=read_config_option("baseurl")),
                        flag=wx.EXPAND | wx.ALL,
                        border=5)

        authorization_sizer = wx.BoxSizer(wx.HORIZONTAL)
        authorization_sizer.Add(ClientDetailsPanel(
            self,
            default_client_id=read_config_option("client_id"),
            default_client_secret=read_config_option("client_secret")),
                                flag=wx.EXPAND | wx.RIGHT,
                                border=2,
                                proportion=1)
        authorization_sizer.Add(UserDetailsPanel(
            self,
            default_user=read_config_option("username"),
            default_pass=read_config_option("password")),
                                flag=wx.EXPAND | wx.LEFT,
                                border=2,
                                proportion=1)
        self._sizer.Add(authorization_sizer, flag=wx.EXPAND | wx.ALL, border=5)

        self._sizer.Add(PostProcessingTaskPanel(
            self, default_post_process=read_config_option("completion_cmd")),
                        flag=wx.EXPAND | wx.ALL,
                        border=5)
        self._sizer.Add(DefaultDirectoryPanel(
            self,
            default_directory=read_config_option("default_dir"),
            monitor_directory=read_config_option("monitor_default_dir",
                                                 expected_type=bool)),
                        flag=wx.EXPAND | wx.ALL,
                        border=5)

        self._sizer.Add(self.CreateSeparatedButtonSizer(flags=wx.OK),
                        flag=wx.EXPAND | wx.ALL,
                        border=5)

        self.SetSizerAndFit(self._sizer)
        self.Layout()

        pub.subscribe(self._field_changed, SettingsDialog.field_changed_topic)
        self.Bind(wx.EVT_CLOSE, self._on_close)
        self.Bind(wx.EVT_BUTTON, self._on_close, id=wx.ID_OK)
        threading.Thread(target=connect_to_irida).start()
Esempio n. 2
0
    def _get_default_directory(self):
        """Read the default directory from the configuration file, or, if the user
        has selected a directory manually, return the manually selected directory.

        Returns:
            A string containing the default directory to scan.
        """

        if not self._selected_directory:
            return read_config_option("default_dir")
        else:
            return self._selected_directory
Esempio n. 3
0
    def _start_upload(self, *args, **kwargs):
        """Initiate uploading runs to the server.

        This will upload multiple runs simultaneously, one per thread.

        Args:
            event: the button event that initiated the method.
        """
        post_processing_task = read_config_option("completion_cmd")
        logging.debug("Running upload for {}".format(str(self._discovered_runs)))
        pub.subscribe(self._post_processing_task_started, RunUploaderTopics.started_post_processing)
        self._upload_thread = RunUploader(api=self._api, runs=self._discovered_runs, post_processing_task=post_processing_task)
        # destroy the upload button once it's been clicked.
        self.Freeze()
        self._upload_sizer.Clear(True)
        self.Layout()
        self.Thaw()
        self._upload_thread.start()
Esempio n. 4
0
    def _post_processing_task_started(self):
        """Show a 'processing' message on the UI while the post processing task is executing."""
        pub.unsubscribe(self._post_processing_task_started, RunUploaderTopics.started_post_processing)
        pub.subscribe(self._post_processing_task_completed, RunUploaderTopics.finished_post_processing)
        pub.subscribe(self._post_processing_task_failed, RunUploaderTopics.failed_post_processing)
        logging.info("Post-processing started, updating UI.")

        self.Freeze()
        self._post_processing_sizer = wx.BoxSizer(wx.HORIZONTAL)
        self._post_processing_placeholder = ProcessingPlaceholderText(self)
        self._post_processing_placeholder.SetFont(wx.Font(pointSize=18, family=wx.FONTFAMILY_DEFAULT, style=wx.NORMAL, weight=wx.FONTWEIGHT_BOLD, face="Segoe UI Symbol"))
        self._post_processing_text = wx.StaticText(self, label="Executing post-processing task.")
        self._post_processing_text.SetFont(wx.Font(18, wx.DEFAULT, wx.NORMAL, wx.BOLD))
        self._post_processing_text.Wrap(350)
        self._post_processing_text.SetToolTipString("Executing command `{}`.".format(read_config_option("completion_cmd")))
        self._post_processing_sizer.Add(self._post_processing_text, flag=wx.RIGHT, border=5, proportion=1)
        self._post_processing_sizer.Add(self._post_processing_placeholder, flag=wx.LEFT, border=5, proportion=0)

        self._sizer.Insert(0, self._post_processing_sizer, flag=wx.EXPAND | wx.ALL, border=5)
        self.Layout()
        self.Thaw()
Esempio n. 5
0
    def _settings_changed(self, api=None):
    	"""Reset the main display and attempt to connect to the server
    	   whenever the connection settings may have changed.

     	Args:
    	    api: A placeholder for a complete api that's passed when the event is fired.
    	"""

        # before doing anything, clear all of the children from the sizer and
        # also delete any windows attached (Buttons and stuff extend from Window!)
        self._sizer.Clear(deleteWindows=True)
        # and clear out the list of discovered runs that we might be uploading to the server.
        self._discovered_runs = []
        # initialize the invalid sheets panel so that it can listen for events
        # before directory scanning starts, but hide it until we actually get
        # an error raised by the validation part.
        self._invalid_sheets_panel = InvalidSampleSheetsPanel(self, self._get_default_directory())
        self._invalid_sheets_panel.Hide()

        should_monitor_directory = read_config_option("monitor_default_dir", expected_type=bool, default_value=False)

        if should_monitor_directory:
            automatic_upload_status_sizer = wx.BoxSizer(wx.HORIZONTAL)
            auto_upload_enabled_text = wx.StaticText(self, label=u"⇌ Automatic upload enabled.")
            auto_upload_enabled_text.SetFont(wx.Font(14, wx.DEFAULT, wx.NORMAL, wx.BOLD))
            auto_upload_enabled_text.SetForegroundColour(wx.Colour(51, 102, 255))
            auto_upload_enabled_text.SetToolTipString("Monitoring {} for CompletedJobInfo.xml".format(self._get_default_directory()))

            self._sizer.Add(auto_upload_enabled_text, flag=wx.ALIGN_CENTER | wx.ALL, border=5)
            logging.info("Going to monitor default directory [{}] for new runs.".format(self._get_default_directory()))
            # topics to handle when monitoring a directory for automatic upload
            pub.subscribe(self._prepare_for_automatic_upload, DirectoryMonitorTopics.new_run_observed)
            pub.subscribe(self._start_upload, DirectoryMonitorTopics.finished_discovering_run)

            threading.Thread(target=monitor_directory, kwargs={"directory": self._get_default_directory()}).start()

       # run connecting in a different thread so we don't freeze up the GUI
        threading.Thread(target=self._connect_to_irida).start()
Esempio n. 6
0
def connect_to_irida():
    """Connect to IRIDA for online validation.

    Returns:
        A configured instance of API.apiCalls.
    """
    client_id = read_config_option("client_id")
    client_secret = read_config_option("client_secret")
    baseURL = read_config_option("baseURL")
    username = read_config_option("username")
    password = read_config_option("password")

    try:
        # Several threads might be attempting to connect at the same time, so lock
        # the connection step, but **do not** block (acquire(False) means do not block)
        # and just return if someone else is already trying to connect.
        if lock.acquire(False):
            logging.info("About to try connecting to IRIDA.")
            api = ApiCalls(client_id, client_secret, baseURL, username, password)
            send_message(APIConnectorTopics.connection_success_topic, api=api)
            return api
        else:
            logging.info("Someone else is already trying to connect to IRIDA.")
    except ConnectionError as e:
        logging.info("Got a connection error when trying to connect to IRIDA.", exc_info=True)
        send_message(APIConnectorTopics.connection_error_url_topic, error_message=(
            "We couldn't connect to IRIDA at {}. The server might be down. Make "
            "sure that the connection address is correct (you can change the "
            "address by clicking on the 'Open Settings' button below) and try"
            " again, try again later, or contact an administrator."
            ).format(baseURL))
        raise
    except (SyntaxError, ValueError) as e:
        logging.info("Connected, but the response was garbled.", exc_info=True)
        send_message(APIConnectorTopics.connection_error_url_topic, error_message=(
            "We couldn't connect to IRIDA at {}. The server is up, but I "
            "didn't understand the response. Make sure that the connection "
            "address is correct (you can change the address by clicking on "
            "the 'Open Settings' button below) and try again, try again"
            " later, or contact an administrator."
            ).format(baseURL))
        raise
    except KeyError as e:
        logging.info("Connected, but the OAuth credentials are wrong.", exc_info=True)

        # this is credentials related, but let's try to figure out why the server
        # is telling us that we can't log in.
        message = str(e.message)

        if "Bad credentials" in message:
            topic = APIConnectorTopics.connection_error_user_credentials_topic
            # if we're getting bad credentials, then that means the API is allowing
            # us to try authenticate with a username and password, so our client id
            # and secret are both correct:
            send_message(APIConnectorTopics.connection_success_valid_client_secret)
        elif "clientId does not exist" in message:
            topic = APIConnectorTopics.connection_error_client_id_topic
        elif "Bad client credentials" in message:
            topic = APIConnectorTopics.connection_error_client_secret_topic
            # if we're getting a bad client secret message, that means that the
            # client ID is valid.
            send_message(APIConnectorTopics.connection_success_valid_client_id)
        else:
            topic = APIConnectorTopics.connection_error_credentials_topic

        send_message(topic, error_message=(
            "We couldn't connect to IRIDA at {}. The server is up, but it's "
            "reporting that your credentials are wrong. Click on the 'Open Settings'"
            " button below and check your credentials, then try again. If the "
            "connection still doesn't work, contact an administrator."
            ).format(baseURL))

        # in spite of it all, this means that we're probably actually trying to connect
        # to a real IRIDA server, so let the settings dialog know that it can render
        # a success icon beside the URL
        send_message(APIConnectorTopics.connection_success_valid_url)
        raise
    except URLError as e:
        logging.info("Couldn't connect to IRIDA because the URL is invalid.", exc_info=True)
        send_message(APIConnectorTopics.connection_error_url_topic, error_message=(
            "We couldn't connect to IRIDA at {} because it isn't a valid URL. "
            "Click on the 'Open Settings' button below to enter a new URL and "
            "try again."
        ).format(baseURL))
        raise
    except:
        logging.info("Some other kind of error happened.", exc_info=True)
        send_message(APIConnectorTopics.connection_error_topic,  error_message=(
            "We couldn't connect to IRIDA at {} for an unknown reason. Click "
            "on the 'Open Settings' button below to check the URL and your "
            "credentials, then try again. If the connection still doesn't "
            "work, contact an administrator."
        ).format(baseURL))
        raise
    finally:
        try:
            lock.release()
        except:
            pass
Esempio n. 7
0
 def _post_processing_task_failed(self):
     """Show a 'failed' message on the UI when the post processing task fails."""
     pub.unsubscribe(self._post_processing_task_failed, RunUploaderTopics.failed_post_processing)
     pub.unsubscribe(self._post_processing_task_completed, RunUploaderTopics.finished_post_processing)
     logging.info("Post-processing failed, updating UI.")
     self.Freeze()
     self._post_processing_text.SetLabel("Post-processing task failed.")
     self._post_processing_text.SetToolTipString("Failed to execute command `{}`.".format(read_config_option("completion_cmd")))
     self._post_processing_text.Wrap(350)
     self._post_processing_placeholder.SetError("Failed to execute command `{}`.".format(read_config_option("completion_cmd")))
     self.Layout()
     self.Thaw()