Example #1
0
class Debugger:

    vstack = vsource = vlocals = vglobals = None

    def __init__(self, pyshell, idb=None):
        if idb is None:
            idb = Idb(self)
        self.pyshell = pyshell
        self.idb = idb
        self.frame = None
        self.make_gui()
        self.interacting = 0
        self.nesting_level = 0

    def run(self, *args):
        # Deal with the scenario where we've already got a program running
        # in the debugger and we want to start another. If that is the case,
        # our second 'run' was invoked from an event dispatched not from
        # the main event loop, but from the nested event loop in 'interaction'
        # below. So our stack looks something like this:
        #       outer main event loop
        #         run()
        #           <running program with traces>
        #             callback to debugger's interaction()
        #               nested event loop
        #                 run() for second command
        #
        # This kind of nesting of event loops causes all kinds of problems
        # (see e.g. issue #24455) especially when dealing with running as a
        # subprocess, where there's all kinds of extra stuff happening in
        # there - insert a traceback.print_stack() to check it out.
        #
        # By this point, we've already called restart_subprocess() in
        # ScriptBinding. However, we also need to unwind the stack back to
        # that outer event loop.  To accomplish this, we:
        #   - return immediately from the nested run()
        #   - abort_loop ensures the nested event loop will terminate
        #   - the debugger's interaction routine completes normally
        #   - the restart_subprocess() will have taken care of stopping
        #     the running program, which will also let the outer run complete
        #
        # That leaves us back at the outer main event loop, at which point our
        # after event can fire, and we'll come back to this routine with a
        # clean stack.
        if self.nesting_level > 0:
            self.abort_loop()
            self.root.after(100, lambda: self.run(*args))
            return
        try:
            self.interacting = 1
            return self.idb.run(*args)
        finally:
            self.interacting = 0

    def close(self, event=None):
        try:
            self.quit()
        except Exception:
            pass
        if self.interacting:
            self.top.bell()
            return
        if self.stackviewer:
            self.stackviewer.close()
            self.stackviewer = None
        # Clean up pyshell if user clicked debugger control close widget.
        # (Causes a harmless extra cycle through close_debugger() if user
        # toggled debugger from pyshell Debug menu)
        self.pyshell.close_debugger()
        # Now close the debugger control window....
        self.top.destroy()

    def make_gui(self):
        pyshell = self.pyshell
        self.flist = pyshell.flist
        self.root = root = pyshell.root
        self.top = top = ListedToplevel(root)
        self.top.wm_title("Debug Control")
        self.top.wm_iconname("Debug")
        top.wm_protocol("WM_DELETE_WINDOW", self.close)
        self.top.bind("<Escape>", self.close)
        #
        self.bframe = bframe = Frame(top)
        self.bframe.pack(anchor="w")
        self.buttons = bl = []
        #
        self.bcont = b = Button(bframe, text="Go", command=self.cont)
        bl.append(b)
        self.bstep = b = Button(bframe, text="Step", command=self.step)
        bl.append(b)
        self.bnext = b = Button(bframe, text="Over", command=self.next)
        bl.append(b)
        self.bret = b = Button(bframe, text="Out", command=self.ret)
        bl.append(b)
        self.bret = b = Button(bframe, text="Quit", command=self.quit)
        bl.append(b)
        #
        for b in bl:
            b.configure(state="disabled")
            b.pack(side="left")
        #
        self.cframe = cframe = Frame(bframe)
        self.cframe.pack(side="left")
        #
        if not self.vstack:
            self.__class__.vstack = BooleanVar(top)
            self.vstack.set(1)
        self.bstack = Checkbutton(cframe,
                                  text="Stack",
                                  command=self.show_stack,
                                  variable=self.vstack)
        self.bstack.grid(row=0, column=0)
        if not self.vsource:
            self.__class__.vsource = BooleanVar(top)
        self.bsource = Checkbutton(cframe,
                                   text="Source",
                                   command=self.show_source,
                                   variable=self.vsource)
        self.bsource.grid(row=0, column=1)
        if not self.vlocals:
            self.__class__.vlocals = BooleanVar(top)
            self.vlocals.set(1)
        self.blocals = Checkbutton(cframe,
                                   text="Locals",
                                   command=self.show_locals,
                                   variable=self.vlocals)
        self.blocals.grid(row=1, column=0)
        if not self.vglobals:
            self.__class__.vglobals = BooleanVar(top)
        self.bglobals = Checkbutton(cframe,
                                    text="Globals",
                                    command=self.show_globals,
                                    variable=self.vglobals)
        self.bglobals.grid(row=1, column=1)
        #
        self.status = Label(top, anchor="w")
        self.status.pack(anchor="w")
        self.error = Label(top, anchor="w")
        self.error.pack(anchor="w", fill="x")
        self.errorbg = self.error.cget("background")
        #
        self.fstack = Frame(top, height=1)
        self.fstack.pack(expand=1, fill="both")
        self.flocals = Frame(top)
        self.flocals.pack(expand=1, fill="both")
        self.fglobals = Frame(top, height=1)
        self.fglobals.pack(expand=1, fill="both")
        #
        if self.vstack.get():
            self.show_stack()
        if self.vlocals.get():
            self.show_locals()
        if self.vglobals.get():
            self.show_globals()

    def interaction(self, message, frame, info=None):
        self.frame = frame
        self.status.configure(text=message)
        #
        if info:
            type, value, tb = info
            try:
                m1 = type.__name__
            except AttributeError:
                m1 = "%s" % str(type)
            if value is not None:
                try:
                    m1 = "%s: %s" % (m1, str(value))
                except:
                    pass
            bg = "yellow"
        else:
            m1 = ""
            tb = None
            bg = self.errorbg
        self.error.configure(text=m1, background=bg)
        #
        sv = self.stackviewer
        if sv:
            stack, i = self.idb.get_stack(self.frame, tb)
            sv.load_stack(stack, i)
        #
        self.show_variables(1)
        #
        if self.vsource.get():
            self.sync_source_line()
        #
        for b in self.buttons:
            b.configure(state="normal")
        #
        self.top.wakeup()
        # Nested main loop: Tkinter's main loop is not reentrant, so use
        # Tcl's vwait facility, which reenters the event loop until an
        # event handler sets the variable we're waiting on
        self.nesting_level += 1
        self.root.tk.call('vwait', '::idledebugwait')
        self.nesting_level -= 1
        #
        for b in self.buttons:
            b.configure(state="disabled")
        self.status.configure(text="")
        self.error.configure(text="", background=self.errorbg)
        self.frame = None

    def sync_source_line(self):
        frame = self.frame
        if not frame:
            return
        filename, lineno = self.__frame2fileline(frame)
        if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename):
            self.flist.gotofileline(filename, lineno)

    def __frame2fileline(self, frame):
        code = frame.f_code
        filename = code.co_filename
        lineno = frame.f_lineno
        return filename, lineno

    def cont(self):
        self.idb.set_continue()
        self.abort_loop()

    def step(self):
        self.idb.set_step()
        self.abort_loop()

    def next(self):
        self.idb.set_next(self.frame)
        self.abort_loop()

    def ret(self):
        self.idb.set_return(self.frame)
        self.abort_loop()

    def quit(self):
        self.idb.set_quit()
        self.abort_loop()

    def abort_loop(self):
        self.root.tk.call('set', '::idledebugwait', '1')

    stackviewer = None

    def show_stack(self):
        if not self.stackviewer and self.vstack.get():
            self.stackviewer = sv = StackViewer(self.fstack, self.flist, self)
            if self.frame:
                stack, i = self.idb.get_stack(self.frame, None)
                sv.load_stack(stack, i)
        else:
            sv = self.stackviewer
            if sv and not self.vstack.get():
                self.stackviewer = None
                sv.close()
            self.fstack['height'] = 1

    def show_source(self):
        if self.vsource.get():
            self.sync_source_line()

    def show_frame(self, stackitem):
        self.frame = stackitem[0]  # lineno is stackitem[1]
        self.show_variables()

    localsviewer = None
    globalsviewer = None

    def show_locals(self):
        lv = self.localsviewer
        if self.vlocals.get():
            if not lv:
                self.localsviewer = NamespaceViewer(self.flocals, "Locals")
        else:
            if lv:
                self.localsviewer = None
                lv.close()
                self.flocals['height'] = 1
        self.show_variables()

    def show_globals(self):
        gv = self.globalsviewer
        if self.vglobals.get():
            if not gv:
                self.globalsviewer = NamespaceViewer(self.fglobals, "Globals")
        else:
            if gv:
                self.globalsviewer = None
                gv.close()
                self.fglobals['height'] = 1
        self.show_variables()

    def show_variables(self, force=0):
        lv = self.localsviewer
        gv = self.globalsviewer
        frame = self.frame
        if not frame:
            ldict = gdict = None
        else:
            ldict = frame.f_locals
            gdict = frame.f_globals
            if lv and gv and ldict is gdict:
                ldict = None
        if lv:
            lv.load_dict(ldict, force, self.pyshell.interp.rpcclt)
        if gv:
            gv.load_dict(gdict, force, self.pyshell.interp.rpcclt)

    def set_breakpoint_here(self, filename, lineno):
        self.idb.set_break(filename, lineno)

    def clear_breakpoint_here(self, filename, lineno):
        self.idb.clear_break(filename, lineno)

    def clear_file_breaks(self, filename):
        self.idb.clear_all_file_breaks(filename)

    def load_breakpoints(self):
        "Load PyShellEditorWindow breakpoints into subprocess debugger"
        pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
        for editwin in pyshell_edit_windows:
            filename = editwin.io.filename
            try:
                for lineno in editwin.breakpoints:
                    self.set_breakpoint_here(filename, lineno)
            except AttributeError:
                continue
Example #2
0
class TopLevel(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent, background="gray")
        self.parent = parent
        self.init_global_vars()
        self.init_UI()
        self.detect_debug_mode()
        self.set_state_stopped()

    def init_global_vars(self):
        self.switch_status = 'none'
        self.home_result = IntVar()
        self.move_result = IntVar()
        self.timer_active = IntVar()
        self.test_active = False
        self.test_paused = False

        self.timer = [0, 0]
        self.timer_reset_val = [0, 0]

        #self.active_cycle = 0
        #self.active_temp = 'foo'
        #self.up_motor_res = 2
        #self.right_motor_res = 2

        self.move_motor_resolution = 2

        self.up_full_steps = 3200
        self.right_full_steps = 7200

        self.debug_mode = False

        self.event_schedule = []

        self.move_total_duration = 0
        self.move_direction = ''
        self.move_started_time = datetime.now()
        self.pause_time = datetime.now()
        self.resume_time = datetime.now()
        self.planned_steps = 0

    def init_UI(self):

        self.parent.title('Liquid Thermal Shock Tester v0.2')
        self.pack(fill=BOTH, expand=True)
        options_frame = Frame(self, background='gray', pady=5, padx=5)
        options_frame.pack(side=LEFT, fill=BOTH, expand=True)

        options_label = Label(options_frame,
                              text='Test Setup',
                              background='gray',
                              font=('Courier', 22, 'bold'),
                              justify=LEFT)
        ul_bold_font = Font(options_label, options_label.cget('font'))
        ul_bold_font.configure(underline=True)
        options_label.configure(font=ul_bold_font)
        options_label.pack(anchor=CENTER, side=TOP, padx=5, pady=5)

        cycles_frame = Frame(options_frame, background='gray', pady=5)
        cycles_frame.pack(side=TOP, fill=BOTH, expand=True)

        cycles_label = Label(cycles_frame,
                             text='# of cycles',
                             background='gray',
                             font=('Courier', 12),
                             justify=CENTER)
        cycles_label.grid(row=0,
                          column=0,
                          rowspan=1,
                          columnspan=2,
                          sticky='news')
        ul_plain_font = Font(cycles_label, cycles_label.cget('font'))
        ul_plain_font.configure(underline=True)
        cycles_label.configure(font=ul_plain_font)

        self.cycles_select_disp = Label(cycles_frame,
                                        text='5',
                                        background='white',
                                        font=('Courier', 32))
        self.cycles_select_disp.grid(row=1,
                                     column=0,
                                     rowspan=2,
                                     columnspan=1,
                                     sticky='wens',
                                     padx=5,
                                     pady=5)

        self.cycles_increase_button = Button(cycles_frame,
                                             text=u'\u25b2',
                                             font=('Courier', 18, 'bold'),
                                             command=self.cycles_increment)
        self.cycles_increase_button.grid(row=1,
                                         column=1,
                                         rowspan=1,
                                         columnspan=1,
                                         sticky='wens',
                                         padx=5,
                                         pady=5)

        self.cycles_decrease_button = Button(cycles_frame,
                                             text=u'\u25BC',
                                             font=('Courier', 18, 'bold'),
                                             command=self.cycles_decrement)
        self.cycles_decrease_button.grid(row=2,
                                         column=1,
                                         rowspan=1,
                                         columnspan=1,
                                         sticky='wens',
                                         padx=5,
                                         pady=5)

        self.fix_grid(cycles_frame)

        soak_time_frame = Frame(options_frame, background='gray', pady=5)
        soak_time_frame.pack(side=TOP, fill=BOTH, expand=True)

        soak_time_label = Label(soak_time_frame,
                                text='Minutes per Soak',
                                background='gray',
                                font=('Courier', 12),
                                justify=CENTER)
        soak_time_label.grid(row=0,
                             column=0,
                             rowspan=1,
                             columnspan=2,
                             sticky='news')
        soak_time_label.configure(font=ul_plain_font)

        self.soak_time_disp = Label(soak_time_frame,
                                    text='5',
                                    background='white',
                                    font=('Courier', 32))
        self.soak_time_disp.grid(row=1,
                                 column=0,
                                 rowspan=2,
                                 columnspan=1,
                                 sticky='wens',
                                 padx=5,
                                 pady=5)

        self.soak_time_increment_button = Button(
            soak_time_frame,
            text=u'\u25b2',
            font=('Courier', 18, 'bold'),
            command=self.soak_time_increment)
        self.soak_time_increment_button.grid(row=1,
                                             column=1,
                                             rowspan=1,
                                             columnspan=1,
                                             sticky='wens',
                                             padx=5,
                                             pady=5)

        self.soak_time_decrement_button = Button(
            soak_time_frame,
            text=u'\u25BC',
            font=('Courier', 18, 'bold'),
            command=self.soak_time_decrement)
        self.soak_time_decrement_button.grid(row=2,
                                             column=1,
                                             rowspan=1,
                                             columnspan=1,
                                             sticky='wens',
                                             padx=5,
                                             pady=5)

        self.fix_grid(soak_time_frame)

        controls_frame = Frame(self, background='gray')
        controls_frame.pack(side=LEFT, fill=BOTH, expand=True)

        run_pause_frame = Frame(controls_frame, background='gray')
        run_pause_frame.pack(side=TOP, fill=BOTH, expand=True, pady=5)

        self.run_button = Button(run_pause_frame,
                                 text='RUN',
                                 background='green',
                                 activebackground='green',
                                 font=('Courier', 30, 'bold'),
                                 width=5,
                                 command=self.run_init)
        self.run_button.grid(row=0, column=0, sticky='wens', padx=5, pady=5)

        self.pause_button = Button(run_pause_frame,
                                   text='PAUSE',
                                   background='orange',
                                   activebackground='orange',
                                   font=('Courier', 30, 'bold'),
                                   width=5,
                                   command=self.pause_button_pressed)
        self.pause_button.grid(row=0, column=1, sticky='wens', padx=5, pady=5)

        self.fix_grid(run_pause_frame)

        stop_button = Button(controls_frame,
                             text='STOP',
                             background='red',
                             activebackground='red',
                             font=('Courier', 36, 'bold'),
                             command=self.stop_test)
        stop_button.pack(side=TOP, fill=BOTH, expand=True, padx=5)

        jog_frame = Frame(controls_frame, background='gray')
        jog_frame.pack(side=TOP, fill=BOTH, expand=True, pady=5)

        jog_label = Label(jog_frame,
                          text='Motor\rjog',
                          font=('Courier', 12, 'bold'),
                          background='gray')
        jog_label.grid(row=1, column=1)

        self.jog_up_button = Button(jog_frame,
                                    text=u'\u25b2',
                                    font=('Courier', 18, 'bold'))
        self.jog_up_button.grid(row=0,
                                column=1,
                                rowspan=1,
                                columnspan=1,
                                sticky='wens',
                                padx=5,
                                pady=5)
        self.jog_up_button.bind("<Button-1>", self.jog_up_on)
        self.jog_up_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_left_button = Button(jog_frame,
                                      text=u'\u25C4',
                                      font=('Courier', 18, 'bold'))
        self.jog_left_button.grid(row=1,
                                  column=0,
                                  rowspan=1,
                                  columnspan=1,
                                  sticky='wens',
                                  padx=5,
                                  pady=5)
        self.jog_left_button.bind("<Button-1>", self.jog_left_on)
        self.jog_left_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_right_button = Button(jog_frame,
                                       text=u'\u25BA',
                                       font=('Courier', 18, 'bold'))
        self.jog_right_button.grid(row=1,
                                   column=2,
                                   rowspan=1,
                                   columnspan=1,
                                   sticky='wens',
                                   padx=5,
                                   pady=5)
        self.jog_right_button.bind("<Button-1>", self.jog_right_on)
        self.jog_right_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_down_button = Button(jog_frame,
                                      text=u'\u25BC',
                                      font=('Courier', 18, 'bold'))
        self.jog_down_button.grid(row=2,
                                  column=1,
                                  rowspan=1,
                                  columnspan=1,
                                  sticky='wens',
                                  padx=5,
                                  pady=5)
        self.jog_down_button.bind("<Button-1>", self.jog_down_on)
        self.jog_down_button.bind("<ButtonRelease-1>", self.jog_off)

        self.fix_grid(jog_frame)

        status_frame = Frame(self, background='gray')
        status_frame.pack(side=LEFT, fill=BOTH, expand=True, padx=5, pady=5)

        status_label = Label(status_frame,
                             text='Tester Status',
                             background='gray',
                             font=('Courier', 22, 'bold'),
                             justify=LEFT)
        status_label.configure(font=ul_bold_font)
        status_label.pack(anchor=CENTER, side=TOP, padx=5, pady=5)

        self.status_disp = Text(status_frame)
        self.status_disp.pack(side=TOP, fill=BOTH, padx=5, pady=5)
        self.status_disp.configure(state='disabled')

        self.power_button = Button(status_frame,
                                   text='POWER OFF',
                                   font=('Courier', 24, 'bold'),
                                   background="red",
                                   activebackground="red",
                                   command=self.shutdown,
                                   height=2)
        self.power_button.pack(side=TOP, fill=BOTH, padx=5, pady=5)

    def fix_grid(self, target_frame):
        [columns, rows] = target_frame.grid_size()
        for i in range(rows):
            target_frame.rowconfigure(i, weight=1)
        for j in range(columns):
            target_frame.columnconfigure(j, weight=1)

    def detect_debug_mode(self):
        if str(sys.argv[0]) == 'debug':
            self.update_status('Tester is in debug mode.', 'newline')
            self.update_status('', 'newline')
            self.update_status('The tester will run with a 6 second',
                               'newline')
            self.update_status('  soak time regardless of the soak', 'newline')
            self.update_status('  time selected in the GUI.', 'newline')
            self.debug_mode = True
        else:
            self.update_status('Welcome to the Liquid Thermal Shock',
                               'newline')
            self.update_status('  Tester. Select the number of', 'newline')
            self.update_status('  cycles and the soak time per cycle',
                               'newline')
            self.update_status('  to begin testing. Please ensure', 'newline')
            self.update_status('  that the limit switches are free', 'newline')
            self.update_status('  from obstructions prior to running',
                               'newline')
            self.update_status('  a test.', 'newline')
            self.debug_mode = False

    def cycles_increment(self):
        """ Increments the number of cycles per test. """

        str_num_cycles = self.cycles_select_disp.cget('text')
        num_cycles = int(str_num_cycles)
        num_cycles += 1
        self.cycles_select_disp.configure(text=str(num_cycles))

    def cycles_decrement(self):
        """ Decrements the number of cycles per test. """

        str_num_cycles = self.cycles_select_disp.cget('text')
        num_cycles = int(str_num_cycles)

        # Check for attempts to set num_cycles < 1.
        if num_cycles <= 1:
            self.cycles_select_disp.configure(text=str(num_cycles))
        else:
            num_cycles -= 1
            self.cycles_select_disp.configure(text=str(num_cycles))

    def soak_time_increment(self):
        """ Increments the soak time. """

        str_soak_time = self.soak_time_disp.cget('text')
        soak_time = int(str_soak_time)
        soak_time += 1
        self.soak_time_disp.configure(text=str(soak_time))
        self.reset_timer()

    def soak_time_decrement(self):
        """ Decrements the soak time. """

        str_soak_time = self.soak_time_disp.cget('text')
        soak_time = int(str_soak_time)

        # Check for attempts to set soak time < 1.
        if soak_time <= 1:
            self.soak_time_disp.configure(text=str(soak_time))
        else:
            soak_time -= 1
            self.soak_time_disp.configure(text=str(soak_time))
        self.reset_timer()

    def reset_timer(self):
        """ Resets the timer to whatever is displayed in the
            soak time window."""

        str_soak_time = self.soak_time_disp.cget('text')

        if self.debug_mode:
            self.timer = [0, 6]
        else:
            self.timer = [int(str_soak_time), 0]

        # Use line below for tester debugging -- forces a 5 second soak time.
        # Comment out for normal operations.
        # self.timer = [0, 5]

    # Callback functions for manual motor jog
    def jog_off(self, event):
        motors_off()

    def jog_up_on(self, event):
        jog_motor('up')

    def jog_down_on(self, event):
        jog_motor('down')

    def jog_left_on(self, event):
        jog_motor('left')

    def jog_right_on(self, event):
        jog_motor('right')

    def shutdown(self):
        """ Shuts down the tester. """

        motors_off()
        confirm_string = "Do you really want to power down the tester?"
        confirm = tkMessageBox.askokcancel("Shutdown", confirm_string)
        if confirm:
            subprocess.call("sudo poweroff", shell=True)
        else:
            pass

    def update_status(self, new_text, writemode):
        """ Prints text to the tester status window. """

        self.status_disp.configure(state='normal')
        if writemode == 'overwrite':
            self.status_disp.delete('end-1c linestart', 'end')
        self.status_disp.insert('end', '\n' + new_text)
        self.status_disp.see(END)
        self.status_disp.configure(state='disabled')

    def append_event(self, cycle, type, destination, direction, steps,
                     duration):
        """ Add new event (motor move or temperature soak) to event schedule. """

        self.event_schedule.append({
            'Cycle': cycle,
            'Event type': type,
            'Destination': destination,
            'Direction': direction,
            'Steps': steps,
            'Duration': duration
        })

    def start_homing_move(self, direction):
        """ Starts the homing procedure in the given direction. """

        self.update_status('Finding ' + direction + ' home position...',
                           'newline')
        self.status_disp.update()
        self.home_result.set(0)
        self.queue = Queue.Queue()
        Find_Home_Nonblocking(self.queue, direction).start()
        self.master.after(100, self.process_homing_queue)
        self.wait_variable(self.home_result)

        if self.home_result.get() == 0:
            self.update_status('Homing error. Test aborted.', 'newline')
            return
        else:
            self.update_status(
                direction.capitalize() + ' home position found.', 'newline')

    def run_init(self):
        """ Run button callback.  
        
            Collects run parameters, creates event schedule, then runs the 
            series of scheduled events.
        """

        self.set_state_running()

        # Set number of steps for each motor move. Depends on motor resolution
        # set in static variables section.
        up_steps = self.up_full_steps * (2**self.move_motor_resolution)
        right_steps = self.right_full_steps * (2**self.move_motor_resolution)

        # Get the total number of cycles
        total_cycles_str = self.cycles_select_disp.cget('text')
        total_cycles_int = int(total_cycles_str)

        # Get the soak time in minutes. This is forced to 0.1 minutes when
        # the GUI is launched in debug mode
        if self.debug_mode:
            soak_time_str = '0.1'
            soak_time_float = 0.1
        else:
            soak_time_str = self.soak_time_disp.cget('text')
            soak_time_float = float(soak_time_str)

        # Build event schedule
        self.event_schedule = []
        for i in range(1, total_cycles_int + 1):
            self.append_event(i, 'move', 'hot', 'down', up_steps,
                              up_steps / 2000.0)
            self.append_event(i, 'soak', 'hot', '', '', soak_time_float)
            self.append_event(i, 'move', 'cold', 'up', up_steps,
                              up_steps / 2000.0)
            self.append_event(i, 'move', 'cold', 'left', right_steps,
                              right_steps / 2000.0)
            self.append_event(i, 'move', 'cold', 'down', up_steps,
                              up_steps / 2000.0)
            self.append_event(i, 'soak', 'cold', '', '', soak_time_float)
            self.append_event(i, 'move', 'hot', 'up', up_steps,
                              up_steps / 2000.0)
            self.append_event(i, 'move', 'hot', 'right', right_steps,
                              right_steps / 2000.0)

        # Set the destination to 'complete' for the final 'up' and 'right' moves.
        # Edit the 'Steps' parameter of the final move to end the test in the
        # center of the rail.
        self.event_schedule[-2]['Destination'] = 'complete'
        self.event_schedule[-1]['Destination'] = 'complete'
        self.event_schedule[-1]['Steps'] = right_steps / 2
        self.event_schedule[-1][
            'Duration'] = self.event_schedule[-1]['Steps'] / 2000.0

        self.test_active = True

        # Print initial runtime message to status window
        if soak_time_float == 1.0:
            soak_time_out = '1 minute'
        else:
            soak_time_out = soak_time_str + ' minutes'

        self.update_status('', 'newline')
        self.update_status('Test started.', 'newline')
        out_string = 'The tester will run for ' + total_cycles_str + ' cycles, '
        self.update_status(out_string, 'newline')
        out_string = soak_time_out + ' per cycle.'
        self.update_status(out_string, 'newline')

        if self.test_active == True:
            self.start_homing_move('up')
        if self.test_active == True and self.home_result.get() == 1:
            self.start_homing_move('right')

        if self.test_active == True and self.home_result.get() == 1:
            self.update_status('Moving to hot position...', 'newline')
            self.run_scheduled_events()

    def run_scheduled_events(self):
        """ Runs the series of events listed in self.event_schedule. """

        if self.test_active == True:

            current_event = self.event_schedule.pop(0)

            if current_event['Event type'] == 'soak':
                self.set_state_running()
                self.reset_timer()
                cycle = str(current_event['Cycle'])
                temperature = current_event['Destination']
                self.timer_active.set(1)
                self.countdown_timer(cycle, temperature)
                self.wait_variable(self.timer_active)

            elif current_event['Event type'] == 'move':

                if current_event['Direction'] == 'up':
                    self.set_state_running()
                    if current_event['Destination'] == 'complete':
                        out_string = 'Test complete, moving to neutral '
                        out_string += '      position...'
                        self.update_status(out_string, 'newline')
                    else:
                        out_string = 'Moving to ' + current_event['Destination']
                        out_string += ' position...'
                        self.update_status(out_string, 'newline')

                elif current_event['Direction'] == 'down':
                    self.set_state_running()

                else:
                    self.pause_button.config(state='normal')
                    self.move_direction = current_event['Direction']
                    self.move_total_duration = current_event['Duration']
                    self.planned_steps = current_event['Steps']

                #self.move_result.set(0)
                self.queue = Queue.Queue()
                self.move_started_time = datetime.now()
                Move_Motor_Nonblocking(self.queue, current_event['Direction'],
                                       self.move_motor_resolution,
                                       current_event['Steps']).start()
                self.master.after(100, self.process_move_queue)
                self.wait_variable(self.move_result)
                motors_off()

        # If there are any events left in the schedule, run the next scheduled
        # event.  If there are no events left in the schedule and the last event
        # was a completed move, then the test is complete and this function should
        # output the 'test complete' message.  If there are no events in the schedule
        # and the last event was not a completed move, then the test is paused and
        # this function should do nothing else.
        if self.event_schedule:
            self.after(1000, self.run_scheduled_events)
        elif self.move_result.get() == 1:
            self.update_status('Test complete.', 'overwrite')
            self.set_state_stopped()
        else:
            pass

    def set_state_running(self):
        """ Deactivates cycle time select, soak time select, motor jog
            and power off buttons.

            This is to stop users from changing test parameters during a
            running test, which could result in some difficult to handle
            undefined states.
        """

        self.cycles_increase_button.config(state='disabled')
        self.cycles_decrease_button.config(state='disabled')
        self.soak_time_increment_button.config(state='disabled')
        self.soak_time_decrement_button.config(state='disabled')
        self.run_button.config(state='disabled')
        self.jog_up_button.config(state='disabled')
        self.jog_down_button.config(state='disabled')
        self.jog_left_button.config(state='disabled')
        self.jog_right_button.config(state='disabled')
        self.power_button.config(state='disabled')
        self.pause_button.config(state='disabled')

        # This is absurd, but apparently setting a button to 'disabled' does
        # not actually disable the button event bindings, so binding the buttons
        # to a 'do_nothing()' function is required.
        self.jog_up_button.bind("<Button-1>", self.do_nothing)
        self.jog_up_button.bind("<ButtonRelease-1>", self.do_nothing)
        self.jog_down_button.bind("<Button-1>", self.do_nothing)
        self.jog_down_button.bind("<ButtonRelease-1>", self.do_nothing)
        self.jog_left_button.bind("<Button-1>", self.do_nothing)
        self.jog_left_button.bind("<ButtonRelease-1>", self.do_nothing)
        self.jog_right_button.bind("<Button-1>", self.do_nothing)
        self.jog_right_button.bind("<ButtonRelease-1>", self.do_nothing)

    def set_state_stopped(self):
        """ Reactivates all of the buttons deactivated in the
            set_state_running function.
        """

        self.test_active = False
        self.test_paused = False

        self.cycles_increase_button.config(state='normal')
        self.cycles_decrease_button.config(state='normal')
        self.soak_time_increment_button.config(state='normal')
        self.soak_time_decrement_button.config(state='normal')
        self.run_button.config(state='normal')
        self.jog_up_button.config(state='normal')
        self.jog_down_button.config(state='normal')
        self.jog_left_button.config(state='normal')
        self.jog_right_button.config(state='normal')
        self.power_button.config(state='normal')
        self.pause_button.config(state='disabled')
        self.pause_button.config(text='PAUSE',
                                 background='orange',
                                 activebackground='orange')

        self.jog_up_button.bind("<Button-1>", self.jog_up_on)
        self.jog_up_button.bind("<ButtonRelease-1>", self.jog_off)
        self.jog_down_button.bind("<Button-1>", self.jog_down_on)
        self.jog_down_button.bind("<ButtonRelease-1>", self.jog_off)
        self.jog_left_button.bind("<Button-1>", self.jog_left_on)
        self.jog_left_button.bind("<ButtonRelease-1>", self.jog_off)
        self.jog_right_button.bind("<Button-1>", self.jog_right_on)
        self.jog_right_button.bind("<ButtonRelease-1>", self.jog_off)

    def do_nothing(self, event):
        """ Does absolutely nothing. This is a workaround for the fact that
            button event bindings are not disabled when a button's state is
            set to 'disabled'.
        """

        pass

    def pause_timer(self):
        """ Displays the running duration of a test pause. """

        if self.test_paused:
            timer_string = '{0:1d}:{1:02d}'.format(self.timer[0],
                                                   self.timer[1])

            out_string = 'Test paused for ' + timer_string
            self.update_status(out_string, 'overwrite')

            self.timer[1] += 1
            if self.timer[1] >= 60:
                self.timer[0] += 1
                self.timer[1] -= 60

            self.after(1000, self.pause_timer)

    def countdown_timer(self, cycle, temperature):
        """ Displays countdown timer and current cycle number/temperature
            information in status window.

            This function will only process if the timer_active flag is set to
            1. The function will then recursively call itself after a 1 second
            wait until the timer_active flag is set to zero.

            The timing is not precise because it will wait 1 full second between
            function calls, and therefore does not take into account the time
            necessary to process the function itself. However, over a typical
            soak time this will only amount to milliseconds, so it's certainly
            close enough for this application.
        """

        if self.timer_active.get() == 1:
            timer_string = '{0:1d}:{1:02d}'.format(self.timer[0],
                                                   self.timer[1])
            out_string = 'Cycle ' + cycle + ' of '
            out_string += self.cycles_select_disp.cget('text') + ', '
            out_string += temperature + '. ' + timer_string + ' remaining.'

            self.update_status(out_string, 'overwrite')

            # Decrement 1 second from timer. If this flips the seconds to a
            # negative value, decrement 1 minute and add 60 seconds
            self.timer[1] -= 1
            if self.timer[1] < 0:
                # If timer is run down to zero, display soak complete message
                # and set timer_active flag to zero.
                if self.timer[0] <= 0:
                    out_string = 'Cycle ' + cycle + ' of '
                    out_string += self.cycles_select_disp.cget('text') + ', '
                    out_string += temperature + ' complete.'
                    self.update_status(out_string, 'overwrite')
                    self.timer_active.set(0)
                else:
                    self.timer[0] -= 1
                    self.timer[1] += 60

            # Have the countdown_timer function recursively call itself
            # after 1000ms.
            self.after(1000, self.countdown_timer, cycle, temperature)

    def stop_test(self):
        """ Stop button callback.  Allows user to abort test sequence. """

        # Clear event schedule and toggle home and move result monitoring
        # variables. This helps prevent errors on restart
        motors_off()

        self.event_schedule = []
        self.home_result.set(0)
        self.move_result.set(0)

        if self.test_active:
            self.update_status('Test stopped by user.', 'newline')

        self.test_active = False

        # Stop and reset timer, reactivate buttons (in case the test
        # needs to be restarted).
        self.timer_active.set(0)
        self.reset_timer()
        self.set_state_stopped()

    def pause_button_pressed(self):
        """ Pause button callback. """

        if self.test_paused:
            self.test_paused = False
            self.resume_test()
        else:
            self.test_paused = True
            self.timer = [0, 0]
            self.pause_test()

    def pause_test(self):
        """ Pauses a running test """

        motors_off()
        self.pause_time = datetime.now()

        self.pause_button.config(text='RESUME',
                                 background='green',
                                 activebackground='green')

        self.resume_schedule = self.event_schedule

        self.event_schedule = []
        self.move_result.set(0)
        pause_delta = self.pause_time - self.move_started_time
        pause_delta_seconds = float(pause_delta.seconds)
        pause_delta_seconds += pause_delta.microseconds / 1000000.0

        steps_prepause = int(pause_delta_seconds * 2000)

        steps_remaining = self.planned_steps - steps_prepause

        move_time_remaining = self.move_total_duration - pause_delta_seconds

        resume_event = {
            'Cycle': '',
            'Event type': 'move',
            'Destination': '',
            'Direction': self.move_direction,
            'Steps': steps_remaining,
            'Duration': move_time_remaining
        }

        self.resume_schedule.insert(0, resume_event)

        self.update_status('', 'newline')
        self.pause_timer()

    def resume_test(self):
        """ Resumes a paused test """

        self.pause_button.config(text='PAUSE',
                                 background='orange',
                                 activebackground='orange')
        self.resume_time = datetime.now()

        self.event_schedule = self.resume_schedule

        pause_duration = self.resume_time - self.pause_time

        pause_duration_seconds = float(pause_duration.seconds)
        pause_duration_seconds += pause_duration.microseconds / 1000000.0

        self.test_active = True
        self.update_status('Test resumed.', 'newline')
        self.run_scheduled_events()

    def process_homing_queue(self):
        """ Checks if homing function has returned a value. """

        # Try to read the first value in the queue. If nothing is there, then
        # the homing function has not yet returned a value and must still be
        # active. In this case, the function recursively calls itself after
        # 100ms. If there is something in the queue, the value is read into
        # the self.home_result variable and the function is not called again.
        try:
            self.home_result.set(self.queue.get(0))
        except Queue.Empty:
            self.master.after(10, self.process_homing_queue)

    def process_move_queue(self):
        """ Checks if motor move queue as returned value. """

        # Try to read the first value in the queue. If nothing is there, then
        # the motor move function has not yet returned a value and must still be
        # active. In this case, the function recursively calls itself after
        # 100ms. If there is something in the queue, the value is read into
        # the self.move_result variable and the function is not called again.

        try:
            self.move_result.set(self.queue.get(0))
        except Queue.Empty:
            self.master.after(100, self.process_move_queue)
Example #3
0
    def init_UI(self):

        self.parent.title('Liquid Thermal Shock Tester v0.2')
        self.pack(fill=BOTH, expand=True)
        options_frame = Frame(self, background='gray', pady=5, padx=5)
        options_frame.pack(side=LEFT, fill=BOTH, expand=True)

        options_label = Label(options_frame,
                              text='Test Setup',
                              background='gray',
                              font=('Courier', 22, 'bold'),
                              justify=LEFT)
        ul_bold_font = Font(options_label, options_label.cget('font'))
        ul_bold_font.configure(underline=True)
        options_label.configure(font=ul_bold_font)
        options_label.pack(anchor=CENTER, side=TOP, padx=5, pady=5)

        cycles_frame = Frame(options_frame, background='gray', pady=5)
        cycles_frame.pack(side=TOP, fill=BOTH, expand=True)

        cycles_label = Label(cycles_frame,
                             text='# of cycles',
                             background='gray',
                             font=('Courier', 12),
                             justify=CENTER)
        cycles_label.grid(row=0,
                          column=0,
                          rowspan=1,
                          columnspan=2,
                          sticky='news')
        ul_plain_font = Font(cycles_label, cycles_label.cget('font'))
        ul_plain_font.configure(underline=True)
        cycles_label.configure(font=ul_plain_font)

        self.cycles_select_disp = Label(cycles_frame,
                                        text='5',
                                        background='white',
                                        font=('Courier', 32))
        self.cycles_select_disp.grid(row=1,
                                     column=0,
                                     rowspan=2,
                                     columnspan=1,
                                     sticky='wens',
                                     padx=5,
                                     pady=5)

        self.cycles_increase_button = Button(cycles_frame,
                                             text=u'\u25b2',
                                             font=('Courier', 18, 'bold'),
                                             command=self.cycles_increment)
        self.cycles_increase_button.grid(row=1,
                                         column=1,
                                         rowspan=1,
                                         columnspan=1,
                                         sticky='wens',
                                         padx=5,
                                         pady=5)

        self.cycles_decrease_button = Button(cycles_frame,
                                             text=u'\u25BC',
                                             font=('Courier', 18, 'bold'),
                                             command=self.cycles_decrement)
        self.cycles_decrease_button.grid(row=2,
                                         column=1,
                                         rowspan=1,
                                         columnspan=1,
                                         sticky='wens',
                                         padx=5,
                                         pady=5)

        self.fix_grid(cycles_frame)

        soak_time_frame = Frame(options_frame, background='gray', pady=5)
        soak_time_frame.pack(side=TOP, fill=BOTH, expand=True)

        soak_time_label = Label(soak_time_frame,
                                text='Minutes per Soak',
                                background='gray',
                                font=('Courier', 12),
                                justify=CENTER)
        soak_time_label.grid(row=0,
                             column=0,
                             rowspan=1,
                             columnspan=2,
                             sticky='news')
        soak_time_label.configure(font=ul_plain_font)

        self.soak_time_disp = Label(soak_time_frame,
                                    text='5',
                                    background='white',
                                    font=('Courier', 32))
        self.soak_time_disp.grid(row=1,
                                 column=0,
                                 rowspan=2,
                                 columnspan=1,
                                 sticky='wens',
                                 padx=5,
                                 pady=5)

        self.soak_time_increment_button = Button(
            soak_time_frame,
            text=u'\u25b2',
            font=('Courier', 18, 'bold'),
            command=self.soak_time_increment)
        self.soak_time_increment_button.grid(row=1,
                                             column=1,
                                             rowspan=1,
                                             columnspan=1,
                                             sticky='wens',
                                             padx=5,
                                             pady=5)

        self.soak_time_decrement_button = Button(
            soak_time_frame,
            text=u'\u25BC',
            font=('Courier', 18, 'bold'),
            command=self.soak_time_decrement)
        self.soak_time_decrement_button.grid(row=2,
                                             column=1,
                                             rowspan=1,
                                             columnspan=1,
                                             sticky='wens',
                                             padx=5,
                                             pady=5)

        self.fix_grid(soak_time_frame)

        controls_frame = Frame(self, background='gray')
        controls_frame.pack(side=LEFT, fill=BOTH, expand=True)

        run_pause_frame = Frame(controls_frame, background='gray')
        run_pause_frame.pack(side=TOP, fill=BOTH, expand=True, pady=5)

        self.run_button = Button(run_pause_frame,
                                 text='RUN',
                                 background='green',
                                 activebackground='green',
                                 font=('Courier', 30, 'bold'),
                                 width=5,
                                 command=self.run_init)
        self.run_button.grid(row=0, column=0, sticky='wens', padx=5, pady=5)

        self.pause_button = Button(run_pause_frame,
                                   text='PAUSE',
                                   background='orange',
                                   activebackground='orange',
                                   font=('Courier', 30, 'bold'),
                                   width=5,
                                   command=self.pause_button_pressed)
        self.pause_button.grid(row=0, column=1, sticky='wens', padx=5, pady=5)

        self.fix_grid(run_pause_frame)

        stop_button = Button(controls_frame,
                             text='STOP',
                             background='red',
                             activebackground='red',
                             font=('Courier', 36, 'bold'),
                             command=self.stop_test)
        stop_button.pack(side=TOP, fill=BOTH, expand=True, padx=5)

        jog_frame = Frame(controls_frame, background='gray')
        jog_frame.pack(side=TOP, fill=BOTH, expand=True, pady=5)

        jog_label = Label(jog_frame,
                          text='Motor\rjog',
                          font=('Courier', 12, 'bold'),
                          background='gray')
        jog_label.grid(row=1, column=1)

        self.jog_up_button = Button(jog_frame,
                                    text=u'\u25b2',
                                    font=('Courier', 18, 'bold'))
        self.jog_up_button.grid(row=0,
                                column=1,
                                rowspan=1,
                                columnspan=1,
                                sticky='wens',
                                padx=5,
                                pady=5)
        self.jog_up_button.bind("<Button-1>", self.jog_up_on)
        self.jog_up_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_left_button = Button(jog_frame,
                                      text=u'\u25C4',
                                      font=('Courier', 18, 'bold'))
        self.jog_left_button.grid(row=1,
                                  column=0,
                                  rowspan=1,
                                  columnspan=1,
                                  sticky='wens',
                                  padx=5,
                                  pady=5)
        self.jog_left_button.bind("<Button-1>", self.jog_left_on)
        self.jog_left_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_right_button = Button(jog_frame,
                                       text=u'\u25BA',
                                       font=('Courier', 18, 'bold'))
        self.jog_right_button.grid(row=1,
                                   column=2,
                                   rowspan=1,
                                   columnspan=1,
                                   sticky='wens',
                                   padx=5,
                                   pady=5)
        self.jog_right_button.bind("<Button-1>", self.jog_right_on)
        self.jog_right_button.bind("<ButtonRelease-1>", self.jog_off)

        self.jog_down_button = Button(jog_frame,
                                      text=u'\u25BC',
                                      font=('Courier', 18, 'bold'))
        self.jog_down_button.grid(row=2,
                                  column=1,
                                  rowspan=1,
                                  columnspan=1,
                                  sticky='wens',
                                  padx=5,
                                  pady=5)
        self.jog_down_button.bind("<Button-1>", self.jog_down_on)
        self.jog_down_button.bind("<ButtonRelease-1>", self.jog_off)

        self.fix_grid(jog_frame)

        status_frame = Frame(self, background='gray')
        status_frame.pack(side=LEFT, fill=BOTH, expand=True, padx=5, pady=5)

        status_label = Label(status_frame,
                             text='Tester Status',
                             background='gray',
                             font=('Courier', 22, 'bold'),
                             justify=LEFT)
        status_label.configure(font=ul_bold_font)
        status_label.pack(anchor=CENTER, side=TOP, padx=5, pady=5)

        self.status_disp = Text(status_frame)
        self.status_disp.pack(side=TOP, fill=BOTH, padx=5, pady=5)
        self.status_disp.configure(state='disabled')

        self.power_button = Button(status_frame,
                                   text='POWER OFF',
                                   font=('Courier', 24, 'bold'),
                                   background="red",
                                   activebackground="red",
                                   command=self.shutdown,
                                   height=2)
        self.power_button.pack(side=TOP, fill=BOTH, padx=5, pady=5)
Example #4
0
    def create_content(self):

        self.pop = Toplevel(self.master, bg="white")
        self.pop.grab_set()  # when you show the popup

        self.pop.wm_title(' ' * 5 + self._title_)
        self.pop.geometry('{:d}x{:d}+{:d}+{:d}'.format(*self._vertex_))

        leftcolumn = Frame(self.pop, bg="white")
        Label(leftcolumn, bg="white").pack(side="top", fill="both", pady=30)
        Label(leftcolumn,
              bg="white", image=self.im_logo2).pack(side="top",
                                                    fill="both",
                                                    padx=10)  #side= LEFT,
        leftcolumn.pack(side="left", fill='both', padx=1)

        rightcolumn = Frame(self.pop, bg="white")
        firstrow = Frame(rightcolumn, bg="white")
        Frame(rightcolumn, bg="white").pack(side="top", pady=10, padx=0)

        Label(firstrow,
              text="GROTOLAM",
              fg="Gray13",
              bg="white",
              font="Verdana 13 bold").pack(side="left", pady=20)
        Label(firstrow, text='', bg="white").pack(side="left", padx=40)
        firstrow.pack(side="top", padx=0)

        secrow = Frame(rightcolumn, bg="white")
        Label(secrow,
              text="v " + __version__.split()[2],
              fg="Gray13",
              bg="white",
              font="Verdana 10").pack(side="left")
        Label(secrow, text='', bg="white").pack(side="left", padx=75)
        secrow.pack(side="top", padx=0)

        # lets create space to do some stuff ...
        Frame(rightcolumn, bg="white").pack(side="top", pady=20, padx=0)

        thirdrow = Frame(rightcolumn, bg="white")

        Label(thirdrow,
              text="2018 Python version by",
              fg="Gray13",
              bg="white",
              font="Verdana 10").pack(side="left")
        Label(thirdrow, text='', bg="white").pack(side="left", padx=16)
        thirdrow.pack(side="top", padx=0)

        fourthrow = Frame(rightcolumn, bg="white")
        Label(fourthrow,
              text="Hernan Chavez Thielemann",
              fg="Gray13",
              bg="white",
              font="Verdana 10").pack(side="left")
        Label(fourthrow, text='', bg="white").pack(side="left", padx=1)
        fourthrow.pack(side="top", padx=0)

        fifthrow = Frame(rightcolumn, bg="white")
        Label(fifthrow, bg="white", image=self.im_smlogo).pack(side="left",
                                                               fill="both",
                                                               padx=10)
        fifthrow.pack(side="top", padx=0)

        sixthrow = Frame(rightcolumn, bg="white")
        href = Label(sixthrow,
                     bg="white",
                     font="Verdana 10",
                     text="Small web page",
                     fg="blue",
                     cursor="hand2")
        f = Font(href, href.cget("font"))
        f.configure(underline=True)
        href.configure(font=f)
        href.pack(side="left")
        href.bind("<Button-1>", self.callback)

        Label(sixthrow, text='', bg="white").pack(side="left", padx=40)
        sixthrow.pack(side="top", padx=0)

        lastrow = Frame(rightcolumn, bg="white")
        self.bottom_button_row(lastrow)
        rightcolumn.pack(side="right", fill='both', padx=5)
Example #5
0
class Gui(object):
    """
        This is a single-transaction dialog box for characterizing
        entries that could not be definitively classified by rule.
    """

    BORDER = 5
    ACCT_WID = 20
    DESC_WID = 40
    PADDING = 5

    def __init__(self, statement, entry):
        """
            instantiate a transaction window
        """
        self.rules = statement.rules

        self.root = Tk()
        self.root.title("Manual Annotation")
        t = Frame(self.root, bd=2 * self.BORDER)

        # top stack: input file name
        f = Frame(t)
        caption = "File: " + statement.filename + ", line: " + str(statement.file_line)
        Label(f, text=caption).pack()
        f.pack(pady=self.PADDING)

        # middle stack: entry details
        f = Frame(t)
        f1 = LabelFrame(f, text="Date")
        self.date = Label(f1, text=entry.date)
        self.date.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Amount")
        self.amount = Label(f1, text=entry.amount)
        self.amount.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Account")
        self.acct = Text(f1, height=1, width=self.ACCT_WID)
        if entry.account is not None:
            self.acct.insert(END, entry.account)
        self.acct.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Description")
        self.desc = Text(f1, height=1, width=self.DESC_WID)
        self.desc.insert(END, entry.description)
        self.desc.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)
        f.pack(pady=self.PADDING)

        # bottom stack: action buttons
        f = Frame(t)
        b = Button(f, text="Accept", command=self.accept)
        b.pack(side=LEFT, padx=self.PADDING)

        # account selection menu
        self.account = StringVar(f)
        self.account.set(entry.account)
        m = OptionMenu(f, self.account, *sorted(statement.acc_list), command=self.chooseAcct)
        m.pack(side=LEFT, padx=self.PADDING)

        # aggregate description selection menu
        self.description = StringVar(f)
        self.menu = OptionMenu(f, self.description, *sorted(statement.agg_list), command=self.chooseDesc)
        self.menu.pack(side=LEFT, padx=self.PADDING)

        b = Button(f, text="Delete", command=self.delete)
        b.pack(side=LEFT, padx=self.PADDING)
        f.pack(padx=self.PADDING, pady=self.PADDING)

        # finalize
        t.pack(side=TOP)
        self.entry = entry  # default: return what we got

    def accept(self):
        """
            Accept button action - create Entry w/current description
        """
        date = self.date.cget("text")
        amount = self.amount.cget("text")
        acct = self.account.get()
        if acct == "None":
            acct = None
        descr = self.desc.get(1.0, END).replace("\n", "")
        self.entry = Entry.Entry(date, amount, acct, descr)
        self.root.destroy()
        self.root.quit()

    def delete(self):
        """
            Delete button action - return a null Entry
        """
        self.entry = None
        self.root.destroy()
        self.root.quit()

    def chooseAcct(self, selection):
        """
            Account menu action - select account
                may have side-effect of enabling standard
                description menu
        """
        self.acct.delete(1.0, END)
        self.acct.insert(1.0, selection)
        return

    def chooseDesc(self, selection):
        """
            Description menu action - select a standard description
        """
        # make sure description goes with the account
        acct = self.account.get()
        if acct is not None and self.rules.validFor(selection, acct):
            self.desc.delete(1.0, END)
            self.desc.insert(1.0, selection)
        return

    def mainloop(self):
        """
            process the dialog and return the constructed entry
        """
        self.root.mainloop()
        return self.entry
Example #6
0
class Server:
    def __init__(self):
        self.HOST = socket.gethostbyname(socket.gethostname())
        self.PORT = 8000
        self.conn, self.addr = None, None
        self.qrImage = None
        self.socket = None
        self.initConnection()
        self.ChatUi()

    def initConnection(self):
        qr = qrcode.QRCode()
        qr.add_data(self.HOST)
        qr.make()
        self.qrImage = qr.make_image()
        main = Tk()
        photo = ImageTk.PhotoImage(self.qrImage)
        label = Label(image=photo)
        label.pack()
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        def task():
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind((self.HOST, self.PORT))
            self.socket.listen(1)
            self.conn, self.addr = self.socket.accept()
            print 'connected by ' + repr(self.addr)
            data = self.conn.recv(1024)
            if "123" in str(data):
                self.conn.sendall("456")
            main.destroy()

        main.after(100, task)
        main.title("Scan this QR")
        main.mainloop()

    def ChatUi(self):
        self.chat = Tk()
        self.chat.title("Chat demo")

        self.chatBox = Label(self.chat, height=20, width=50)
        self.chatBox.pack()

        self.ipBox = Entry(self.chat, width=50)
        self.ipBox.pack()

        self.sendBtn = Button(self.chat,
                              command=self.sendMsg,
                              text="Send",
                              width=50)
        self.sendBtn.pack()

        Thread(target=self.recieveMsg).start()

        self.chat.mainloop()

    def recieveMsg(self):
        while True:
            data = self.conn.recv(1024)
            text = self.chatBox.cget("text") + "\n" + data
            self.chatBox.configure(text=text)

    def sendMsg(self):
        reply = self.ipBox.get()
        text = self.chatBox.cget("text") + "\n" + reply
        self.chatBox.configure(text=text)
        self.conn.sendall(reply)
Example #7
0
class guiDemo3(Frame):

    def __init__(self,parent):
        Frame.__init__(self,parent)
        self.parent = parent
        self.dict = {} #temporary
        self.initUI() #start up the main menu

    def initUI(self):
        try:
            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.mainMenuLabel= Label(self, text="Main Menu")
            self.mainMenuLabel.pack(side=TOP,padx=5, pady=5)
            self.singleModeButton= Button(self, text="Single Computer Mode", command=self.unpackInitUI_LoadSingleComputerMode)
            self.singleModeButton.pack(side=TOP, padx=5, pady=5)
            self.networkModeButton= Button(self, text="Networking Mode", command=self.unpackInitUI_LoadNetworkMode)
            self.networkModeButton.pack(side=TOP, padx=5, pady=5)

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in initUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of initUI////////////////////////////

    def unpackInitUI_LoadSingleComputerMode(self):
        self.closeButton.pack_forget()
        self.mainMenuLabel.pack_forget()
        self.singleModeButton.pack_forget()
        self.networkModeButton.pack_forget()
        self.singleModeUI()

    def unpackInitUI_LoadNetworkMode(self):
        self.closeButton.pack_forget()
        self.mainMenuLabel.pack_forget()
        self.singleModeButton.pack_forget()
        self.networkModeButton.pack_forget()
        self.networkModeUI()

    def unpackSingleModeUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.singleModeLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.initUI()

    def unpackSingleModeUI_LoadSingleDictionaryUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.singleModeLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.dictionaryCrackingMethodUI(0)

    def unpackSingleModeUI_LoadSingleBruteForceUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.singleModeLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodUI(0)

    def unpackSingleModeUI_LoadSingleRainbowTableUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.singleModeLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodUI(0)

    def singleModeUI(self):
        try:
            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackSingleModeUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.singleModeLabel= Label(self, text="Single Computer Mode")
            self.singleModeLabel.pack(side=TOP, padx=5, pady=5)
            self.selectCrackingMethodLabel= Label(self, text="Select Your Cracking Method")
            self.selectCrackingMethodLabel.pack(side=TOP, padx=5, pady=5)
            self.dictionaryCrackingMethodButton= Button(self, text="Dictionary", command=self.unpackSingleModeUI_LoadSingleDictionaryUI)
            self.dictionaryCrackingMethodButton.pack(side=TOP, padx=5, pady=5)
            self.bruteForceCrackingMethodButton= Button(self, text="Brute-Force (default)", command=self.unpackSingleModeUI_LoadSingleBruteForceUI)
            self.bruteForceCrackingMethodButton.pack(side=TOP, padx=5, pady=5)
            self.rainbowTableCrackingMethodButton= Button(self, text="Rainbow Table", command=self.unpackSingleModeUI_LoadSingleRainbowTableUI)
            self.rainbowTableCrackingMethodButton.pack(side=TOP, padx=5, pady=5)

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in singleModeUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #End of single mode

    def unpackNetworkModeUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkModeLabel.pack_forget()
        self.selectNetworkModuleLabel.pack_forget()
        self.serverModuleButton.pack_forget()
        self.clientModuleButton.pack_forget()
        self.initUI()

    def networkModeUI(self):
        try:
            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackNetworkModeUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.networkModeLabel= Label(self, text="Network Mode: Server/Client Selection Screen")
            self.networkModeLabel.pack(side=TOP, padx=5, pady=5)
            self.selectNetworkModuleLabel= Label(self, text="Select Server or Client")
            self.selectNetworkModuleLabel.pack(side=TOP, padx=5, pady=5)
            self.serverModuleButton= Button(self, text="I am the Server", command= self.unpackNetworkModeUI_LoadNetworkServerUI)
            self.serverModuleButton.pack(side=TOP, padx=5, pady=5)
            self.clientModuleButton= Button(self, text="I am a Client", command= self.unpackNetworkModeUI_LoadNetworkClientUI)
            self.clientModuleButton.pack(side=TOP, padx=5, pady=5)

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in networkModeUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of networkModeUI

    def unpackNetworkModeUI_LoadNetworkServerUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkModeLabel.pack_forget()
        self.selectNetworkModuleLabel.pack_forget()
        self.serverModuleButton.pack_forget()
        self.clientModuleButton.pack_forget()
        self.networkServerUI()

    def unpackNetworkModeUI_LoadNetworkClientUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkModeLabel.pack_forget()
        self.selectNetworkModuleLabel.pack_forget()
        self.serverModuleButton.pack_forget()
        self.clientModuleButton.pack_forget()
        self.networkClientUI()

    def unpackNetworkClientUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkClientLabel.pack_forget()
        self.insertServerIPLabel.pack_forget()
        self.insertServerIPTextfield.pack_forget()
        self.startClientButton.pack_forget()
        self.initUI()

    def networkClientUI(self):
        try:
            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackNetworkClientUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.networkClientLabel= Label(self, text="Network Client")
            self.networkClientLabel.pack(side=TOP, padx=5, pady=5)
            self.insertServerIPLabel= Label(self, text="Enter in the Server's IP:")
            self.insertServerIPLabel.pack(side=TOP, padx=5, pady=5)
            self.insertServerIPTextfield= Entry(self, bd=5)
            self.insertServerIPTextfield.pack(side=TOP, padx=5, pady=5)
            #TODO allow right click for pasting into box
            self.startClientButton= Button(self, text="Start Client", command=lambda: self.startClient(str(self.insertServerIPTextfield.get())))
            self.startClientButton.pack(side=TOP, padx=5, pady=5)
        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in networkClientUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of networkclient UI

    def startClient(self,inputIP):
        try:
            if(len(inputIP) < 1):
                showwarning("Network Client Start Warning: NO IP","No IP address has been entered!")
            else:
                self.networkClient= Process(target=Client, args=(inputIP,))
                self.networkClient.start()
                self.networkClientStatusUI()
        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in startClient definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="

    def networkClientStatusUI(self):
        self.networkClientStatusWindow= Tk()
        self.networkClientStatusWindow.geometry("640x480")
        self.networkClientStatusWindow.title("Network Client Status Window")
        self.networkClientStatusWindow.style = Style()
        self.networkClientStatusWindow.style.theme_use("default")
        self.networkClientStatusWindow.pack(fill=BOTH, expand=1)
        #TODO throws an attribute error on 'pack', thus nothing is drawn to the screen, fix this
        self.CloseButton= Button(self, text="Close Status Window", command=lambda: closeStatusWindow())
        self.CloseButton.pack(side=BOTTOM, padx=5, pady=5)

        def closeStatusWindow(self):
            self.networkClientStatusWindow.destroy()


    def unpackNetworkServerUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkServerLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.initUI()

    def networkServerUI(self):
        try:
            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackNetworkServerUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.networkServerLabel= Label(self, text="Network Server")
            self.networkServerLabel.pack(side=TOP, padx=5,  pady=5)
            self.selectCrackingMethodLabel= Label(self, text="Select Your Cracking Method")
            self.selectCrackingMethodLabel.pack(side=TOP, padx=5, pady=5)
            self.dictionaryCrackingMethodButton= Button(self, text="Dictionary", command=self.unpackNetworkServerUI_LoadNetworkDictionaryUI)
            self.dictionaryCrackingMethodButton.pack(side=TOP, padx=5, pady=5)
            self.bruteForceCrackingMethodButton= Button(self, text="Brute-Force (default)", command=self.unpackNetwrokServerUI_LoadNetworkBruteForceUI)
            self.bruteForceCrackingMethodButton.pack(side=TOP, padx=5, pady=5)
            self.rainbowTableCrackingMethodButton= Button(self, text="Rainbow Table", command=self.unpackNetworkServerUI_LoadNetworkRainbowTableUI)
            self.rainbowTableCrackingMethodButton.pack(side=TOP, padx=5, pady=5)
        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in networkServerUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of networkServerUI

    def unpackNetworkServerUI_LoadNetworkDictionaryUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkServerLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.dictionaryCrackingMethodUI(1)

    def unpackNetwrokServerUI_LoadNetworkBruteForceUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkServerLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodUI(1)

    def unpackNetworkServerUI_LoadNetworkRainbowTableUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.networkServerLabel.pack_forget()
        self.selectCrackingMethodLabel.pack_forget()
        self.dictionaryCrackingMethodButton.pack_forget()
        self.bruteForceCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodButton.pack_forget()
        self.rainbowTableCrackingMethodUI(1)

    def unpackDictionaryCrackingMethodUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.dictionaryCrackingMethodLabel.pack_forget()
        self.currentModeLabel.pack_forget()
        self.dictionaryFileLocationLabel.pack_forget()
        self.selectedDictionaryFileLabel.pack_forget()
        self.selectDictionaryFileButton.pack_forget()
        self.inputHashTextFieldLabel.pack_forget()
        self.inputHashTextField.pack_forget()
        self.selectAlgorithmLabel.pack_forget()
        self.md5RadioButton.pack_forget()
        self.sha1RadioButton.pack_forget()
        self.sha224RadioButton.pack_forget()
        self.sha256RadioButton.pack_forget()
        self.sha512RadioButton.pack_forget()
        self.startDictionaryCrackButton.pack_forget()
        self.initUI()

    def dictionaryCrackingMethodUI(self,mode):
        #mode is either 1 (network) or 0 (single)
        currentMode= "ERROR: Mode not selected" #initialize variable
        self.selectedDictionaryFile= ""
        selectedAlgorithm= "MD5" #set to md5 as the default
        inputHash= StringVar()
        inputHash.set("")
        try:
            if(mode == 0):
                currentMode= "Single"
            elif(mode == 1):
                currentMode= "Network"
            else:
                raise Exception("ERROR: Invalid mode parameter: '"+str(mode)+"'")

            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackDictionaryCrackingMethodUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.dictionaryCrackingMethodLabel= Label(self, text="Dictionary Cracking Method")
            self.dictionaryCrackingMethodLabel.pack(side=TOP, padx=5, pady=5)
            self.currentModeLabel = Label(self,text="Current Mode: "+str(currentMode))
            self.currentModeLabel.pack(side=TOP, padx=5, pady=5)
            self.dictionaryFileLocationLabel= Label(self, text="Dictionary File to be used:")
            self.dictionaryFileLocationLabel.pack(side=TOP, padx=5, pady=5)
            self.selectedDictionaryFileLabel= Label(self, text=str(self.selectedDictionaryFile))
            self.selectedDictionaryFileLabel.pack(side=TOP, padx=5, pady=5)
            self.selectDictionaryFileButton= Button(self, text="Select Dictionary File", textvariable= str(self.selectedDictionaryFile), command=self.selectFileWindow) #
            self.selectDictionaryFileButton.pack(side=TOP, padx=5, pady=5)
            #TODO modify the dictionary file so that when a file is selected, that filepath is passed onto server
            #TODO check for dictionary file existance before handling (and file extensions for windows)
            #TODO insert option to crack a file of hashes (pass file to the server/single)
            #TODO check for file existance before handling (and file extensions for windows)
            self.inputHashTextFieldLabel= Label(self, text="The hash to be cracked:")
            self.inputHashTextFieldLabel.pack(side=TOP, padx=5, pady=5)
            self.inputHashTextField= Entry(self, bd=5, textvariable= inputHash)
            self.inputHashTextField.pack(side=TOP, padx=5, pady=5)
            self.selectAlgorithmLabel = Label(self, text="Select the Cracking Algorithm:")
            self.selectAlgorithmLabel.pack(side=TOP, padx=5, pady=5)
            self.md5RadioButton=  Radiobutton(self, text="MD5 (default)", variable= selectedAlgorithm, value="MD5" )
            self.md5RadioButton.pack(side=LEFT, padx=5, pady=5)
            self.sha1RadioButton= Radiobutton(self, text="SHA 1", variable= selectedAlgorithm, value="SHA 1")
            self.sha1RadioButton.pack(side=LEFT, padx=5, pady=5)
            self.sha224RadioButton= Radiobutton(self, text="SHA 224", variable= selectedAlgorithm, value="SHA 224")
            self.sha224RadioButton.pack(side=LEFT, padx=5, pady=5)
            self.sha256RadioButton= Radiobutton(self, text="SHA 256", variable= selectedAlgorithm, value="SHA 256")
            self.sha256RadioButton.pack(side=LEFT, padx=5, pady=5)
            self.sha512RadioButton= Radiobutton(self, text="SHA 512", variable= selectedAlgorithm, value="SHA 512")
            self.sha512RadioButton.pack(side=LEFT, padx=5, pady=5)
            #TODO display result in a noneditable text view
            if(currentMode is 'Single'):
                self.dict = {'cracking method': "dic", 'file name': str(self.selectedDictionaryFileLabel.cget("text")), 'algorithm': selectedAlgorithm, 'hash': str(inputHash.get()), 'single':"True"}
                print "selectedDictionaryFileLabel text="+str(self.selectedDictionaryFileLabel.cget("text"))
                self.startDictionaryCrackButton= Button(self, text="Start Dictionary Crack (Single Mode)", command=lambda: self.startNetworkServer(self.dict))
                self.startDictionaryCrackButton.pack(side=BOTTOM, padx=5, pady=5)
            elif(currentMode is 'Network'):
                print "GUI DEBUG: Inside elif(currentMode is 'Network)"
                if(len(str(self.inputHashTextField)) < 1):
                    showwarning("Empty hash text field", "The hash text field is empty")
                else:
                    print "GUI DEBUG: '"+str(self.inputHashTextField.get())+"'"
                    self.dict = {'cracking method': "dic", 'file name': str(self.selectedDictionaryFile), 'algorithm': selectedAlgorithm, 'hash': str(inputHash.get())}
                    self.startDictionaryCrackButton= Button(self, text="Start Dictionary Crack (Network Mode)", command=lambda: self.startNetworkServer(self.dict))
                    self.startDictionaryCrackButton.pack(side=BOTTOM, padx=5, pady=5)

            else:
                raise Exception("GUI ERROR: Invalid currentMode in startDictionaryCrackButton: '"+str(currentMode)+"'")

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in dictionaryCrackingMethodUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of dictionary cracking methodUI

    def setDictHash(self,newHash):
        print "GUI DEBUG: hash is: '"+str(newHash)+"'"
        self.dict['hash']= str(newHash)

    def startNetworkServer(self, crackingMethod):
        print "GUI DEBUG: hash is: '"+str(crackingMethod['hash'])+"'"
        self.networkServer= Process(target=Server, args=(crackingMethod,))
        self.networkServer.start()
        #TODO idea: create a server is running window, with the stats

    def unpackBruteForceCrackingMethodUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.inputHashTextFieldLabel.pack_forget()
        self.inputHashTextField.pack_forget()
        self.bruteForceCrackingMethodLabel.pack_forget()
        self.currentModeLabel.pack_forget()
        self.startBruteForceCrackButton.pack_forget()
        self.algorithmSelectionLabel.pack_forget()
        self.algorithmOptionMenu.pack_forget()
        self.alphabetSelectionLabel.pack_forget()
        self.alphabetOptionMenu.pack_forget()
        self.minKeyLengthLabel.pack_forget()
        self.minKeyLengthTextField.pack_forget()
        self.maxKeyLengthLabel.pack_forget()
        self.maxKeyLengthTextField.pack_forget()
        self.outputHashTextFieldLabel.pack_forget()
        self.outputHashTextField.pack_forget()
        self.initUI()

    def bruteForceCrackingMethodUI(self, mode):
        #mode is either 1 (network) or 0 (single)
        currentMode= None
        selectedAlgorithm= StringVar()
        selectedAlgorithm.set("MD5")
        selectedAlphabet= StringVar()
        selectedAlphabet.set("All")
        minKeyLength= IntVar()
        minKeyLength.set(5)
        maxKeyLength= IntVar()
        maxKeyLength.set(15)
        inputHash= StringVar()
        inputHash.set("")
        try:
            if(mode==0):
                currentMode= "Single"
            elif(mode ==1):
                currentMode= "Network"
            else:
                raise Exception("ERROR: Invalid mode parameter: '"+str(mode)+"'")

            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackBruteForceCrackingMethodUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.bruteForceCrackingMethodLabel = Label(self, text="Brute-Force Cracking Method")
            self.bruteForceCrackingMethodLabel.pack(side=TOP, padx=5, pady=5)
            self.currentModeLabel= Label(self, text="Current Mode: "+str(currentMode))
            self.currentModeLabel.pack(side=TOP, padx=5, pady=5)
            self.algorithmSelectionLabel= Label(self, text="Select which algorithm you want to use:")
            self.algorithmSelectionLabel.pack(side=TOP, padx=5, pady=5)
            self.algorithmOptionMenu= OptionMenu(self, selectedAlgorithm, "MD5", "SHA 1", "SHA 224", "SHA 256", "SHA 512")
            self.algorithmOptionMenu.pack(side=TOP, padx=5, pady=5)
            self.alphabetSelectionLabel= Label(self, text="Select which alphabet you want to use:")
            self.alphabetSelectionLabel.pack(side=TOP, padx=5, pady=5)
            self.alphabetOptionMenu= OptionMenu(self, selectedAlphabet, "All", "ASCII_Uppercase", "ASCII_Lowercase", "Digits", "Special_Symbols")
            self.alphabetOptionMenu.pack(side=TOP, padx=5, pady=5)
            self.minKeyLengthLabel= Label(self, text="Select the minimum key length: (Default is 5)")
            self.minKeyLengthLabel.pack(side=TOP, padx=5, pady=5)
            self.minKeyLengthTextField= Entry(self, bd=5, textvariable= minKeyLength)
            self.minKeyLengthTextField.pack(side=TOP, padx=5, pady=5)
            self.maxKeyLengthLabel= Label(self, text="Select the maximum key length:  (Default is 15)")
            self.maxKeyLengthLabel.pack(side=TOP, padx=5, pady=5)
            self.maxKeyLengthTextField= Entry(self, bd=5, textvariable= maxKeyLength)
            self.maxKeyLengthTextField.pack(side=TOP, padx=5, pady=5)
            #TODO add support for combination of alphabets
            #TODO insert option to hash a file of hashes (pass the file to server/single)
            #TODO check for file existance before handling (and file extensions for windows)
            self.inputHashTextFieldLabel= Label(self, text="The hash to be cracked:")
            self.inputHashTextFieldLabel.pack(side=TOP, padx=5, pady=5)
            self.inputHashTextField= Entry(self, bd=5, textvariable= inputHash)
            self.inputHashTextField.pack(side=TOP, padx=5, pady=5)
            #TODO display results is a copiable textview

            if(currentMode is 'Single'):
                self.dict = {'cracking method': "bf", 'hash': str(inputHash.get()), 'algorithm':str(selectedAlgorithm.get()),
                             'alphabet':str(selectedAlphabet.get()), 'min key length':int(minKeyLength.get()), 'max key length':int(maxKeyLength.get()), 'single':"True"}
                self.startBruteForceCrackButton= Button(self, text="Start Brute-Force Crack (Single Mode)", command=lambda: self.startNetworkServer(self.dict))
                self.startBruteForceCrackButton.pack(side=BOTTOM, padx=5, pady=5)

            elif(currentMode is 'Network'):
               # print "GUI DEBUG: Inside elif(currentMode is 'Network)"
                #if(len(str(inputHash.get())) < 1):
                 #   showwarning("Empty hash text field", "The hash text field is empty")
                #else:
                print "GUI DEBUG: '"+str(self.inputHashTextField.get())+"'"
                self.dict = {'cracking method': "bf", 'hash': str(inputHash.get()), 'algorithm':str(selectedAlgorithm.get()),
                             'alphabet':str(selectedAlphabet.get()), 'min key length':int(minKeyLength.get()), 'max key length':int(maxKeyLength.get())}
                self.startBruteForceCrackButton= Button(self, text="Start Brute-Force Crack (Network Mode)", command=lambda: self.startNetworkServer(self.dict))
                self.startBruteForceCrackButton.pack(side=BOTTOM, padx=5, pady=5)
            else:
                raise Exception("ERROR: Invalid mode parameter in Brute-Force CrackingUI: '"+str(mode)+"'")

            #This will display the results, could set to show up after the program is run.
            self.outputHashTextFieldLabel= Label(self, text="Results")
            self.outputHashTextFieldLabel.pack(side=TOP, padx=5, pady=5)
            self.outputHashTextField= Entry(self, bd=5)
            self.outputHashTextField.insert(0, "Test")
            self.outputHashTextField.pack(side=TOP,padx=5, pady=5)

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in bruteForceCrackingMethodUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of brute force cracking UI

    def unpackRainbowTableCrackingMethodUI_LoadInitUI(self):
        self.closeButton.pack_forget()
        self.returnToInitUIButton.pack_forget()
        self.rainbowTableCrackingMethodLabel.pack_forget()
        self.currentModeLabel.pack_forget()
        self.initUI()

    def rainbowTableCrackingMethodUI(self, mode):
        #mode is either 1 (network) or 0 (single)
        currentMode= None
        try:
            if(mode == 0):
                currentMode = "Single"
            elif(mode == 1):
                currentMode = "Network"
            else:
               raise Exception("ERROR: Invalid mode parameter: '"+str(mode)+"'")

            self.parent.title("Mighty Cracker")
            self.style = Style()
            self.style.theme_use("default")

            self.pack(fill=BOTH, expand=1)

            #load buttons and labels
            self.closeButton= Button(self, text="Close Program", command=self.confirmExit)
            self.closeButton.pack(side=BOTTOM, padx=5, pady=5)
            self.returnToInitUIButton= Button(self, text="Return to Main Menu", command=self.unpackRainbowTableCrackingMethodUI_LoadInitUI)
            self.returnToInitUIButton.pack(side=BOTTOM, padx=5, pady=5)
            self.rainbowTableCrackingMethodLabel= Label(self, text="Rainbow Table Cracking Method")
            self.rainbowTableCrackingMethodLabel.pack(side=TOP, padx=5, pady=5)
            self.currentModeLabel= Label(self,text="Current Mode: "+str(currentMode))
            self.currentModeLabel.pack(side=TOP, padx=5, pady=5)
            #TODO insert Rainbow table settings here

        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in rainbowTableCrackingMethodUI definition Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
    #end of rainbow table cracking UI

    def selectFileWindow(self):
        filename= ""
        filename= askopenfilename()
        #remove the file extension
       # modifiedFileName= self.removeFileNameExtension(filename)
        print "Modified fileName= '"+str(filename)+"'"
        self.selectedDictionaryFileLabel.config(text=str(filename))
        self.selectedDictionaryFile= str(self.selectedDictionaryFileLabel.cget("text"))

    '''
    def removeFileNameExtension(self, inputFileName):
        outboundFileName= ""
        lastForwardSlashPos=0
        for i in range(0, len(inputFileName)):
            if(inputFileName[i] == "."):
                break
            elif(inputFileName[i] == "/"):
                lastForwardSlashPos= i
                outboundFileName+= inputFileName[i]
            else:
                outboundFileName+= inputFileName[i]
        print "FileName after extension is removed: '"+str(outboundFileName)+"'"
        pathlessFileName= self.removeAbsoluteFilePath(outboundFileName, lastForwardSlashPos)
        print "FileName after absolute filepath was removed: '"+str(pathlessFileName)+"'"
        return pathlessFileName

    def removeAbsoluteFilePath(self, inboundFilePath, lastForwardSlashPos):
        relativeFilePath= ""
        for i in range(lastForwardSlashPos+1, len(inboundFilePath)):
            if(inboundFilePath[i] is not None):
                relativeFilePath+= inboundFilePath[i]
            else:
                break
        return relativeFilePath
    '''

    def confirmExit(self):
        result= askyesno('Exit Confirmation', 'Are you sure you want to quit this application? \n (WARNING: All server, client, and single computer processes will be terminated!!)')
        if result == True:
            self.onExit()
        #if no is selected, then the window just closes

    def onExit(self):
       # self.networkServer.join()
        try:
            self.networkServer.terminate()
        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in onExit terminate networkserver process Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="
        #self.networkClient.join()
        try:
            self.networkClient.terminate()
        except Exception as inst:
            print "============================================================================================="
            print "GUI ERROR: An exception was thrown in onExit terminate networkclient process Try block"
            #the exception instance
            print type(inst)
            #srguments stored in .args
            print inst.args
            #_str_ allows args tto be printed directly
            print inst
            print "============================================================================================="

        self.parent.destroy()
Example #8
0
class Debugger:

    vstack = vsource = vlocals = vglobals = None

    def __init__(self, pyshell, idb=None):
        if idb is None:
            idb = Idb(self)
        self.pyshell = pyshell
        self.idb = idb
        self.frame = None
        self.make_gui()
        self.interacting = 0
        self.nesting_level = 0

    def run(self, *args):
        # Deal with the scenario where we've already got a program running
        # in the debugger and we want to start another. If that is the case,
        # our second 'run' was invoked from an event dispatched not from
        # the main event loop, but from the nested event loop in 'interaction'
        # below. So our stack looks something like this:
        #       outer main event loop
        #         run()
        #           <running program with traces>
        #             callback to debugger's interaction()
        #               nested event loop
        #                 run() for second command
        #
        # This kind of nesting of event loops causes all kinds of problems
        # (see e.g. issue #24455) especially when dealing with running as a
        # subprocess, where there's all kinds of extra stuff happening in
        # there - insert a traceback.print_stack() to check it out.
        #
        # By this point, we've already called restart_subprocess() in
        # ScriptBinding. However, we also need to unwind the stack back to
        # that outer event loop.  To accomplish this, we:
        #   - return immediately from the nested run()
        #   - abort_loop ensures the nested event loop will terminate
        #   - the debugger's interaction routine completes normally
        #   - the restart_subprocess() will have taken care of stopping
        #     the running program, which will also let the outer run complete
        #
        # That leaves us back at the outer main event loop, at which point our
        # after event can fire, and we'll come back to this routine with a
        # clean stack.
        if self.nesting_level > 0:
            self.abort_loop()
            self.root.after(100, lambda: self.run(*args))
            return
        try:
            self.interacting = 1
            return self.idb.run(*args)
        finally:
            self.interacting = 0

    def close(self, event=None):
        try:
            self.quit()
        except Exception:
            pass
        if self.interacting:
            self.top.bell()
            return
        if self.stackviewer:
            self.stackviewer.close(); self.stackviewer = None
        # Clean up pyshell if user clicked debugger control close widget.
        # (Causes a harmless extra cycle through close_debugger() if user
        # toggled debugger from pyshell Debug menu)
        self.pyshell.close_debugger()
        # Now close the debugger control window....
        self.top.destroy()

    def make_gui(self):
        pyshell = self.pyshell
        self.flist = pyshell.flist
        self.root = root = pyshell.root
        self.top = top = ListedToplevel(root)
        self.top.wm_title("Debug Control")
        self.top.wm_iconname("Debug")
        top.wm_protocol("WM_DELETE_WINDOW", self.close)
        self.top.bind("<Escape>", self.close)
        #
        self.bframe = bframe = Frame(top)
        self.bframe.pack(anchor="w")
        self.buttons = bl = []
        #
        self.bcont = b = Button(bframe, text="Go", command=self.cont)
        bl.append(b)
        self.bstep = b = Button(bframe, text="Step", command=self.step)
        bl.append(b)
        self.bnext = b = Button(bframe, text="Over", command=self.next)
        bl.append(b)
        self.bret = b = Button(bframe, text="Out", command=self.ret)
        bl.append(b)
        self.bret = b = Button(bframe, text="Quit", command=self.quit)
        bl.append(b)
        #
        for b in bl:
            b.configure(state="disabled")
            b.pack(side="left")
        #
        self.cframe = cframe = Frame(bframe)
        self.cframe.pack(side="left")
        #
        if not self.vstack:
            self.__class__.vstack = BooleanVar(top)
            self.vstack.set(1)
        self.bstack = Checkbutton(cframe,
            text="Stack", command=self.show_stack, variable=self.vstack)
        self.bstack.grid(row=0, column=0)
        if not self.vsource:
            self.__class__.vsource = BooleanVar(top)
        self.bsource = Checkbutton(cframe,
            text="Source", command=self.show_source, variable=self.vsource)
        self.bsource.grid(row=0, column=1)
        if not self.vlocals:
            self.__class__.vlocals = BooleanVar(top)
            self.vlocals.set(1)
        self.blocals = Checkbutton(cframe,
            text="Locals", command=self.show_locals, variable=self.vlocals)
        self.blocals.grid(row=1, column=0)
        if not self.vglobals:
            self.__class__.vglobals = BooleanVar(top)
        self.bglobals = Checkbutton(cframe,
            text="Globals", command=self.show_globals, variable=self.vglobals)
        self.bglobals.grid(row=1, column=1)
        #
        self.status = Label(top, anchor="w")
        self.status.pack(anchor="w")
        self.error = Label(top, anchor="w")
        self.error.pack(anchor="w", fill="x")
        self.errorbg = self.error.cget("background")
        #
        self.fstack = Frame(top, height=1)
        self.fstack.pack(expand=1, fill="both")
        self.flocals = Frame(top)
        self.flocals.pack(expand=1, fill="both")
        self.fglobals = Frame(top, height=1)
        self.fglobals.pack(expand=1, fill="both")
        #
        if self.vstack.get():
            self.show_stack()
        if self.vlocals.get():
            self.show_locals()
        if self.vglobals.get():
            self.show_globals()

    def interaction(self, message, frame, info=None):
        self.frame = frame
        self.status.configure(text=message)
        #
        if info:
            type, value, tb = info
            try:
                m1 = type.__name__
            except AttributeError:
                m1 = "%s" % str(type)
            if value is not None:
                try:
                    m1 = "%s: %s" % (m1, str(value))
                except:
                    pass
            bg = "yellow"
        else:
            m1 = ""
            tb = None
            bg = self.errorbg
        self.error.configure(text=m1, background=bg)
        #
        sv = self.stackviewer
        if sv:
            stack, i = self.idb.get_stack(self.frame, tb)
            sv.load_stack(stack, i)
        #
        self.show_variables(1)
        #
        if self.vsource.get():
            self.sync_source_line()
        #
        for b in self.buttons:
            b.configure(state="normal")
        #
        self.top.wakeup()
        # Nested main loop: Tkinter's main loop is not reentrant, so use
        # Tcl's vwait facility, which reenters the event loop until an
        # event handler sets the variable we're waiting on
        self.nesting_level += 1
        self.root.tk.call('vwait', '::idledebugwait')
        self.nesting_level -= 1
        #
        for b in self.buttons:
            b.configure(state="disabled")
        self.status.configure(text="")
        self.error.configure(text="", background=self.errorbg)
        self.frame = None

    def sync_source_line(self):
        frame = self.frame
        if not frame:
            return
        filename, lineno = self.__frame2fileline(frame)
        if filename[:1] + filename[-1:] != "<>" and os.path.exists(filename):
            self.flist.gotofileline(filename, lineno)

    def __frame2fileline(self, frame):
        code = frame.f_code
        filename = code.co_filename
        lineno = frame.f_lineno
        return filename, lineno

    def cont(self):
        self.idb.set_continue()
        self.abort_loop()

    def step(self):
        self.idb.set_step()
        self.abort_loop()

    def next(self):
        self.idb.set_next(self.frame)
        self.abort_loop()

    def ret(self):
        self.idb.set_return(self.frame)
        self.abort_loop()

    def quit(self):
        self.idb.set_quit()
        self.abort_loop()

    def abort_loop(self):
        self.root.tk.call('set', '::idledebugwait', '1')

    stackviewer = None

    def show_stack(self):
        if not self.stackviewer and self.vstack.get():
            self.stackviewer = sv = StackViewer(self.fstack, self.flist, self)
            if self.frame:
                stack, i = self.idb.get_stack(self.frame, None)
                sv.load_stack(stack, i)
        else:
            sv = self.stackviewer
            if sv and not self.vstack.get():
                self.stackviewer = None
                sv.close()
            self.fstack['height'] = 1

    def show_source(self):
        if self.vsource.get():
            self.sync_source_line()

    def show_frame(self, stackitem):
        self.frame = stackitem[0]  # lineno is stackitem[1]
        self.show_variables()

    localsviewer = None
    globalsviewer = None

    def show_locals(self):
        lv = self.localsviewer
        if self.vlocals.get():
            if not lv:
                self.localsviewer = NamespaceViewer(self.flocals, "Locals")
        else:
            if lv:
                self.localsviewer = None
                lv.close()
                self.flocals['height'] = 1
        self.show_variables()

    def show_globals(self):
        gv = self.globalsviewer
        if self.vglobals.get():
            if not gv:
                self.globalsviewer = NamespaceViewer(self.fglobals, "Globals")
        else:
            if gv:
                self.globalsviewer = None
                gv.close()
                self.fglobals['height'] = 1
        self.show_variables()

    def show_variables(self, force=0):
        lv = self.localsviewer
        gv = self.globalsviewer
        frame = self.frame
        if not frame:
            ldict = gdict = None
        else:
            ldict = frame.f_locals
            gdict = frame.f_globals
            if lv and gv and ldict is gdict:
                ldict = None
        if lv:
            lv.load_dict(ldict, force, self.pyshell.interp.rpcclt)
        if gv:
            gv.load_dict(gdict, force, self.pyshell.interp.rpcclt)

    def set_breakpoint_here(self, filename, lineno):
        self.idb.set_break(filename, lineno)

    def clear_breakpoint_here(self, filename, lineno):
        self.idb.clear_break(filename, lineno)

    def clear_file_breaks(self, filename):
        self.idb.clear_all_file_breaks(filename)

    def load_breakpoints(self):
        "Load PyShellEditorWindow breakpoints into subprocess debugger"
        pyshell_edit_windows = self.pyshell.flist.inversedict.keys()
        for editwin in pyshell_edit_windows:
            filename = editwin.io.filename
            try:
                for lineno in editwin.breakpoints:
                    self.set_breakpoint_here(filename, lineno)
            except AttributeError:
                continue
Example #9
0
class Server:
    def __init__(self):
        self.HOST = socket.gethostbyname(socket.gethostname())
        self.PORT = 8000
        self.conn, self.addr = None, None
        self.qrImage = None
        self.socket = None
        self.initConnection()
        self.ChatUi()

    def initConnection(self):
        qr = qrcode.QRCode()
        qr.add_data(self.HOST)
        qr.make()
        self.qrImage = qr.make_image()
        main = Tk()
        photo = ImageTk.PhotoImage(self.qrImage)
        label = Label(image=photo)
        label.pack()
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        def task():
            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.socket.bind((self.HOST, self.PORT))
            self.socket.listen(1)
            self.conn, self.addr = self.socket.accept()
            print 'connected by ' + repr(self.addr)
            data = self.conn.recv(1024)
            if "123" in str(data):
                self.conn.sendall("456")
            main.destroy()
        main.after(100, task)
        main.title("Scan this QR")
        main.mainloop()

    def ChatUi(self):
        self.chat = Tk()
        self.chat.title("Chat demo")

        self.chatBox = Label(self.chat, height=20, width=50)
        self.chatBox.pack()

        self.ipBox = Entry(self.chat, width=50)
        self.ipBox.pack()

        self.sendBtn = Button(self.chat, command=self.sendMsg, text="Send", width=50)
        self.sendBtn.pack()

        Thread(target=self.recieveMsg).start()

        self.chat.mainloop()


    def recieveMsg(self):
        while True:
            data = self.conn.recv(1024)
            text = self.chatBox.cget("text") + "\n" + data
            self.chatBox.configure(text=text)


    def sendMsg(self):
        reply = self.ipBox.get()
        text = self.chatBox.cget("text") + "\n" + reply
        self.chatBox.configure(text=text)
        self.conn.sendall(reply)
Example #10
0
class Gui(object):
    """
        This is a single-transaction dialog box for characterizing
        entries that could not be definitively classified by rule.
    """

    BORDER = 5
    ACCT_WID = 20
    DESC_WID = 40
    PADDING = 5

    def __init__(self, statement, entry):
        """
            instantiate a transaction window
        """
        self.rules = statement.rules

        self.root = Tk()
        self.root.title('Manual Annotation')
        t = Frame(self.root, bd=2 * self.BORDER)

        # top stack: input file name
        f = Frame(t)
        caption = "File: " + statement.filename + ", line: " + \
            str(statement.file_line)
        Label(f, text=caption).pack()
        f.pack(pady=self.PADDING)

        # middle stack: entry details
        f = Frame(t)
        f1 = LabelFrame(f, text="Date")
        self.date = Label(f1, text=entry.date)
        self.date.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Amount")
        self.amount = Label(f1, text=entry.amount)
        self.amount.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Account")
        self.acct = Text(f1, height=1, width=self.ACCT_WID)
        if entry.account is not None:
            self.acct.insert(END, entry.account)
        self.acct.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)

        f1 = LabelFrame(f, text="Description")
        self.desc = Text(f1, height=1, width=self.DESC_WID)
        self.desc.insert(END, entry.description)
        self.desc.pack(padx=self.PADDING, pady=self.PADDING)
        f1.pack(side=LEFT, padx=self.PADDING)
        f.pack(pady=self.PADDING)

        # bottom stack: action buttons
        f = Frame(t)
        b = Button(f, text="Accept", command=self.accept)
        b.pack(side=LEFT, padx=self.PADDING)

        # account selection menu
        self.account = StringVar(f)
        self.account.set(entry.account)
        m = OptionMenu(f,
                       self.account,
                       *sorted(statement.acc_list),
                       command=self.chooseAcct)
        m.pack(side=LEFT, padx=self.PADDING)

        # aggregate description selection menu
        self.description = StringVar(f)
        self.menu = OptionMenu(f,
                               self.description,
                               *sorted(statement.agg_list),
                               command=self.chooseDesc)
        self.menu.pack(side=LEFT, padx=self.PADDING)

        b = Button(f, text="Delete", command=self.delete)
        b.pack(side=LEFT, padx=self.PADDING)
        f.pack(padx=self.PADDING, pady=self.PADDING)

        # finalize
        t.pack(side=TOP)
        self.entry = entry  # default: return what we got

    def accept(self):
        """
            Accept button action - create Entry w/current description
        """
        date = self.date.cget("text")
        amount = self.amount.cget("text")
        acct = self.account.get()
        if acct == "None":
            acct = None
        descr = self.desc.get(1.0, END).replace('\n', '')
        self.entry = Entry.Entry(date, amount, acct, descr)
        self.root.destroy()
        self.root.quit()

    def delete(self):
        """
            Delete button action - return a null Entry
        """
        self.entry = None
        self.root.destroy()
        self.root.quit()

    def chooseAcct(self, selection):
        """
            Account menu action - select account
                may have side-effect of enabling standard
                description menu
        """
        self.acct.delete(1.0, END)
        self.acct.insert(1.0, selection)
        return

    def chooseDesc(self, selection):
        """
            Description menu action - select a standard description
        """
        # make sure description goes with the account
        acct = self.account.get()
        if acct is not None and self.rules.validFor(selection, acct):
            self.desc.delete(1.0, END)
            self.desc.insert(1.0, selection)
        return

    def mainloop(self):
        """
            process the dialog and return the constructed entry
        """
        self.root.mainloop()
        return (self.entry)