예제 #1
0
class MainWindow(wx.Frame):

    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, 'Planet Hunt', size=(1400, 600))

        self.splitter = MultiSplitterWindow(self, style=wx.SP_LIVE_UPDATE)
        # The passing references to panels and controsl to each other
        # seems a bit sloppy and I want to do away with it. Not sure how yet.
        data_display_panel = DataDisplayPanel(self.splitter)
        data_modify_panel = DataModifyPanel(self.splitter, data_display_panel)
        data_search_panel = DataSearchPanel(self.splitter, data_display_panel,
                                            data_modify_panel)
        self.splitter.AppendWindow(data_search_panel, sashPos=150)
        self.splitter.AppendWindow(data_display_panel, sashPos=1050)
        self.splitter.AppendWindow(data_modify_panel)

        status_bar = self.CreateStatusBar()
        menubar_main = wx.MenuBar()
        file_menu = wx.Menu()
        edit_menu = wx.Menu()
        file_menu.Append(wx.NewIdRef(), 'Connect...',
                         'Connect to a new server')
        file_menu.Append(wx.NewIdRef(), 'Close', 'Quit the application')
        menubar_main.Append(file_menu, 'File')
        menubar_main.Append(edit_menu, 'Edit')
        self.SetMenuBar(menubar_main)
        self.SetStatusBar(status_bar)

    def force_update(self):
        # Jiggle the splitter 'sash' around to force a redraw.
        # No, I don't like having to do this but I can't figure out the
        # proper way to make the matplotlib graphs actually show up.
        sp = self.splitter.GetSashPosition(0)
        self.splitter.SetSashPosition(0, sp+1)
        self.splitter.SetSashPosition(0, sp+0)

    def close_window(self, event):
        self.Destroy()
예제 #2
0
class PanelMiners(wx.Panel):
    lock = threading.RLock()

    def __init__(self, parent, frame, num_miners=4):
        wx.Panel.__init__(self, parent=parent, id=wx.ID_ANY)

        self.parent = parent
        self.frame = frame
        self.resize_lock = False

        self.num_miners = num_miners

        self.devicesJson = self.loadDevices()

        self.splitter = MultiSplitterWindow(self,
                                            id=wx.ID_ANY,
                                            style=wx.SP_LIVE_UPDATE)
        self.splitter.SetOrientation(wx.HORIZONTAL)

        self.splitter.SetMinimumPaneSize(1)

        self.miner0 = PMI.PanelMinerInstance(self.splitter, self, "Miner #0",
                                             self.devicesJson['miner0'],
                                             self.devicesJson['miner0num'],
                                             self.devicesJson['devices'])
        self.miner1 = PMI.PanelMinerInstance(self.splitter, self, "Miner #1",
                                             self.devicesJson['miner1'],
                                             self.devicesJson['miner1num'],
                                             self.devicesJson['devices'])
        self.miner2 = PMI.PanelMinerInstance(self.splitter, self, "Miner #2",
                                             self.devicesJson['miner2'],
                                             self.devicesJson['miner2num'],
                                             self.devicesJson['devices'])
        self.miner3 = PMI.PanelMinerInstance(self.splitter, self, "Miner #3",
                                             self.devicesJson['miner3'],
                                             self.devicesJson['miner3num'],
                                             self.devicesJson['devices'])

        self.splitter.AppendWindow(self.miner0)
        self.splitter.AppendWindow(self.miner1)
        self.splitter.AppendWindow(self.miner2)
        self.splitter.AppendWindow(self.miner3)

        self.splitter.Bind(wx.EVT_SIZE, self.resizeMinerPanels)
        #self.splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGING, self.sashChanging)
        #self.splitter.Bind(wx.EVT_SPLITTER_SASH_POS_CHANGED, self.resizeMinerPanels)

        self.collapsePanel = CollapsePanel(self, self.devicesJson['resize'],
                                           self.devicesJson['transfer'])

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        sizerW = wx.BoxSizer(wx.HORIZONTAL)
        sizer.Add(self.splitter, 1, wx.EXPAND)
        sizerW.Add(self.collapsePanel, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, -1)
        sizer.Add(sizerW, 0, wx.EXPAND | wx.TOP, 1)

        self.SetSizer(sizer)

    def loadDevices(self):
        f = open(DEVICES_FILE)
        data = f.read()
        f.close()

        return json.loads(data)

    def saveDevices(self):
        sel0 = self.miner0.handler.deviceCombo.GetValue()
        sel1 = self.miner1.handler.deviceCombo.GetValue()
        sel2 = self.miner2.handler.deviceCombo.GetValue()
        sel3 = self.miner3.handler.deviceCombo.GetValue()

        num0 = self.miner0.handler.deviceNum.GetValue()
        num1 = self.miner1.handler.deviceNum.GetValue()
        num2 = self.miner2.handler.deviceNum.GetValue()
        num3 = self.miner3.handler.deviceNum.GetValue()

        self.devicesJson['miner0'] = sel0
        self.devicesJson['miner1'] = sel1
        self.devicesJson['miner2'] = sel2
        self.devicesJson['miner3'] = sel3

        self.devicesJson['miner0num'] = num0
        self.devicesJson['miner1num'] = num1
        self.devicesJson['miner2num'] = num2
        self.devicesJson['miner3num'] = num3

        self.devicesJson['resize'] = self.collapsePanel.resizeBtn.GetValue()
        self.devicesJson['transfer'] = self.collapsePanel.transferBtn.GetValue(
        )

        io.open(DEVICES_FILE, 'wt',
                encoding='utf-8').write(unicode(json.dumps(self.devicesJson)))

    def deviceChanged(self):
        if self.collapsePanel.transferBtn.GetValue():
            devices = [
                self.miner0.handler.getDevice(),
                self.miner1.handler.getDevice(),
                self.miner2.handler.getDevice(),
                self.miner3.handler.getDevice()
            ]

            self.frame.notebook.broadcastEventToAllTabs(event_id="miner",
                                                        event_value=devices)

    def executeAlgo(self, maxAlgo, switch):
        if switch:
            self.stopMiners()
        else:
            self.stopCrashedMiners()

        ret0 = self.miner0.executeAlgo(maxAlgo, switch)
        ret1 = self.miner1.executeAlgo(maxAlgo, switch)
        ret2 = self.miner2.executeAlgo(maxAlgo, switch)
        ret3 = self.miner3.executeAlgo(maxAlgo, switch)

        if (ret0 is None and ret1 is None and ret2 is None and ret3 is None):
            return None

        return ret0 or ret1 or ret2 or ret3

    def stopMiners(self, wait=False, exit=False):
        self.miner0.stopMiner(exit)
        self.miner1.stopMiner(exit)
        self.miner2.stopMiner(exit)
        self.miner3.stopMiner(exit)

        if exit:
            self.stopLoop(self.checkMinersExited)

        elif wait:
            self.stopLoop(self.checkMinersReady)

        self.frame.notebook.broadcastEventToAllTabs(event_id="stop_mining")

    def stopCrashedMiners(self):
        if self.miner0.minerStatus() == PMI.STATUS_CRASHED:
            self.miner0.stopMiner()

        if self.miner1.minerStatus() == PMI.STATUS_CRASHED:
            self.miner1.stopMiner()

        if self.miner2.minerStatus() == PMI.STATUS_CRASHED:
            self.miner2.stopMiner()

        if self.miner3.minerStatus() == PMI.STATUS_CRASHED:
            self.miner3.stopMiner()

    def stopLoop(self, endFunction):
        success = False
        i = 0
        str_ini = "Waiting for miners to die "

        from miner import PanelMinerInstance

        while i < PanelMinerInstance.MAX_ITERATIONS:
            if not endFunction():
                time.sleep(0.5)
                i += 1
                str_out = str_ini + str(i)
                print str_out

            else:
                str_out = "MINERS done, Bye!"
                print str_out
                #time.sleep(2)
                success = True
                break

        print "Miners: Exited with success = " + str(success)

        if not success:
            str_out = "MINERS Dammit"
            print str_out
            time.sleep(5)

    def checkMinerCrashed(self):
        if self.miner0.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner1.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner2.minerStatus() == PMI.STATUS_CRASHED or \
           self.miner3.minerStatus() == PMI.STATUS_CRASHED:

            return False

        return True

    def checkMinersReady(self):
        if ( self.miner0.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner1.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner2.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ) and \
           ( self.miner3.minerStatus() in (PMI.STATUS_READY, PMI.STATUS_DISABLED, PMI.STATUS_CRASHED, PMI.STATUS_EXITED, PMI.STATUS_EXITING ) ):

            return True

        return False

    def checkMinersExited(self):
        if ( self.miner0.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner1.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner2.minerStatus() == PMI.STATUS_EXITED ) and \
           ( self.miner3.minerStatus() == PMI.STATUS_EXITED ):

            return True

        return False

    def checkMinersSelected(self):
        if ( self.miner0.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner1.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner2.minerStatus() == PMI.STATUS_DISABLED ) and \
           ( self.miner3.minerStatus() == PMI.STATUS_DISABLED ):

            return False

        return True

    def resizeMinerPanels(self, event=None, slide=False, forceResize=False):
        try:
            if not self.collapsePanel.resizeBtn.GetValue() and not forceResize:
                event.Skip()
                return

            width = self.parent.GetSize()[0]
            best = width / self.num_miners

            num_ready = sum(
                1 for miner in
                [self.miner0, self.miner1, self.miner2, self.miner3]
                if miner.minerStatus() is not PMI.STATUS_DISABLED)
            #num_rinning = sum(1 for miner in [self.miner0, self.miner1, self.miner2, self.miner3] if miner.minerStatus() == PMI.STATUS_RUNNING)

            factor = 1.5
            factor = factor if num_ready == 0 else factor + (
                float(num_ready * 1.5) / 10)
            #factor = 1.5 if num_ready == 0 else 1.5 * ( 1 + ( self.num_miners - float(num_ready) - 1 ) / 10 )

            num_not_ready = self.num_miners - num_ready

            if num_ready == 0 or num_not_ready == 0 or forceResize:
                wide = narrow = best
            else:
                factored_num_ready = num_ready * factor

                factored_total = factored_num_ready + num_not_ready

                factor_ready = float(factored_num_ready) / factored_total
                factor_not_ready = float(num_not_ready) / factored_total

                wide = (factor_ready * width) / num_ready
                narrow = (factor_not_ready * width) / num_not_ready

            #no slide effect allowed for resize event triggered calls to the function for performance reasons.
            if not slide:
                self.splitter.SetSashPosition(
                    0,
                    int(wide if self.miner0.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    1,
                    int(wide if self.miner1.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    2,
                    int(wide if self.miner2.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))
                self.splitter.SetSashPosition(
                    3,
                    int(wide if self.miner3.minerStatus() != PMI.
                        STATUS_DISABLED else narrow))

                if event:
                    event.Skip()

                return

            thread = threading.Thread(target=self.resizeMinerPanelsThread,
                                      args=(wide, narrow))
            thread.start()

        except (PyDeadObjectError, AttributeError):
            pass

    def resizeMinerPanelsThread(self, wide, narrow):
        try:
            #with PanelMiners.lock:
            if self.resize_lock:
                time.sleep(0.5)

            if not self.resize_lock:
                self.resize_lock = True

                target0 = int(wide if self.miner0.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target1 = int(wide if self.miner1.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target2 = int(wide if self.miner2.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)
                target3 = int(wide if self.miner3.minerStatus() != PMI.
                              STATUS_DISABLED else narrow)

                steps = 15

                for w in range(1, steps):
                    #if self.resize_lock == False:
                    #    break

                    delta0 = target0 - self.splitter.GetSashPosition(0)
                    delta1 = target1 - self.splitter.GetSashPosition(1)
                    delta2 = target2 - self.splitter.GetSashPosition(2)
                    delta3 = target3 - self.splitter.GetSashPosition(3)

                    pct = float(w) / steps

                    self.splitter.SetSashPosition(
                        0,
                        self.splitter.GetSashPosition(0) + pct * delta0)
                    self.splitter.SetSashPosition(
                        1,
                        self.splitter.GetSashPosition(1) + pct * delta1)
                    self.splitter.SetSashPosition(
                        2,
                        self.splitter.GetSashPosition(2) + pct * delta2)
                    self.splitter.SetSashPosition(
                        3,
                        self.splitter.GetSashPosition(3) + pct * delta3)

                    time.sleep(0.01)

                self.resize_lock = False

        except PyDeadObjectError:
            pass

    def setButtonExpanded(self, expanded):
        self.collapsePanel.setButtonExpanded(expanded)

    def getExpansionStatus(self):
        return self.collapsePanel.collapseBtn.GetValue()