Пример #1
0
def _display_error_dialog(frame,
                          exc,
                          pipeline,
                          message=None,
                          tb=None,
                          continue_only=False,
                          remote_exc_info=None):
    '''Display an error dialog, returning an indication of whether to continue

    frame - parent frame for application
    exc - exception that caused the error
    pipeline - currently executing pipeline
    message - message to display
    tb - traceback
    continue_only - show "continue" option, only
    remote_exc_info - None (the default) for exceptions in the current process.
        For remote processes:
            (exc_name, exc_message, traceback_text, filename, 
             line_number, remote_event_queue)

    Returns either ED_STOP or ED_CONTINUE indicating how to handle.
    '''

    import wx
    assert wx.Thread_IsMain(), "Can only display errors from WX thread."

    if remote_exc_info:
        from_subprocess = True
        exc_name, exc_message, traceback_text, \
            filename, line_number, remote_debug_callback = remote_exc_info
        if message is None:
            message = exc_message
    else:
        from_subprocess = False
        if message is None:
            message = str(exc)
        if tb is None:
            traceback_text = traceback.format_exc()
            tb = sys.exc_info()[2]
        else:
            traceback_text = "".join(
                traceback.format_exception(type(exc), exc, tb))

        # find the place where this error occurred, and if we've already
        # reported it, don't do so again (instead, just log it to the
        # console), to prevent the UI from becoming unusable.
        filename, line_number, _, _ = traceback.extract_tb(tb)[-1]

    if (filename, line_number) in previously_seen_error_locations:
        if from_subprocess:
            logging.root.error(
                "Previously displayed remote exception:\n%s\n%s", exc_name,
                traceback_text)
        else:
            logging.root.error("Previously displayed uncaught exception:",
                               exc_info=(type(exc), exc, tb))
        return ED_CONTINUE
    previously_seen_error_locations.add((filename, line_number))

    dialog = wx.Dialog(frame,
                       title="Pipeline error",
                       style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)
    sizer = wx.BoxSizer(wx.VERTICAL)
    dialog.SetSizer(sizer)
    question_control = wx.StaticText(
        dialog, -1, "Encountered error while processing. "
        "Do you want to stop processing?")
    question_control.Font = wx.Font(int(dialog.Font.GetPointSize() * 5 / 4),
                                    dialog.Font.GetFamily(),
                                    dialog.Font.GetStyle(), wx.FONTWEIGHT_BOLD)
    sizer.Add(question_control, 0, wx.EXPAND | wx.ALL, 5)
    error_control = wx.StaticBox(dialog, -1, "Error:")
    error_box = wx.StaticBoxSizer(error_control, wx.HORIZONTAL)
    message_control = wx.StaticText(dialog, -1, message)
    error_box.Add(message_control, 1, wx.EXPAND | wx.RIGHT, 5)
    sizer.Add(error_box, 1, wx.EXPAND | wx.ALL, 5)
    aux_button_box = wx.BoxSizer(wx.VERTICAL)
    error_box.Add(aux_button_box, 0, wx.EXPAND)

    #
    # Handle show details button
    #
    details_button = wx.Button(dialog, -1, "Details...")
    details_button.SetToolTipString("Show error details")
    aux_button_box.Add(details_button, 0, wx.EXPAND | wx.BOTTOM, 5)
    details_on = [False]

    def on_details(event):
        if not details_on[0]:
            message_control.Label = "%s\n%s" % (message, traceback_text)
            message_control.Refresh()
            details_button.Label = "Hide details..."
            details_button.Refresh()
            dialog.Fit()
            details_on[0] = True
        else:
            message_control.Label = message
            message_control.Refresh()
            details_button.Label = "Details..."
            details_button.Refresh()
            dialog.Fit()
            details_on[0] = False

    dialog.Bind(wx.EVT_BUTTON, on_details, details_button)

    #
    # Handle copy button
    #
    copy_button = wx.Button(dialog, -1, "Copy to clipboard")
    copy_button.SetToolTipString("Copy error to clipboard")
    aux_button_box.Add(copy_button, 0, wx.EXPAND | wx.BOTTOM, 5)

    def on_copy(event):
        if wx.TheClipboard.Open():
            try:
                wx.TheClipboard.Clear()
                wx.TheClipboard.SetData(wx.TextDataObject(traceback_text))
                wx.TheClipboard.Flush()
            finally:
                wx.TheClipboard.Close()

    dialog.Bind(wx.EVT_BUTTON, on_copy, copy_button)

    #
    # Handle pdb button
    #
    if ((tb or remote_exc_info)
            is not None) and (not hasattr(sys, 'frozen')
                              or os.getenv('CELLPROFILER_DEBUG')):
        if not from_subprocess:
            pdb_button = wx.Button(dialog, -1, "Debug in pdb...")
            pdb_button.SetToolTipString("Debug in python's pdb on the console")
            aux_button_box.Add(pdb_button, 0, wx.EXPAND | wx.BOTTOM, 5)

            def handle_pdb(event):
                import pdb
                pdb.post_mortem(tb)
                # This level of interest seems to indicate the user might
                # want to debug this error if it occurs again.
                if (filename, line_number) in previously_seen_error_locations:
                    previously_seen_error_locations.remove(
                        (filename, line_number))
        else:
            pdb_button = wx.Button(dialog, -1, "Debug remotely...")
            pdb_button.SetToolTipString("Debug remotely in pdb via telnet")
            aux_button_box.Add(pdb_button, 0, wx.EXPAND | wx.BOTTOM, 5)

            def handle_pdb(event):
                if not remote_debug_callback():
                    # The user has told us that remote debugging has gone wonky
                    pdb_button.Enable(False)
                # This level of interest seems to indicate the user might
                # want to debug this error if it occurs again.
                if (filename, line_number) in previously_seen_error_locations:
                    previously_seen_error_locations.remove(
                        (filename, line_number))

        dialog.Bind(wx.EVT_BUTTON, handle_pdb, pdb_button)

    #
    # Handle the "stop" button being pressed
    #
    result = [None]

    def on_stop(event):
        dialog.SetReturnCode(wx.YES)
        result[0] = ED_STOP
        dialog.Close()
        event.Skip()

    stop_button = wx.Button(dialog, label="Stop processing...")
    dialog.Bind(wx.EVT_BUTTON, on_stop, stop_button)

    #
    # Handle the "continue" button being pressed
    #
    def on_continue(event):
        result[0] = ED_CONTINUE
        dialog.SetReturnCode(wx.NO)
        dialog.Close()
        event.Skip()

    continue_button = wx.Button(dialog, label="Continue processing...")
    dialog.Bind(wx.EVT_BUTTON, on_continue, continue_button)

    #
    # Handle report button
    #
    def handle_report(event):
        on_report(event, dialog, traceback_text, pipeline)

    report_button = wx.Button(dialog, label="Send report...")
    report_button.SetToolTipString(
        "Upload error report to the CellProfiler Project")
    dialog.Bind(wx.EVT_BUTTON, handle_report, report_button)

    #
    # Handle "Skip Image" button being pressed
    #
    def on_skip(event):
        result[0] = ED_SKIP
        dialog.Close()
        event.Skip()

    skip_button = wx.Button(dialog, label='Skip Image, Continue Pipeline')
    dialog.Bind(wx.EVT_BUTTON, on_skip, skip_button)

    button_sizer = wx.BoxSizer(wx.HORIZONTAL)
    button_sizer.Add((2, 2))
    button_sizer.Add(stop_button)
    button_sizer.Add((5, 5), proportion=1)
    button_sizer.Add(continue_button)
    button_sizer.Add((5, 5), proportion=1)
    button_sizer.Add(report_button)
    button_sizer.Add((5, 5), proportion=1)
    button_sizer.Add(skip_button)
    button_sizer.Add((2, 2))
    if continue_only:
        button_sizer.Hide(stop_button)
        button_sizer.Hide(skip_button)

    sizer.Add(button_sizer, 0, wx.EXPAND | wx.ALL, 4)

    dialog.Fit()
    dialog.ShowModal()
    return result[0]
Пример #2
0
    def write(self, string):
        if not wx.Thread_IsMain():
            # Aquire the GUI mutex before making GUI calls.  Mutex is released
            # when locker is deleted at the end of this function.
            #
            # TODO: This should be updated to use wx.CallAfter similarly to how
            # PyOnDemandOutputWindow.write was so it is not necessary
            # to get the gui mutex
            locker = wx.MutexGuiLocker()

        if self.Enabled:
            if self.f:
                self.f.write(string)
                self.f.flush()

            move = 1
            if (hasattr(self, "text") and self.text is not None
                    and self.text.GetInsertionPoint() !=
                    self.text.GetLastPosition()):
                move = 0

            if not self.frame:
                self.frame = wx.Frame(self.parent,
                                      -1,
                                      self.title,
                                      size=(450, 300),
                                      style=wx.DEFAULT_FRAME_STYLE
                                      | wx.NO_FULL_REPAINT_ON_RESIZE)

                self.text = wx.TextCtrl(self.frame,
                                        -1,
                                        "",
                                        style=wx.TE_MULTILINE | wx.TE_READONLY
                                        | wx.TE_RICH)

                self.frame.sb = _MyStatusBar(
                    self.frame,
                    callbacks=[
                        self.DisableOutput, self.CloseFile, self.OpenNewFile
                    ],
                    useopenbutton=hasattr(self, "nofile"))
                self.frame.SetStatusBar(self.frame.sb)
                self.frame.Show(True)
                self.frame.Bind(wx.EVT_CLOSE, self.OnCloseWindow)

                if hasattr(self, "nofile"):
                    self.text.AppendText(
                        "Please close this window (or select the "
                        "'Dismiss' button below) when desired.  By "
                        "default all messages written to this window "
                        "will NOT be written to a file--you "
                        "may change this by selecting 'Open New File' "
                        "below, allowing you to select a "
                        "new file...\n\n")
                else:
                    tempfile.tempdir = self.dir
                    filename = ''
                    try:
                        self.f = tempfile.NamedTemporaryFile(mode='w',
                                                             delete=False)
                        filename = os.path.abspath(self.f.name)

                        self.frame.sb.SetStatusText(
                            "File '%s' opened..." % filename, 0)
                    except EnvironmentError:
                        self.frame.sb.SetStatusText(
                            "File creation failed "
                            "(filename '%s')..." % filename, 0)
                    self.text.AppendText(
                        "Please close this window (or select the "
                        "'Dismiss' button below) when desired.  By "
                        "default all messages written to this window "
                        "will also be written to the file '%s'--you "
                        "may close this file by selecting 'Close "
                        "File' below, whereupon this button will be "
                        "replaced with one allowing you to select a "
                        "new file...\n\n" % filename)

            self.text.AppendText(string)

            if move:
                self.text.ShowPosition(self.text.GetLastPosition())

            if not hasattr(self, "no__debug__"):
                for m in sys.modules.values():
                    if m is not None:  # and "__debug__" in m.__dict__:
                        m.__dict__["__debug__"] = 1

            if hasattr(self, "othermenu") and self.othermenu is not None:
                i = self.othermenu.FindMenuItem(self.menuname,
                                                self.disableitem)
                self.othermenu.Enable(i, 1)
                i = self.othermenu.FindMenuItem(self.menuname, self.enableitem)
                self.othermenu.Enable(i, 0)
Пример #3
0
def maybeCallAfter(func, *args, **kw):
    if wx.Thread_IsMain():
        func(*args, **kw)
    else:
        wx.CallAfter(func, *args, **kw)
 def __check_thread(self):
     if __debug__ and not wx.Thread_IsMain():
         print >> sys.stderr, "EmbeddedPlayer: __check_thread thread", currentThread(
         ).getName(), "is NOT MainThread"
         print_stack()
Пример #5
0
    def startDownload(self,
                      torrentfilename=None,
                      destdir=None,
                      infohash=None,
                      tdef=None,
                      cmdline=False,
                      vodmode=False,
                      hops=0,
                      selectedFiles=None,
                      hidden=False):
        self._logger.debug(u"startDownload: %s %s %s %s %s", torrentfilename,
                           destdir, tdef, vodmode, selectedFiles)

        # TODO(lipu): remove the assertions after it becomes stable
        if infohash is not None:
            assert isinstance(infohash,
                              str), "infohash type: %s" % type(infohash)
            assert len(infohash) == 20, "infohash length is not 20: %s, %s" % (
                len(infohash), infohash)

        # the priority of the parameters is: (1) tdef, (2) infohash, (3) torrent_file.
        # so if we have tdef, infohash and torrent_file will be ignored, and so on.
        if tdef is None:
            if infohash is not None:
                # try to get the torrent from torrent_store if the infohash is provided
                torrent_data = self.utility.session.get_collected_torrent(
                    infohash)
                if torrent_data is not None:
                    # use this torrent data for downloading
                    tdef = TorrentDef.load_from_memory(torrent_data)

            if tdef is None:
                assert torrentfilename is not None, "torrent file must be provided if tdef and infohash are not given"
                # try to get the torrent from the given torrent file
                torrent_data = fix_torrent(torrentfilename)
                if torrent_data is None:
                    # show error message: could not open torrent file
                    dlg = wx.MessageBox(
                        self,
                        "Could not open torrent file %s" % torrentfilename,
                        "Error", wx.OK | wx.ICON_ERROR)
                    dlg.ShowModal()
                    dlg.Destroy()
                    return

                tdef = TorrentDef.load_from_memory(torrent_data)

        assert tdef is not None, "tdef MUST not be None after loading torrent"

        try:
            d = self.utility.session.get_download(tdef.get_infohash())
            if d:
                new_trackers = list(
                    set(tdef.get_trackers_as_single_tuple()) -
                    set(d.get_def().get_trackers_as_single_tuple()))
                if not new_trackers:
                    raise DuplicateDownloadException()

                else:

                    @forceWxThread
                    def do_gui():
                        # Show update tracker dialog
                        dialog = wx.MessageDialog(
                            None,
                            'This torrent is already being downloaded. Do you wish to load the trackers from it?',
                            'Tribler',
                            wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION)
                        if dialog.ShowModal() == wx.ID_YES:
                            # Update trackers
                            self.utility.session.update_trackers(
                                tdef.get_infohash(), new_trackers)
                        dialog.Destroy()

                    do_gui()
                return

            defaultDLConfig = DefaultDownloadStartupConfig.getInstance()
            dscfg = defaultDLConfig.copy()

            cancelDownload = False
            useDefault = not self.utility.read_config('showsaveas')
            safe_seeding = self.utility.read_config(
                'default_safeseeding_enabled')
            if not useDefault and not destdir:
                defaultname = tdef.get_name_as_unicode(
                ) if tdef.is_multifile_torrent() else None

                if wx.Thread_IsMain():
                    dlg = SaveAs(None, tdef, dscfg.get_dest_dir(), defaultname,
                                 selectedFiles)
                    dlg.CenterOnParent()

                    if isinstance(tdef, TorrentDefNoMetainfo):
                        # Correct for the smaller size of the dialog if there is no metainfo
                        center_pos = dlg.GetPosition()
                        center_pos[1] -= 150
                        dlg.SetPosition(center_pos)

                    if dlg.ShowModal() == wx.ID_OK:
                        # If the dialog has collected a torrent, use the new tdef
                        tdef = dlg.GetCollected() or tdef

                        if tdef and tdef.is_multifile_torrent():
                            selectedFiles = dlg.GetSelectedFiles()
                        destdir = dlg.GetPath()

                        # Anonymity over exit nodes or hidden services
                        safe_seeding = dlg.UseSafeSeeding()
                        if dlg.UseTunnels():
                            hops = self.utility.read_config(
                                'default_number_hops')

                    else:
                        cancelDownload = True
                    dlg.Destroy()
                else:
                    raise Exception("cannot create dialog, not on wx thread")

            # use default setup
            else:
                if useDefault:
                    if self.utility.read_config('default_anonymity_enabled'):
                        # only load default anonymous level if we use default settings
                        hops = self.utility.read_config('default_number_hops')
                    else:
                        hops = 0

            if hops > 0:
                if not tdef:
                    raise Exception(
                        'Currently only torrents can be downloaded in anonymous mode'
                    )

            dscfg.set_hops(hops)
            dscfg.set_safe_seeding(safe_seeding)

            if not cancelDownload:
                if destdir is not None:
                    dscfg.set_dest_dir(destdir)

                if selectedFiles and len(selectedFiles) == 1:
                    # we should filter files to see if they are all playable
                    videofiles = selectedFiles

                elif tdef and not selectedFiles:
                    videofiles = tdef.get_files(exts=videoextdefaults)

                else:
                    videofiles = []

                # disable vodmode if no videofiles, unless we still need to collect the torrent
                if vodmode and len(videofiles) == 0 and (
                        not tdef
                        or not isinstance(tdef, TorrentDefNoMetainfo)):
                    vodmode = False

                if vodmode:
                    self._logger.info(
                        'MainFrame: startDownload: Starting in VOD mode')
                    result = self.utility.session.start_download_from_tdef(
                        tdef, dscfg)
                    self.guiUtility.library_manager.playTorrent(
                        tdef.get_infohash(),
                        videofiles[0] if len(videofiles) == 1 else None)

                else:
                    if selectedFiles:
                        dscfg.set_selected_files(selectedFiles)

                    self._logger.debug(
                        'MainFrame: startDownload: Starting in DL mode')
                    result = self.utility.session.start_download_from_tdef(
                        tdef, dscfg, hidden=hidden)

                if result and not hidden:
                    self.show_saved(tdef)

                return result

        except DuplicateDownloadException as e:
            # If there is something on the cmdline, all other torrents start
            # in STOPPED state. Restart
            if cmdline:
                dlist = self.utility.session.get_downloads()
                for d in dlist:
                    if d.get_def().get_infohash() == tdef.get_infohash():
                        d.restart()
                        break

            if wx.Thread_IsMain():
                # show nice warning dialog
                dlg = wx.MessageDialog(
                    None,
                    "You are already downloading this torrent, see the Downloads section.",
                    "Duplicate download", wx.OK | wx.ICON_ERROR)
                result = dlg.ShowModal()
                dlg.Destroy()

            else:
                print_exc()
                self.onWarning(e)

        except Exception as e:
            print_exc()
            self.onWarning(e)

        return None
Пример #6
0
 def callafterwrap(*args, **kwargs):
     if wx.Thread_IsMain():
         return funct(*args, **kwargs)
     else:
         wx.CallAfter(funct, *args, **kwargs)
Пример #7
0
def alive():
    return True


class Server(Thread):
    def run(self):
        server = SimpleXMLRPCServer(("localhost", 8000), allow_none=True)
        server.register_introspection_functions()
        server.register_function(plot)
        server.register_function(alive)
        print "Listening on port 8000..."
        server.serve_forever()


server = Server()
server.start()
app = wx.GetApp()
assert app is not None
assert wx.Thread_IsMain()
evtloop = wx.EventLoop()
ea = wx.EventLoopActivator(evtloop)
while 1:
    gui_lock.acquire()
    while evtloop.Pending():
        evtloop.Dispatch()
        app.ProcessIdle()
        gui_lock.release()
        gui_lock.acquire()
    gui_lock.release()
    sleep(0.001)
Пример #8
0
 def write(self, text):
     if not wx.Thread_IsMain():
         wx.CallAfter(self._do_write, text)
     else:
         self._do_write(text)
Пример #9
0
 def new_guithread_function(*args, **kwargs):
     if wx.Thread_IsMain():
         return function(*args, **kwargs)
     else:
         wx.CallAfter(function, *args, **kwargs)
Пример #10
0
	def syncwrap( *args, **kwargs ):
		if wx.Thread_IsMain():
			return self.func( *args, **kwargs )
		else:
			sync = Synchronizer( func, *args, **kwargs )
			return sync.Run()