示例#1
0
class TraceFrame(Frame):

    def __init__(self, *args, **kwargs):
        Frame.__init__(self, *args, **kwargs)

        self.t = ScrolledText(self, wrap="word")
        self.t.configure(background="light cyan")
        self.t.configure(height = 10)
        self.t.tag_config("in", foreground="forest green")
        self.t.tag_config("err", foreground="orange red")
        self.t.tag_config("time", foreground="sea green")
        self.t.tag_config("curr", foreground="black")
        self.t.tag_config("out", foreground="firebrick")
        self.t.pack(side="top", fill="both", expand=True)



    def add_To_Trace(self, st, tag):
        '''
        :param st: txte a afficher
        :param tag:  type de texte a afficher
        :return:
        '''
        self.t.insert(INSERT, st, tag)
        self.t.see(END)

    def clear_Trace(self):
        '''
        Efface la zone de texte
        :return:
        '''
        self.t.delete('1.0', 'end')
示例#2
0
class App(object):

  def __init__(self):
    self.window = tk.Tk()
    self.window.attributes("-fullscreen",True)
    self.window.minsize(width=320, height=240)
    self.window.maxsize(width=320, height=240)

    self.buttonFrame = tk.Frame(self.window)

    self.printButton=tk.Button(self.buttonFrame, text='PRINT!', height=2, command=self.printTxt)
    self.printButton.pack(side=tk.LEFT, fill=tk.X, padx=5, pady=5)

    self.loadButton=tk.Button(self.buttonFrame, text='LOAD', height=2, command=self.load)
    self.loadButton.pack(side=tk.LEFT, fill=tk.X, padx=5, pady=5, expand=1)

    self.exitButton=tk.Button(self.buttonFrame, text='EXIT', height=2, command=self.exitWin)
    self.exitButton.pack(side=tk.LEFT, fill=tk.X, padx=5, pady=5, expand=1)

    self.buttonFrame.pack(side=tk.TOP)

    self.filename = '/home/pi/Desktop/fly.txt'

    self.txt = ScrolledText(self.window)
    self.txt.vbar.config(width=18)
    self.txt.pack(expand=True, fill=tk.BOTH)

    self.loadFile()

    self.poll()

  def poll(self):
    if(float(self.txt.vbar.get()[1])==1):
      self.txt.see(1.0) #goto top
    else:
      self.txt.yview(tk.SCROLL,1,tk.UNITS)
    self.window.after(1000, self.poll)

  def load(self):
    self.filename = askopenfilename(initialdir="/home/pi/Desktop", title="SELECT TXT", filetypes=(("txt files","*.txt"),("all files","*.*")) )
    self.loadFile()

  def loadFile(self):
    self.txt.delete(1.0,tk.END)
    fly = open(self.filename,'r')
    self.txt.insert(1.0, fly.read())
    fly.close()

  def printTxt(self):
    call(["lp", self.filename])
    tkMessageBox.showinfo("PRINT", "it's printing!")

  def exitWin(self):
    result = tkMessageBox.askquestion("EXIT?!", "zomg, u sure?", icon='warning')
    if result == 'yes':
      self.window.quit()
示例#3
0
文件: gui.py 项目: binplumage/pocky
class MainApplication():
    def __init__(self, master):

        self.filename = ""
        self.confg = ""
        self.master = master
        #setting color.
        bkc = "floral white"
        fgc = "RosyBrown4"
        bgc = "misty rose"

        self.FontForButton = tkFont.Font(family="Verdana", size=12)
        self.FontForLabel = tkFont.Font(family="Verdana", weight="bold")
        self.frame = tk.Frame(self.master, bg=bkc)
        self.frame.pack()
        self.chose_button = tk.Button(self.frame, text = u"選擇檔案", command = self.open_file, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.chose_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.chose_confg_button = tk.Button(self.frame, text = u"選擇設定檔", command = self.get_confg, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.chose_confg_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.run_button = tk.Button(self.frame, text = u"執行", command = self.run, font=self.FontForButton, width = 20, bg=bgc, fg=fgc)
        self.run_button.pack(padx = 5, pady = 10, side = tk.TOP)
        self.text = ScrolledText(self.frame)
        self.text.pack()
        self.mdby = tk.Label(self.frame, text="\nPowered By MITLab", font=self.FontForLabel, fg="SkyBlue1", bg=bkc)
        self.mdby.pack(side='bottom')

    def open_file(self):
        self.filename = tkFileDialog.askopenfilename()
        if self.filename :
            setup_env.display_message(u"選擇檔案: " + self.filename)

    def get_confg(self):
        self.confg = tkFileDialog.askopenfilename()
        if self.confg :
            setup_env.display_message(u"選擇設定檔案: " + self.confg)

    def write(self, massage):
        self.text.insert(tk.END, massage)
        self.text.see(tk.END)
        self.text.update_idletasks()#display message real time

    def run(self):
        try:
            if not self.filename or not self.confg:
                raise Exception('請選擇檔案!')
            setup_env.display_message(u"開始執行...")
            setup_env.set_environment(self.confg)
            table = rw_data.read_excel(self.filename, 0)
            rw_data.get_title_col(table)
            cmp_data.filter_data(table)
            cmp_data.cmp_data()
        except Exception as e:
            setup_env.display_message(e.message)
        finally:
            setup_env.clean_envirnoment()
class GuiOutput:
    def __init__(self, parent=None):
        self.text = None
        if parent: self.popupnow(parent)         # popup now or on first write
    def popupnow(self, parent=None):             # in parent now, Toplevel later
        if self.text: return
        self.text = ScrolledText(parent or Toplevel())
        self.text.config(font=('courier', 9, 'normal'))
        self.text.pack()
    def write(self, text):
        self.popupnow()
        self.text.insert(END, str(text))
        self.text.see(END)
        self.text.update()
    def writelines(self, lines):                 # lines already have '\n'
        for line in lines: self.write(line)      # or map(self.write, lines)
示例#5
0
    def onHist(self):
        # show recent calcs log popup
        from ScrolledText import ScrolledText
        new = Toplevel()  # make new window
        ok = Button(new, text="OK", command=new.destroy)
        ok.pack(pady=1, side=BOTTOM)  # pack first=clip last
        text = ScrolledText(new, bg='beige')  # add Text + scrollbar
        text.insert('0.0', self.eval.getHist())  # get Evaluator text
        text.see(END)  # 3.0: scroll to end
        text.pack(expand=YES, fill=BOTH)

        # new window goes away on ok press or enter key
        new.title("PyCalc History")
        new.bind("<Return>", (lambda event: new.destroy()))
        ok.focus_set()  # make new window modal:
        new.grab_set()  # get keyboard focus, grab app
        new.wait_window()  # don't return till new.destroy
示例#6
0
文件: LogViewer.py 项目: jfmc/logen
class StringViewer(Frame):
    def __init__(self, parent, get_func, title=None):
        Frame.__init__(self,parent)
        self.text = ScrolledText(parent)
        self.text.pack(fill=BOTH,expand="yes")
        self.prev = get_func()
        self.text.insert(END,self.prev)                        
        self.after(1000, self.poll)
        self.get_func=get_func
        parent.wm_title(title)
        
    def poll(self):

        str =  self.get_func()
        if not str == self.prev:
            self.text.delete("1.0", END)
            self.text.insert(END, self.get_func())
            self.text.see(END)
            
        self.after(1000,self.poll)
示例#7
0
class StringViewer(Frame):
    def __init__(self, parent, get_func, title=None):
        Frame.__init__(self, parent)
        self.text = ScrolledText(parent)
        self.text.pack(fill=BOTH, expand="yes")
        self.prev = get_func()
        self.text.insert(END, self.prev)
        self.after(1000, self.poll)
        self.get_func = get_func
        parent.wm_title(title)

    def poll(self):

        str = self.get_func()
        if not str == self.prev:
            self.text.delete("1.0", END)
            self.text.insert(END, self.get_func())
            self.text.see(END)

        self.after(1000, self.poll)
示例#8
0
	def __init__(self):
		Toplevel.__init__(self)
		self.geometry('500x400')
		Label(self, text = 'Read Me').pack()
		text= ScrolledText(self, bg="lightgray")
		text['font'] = ('console','10')
		text.insert(END,"			welcome to monitor tool\n\n \
Here is some notes which will help you use monitor tool\n\n\
1. About SMTP setting, please input your smtp user/passwd information, till now only QQ email smtp is varified\
for other smtp emails can not garantee. also you should open POP3/SMTP setting, the passwd is grant access passwd\
you can click verity email button to check the input smtp server is okay or not\n\n\
2. About server information, please input the target server ip/user/passwd and command keyword which will be used\
to search its pid, ps -ef | grep <command keyword>. also input the command log path, which will be used to fetch command\
result,  the frequency(mins), default value is 5 mins, means monitor will ssh to server every 5 mins to fetch pid status\n\n\
3. About the email to address, you can add more then one email address into this enty, like ***@qq.com;***@ericsson.com\n\n\
4. About Enable report progress, if want to know the script progress every certain period(30 mins, 1 hour...), you can select this checkbutton\
   the monitor will fetch script log and send out by email")
		text.see("end")
		text.pack()
		text.config(state=DISABLED)
class GuiOutput:
    def __init__(self, parent=None):
        self.text = None
        if parent: self.popupnow(parent)  # popup now or on first write

    def popupnow(self, parent=None):  # in parent now, Toplevel later
        if self.text: return
        self.text = ScrolledText(parent or Toplevel())
        self.text.config(font=('courier', 9, 'normal'))
        self.text.pack()

    def write(self, text):
        self.popupnow()
        self.text.insert(END, str(text))
        self.text.see(END)
        self.text.update()

    def writelines(self, lines):  # lines already have '\n'
        for line in lines:
            self.write(line)  # or map(self.write, lines)
示例#10
0
文件: GuiStream.py 项目: twdb/txhis
class GuiOutput:
    def __init__(self, name,parent=None):
        self.text = None
        self.titleName = name
        if parent: self.popupnow(name,parent)         # popup now or on first write
    def popupnow(self,name,parent=None):             # in parent now, Toplevel later
        if self.text: return
        newTopLevel = Toplevel()
        self.text = ScrolledText(parent or newTopLevel)
        newTopLevel.title(name)
        self.text.config(font=('courier', 9, 'normal'))
        #if it is a toplevel textbox, set its title.
        self.text.pack()
    def write(self, text):
        self.popupnow(self.titleName)
        #if len(self.text.get("1.0")) > 1024:
        #    self.text.delete("1.0",END)
        self.text.insert(END, str(text))
        self.text.see(END)
        self.text.update()
    def writelines(self, lines):                 # lines already have '\n'
        for line in lines: self.write(line)      # or map(self.write, lines)
    def flush(self):
        pass
示例#11
0
文件: im2.py 项目: mordervomubel/im
class ChatWindow(Toplevel):
	chats = {}

	@staticmethod
	def get(peer):
		try:
			return ChatWindow.chats[peer]
		except KeyError:
			ChatWindow.chats[peer] = ChatWindow(peer)
			return ChatWindow.chats[peer]
		
	def __init__(self, peer):
		Toplevel.__init__(self, mainwindow)
		self.peer = peer

		self.title(peer[0] + ':' + str(peer[1]))

		#self.root = Tk()
		#self.main = Frame(self.root)
		self.main = Frame(self)
		self.main.pack(expand=True, fill=BOTH)

		self.chat_Text = ScrolledText(self.main)
		self.chat_Text.pack(expand=True, fill=BOTH)
		self.chat_Text['height'] = 10
		#print self.keys()
		#print self.chat_Text.keys()

		self.send_Frame = Frame(self.main)
		self.send_Frame.pack(fill=X)

		self.send_Text = Entry(self.send_Frame)
		self.send_Text.pack(side=LEFT, expand=True, fill=X)
		self.send_Text.bind('<Return>', self.send_Action)
		self.send_Button = Button(self.send_Frame, text='Send', command=self.send_Action)
		self.send_Button.pack(side=LEFT)

		self.status_Label = Label(self.main, text='Peer: ' + self.peer[0] + ':' + str(self.peer[1]))
		self.status_Label.pack()

		self.send_Text.focus()

		#self.protocol("WM_DELETE_WINDOW", self._destroy)
	
	def destroy(self):
		#print 'destroy'
		del ChatWindow.chats[self.peer]
		Toplevel.destroy(self)

	def send_Action(self, *args):
		text = self.send_Text.get()
		message = myname + ': ' + text
		if (text.strip()):
			self.chat_Text.insert(END, timestamp() + ' ' + message)
			self.chat_Text.see(END)
			self.send_Text.delete(0, len(text))

			sock.sendto('TEXT' + message, self.peer)
			sock.lastActive = time.time()
		else:
			self.send_Text.delete(0,END)
示例#12
0
class Globby_Text_Editor(tk.Frame):
    def __init__(self, parent_widget, settings):
        # some initial values
        # TODO this Values are obsolete since Project_Settings covers them
        # --> self.settings.projects_path
        self.hash_opened_filename = None
        self.opened_filename = None
        self.settings = settings

        self.edit_button_list=[
            {'text':'new page', 'cmd':self.on_new_page,
                'keytxt':'CTRL+n','hotkey':'<Control-n>'},
            {'text':'del page', 'cmd':self.on_del_page,
                'keytxt':'CTRL+n','hotkey':'<DELETE>'} ,
            {'text':'save', 'cmd':self.on_save,
                'keytxt':'CTRL+s','hotkey':'<Control-s>'},
            {'text':'undo', 'cmd':self.on_undo,
                'keytxt':'CTRL+z','hotkey':'<Control-z>'},
            {'text':'redo', 'cmd':self.on_redo,
                'keytxt':'CTRL+y','hotkey':'<Control-y>'}]

        self.syntax_button_list=[
            {'text':'**bold**', 'cmd':self.on_tag_insert, 'open_tag':'**',
                'close_tag':'**','keytxt':'CTRL+b','hotkey':'<Control-b>'},
            {'text':'//italic//', 'cmd':self.on_tag_insert, 'open_tag':'//',
                'close_tag':'//', 'keytxt':'CTRL+i','hotkey':'<Control-i>'},
            {'text':'__underline__', 'cmd':self.on_tag_insert, 'open_tag':'__',
                'close_tag':'__', 'keytxt':'CTRL+u','hotkey':'<Control-u>'},
            {'text':'[Link]', 'cmd':self.on_tag_insert, 'open_tag':'[',
                'close_tag':']', 'keytxt':'CTRL+l','hotkey':'<Control-l>'},
            {'text':'¸¸sub¸¸', 'cmd':self.on_tag_insert, 'open_tag':'¸¸',
                'close_tag':'¸¸', 'keytxt':'CTRL+d','hotkey':'<Control-d>'},
            {'text':'^^upper^^', 'cmd':self.on_tag_insert, 'open_tag':'^^',
                'close_tag':'^^', 'keytxt':'CTRL+q','hotkey':'<Control-q>'},
            {'text':'-~smaller~-', 'cmd':self.on_tag_insert, 'open_tag':'-~',
                'close_tag':'~-', 'keytxt':'CTRL+w','hotkey':'<Control-w>'},
            {'text':'+~bigger~+', 'cmd':self.on_tag_insert, 'open_tag':'+~',
                'close_tag':'~+', 'keytxt':'CTRL+e','hotkey':'<Control-e>'},
            {'text':'~~strike_thru~~', 'cmd':self.on_tag_insert, 'open_tag':'~~',
                'close_tag':'~~', 'keytxt':'CTRL+t','hotkey':'<Control-t>'} ]

        # build Widgets
        tk.Frame.__init__(self, parent_widget)
        self.pack(fill=tk.BOTH, expand=tk.YES)

        #self.baseframe = tk.Frame(parent_widget)
        #self.baseframe.pack(fill=tk.BOTH, expand=tk.YES)
        self.editor()
        self.button_frame()

        # start tracking text changes inside the editfield
        thread.start_new_thread(self.on_txt_changes, ('',))



    def editor(self):
        """ combine some Widgets to an enhanced editor (incl. Scrollbar)

        --> self.text
                the text widget itself

        --> self.opened_file_label
                Label on top of the editfield to show the name of the current
                opened File
                It can be used to show textchanges
        """
        # build widgets
        self.txtfrm = tk.Frame(self)
        self.txtfrm.pack(fill=tk.BOTH, side=tk.LEFT, expand=tk.YES)
        self.opened_file_label = tk.Label(self.txtfrm, text="No File chosen")
        self.opened_file_label.pack(fill=tk.X)
        self.text = ScrolledText(self.txtfrm, bg="white",
                                undo=1, maxundo=30,
                                wrap=tk.WORD)
        self.text.pack(fill=tk.BOTH, expand=tk.YES, side=tk.LEFT)
        self.text.insert(1.0, u"Please open a File to edit")

        # build first(reference -- new name??) hash for comparison on changes
        self.hash_opened_filename = hash(self.text.get(1.0,tk.END))

        # Set focus on textwidget and move cursor to the upper left
        self.text.focus_set()
        self.text.mark_set(tk.INSERT, '0.0')      # goto line
        self.text.see(tk.INSERT)                  # scroll to line


    def label_button_row(self, parent_widget=None,
                            btnlst=None, start_count=0):
        """Build a 2 column table with a label beside each button in a row.
        Bind a keyboard sequence to the button command.
        Display this keyboard sequence on the label.

        todo:
            - think about a parameter for the widget to bind the Hotkeys
            - rename to: labled_button_row, draw_labled_button_row

        Parameter:
        --> parent_widget:
                Parent widget to place the table

        --> btnlst:
                Type: List of dicts representing a button
                Example:
                    {'text':'**bold**',     # displayed on the Button (string)
                    'cmd':self.on_tag_insert,   # command
                    'open_tag':'**',        # chars representing the beginning
                                            # of a tag for inserting (string)
                    'close_tag':'**',       # chars representing the end
                                            # of a tag for inserting (string)
                    'keytxt':'CTRL+b',      # displayed on the Label (string)
                    'hotkey':'<Control-b>'} # keyboard sequence (string)
                Note:
                    The existence of 'open_tag' and 'close_tag' in btnlst
                    decides which command is bound to the Button.
                    If they aren't there 'cmd' must be a function without
                    parameters!!!
                    otherwise 'cmd' needs following parameters:
                        otag = btn['open_tag']
                        ctag = btn['close_tag']
                        event = None  # Placeholder for a keysequence

        --> start_count:
                Type: int

                Description:
                    The table is relized with tkinter grid layout manager.
                    start_count is used if there is already a grid
                    (with a Label beside a button).
                    start_count can add the automatic genrated
                    buttons under the existing.
                    In Globby_Editor it is used to put a label_button_row
                    under a Tkinter menubutton(file choose, headlines).
        """
        i = start_count
        for btn in btnlst:
            try:
                otag = btn['open_tag']
                ctag = btn['close_tag']
                event = None
                doit = lambda e=event, o=otag, c=ctag:self.on_tag_insert(e,o,c)
                tk.Button(parent_widget, text=btn['text'], command=doit,
                        relief=tk.RIDGE
                        ).grid(column=0, row=i, sticky=tk.W+tk.E)
                self.text.bind(btn['hotkey'],doit)
            except KeyError:
                tk.Button(parent_widget, text=btn['text'], command=btn['cmd'],
                        relief=tk.RIDGE
                        ).grid(column=0, row=i, sticky=tk.W+tk.E)
            tk.Label(parent_widget, text=btn['keytxt'], relief=tk.FLAT
                ).grid(column=1, row=i, sticky=tk.W)
            i +=1


    def button_frame(self):
        """draws a frame to hold a edit- and syntax-buttons under each other
        """
        self.btnfrm = tk.Frame(self)
        self.btnfrm.pack(fill=tk.BOTH, side=tk.LEFT)
        self.edit_buttons()
        self.syntax_buttons()


    def edit_buttons(self):
        """draws a frame with buttons for editing (save, undo, redo, open)
        """

        # genrate a labelframe
        self.efrm = tk.LabelFrame(self.btnfrm, text="Edit Buttons")
        self.efrm.pack(fill=tk.BOTH, padx=5, pady=5)

        # generate a button with a pulldown menue to open a file to edit
        self.file_open_mbtn = tk.Menubutton(self.efrm, text='Open File')
        # generate the pulldown menue
        self.file_open_menu = tk.Menu(self.file_open_mbtn,
                                        postcommand=self.gen_file2edit_menu)
        # bind the pulldown menue to the menubutton
        self.file_open_mbtn.config(menu=self.file_open_menu, relief=tk.RIDGE)


        self.file_open_mbtn.grid(column=0,row=0, sticky=tk.W+tk.E)

        # label beside the Button to display the associated keyboard shortcut
        self.file_open_lbl = tk.Label(self.efrm, text='CTRL+o', relief=tk.FLAT)
        self.file_open_lbl.grid(column=1, row=0, sticky=tk.W+tk.E)


        # generate buttons as described in self.edit_button_list
        self.label_button_row(self.efrm, self.edit_button_list, 2)


        # bind keyboard shortcut to the menue
        self.text.bind('<Control-o>',
                lambda e: self.file_open_menu.tk_popup(e.x_root, e.y_root))


    def gen_file2edit_menu(self):
        """generates a (new) menu bound to the file chooser button
        so every time when a project is created or deleted
        gen_choose_project_menu should be called
        """
        # delete all existing menue entrys
        self.file_open_menu.delete(0,tk.END)
        proj_path = os.path.join(self.settings.projects_path,
                                self.settings.current_project )
        print "proj_path", proj_path
        for this_file in os.listdir(proj_path):
            splitted = os.path.splitext(this_file)
            if splitted[1] == ".txt" and splitted[0] != "menue":
                #print "this_file",this_file
                open_file = os.path.join(proj_path, this_file)
                do_it = lambda bla = open_file:self.on_open(bla)
                self.file_open_menu.add_command(label=splitted, command=do_it)




    def syntax_buttons(self):
        """draws a frame with buttons for insert (wiki)markup

        idea: new parameter for on_tag_insert()
            jump_in_between=True/False so a pulldown list for different levels
            of headlines arn't necessary
        """

        # genrate a labelframe
        self.sfrm = tk.LabelFrame(self.btnfrm, text="Syntax Buttons")
        self.sfrm.pack(fill=tk.BOTH, padx=5, pady=5)

        # generate a button with a pulldown menue für headline Syntax
        self.headln_menubtn = tk.Menubutton(self.sfrm, text='= Headlines =')
        # generate the pulldown menue
        self.headln_menu = tk.Menu(self.headln_menubtn)
        # bind the pulldown menue to the menubutton
        self.headln_menubtn.config(menu=self.headln_menu, relief=tk.RIDGE)
        # generate menue entrys
        i=1
        for entry in ('h1','h2','h3','h4','h5','h6'):
            otag = '\n\n'+'='*i+' '
            ctag = ' '+'='*i+'\n\n'
            doit = lambda event=None, o=otag, c=ctag:self.on_tag_insert(event,o,c)
            self.headln_menu.add_command(label=entry, command=doit)
            i+=1
        self.headln_menubtn.grid(column=0,row=0, sticky=tk.W+tk.E)

        # label beside the Button to display the associated keyboard shortcut
        self.headln_lbl = tk.Label(self.sfrm, text='CTRL+h', relief=tk.FLAT)
        self.headln_lbl.grid(column=1, row=0, sticky=tk.W+tk.E)

        # generate buttons as described in self.edit_button_list
        self.label_button_row(self.sfrm, self.syntax_button_list, 1)

        # bind keyboard shortcut to the menue
        self.text.bind('<Control-h>',
                lambda e: self.headln_menu.tk_popup(e.x_root, e.y_root))


    def on_txt_changes(self, dummy_value=tk.NONE):
        """ tracks text changes inside the editfield by comparing hash values
        new name: visualize_txt_changes???
        """
        while True:
            new_hash = hash(self.text.get(1.0, tk.END))
            if new_hash != self.hash_opened_filename:
                #print "changes"
                self.opened_file_label.configure(fg="red")
            else:
                #print "no changes"
                self.opened_file_label.configure(fg="black")
            sleep(0.2)


    def on_open(self, file_to_open=None):
        """- opens a *.txt file from project folder
        - generates a reference hash.
        - Brings the cursor to the upper left and show this position
          in the textfield

        Parameter:
        --> file_to_open:
                complete path for file to open
        idea:
            - rename file_to_open to openfile or file_to_open
        """
        self.opened_file_to_open = file_to_open
        self.opened_file_label.configure(text=file_to_open)
        self.text.delete(1.0, tk.END)

        self.opened_filename = os.path.basename(file_to_open)


        # write file content into the editfield
        editfile = codecs.open(file_to_open,'r', 'utf-8')
        self.text.insert(1.0, editfile.read())
        editfile.close()

        # generate reference hash for a comparison to track text changes
        self.hash_opened_filename = hash(self.text.get(1.0,tk.END))

        self.text.edit_reset()                  # clear tk's undo/redo stacks
        self.text.focus_set()                   # focus to textfield
        self.text.mark_set(tk.INSERT, '0.0')    # place cursor to upper left
        self.text.see(tk.INSERT)                # and display this line


    def on_save(self):
        """ Safes the current edited file"""
        if self.opened_filename:
            print "on_safe_"
            print "  self.opened_filename",self.opened_filename

            self.hash_opened_filename = hash(self.text.get(1.0,tk.END))


            path_to_safe_file = os.path.join(self.settings.projects_path,
                                    self.settings.current_project,
                                    self.opened_filename)

            safefile = codecs.open(path_to_safe_file,'w', 'utf-8')
            safefile.write(self.text.get(1.0,tk.END))
            safefile.close()
            self.text.edit_reset()        #clear tk's undo/redo stacks
        else:
            showinfo('Globby Text Editor','No File to save \n\n'
                    'You need to choose a File before editing')


    def on_undo(self):
        try:                                    # tk8.4 keeps undo/redo stacks
            self.text.edit_undo( )              # exception if stacks empty
        except tk.TclError:
            showinfo('Globby Text Editor', 'Nothing to undo')


    def on_redo(self):
        print "redo"
        try:                                  # tk8.4 keeps undo/redo stacks
            self.text.edit_redo()             # exception if stacks empty
        except tk.TclError:
            showinfo('Globby Text Editor', 'Nothing to redo')


    def on_new_page(self):
        """ Ask the user to name the new File, create a blank File and load it
        into the Editorwidget

        TODO:   check if file with the new filename allready exists
                check if Filename contains Specialchars
        """
        print "on_new_page"
        nfile_name = tkSimpleDialog.askstring("New File Name",
                                    "Fill in a new File Name")
        proj_path = os.path.join(self.settings.projects_path,
                                self.settings.current_project)
        nfile_name = os.path.join(proj_path, nfile_name.strip()+'.txt')
        nfile = codecs.open(nfile_name, 'w', 'utf-8')

        current_project = self.settings.current_project
        infostring1 = u'# Diese Datei wurde automatisch mit '
        infostring2 = u'dem Projekt "%s" erstellt' % current_project
        nfile.write(infostring1+infostring2 )
        nfile.close()

        self.on_open(nfile_name)

    def on_del_page(self):
        """"""
        print "del page"
        # self.settings.current_project
        del_file = os.path.join(self.settings.projects_path,
                                    self.settings.current_project,
                                    self.opened_filename)

        del_page = askyesno("Do you really want to delete ", del_file)

        if del_page:
            #self.set_project(self.new_project_name)
            print "%s geloescht" % del_file
            os.remove(del_file)


    def on_tag_insert(self, event=None, open_tag=None, close_tag=None):
        """ inserts a (wiki)tag to the current cursor position.

        If there is no text marked in the editfield, open_tag and close_tag
        are inserted to the current cursor position behind each other and the
        cursor jumps in between.
        Otherwise the marked string is enclosed by open_tag and close_tag and
        inserted to the current cursor position. Here the new cursor position
        is right behind the complete inserted string with tags.

        At this moment this behavior is quite buggy :-(

        idea:
            - new parameter for on_tag_insert()
              jump_in_between=True/False so a pulldown list for different levels
              of headlines arn't necessary
            - rename to: on_insert_tag?? on_tag_insert

        Parameter:
        --> event                       # keyboard shortcut
        --> open_tag                    # string
        --> close_tag                   # string

        """
        #print 'event',event
        #print 'open_tag',open_tag
        #print 'close_tag',close_tag

        ## when no String is selected:
        if not self.text.tag_ranges(tk.SEL):
            print "no String is selected"
            insert_point = self.text.index('insert')
            insertline = insert_point.split('.')[0]
            addit = 1
            if event != None:
                print "event not None"
                addit = 2
            insertrow = str(int(insert_point.split('.')[1])+len(open_tag)+addit)
            new_insert_point = insertline+'.'+ insertrow
            self.text.insert(insert_point, open_tag+''+close_tag)
            # place cursor to insert_point
            self.text.mark_set(tk.INSERT, new_insert_point)
            # display this position on the editfield
            self.text.see(tk.INSERT)

        ## when a String is selected:
        else:
            #print "im else"
            marked_text = self.text.get(self.text.index(tk.SEL_FIRST),
                                        self.text.index(tk.SEL_LAST))
            replace_index = self.text.index(tk.SEL_FIRST)
            print "replace_index in selected", replace_index
            self.text.delete(self.text.index(tk.SEL_FIRST),
                            self.text.index(tk.SEL_LAST))
            self.text.insert(replace_index, open_tag+marked_text+close_tag)
示例#13
0
class MyThing(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        self.textBox = ScrolledText(self, height=30, width=85)
        self.textBox.pack()
        self.addText()

    def leftMouseClick(self, event):
        print "got a click"
        mouseIndex = "@%d,%d" % (event.x, event.y)
        current = self.textBox.index(mouseIndex)
        row = current.split(".")[0] + ".0"
        rowFl = float(row) + 1.0
        row = str(rowFl)
        target = self.rowIndex[row]
        target = float(target) + 12.0
        target = str(target)
        print "moving to target", target
        self.textBox.see(target)

    def rightMouseClick(self, event):
        self.textBox.see("0.0")

    def addText(self):
        f = open("help.txt", 'r')
        lines = f.readlines()
        f.close()
        flag = 1
        i = 0
        sectionOrder = {}
        sectionHeads = {}
        outlines = {}
        targetId = 0
        defaultTarget = ""
        tocEntries = []
        lineId = 0
        for line in lines:
            if line[0:1] == "#":
                tocEntries.append(line)
                if flag:
                    top = lineId
                    flag = 0
            lineId += 1

        self.tocEntries = tocEntries
        # header text
        header = lines[0:top]

        for line in header:
            hid = self.textBox.insert(END, line, "header")
            self.textBox.tag_config("header", foreground=FGCOLOR)
            self.textBox.tag_config("header", background=BGCOLOR)

        self.textBox.insert(END, "Table of Contents\n", "toc")
        self.textBox.tag_config("toc", foreground="red")
        self.textBox.tag_config("toc", background=BGCOLOR)
        self.textBox.insert(
            END, "(Left-click entry to navigate, right-click to return)\n\n",
            "directions")
        self.textBox.tag_config("directions", background=BGCOLOR)
        self.textBox.tag_config("directions", foreground="purple")

        sectionDict = {}
        rowIndex = {}
        for tocEntry in tocEntries:
            if tocEntry[0:2] == "##":
                line = "\t" + tocEntry[2:]
            else:
                line = tocEntry[1:]
            rowPosition = self.textBox.index(END).split(".")[0] + ".0"
            rowIndex[rowPosition] = "0.0"
            sectionDict[tocEntry] = rowPosition
            self.textBox.insert(END, line, "tocEntry")

        self.textBox.tag_bind("tocEntry", '<ButtonRelease-1>',
                              self.leftMouseClick)
        self.textBox.tag_config("tocEntry", background=BGCOLOR)
        self.textBox.tag_config("tocEntry", foreground=hfg)
        for i in range(50):
            self.textBox.insert(END, "\n", "regular")

        lines = lines[top:]
        for line in lines:
            if sectionDict.has_key(line):
                print "section id", line
                position = self.textBox.index(END)
                tocPosition = sectionDict[line]
                rowIndex[tocPosition] = position
                line = line.replace("#", "")

            self.textBox.insert(END, line, "regular")

        self.rowIndex = rowIndex

        self.sectionDict = sectionDict

        self.textBox.see("0.0")

        self.textBox.bind_all('<ButtonRelease-3>', self.rightMouseClick)
        self.textBox.tag_config("regular", background=BGCOLOR)
        self.textBox.tag_config("regular", foreground="black")
示例#14
0
文件: gui.py 项目: plumage29/pocky
class MainApplication():
    def __init__(self, master):

        self.filename = ""
        self.confg = ""
        self.master = master
        #setting color.
        bkc = "floral white"
        fgc = "RosyBrown4"
        bgc = "misty rose"

        self.FontForButton = tkFont.Font(family="Verdana", size=12)
        self.FontForLabel = tkFont.Font(family="Verdana", weight="bold")
        self.frame = tk.Frame(self.master, bg=bkc)
        self.frame.pack()
        self.chose_button = tk.Button(self.frame,
                                      text=u"選擇檔案",
                                      command=self.open_file,
                                      font=self.FontForButton,
                                      width=20,
                                      bg=bgc,
                                      fg=fgc)
        self.chose_button.pack(padx=5, pady=10, side=tk.TOP)
        self.chose_confg_button = tk.Button(self.frame,
                                            text=u"選擇設定檔",
                                            command=self.get_confg,
                                            font=self.FontForButton,
                                            width=20,
                                            bg=bgc,
                                            fg=fgc)
        self.chose_confg_button.pack(padx=5, pady=10, side=tk.TOP)
        self.run_button = tk.Button(self.frame,
                                    text=u"執行",
                                    command=self.run,
                                    font=self.FontForButton,
                                    width=20,
                                    bg=bgc,
                                    fg=fgc)
        self.run_button.pack(padx=5, pady=10, side=tk.TOP)
        self.text = ScrolledText(self.frame)
        self.text.pack()
        self.mdby = tk.Label(self.frame,
                             text="\nPowered By MITLab",
                             font=self.FontForLabel,
                             fg="SkyBlue1",
                             bg=bkc)
        self.mdby.pack(side='bottom')

    def open_file(self):
        self.filename = tkFileDialog.askopenfilename()
        if self.filename:
            setup_env.display_message(u"選擇檔案: " + self.filename)

    def get_confg(self):
        self.confg = tkFileDialog.askopenfilename()
        if self.confg:
            setup_env.display_message(u"選擇設定檔案: " + self.confg)

    def write(self, massage):
        self.text.insert(tk.END, massage)
        self.text.see(tk.END)
        self.text.update_idletasks()  #display message real time

    def run(self):
        try:
            if not self.filename or not self.confg:
                raise Exception('請選擇檔案!')
            setup_env.display_message(u"開始執行...")
            setup_env.set_environment(self.confg)
            table = rw_data.read_excel(self.filename, 0)
            rw_data.get_title_col(table)
            cmp_data.filter_data(table)
            cmp_data.cmp_data()
        except Exception as e:
            setup_env.display_message(e.message)
        finally:
            setup_env.clean_envirnoment()
示例#15
0
class BackupUI(Frame):

    def __init__(self, parent=None, **options):
        Frame.__init__(self, parent, padx=10, pady=10)

        self.dataQueue = queue.Queue()
        self.thread = None
        self.outputPath = StringVar()
        self.userVar = IntVar()
        self.photoVar = IntVar()
        self.photoVar.set(1)

        self.top = Frame(self)
        self.top.pack(side=TOP, expand=YES, fill=X)
        self.top.config(bd=2)
        self.createForm()
        self.createButtons()
        self.createText()

    def createButtons(self):

        frm = Frame(self.top)
        frm.pack(side=RIGHT, expand=YES, anchor=NE)
        self.btnStart = Button(frm, text='开始备份', command=self.start)
        self.btnStart.pack(side=TOP)
        self.btnStop = Button(frm, text='停止备份', command=self.stop)
        self.btnStop.pack(side=TOP)
        self.btnStop.config(state=DISABLED)

        frm = Frame(self.top)
        frm.pack(side=RIGHT, expand=YES, anchor=NE)
        self.userCheck = Checkbutton(frm, text='备份好友资料', variable=self.userVar)
        self.userCheck.config(command=self.callback)
        self.userCheck.pack(side=TOP)
        self.photoCheck = Checkbutton(
            frm, text='备份相册照片', variable=self.photoVar)
        self.photoCheck.config(command=self.callback)
        self.photoCheck.pack(side=TOP)

        frm = Frame(self, pady=5, padx=5)
        frm.pack(side=TOP, anchor=W)
        self.btnSelect = Button(frm, text='选择保存路径', command=self.selectPath)
        self.btnSelect.pack(side=LEFT)
        self.savePath = Entry(frm, width=45, textvariable=self.outputPath)
        self.savePath.pack(side=LEFT)
        self.savePath.insert(END, os.path.abspath(os.path.join('.', 'output')))

    def createForm(self):
        self.login = Frame(self.top)
        # self.login.config(padx=4, pady=4)
        self.login.pack(side=LEFT, anchor=W)
        fields = const.LOGIN_FIELDS

        self.inputs = []
        for i in range(len(fields)):
            lbl = Label(self.login, text=fields[i])
            lbl.grid(row=i, column=0)
            var = StringVar()
            self.inputs.append(var)
            ent = Entry(self.login, textvariable=var)
            ent.grid(row=i, column=1)
            self.login.rowconfigure(i, weight=1)
        self.login.columnconfigure(0, weight=1)
        self.login.columnconfigure(1, weight=1)

    def createText(self):
        winfont = ('simhei', 10, 'normal')
        font = ('Helvetica', 12, 'normal')

        self.content = Frame(self, pady=5)
        self.content.pack(side=LEFT, expand=YES, fill=BOTH)
        self.text = ScrolledText(self.content)
        self.text.pack(side=TOP, expand=YES, fill=BOTH)
        self.text.config(bg='light gray', fg='black')
        self.text.config(padx=10, pady=10, font=winfont if isWin32 else font)
        self.text.insert(END, const.USER_GUIDE)
        self.text.config(state=DISABLED)

    def selectPath(self):
        path = askdirectory(initialdir='.')
        if path:
            self.savePath.delete(0, END)
            self.savePath.insert(END, path)

    def callback(self):
        #print('callback', self.userVar.get(), self.photoVar.get())
        pass

    def write(self, message):
        if message and message.strip():
            # timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S.%f')
            timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            self.dataQueue.put(timestamp+" - "+message+'\n')

    def updateText(self, message):
        self.text.config(state=NORMAL)
        self.text.insert(END, str(message))
        self.text.config(state=DISABLED)
        self.text.see(END)
        self.text.update()

    def updateUI(self):
        try:
            message = self.dataQueue.get(block=False)
            if message:
                self.updateText(message)
        except queue.Empty:
            pass
        running = self.thread and self.thread.is_alive()
        self.btnStart.config(state=DISABLED if running else NORMAL)
        self.btnStop.config(state=NORMAL if running else DISABLED)
        self.after(100, self.updateUI)

    def stop(self):
        if getattr(self, 'thread'):
            self.thread.stop()

    def start(self):
        keys = ['username', 'password', 'target']
        values = map(lambda x: x.get(), self.inputs)
        if not any(values):
            showerror(const.NO_INPUT_TITLE, const.NO_INPUT_MESSAGE)
            return
        options = dict(zip(keys, values))
        options['output'] = self.savePath.get()
        options['include_user'] = self.userVar.get()
        options['include_photo'] = self.photoVar.get()
        print('启动参数:', options)
        self.text.config(state=NORMAL)
        self.text.delete('0.0', END)
        self.text.config(state=DISABLED)
        self.updateUI()
        self.thread = BackupThread(self, self.dataQueue, **options)
        self.thread.start()
    class MainWindow(Tkinter.Tk, TkSelectMixIn):
        def __init__(self):
            Tkinter.Tk.__init__(self)

            self.textbox = ScrolledText(self, bg='white')
            self.textbox.pack(fill=BOTH, expand=1)
            self.server()
            self.start()

        def server(self):
            # inicializa o servidor

            self.sock = socket.socket(socket.AF_INET, \
                                      socket.SOCK_STREAM)
            self.sock.bind(('localhost', 8000))
            self.sock.listen(1)

            # a chamada para input_read para o socket do servidor e
            # um pouco diferente, tendo como callback o metodo
            # self.accept
            self.server_tag = self.input_add(self.sock, \
                                             INPUT_READ, self.accept)
            # mantemos uma lista dos clientes conectados
            self.clients = {}

        def accept(self, source, condition):
            # metodo chamado quando o servidor tem um cliente
            # esperando para ser aceito

            conn, addr = source.accept()
            self.insert("%s:%s conectado\n" % addr)

            # insere o cliente na lista e registra o metodo self.write
            # como callback para quando existirem dados esperando para
            # serem lidos.

            self.clients[addr] = (conn,
                                  self.input_add(conn, INPUT_READ, self.write))

        def write(self, source, condition):
            # metodo chamado quando um cliente envia dados

            data = source.recv(1024)
            if not data.strip() or data.strip() == 'bye':
                # se o cliente enviar um "bye" ou uma linha em branco,
                # desconecte-o
                source.close()

                for addr, (conn, tag) in self.clients.iteritems():
                    if source is conn:
                        self.input_remove(tag)
                        self.insert('%s:%s desconectado\n' % addr)
                        del self.clients[addr]
                        break
            else:
                for (addr, port), (conn, tag) in \
                   self.clients.iteritems():
                    if source is conn:
                        self.insert('%s:%s>>>%s\n'%(addr, port, \
                                    data.strip()))
                        break

        def insert(self, data):
            self.textbox.insert(END, data)
            self.textbox.see(END)

        def quit(self):
            self.input_remove(self.server_tag)
            for add, (conn, tag) in self.clients.iteritems():
                self.input_remove(tag)
                conn.close()
            self.sock.close()
            Tkinter.Tk.destroy(self)
示例#17
0
class ServerGUI(object):
    server_on = False

    def __init__(self, window_title="Server GUI"):
        self.base_gui = pygui.Tk()

        self.window_title = window_title
        self.server_port = 0
        self.server = None

        # [GUI Initialization] ::start
        self.server_config_frame = pygui.Frame(self.base_gui)
        self.port_to_use_field = pygui.Entry(self.server_config_frame)
        self.server_controls_frame = pygui.Frame(self.base_gui)
        self.create_server_btn = pygui.Button(self.server_controls_frame,
                                              text="Start Server",
                                              command=self.invoke_server)
        self.stop_server_btn = pygui.Button(self.server_controls_frame,
                                            text="Stop Server",
                                            command=self.stop_server)
        self.quit_btn = pygui.Button(self.server_controls_frame,
                                     text="Quit",
                                     command=self.destroy_gui)
        # [GUI Initialization] ::end

        self.server_logs_frame = pygui.Frame(self.base_gui)
        self.activity_log_area = ScrolledText(self.server_logs_frame,
                                              height=10,
                                              width=50)

    def bootstrap(self):
        if self.server is None:
            print "Server Object must be specified. Call the set_server() method and set the ServerGUI Object."
            sys.exit(1)

        # set window title
        self.base_gui.wm_title(self.window_title)

        # [Config Section] :start
        self.server_config_frame.pack(side=pygui.TOP, pady=10)

        # Add field for port to use
        pygui.Label(self.server_config_frame,
                    text="Server port to use").grid(row=0, column=0)

        self.port_to_use_field.grid(row=0, column=1)
        self.port_to_use_field.bind("<Return>", self.invoke_server)
        # [Config Section] :end

        # [Controls Section] ::start
        self.server_controls_frame.pack(side=pygui.RIGHT, fill=pygui.Y)

        # Add Start server button
        self.create_server_btn.grid(row=0, column=1)

        # Stop Server
        self.stop_server_btn.grid(row=1, column=1)

        # Quit Button
        self.quit_btn.grid(row=2, column=1)
        # [Controls Section] ::end

        # [Logs Section] ::start
        self.server_logs_frame.pack(side=pygui.LEFT, padx=10, pady=10)

        # Create a text area for showing logs.
        pygui.Label(self.server_logs_frame, text="Logs").grid(row=0)

        self.activity_log_area.edit_modified(0)
        self.activity_log_area.grid(row=1)
        self.activity_log_area.config(highlightbackground="black")
        self.activity_log_area.bind('<<Modified>>', self.scroll_to_end)
        # [Logs Section] ::end

        # handle close button
        self.base_gui.protocol("WM_DELETE_WINDOW", self.destroy_gui)

        # Start the GUI
        self.base_gui.mainloop()

    def set_server(self, server):
        self.server = server

    def scroll_to_end(self, *_):
        # scroll to the end of text area
        self.activity_log_area.see(pygui.END)
        self.activity_log_area.edit_modified(0)

    def destroy_gui(self):
        self.stop_server()
        self.base_gui.destroy()

    def stop_server(self, *_):
        if self.server_on is True:
            self.server.stop(self.log)

            # set the SERVER_ON flag to false to enable create a new server instance
            self.server_on = False
        else:
            self.log("Server already stopped.")

    def invoke_server(self, *_):
        portval = self.port_to_use_field.get()

        if portval != '':
            # check if the input for port number is a valid integer
            try:
                self.server_port = int(portval)
            except ValueError:
                msgBox.showinfo("Client GUI", "Invalid Port Number")
                return

            # start the server if not yet started
            if self.server_on is False:
                # log the message
                self.server.set_port(self.server_port)

                if not self.server.invoke(self.log):
                    msgBox.showinfo(
                        "Client GUI",
                        "Cannot bind to port: %s. Please select another port to bind on."
                        % str(self.server_port))

                    return

                # Prevent starting another instance of server
                self.server_on = True
            else:
                self.log("Server already started on port: " +
                         str(self.server_port))
        else:
            self.log(
                "Please provide port number for the server to bind on. Thanks!"
            )

    def log(self, message):
        self.activity_log_area.insert(pygui.END, message + "\n")
class my_form(Frame):
    """Form"""
    def __init__(self, master=None):
        """create elements of form"""
        Frame.__init__(self, master)
        self.pack()

        self.textBox = ScrolledText(self, height=5, width=115)
        #self.textBox.pack()
        self.textBox.tag_config("b", foreground="blue")
        self.textBox.tag_config("r", foreground="red")

        self.label_dummy = Label(self, width=100, text=" ")
        self.label_dummy.pack()

        self.label_dummy1 = Label(self, width=100, text=" ")
        self.pressButton = Button(self,
                text="Write ID3 Tags", command=self.write_id3_tags_prepare)
        #self.pressButton.pack()

        # registering callback
        self.listenID = self.after(400, self.lets_rock)

    def display_logging(self, log_message, text_format):
        """display messages in form, loading periodically """
        if text_format is None:
            self.textBox.insert(END, log_message + "\n")
        else:
            self.textBox.insert(END, log_message + "\n", text_format)

    def write_id3_tags_prepare(self):
        """prepare for writing tags"""
        result = tkMessageBox.askquestion(
                        self.msg[5], self.msg[6], icon='warning')
        if result == 'yes':
            self.display_logging(self.msg[7], None)
            z = 0
            for item in self.mp3_files:
                self.display_logging(self.entry_a[z].get(), "b")
                self.display_logging(self.entry_b[z].get(), "b")
                write_id3_tags(self, item,
                    self.entry_a[z].get(), self.entry_b[z].get())
                self.textBox.see(END)
                z += 1
        else:
            self.display_logging(self.msg[8], None)
            self.textBox.see(END)

    def lets_rock(self):
        """man funktion"""
        print "lets rock"
        switch_lang(self)
        self.display_logging(self.msg[1], None)

        # check packages
        check_package = True
        check_package = check_packages(self,
                                ["sox", "mp3gain", "mp3splt", "easytag"])
        if check_package is None:
            return

        try:
            path_files = (
                os.environ['NAUTILUS_SCRIPT_SELECTED_FILE_PATHS'].splitlines())
        except Exception, e:
            self.display_logging("Error: %s" % str(e), "r")
            self.display_logging(self.err[2], None)
            return

        self.display_logging(self.msg[2], None)
        self.display_logging(os.path.dirname(path_files[0]), None)
        self.display_logging(self.msg[3], None)
        self.mp3_files = []
        for item in path_files:
            if string.rfind(item, ".mp3") == -1:
                # no mp3:
                continue
            self.mp3_files.append(item)
            self.display_logging(extract_filename(item), "b")

        # check for mp3 files
        if len(self.mp3_files) == 0:
            self.display_logging(self.err[3], "r")
            self.display_logging(self.msg[4], None)
            return
        #return
        z = 0
        self.label_dummy = []
        self.label = []
        self.entry_a = []
        self.entry_b = []
        for item in self.mp3_files:
            if z == 10:
                self.display_logging(self.msg[9], "b")
                continue
            #self.display_logging(extract_filename(item), "r")
            author, title = read_id3_tags(self, item)
            try:
                self.my_label = Label(self,
                    width=100, text=extract_filename(item))
                self.label.append(self.my_label)
                self.label[z].pack()

                self.my_entry_a = Entry(self, width=100)
                self.entry_a.append(self.my_entry_a)
                self.entry_a[z].pack()
                self.entry_a[z].insert(0, author)

                self.my_entry_b = Entry(self, width=100)
                self.entry_b.append(self.my_entry_b)
                self.entry_b[z].pack()
                self.entry_b[z].insert(0, title)

                self.my_label_dummy = Label(self, width=100, text=" ")
                self.label_dummy.append(self.my_label_dummy)
                self.label_dummy[z].pack()
                z += 1
            except Exception, e:
                self.display_logging("Error: %s" % str(e), "r")
示例#19
0
class ClientGUI(object):

  def __init__(self, windowTitle="Client GUI"):
    # create new instance of TK
    self.base_gui = pygui.Tk()

    # store the windowTitle in an object attribute
    self.base_window_title = windowTitle

    # Connection Details
    self.connection_host = ''
    self.connection_name = ''
    self.connection_port = 0

    # Client Object
    self.client = None

    # [Connection GUI Initialization] ::start
    self.connection_gui_bootstrapped = False
    self.connection_config_frame = pygui.Frame(self.base_gui)
    self.host_to_use_field = pygui.Entry(self.connection_config_frame)
    self.port_to_use_field = pygui.Entry(self.connection_config_frame)
    self.name_field = pygui.Entry(self.connection_config_frame)
    self.connect_server_btn = pygui.Button(self.connection_config_frame, text="Connect", command=self.connect_to_server)
    # [Connection GUI Initialization] ::end

    # [Main GUI Initialization] ::start
    self.main_gui_bootstrapped = False
    self.chat_room_frame = pygui.Frame(self.base_gui)
    self.activity_log_area = ScrolledText(self.chat_room_frame, height=10, width=50)
    self.message_field = pygui.Entry(self.chat_room_frame)
    self.submit_msg_btn = pygui.Button(self.chat_room_frame, text="Send", command=self.send_msg)

    self.exit_chat_btn = pygui.Button(self.chat_room_frame,
                                      text="Leave Chat Room",
                                      command=lambda: self.switch_context('connection'))
    # [Connection GUI Initialization] ::end

  def bootstrap(self):
    if self.client is None:
      print "Client Object must be specified. Call the set_client() method and set the ClientGUI Object."
      sys.exit(1)

    self.connection_gui()

    # set window title
    self.base_gui.wm_title(self.base_window_title)

    # handle close button
    self.base_gui.protocol("WM_DELETE_WINDOW", self.destroy_gui)

    # Start the GUI
    self.base_gui.mainloop()

  def connection_gui(self):
    # [Config Section] :start
    # assemble the UI and the frame if the attribute does not exist
    if self.connection_gui_bootstrapped is False:
      # Add field for host/hostname to use
      pygui.Label(self.connection_config_frame, text="Host").grid(row=0, column=0)
      self.host_to_use_field.grid(row=0, column=1)

      # Add field for port to use
      pygui.Label(self.connection_config_frame, text="Port").grid(row=1, column=0)
      self.port_to_use_field.grid(row=1, column=1)

      # Add field for chat username/alias
      pygui.Label(self.connection_config_frame, text="Name").grid(row=2, column=0)
      self.name_field.grid(row=2, column=1)

      self.connect_server_btn.grid(row=3, column=1)

      self.connection_gui_bootstrapped = True

    self.connection_config_frame.pack(side=pygui.TOP, padx=10, pady=10)
    # [Config Section] :end

  def main_gui(self):
    # [Chat Room] ::start
    # assemble the UI and the frame if the attribute does not exist
    if self.main_gui_bootstrapped is False:
      self.activity_log_area.grid(row=0)
      self.activity_log_area.edit_modified(0)
      self.activity_log_area.config(highlightbackground="black")
      self.activity_log_area.bind('<<Modified>>', self.scroll_to_end)

      self.message_field.grid(row=1, column=0)
      self.message_field.config(width=30)
      self.message_field.bind("<Return>", self.send_msg)

      self.submit_msg_btn.grid(row=1, column=1)

      self.exit_chat_btn.grid(row=2)

      self.main_gui_bootstrapped = True

    # empty the chat logs
    self.activity_log_area.delete("1.0", pygui.END)

    # show the frame for chat room
    self.chat_room_frame.pack(side=pygui.TOP, padx=10, pady=10)
    # [Chat Room] ::end

  def destroy_gui(self):
    # disconnect from the server
    self.client.disconnect()

    # destroy the window
    self.base_gui.destroy()

  def switch_context(self, context):
    if context == 'main':
      # hide the connection frame/GUI from the window
      if hasattr(self, 'connection_config_frame'):
        self.connection_config_frame.pack_forget()

      self.main_gui()

      title = "%s connected on %s:%s - %s" % (strip_uid(self.connection_name),
                                              self.connection_host,
                                              str(self.connection_port),
                                              self.base_window_title)

      # change the window title to show the connection details
      self.base_gui.wm_title(title)

    else:
      # disconnect from the server
      self.client.disconnect()

      # hide the chat room frame/GUI from the window
      if hasattr(self, 'chat_room_frame'):
        self.chat_room_frame.pack_forget()

      self.connection_gui()

      # set window title
      self.base_gui.wm_title(self.base_window_title)

  def scroll_to_end(self, *_):
    # scroll to the end of text area
    self.activity_log_area.see(pygui.END)
    self.activity_log_area.edit_modified(0)

  def connect_to_server(self):
    hostval = self.host_to_use_field.get()
    portval = self.port_to_use_field.get()
    nameval = self.name_field.get()

    if hostval != '' and portval != '' and nameval != '':
      self.connection_host = str(hostval)
      self.connection_name = str(nameval)

      # check if the host supplied is a valid ip address
      if not is_ipv4(self.connection_host):
        msgBox.showinfo("Client GUI", "Invalid IP Address")
        return

      # check if the input for port number is a valid integer
      try:
        self.connection_port = int(portval)
      except ValueError:
        msgBox.showinfo("Client GUI", "Invalid Port Number")
        return

      # initiate client-server connection
      if self.client.connect(self.connection_host, self.connection_port, self.connection_name) is True:
        # swap UI components/widgets
        self.switch_context('main')

        # log any broadcast message and disconnect on lost connection
        self.client.start_communications(self.log, lambda: self.switch_context('connection'))
      else:
        msgBox.showinfo("Client GUI", "Cant connect to server. Please try again later.")

    else:
      msgBox.showinfo("Client GUI", "Please enter the host, and port to connect to as well as your chat name")

  def set_client(self, client):
    self.client = client

  def send_msg(self, *_):
    message = self.message_field.get()

    # only send messages which are not empty
    if message:
      # show the message on your side
      self.log('[' + strip_uid(self.connection_name) + '] ' + message)

      # send the message to the other side
      self.client.send_msg(str(message))

      # delete the message
      self.message_field.delete(0, pygui.END)

  def log(self, message):
    self.activity_log_area.insert(pygui.END, message + "\n")
示例#20
0
displayT.configure(state="disabled")
displayT.pack()

# User input textbox (at the lower part of the window, only 2 rows x 80 column)
inputT = Text(root, height=2, width=80, bg='#ffa64d')
inputT.insert(END, "")
inputT.bind('<KeyRelease>', inputKeyup)

inputT.pack(side=LEFT)
sendbutton = Button(root, text="Send")
sendbutton.bind('<Button-1>', sendmsg)
sendbutton.pack()
quitbutton = Button(root, text="Quit")
quitbutton.bind('<Button-1>', quit)
quitbutton.pack()
inputT.focus_set()  # ensure focus on the input textbox

#Startup message
displayT.configure(state="normal")
displayT.insert(END, 'Enter "!help" for the list of available commands.\n')
displayT.see(END)  # simulate autoscroll
displayT.configure(state="disabled")

# starting a separate thread to monitor and display incoming message from
# chat server
t = threading.Thread(target=monitor, args=(socket, ))
t.start()

# mainloop() is required to start the window activities.
mainloop()
示例#21
0
class LoggingUI(TimedFrame):
    u'''ロギング用UI'''
    def __init__(self, *args, **kwargs):
        TimedFrame.__init__(self, *args, **kwargs)
        self.pack()
        self.init()
        self.startTimer()
    
    def init(self):
        if not config.normalize.points:
            self._label = tk.Label(self, text = u'まだ正規化が済んでいません。\n正規化を行ってください。')
            self._label.pack()
            return

        if not config.template.images or len(config.template.images) < 10 or not all(config.template.images):
            self._label = tk.Label(self, text = u'まだ学習が済んでいません。\n学習を行ってください。')
            self._label.pack()
            return
        
        # テンプレートの読み込み
        self.loadTemplates()
        
        # カメラの準備
        self._camera = cv.CaptureFromCAM(config.camera.id)
        
        # 左側UI
        frame1 = tk.Frame(self)
        frame1.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)
        
        # カメラ画像表示用Canvasなどの準備
        self._cvmat = None
        self._image = tk.PhotoImage(width = config.canvas.width, height = config.canvas.height)
        self._canvas = tk.Canvas(frame1, width = config.canvas.width, height = config.canvas.height)
        self._canvas.create_image(config.canvas.width / 2, config.canvas.height / 2, image = self._image, tags = 'image')
        self._canvas.pack(expand = True, fill = tk.BOTH)
        
        # ボタン
        self._main_button = tk.Button(frame1)
        self._main_button.pack(side = tk.LEFT)
        self.logStop()
        self._reset_button = tk.Button(frame1, text = u'リセット', command = self.reset)
        self._reset_button.pack(side = tk.RIGHT)
        
        # 生データ表示領域
        self._textarea = ScrolledText(self, width = 6, height = 18)
        self._textarea.pack(side = tk.LEFT, expand = True)
        
        # 右側UI
        frame2 = tk.Frame(self)
        frame2.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)
        
        # ログデータ表示領域
        self._graph = tk.Canvas(frame2, width = config.canvas.width, height = config.canvas.height, bg = 'white')
        self._graph.pack(expand = True, fill = tk.BOTH)
        self._bar_graph = BarGraph(A(width = config.canvas.width, height = config.canvas.height), config.logging.graph_max_count)
        
        # ボタン
        self._out_button = tk.Button(frame2, text = u'生データをコピー', command = self.datacopy)
        self._out_button.pack(side = tk.LEFT)
        self._gchart_button = tk.Button(frame2, text = u'Google Chart URLをコピー', command = self.gchart)
        self._gchart_button.pack(side = tk.RIGHT)
        
        # 画像をフィルタするための変数
        self._clip_rect, self._perspective_points = Points2Rect(config.normalize.points)
        
        # ロギング開始、停止のフラグ
        self._take_log = False
        
        # ログ
        self._log = []
        
        # カメラ画像の更新を1秒間隔にする
        self.addTiming(self.showImage, 1)
    
    def setValue(self, value):
        if value is None: value = 0
        self._bar_graph.setValue(value)
        
        self._graph.delete('bar')
        for bar in self._bar_graph.getAllBars():
            self._graph.create_rectangle(
                bar.p1.x, bar.p1.y,
                bar.p2.x, bar.p2.y,
                fill = 'green', stipple = 'gray25',
                tags = 'bar'
            )
    
    def loadTemplates(self):
        u'''テンプレート画像の読み込み'''
        self._templates = []
        for i, cvimageinfo in enumerate(config.template.images):
            cvmat = cv.CreateMatHeader(cvimageinfo.rows, cvimageinfo.cols, cvimageinfo.type)
            cv.SetData(cvmat, cvimageinfo.data)
            self._templates.append(A(
                image = cv.GetImage(cvmat),
                number = i,
                result = None,
            ))
    
    def showImage(self):
        u'''カメラ画像の表示'''
        captured = cv.QueryFrame(self._camera)
        self._cvmat = self.filter(captured)
        self._image = CvMat2TkImage(self._cvmat)
        self._canvas.itemconfigure('image', image = self._image)
        if self._take_log:
            self.logging()
    
    def logging(self):
        u'''ログを取る'''
        target = self._cvmat
        digits_sieve = DigitsSieve()
        for template in self._templates:
            if not template.result:
                # マッチング結果保存用領域の準備
                template.result = cv.CreateImage(
                    (target.width - template.image.width + 1, target.height - template.image.height + 1),
                    cv.IPL_DEPTH_32F, 1,
                )
            
            cv.MatchTemplate(target, template.image, template.result, config.logging.match_method)

            # 数値の読み取り
            minVal, maxVal, minLoc, maxLoc = cv.MinMaxLoc(template.result)
            while maxVal > config.logging.match_threshold:
                # 検出された数値情報の保持
                digits_sieve.push(A(
                    number = template.number,
                    x = maxLoc[0],
                    y = maxLoc[1],
                    width = template.image.width,
                    height = template.image.height,
                    score = maxVal,
                ))
                
                # 現在の位置周辺のスコアをクリアし、次にスコアの高い位置を取得する
                SetReal2DAround(template.result, maxLoc, config.logging.match_exclusion_size, 0.0)
                minVal, maxVal, minLoc, maxLoc = cv.MinMaxLoc(template.result)
        
        value = digits_sieve.getValue()
        if value is not None:
            self._log.append(value)
            self.setValue(value)
            self._textarea.insert(tk.END, '%d\n' % value)
            self._textarea.see(tk.END)

    def logStart(self):
        u'''ロギングを開始する'''
        self._main_button.configure(text = u'ストップ', command = self.logStop)
        self._take_log = True
        
    def logStop(self):
        u'''ロギングを停止する'''
        self._main_button.configure(text = u'スタート', command = self.logStart)
        self._take_log = False
    
    def reset(self):
        u'''リセット'''
        self._bar_graph.init()
        self.setValue(0)
        self._log = []
        self._textarea.delete('1.0', tk.END)
    
    def datacopy(self):
        u'''生データをクリップボードにコピーする'''
        text = self._textarea.get('1.0', tk.END)
        self.clipboard_clear()
        self.clipboard_append(text)
    
    def gchart(self):
        u'''Google Chart API用のURLをクリップボードにコピーする'''
        if  self._log \
            and len(self._log) > 0 \
            and max(self._log) > 0:
                
                unit = float(4095) / max(self._log)
                url = gExtendedUrl(
                    map(lambda x: unit * x, self._log),
                    cht = 'bvs', # 棒グラフ
                    chxt = 'y', # y軸の目盛り表示
                    chxr = '0,0,%d' % max(self._log), # y軸の最小最大値
                    chg = '0,10,3,2', # 補助線
                    chbh = '%d,1' % (480 / len(self._log) - 1), # 棒グラフの棒の幅
                )
                self.clipboard_clear()
                self.clipboard_append(url)
        
    def filter(self, cvmat):
        u'''画像をフィルタする'''
        # サイズ調整
        thumbnail = cv.CreateMat(config.canvas.height, config.canvas.width, cv.CV_8UC3)
        cv.Resize(cvmat, thumbnail)
        return NormalizeImage(thumbnail, self._clip_rect, self._perspective_points)
示例#22
0
class Interactive(object):
    def __init__(self):
        self.printQueue = Queue()
        # Tkinter components:
        self.root = Tk()
        self.root.title = "PGF API App"
        self.text_box = ScrolledText(self.root)
        self.runPrintQueue = True
        self.is_running = False
        self.prompt_var = StringVar()
        self.user_input = StringVar()
        self.of = RediOrderFactory()
        self.google_sheet = None

    def gui_start(self):
        printer_thread = Thread(target=self.queue_printer)
        printer_thread.daemon = True
        printer_thread.start()
        # start printer_thread

        self.text_box.pack()
        self.text_box.config(state=DISABLED)

        user_prompt_entry = Entry(self.root, textvariable=self.prompt_var)
        user_prompt_entry.pack(fill=BOTH)

        entry_var = StringVar()
        entry_box = Entry(self.root, textvariable=entry_var)

        def enter_pressed(event):
            print event
            self.user_input = entry_box.get()

            self.print_user_input(self.user_input)
            request_thread = Thread(target=self.process_user_input,
                                    args=[entry_box.get()])
            # self.process_user_input(entry_box.get())
            request_thread.start()
            entry_box.delete(0, 'end')

        entry_box.bind("<Return>", enter_pressed)
        entry_box.pack(fill=BOTH)
        entry_box.focus_set()

        self.user_input.set('')

        mainloop()
        self.runPrintQueue = False

    def queue_printer(self):
        while True:
            item = self.printQueue.get()

            self.text_box.config(state=NORMAL)
            self.text_box.insert(END, item)
            if isinstance(item, basestring):
                self.text_box.insert(END, '\n')
            if isinstance(item, ListType):
                self.text_box.insert(END, '\n')
            self.text_box.config(state=DISABLED)
            self.text_box.see('end')
            if not self.runPrintQueue:
                break
            time.sleep(.1)
            self.printQueue.task_done()

    def print_user_input(self, item):
        self.text_box.config(state=NORMAL)
        self.text_box.tag_config("b", foreground="blue")
        self.text_box.insert(END, item, "b")
        self.text_box.insert(END, '\n')
        self.text_box.config(state=DISABLED)
        self.text_box.see('end')

    def print2(self, txt):
        print txt
        self.printQueue.put(txt)

    def process_user_input(self, ui):
        # build this one function at a time
        if ui[:4].upper() == 'ECHO':
            self.print2(ui[4:])
            self.prompt_var.set(ui[4:])
        elif ui.upper() == 'QUIT' or ui.upper() == 'Q':
            self.print2('Breaking out of interactive.')
            sys.stdout.flush()
            self.root.quit()
            return -1
        elif ui.upper() == 'LOAD SHEET':
            self.print2('Called Load Sheet')
            try:
                self.google_sheet = gs.GoogleSheetDailyTradingProcedure()

                self.print2('wait a moment . . . ')
                sys.stdout.flush()
                self.google_sheet.load_sheet()
                self.print2('sheet loaded')

            except E:
                self.print2('problem loading sheet' + E)

        elif ui.upper() == 'PRINT SHEET':
            if self.google_sheet:
                for row in self.google_sheet.sheet:
                    self.print2(row)

            else:
                self.print2('Load sheet first. (cmd = load sheet)')

        elif ui.upper()[:10] == 'SUBMIT ROW':
            row = int(ui.split(' ')[2]) - 1

            self.submit_row(row)
            # submit_row_thread = Thread(target=self.submit_row,args=[row])
            # submit_row_thread.start()
        elif ui.upper() == 'SUBMIT ALL':
            if self.google_sheet.sheet:
                i = -1
                for _ in self.google_sheet.sheet:
                    i += 1
                    if i < 2:
                        continue
                    a = self.submit_row(i)
                    if a == 'b':
                        break
            else:
                pass
        elif ui.upper() == 'LOAD ADRS':
            self.google_sheet = gs.GoogleSheetDailyTradingProcedure()
            sheet_id = '1Z3POIK8N5Vi_CsF_MDLszrJeNviBwrU9BuVFC8h-xgQ'
            worksheet_range = 'ADRs Test!A1:F'
            self.print2('wait a moment')
            sys.stdout.flush()
            self.google_sheet.load_sheet(sheet_id, worksheet_range)
            self.print2('adrs loaded')
        elif ui.upper()[:14] == 'SUBMIT ADR ROW':
            r = int(ui.split(' ')[3])
            self.submit_our_adr_row(r)
            self.print2('submit adr row')
        elif ui.upper() == 'SUBMIT ALL ADRS':
            if self.google_sheet.sheet:
                i = -1
                for _ in self.google_sheet.sheet:
                    i += 1
                    if i < 2:
                        continue
                    a = self.submit_our_adr_row(i)

                    if a == 'b':
                        break
            else:
                pass
            self.print2('submit adrs')
        elif ui.upper() == 'SUBMIT ALL MOCS':
            if self.google_sheet.sheet:
                i = -1
                for _ in self.google_sheet.sheet:
                    i += 1
                    if i < 2:
                        continue
                    a = self.submit_our_moc_row(i)
                    if a == 'b':
                        break
            else:
                pass
        elif ui.upper()[:14] == 'SUBMIT MOC ROW':
            r = int(ui.split(' ')[3])
            self.submit_our_moc_row(r)
            self.print2('submit adr row')
        elif ui.upper()[:8] == 'STOP ROW':
            stop_tokens = ui.split(' ')
            row_num = int(stop_tokens[2]) - 1
            row = self.google_sheet.sheet[row_num]
            if len(stop_tokens) == 4:
                quantity = int(stop_tokens[3])
            else:
                quantity = int(row[4])
            side = 'sell' if (row[3].upper() == 'LONG' or row[3].upper()
                              == 'BUY' or row[3].upper() == 'B') else 'buy'
            if side == 'sell':
                quantity *= -1
            symbol = row[2].split()[0].upper()
            stop_price = 0
            if len(row) >= 13:
                stop_price = round(float(row[12]), 2)
            account = row[1].upper()
            if side == 'sell':
                stop_limit = round(stop_price * .99, 2)
            else:
                stop_limit = round(stop_price * 1.01, 2)
            self.of.generate_stop_limit_order(quantity, symbol, stop_price,
                                              stop_limit, account)
        elif ui.upper()[:9] == 'PRINT ROW':
            if self.google_sheet:
                tokens = ui.split(' ')
                self.print2(self.google_sheet.sheet[int(tokens[2]) - 1])
            else:
                self.print2('Load sheet first. (cmd = load sheet)')
        else:
            if ui != 'y' and ui != 'n' and ui != 'b':
                self.print2('Command not understood.')

    def submit_row(self, r, confirm=True):
        try:
            if self.google_sheet:
                row = self.google_sheet.sheet[r]
                self.print2(row)
                sys.stdout.flush()

                account = row[1].upper()
                symbol = row[2].split()[0].upper()
                if symbol == '':
                    return
                if row[4] == '':
                    self.print2(
                        "Row doesn't have quantity. Enter quantity and reload sheet."
                    )
                    sys.stdout.flush()
                    return
                quantity = int(row[4])
                side = 'buy' if (row[3].upper() == 'LONG' or row[3].upper()
                                 == 'BUY' or row[3].upper() == 'B') else 'sell'
                if side == 'sell':
                    quantity *= -1
                o_type = None
                if len(row) >= 7:
                    o_type = row[6].upper()
                price = 0
                if len(row) >= 8:
                    if row[7] == '':
                        price = 0
                    else:
                        price = float(
                            row[7][1:]) if row[7][0] == '$' else float(row[7])
                trade_date = None
                if len(row) >= 9:
                    trade_date = row[8]

                if str(datetime.datetime.now())[:10] != trade_date:
                    self.print2('Date is not today')
                    sys.stdout.flush()
                    return

                order_string = '{} {} {} {} {} in {}'.format(
                    side, abs(quantity), symbol, price, o_type, account)
                if confirm:
                    confirm_msg = '{}? (y/n/b)'.format(order_string)

                    self.user_input = ''
                    self.prompt_var.set(confirm_msg)
                    while self.user_input == '':
                        time.sleep(.1)
                    inp = self.user_input
                    self.prompt_var.set('')
                else:
                    inp = 'y'

                if inp == 'y':
                    o = False
                    if o_type == 'MOO':
                        o = self.of.generate_opg_market_order(
                            quantity, symbol, account)
                    elif o_type == 'LOO':
                        o = self.of.generate_opg_limit_order(
                            quantity, symbol, price, account)
                    elif o_type == 'LOC':
                        o = self.of.generate_loc_order(quantity, symbol, price,
                                                       account)
                    elif o_type == 'MOC':
                        o = self.of.generate_moc_order(quantity, symbol,
                                                       account)
                    elif o_type == 'LIMIT' or o_type == 'LMT':
                        o = self.of.generate_limit_order(
                            quantity, symbol, price, account)
                    time.sleep(.05)
                    if o:
                        return '1'
                    else:
                        return '0'
                elif inp == 'b':
                    return 'b'  # user requested break
                else:
                    return inp
            else:
                self.print2('Load sheet first. (cmd = load sheet)')
                sys.stdout.flush()
                return 'b'
        except Exception as e:
            self.print2('row {} failed to submit: {}'.format(r + 1, e))
            sys.stdout.flush()

    def submit_our_adr_row(self, r, confirm=False):

        try:
            if self.google_sheet:
                row = self.google_sheet.sheet[r - 1]
                self.print2(row)
                sys.stdout.flush()

                symbol = row[1].split()[0].upper()
                if symbol == '':
                    return
                if row[3] == '':
                    self.print2(
                        "Row doesn't have quantity. Enter quantity and reload sheet."
                    )
                    sys.stdout.flush()
                    return
                quantity = int(row[3])
                if row[2] == '':
                    return
                side = 'buy' if (row[2].upper() == 'LONG' or row[2].upper()
                                 == 'BUY' or row[2].upper() == 'B') else 'sell'
                if side == 'sell':
                    quantity *= -1
                order_type = None
                if len(row) >= 6:
                    order_type = row[5].upper()
                price = 0
                if len(row) >= 5:
                    if row[4] == '':
                        price = 0
                    else:
                        price = float(
                            row[4][1:]) if row[4][0] == '$' else float(row[4])
                trade_date = None
                if len(row) >= 1:
                    trade_date = row[0]

                if str(datetime.datetime.now())[:10] != trade_date:
                    self.print2('Date is not today')
                    sys.stdout.flush()
                    return

                order_string = '{} {} {} {} {}'.format(side, abs(quantity),
                                                       symbol, price,
                                                       order_type)
                if confirm:
                    sys.stdout.write('{} {} {} {} {}? (y/n/b)'.format(
                        side, abs(quantity), symbol, price, order_type))
                    sys.stdout.flush()
                    inp = raw_input()
                else:
                    inp = 'y'
                if inp == 'y':
                    o = 0
                    if order_type == 'MOO':
                        o = self.of.generate_opg_market_order(quantity, symbol)
                    elif order_type == 'LOO':
                        o = self.of.generate_opg_limit_order(
                            quantity, symbol, price)
                    elif order_type == 'LOC':
                        o = self.of.generate_loc_order(quantity, symbol, price)
                    elif order_type == 'MOC':
                        o = self.of.generate_moc_order(quantity, symbol)
                    elif order_type == 'LIMIT' or order_type == 'LMT':
                        o = self.of.generate_limit_order(
                            quantity, symbol, price)
                    if o:
                        return '1'
                    else:
                        return '0'
                if inp == 'b':
                    return 'b'
                else:
                    self.print2('order not submitted: {}'.format(order_string))
                    sys.stdout.flush()
                return ''
            else:
                self.print2('Load sheet first. (cmd = load sheet)')
                sys.stdout.flush()
                return 'b'
        except Exception as e:
            self.print2('row {} failed to submit: {}'.format(r + 1, e))
            sys.stdout.flush()

    def submit_our_moc_row(self, r, confirm=False):

        try:
            if self.google_sheet:
                row = self.google_sheet.sheet[r - 1]
                self.print2(row)
                sys.stdout.flush()

                symbol = row[1].split()[0].upper()
                if symbol == '':
                    return
                if row[3] == '':
                    self.print2(
                        "Row doesn't have quantity. Enter quantity and reload sheet."
                    )
                    sys.stdout.flush()
                    return
                quantity = int(row[3])
                if row[2] == '':
                    return
                side = 'sell' if (row[2].upper() == 'LONG' or row[2].upper()
                                  == 'BUY' or row[2].upper() == 'B') else 'buy'
                if side == 'sell':
                    quantity *= -1
                order_type = 'MOC'
                price = 0
                order_string = '{} {} {} {} {}'.format(side, abs(quantity),
                                                       symbol, price,
                                                       order_type)
                if confirm:
                    sys.stdout.write('{} {} {} {} {}? (y/n/b)'.format(
                        side, abs(quantity), symbol, price, order_type))
                    sys.stdout.flush()
                    inp = raw_input()
                else:
                    inp = 'y'

                if inp == 'y':
                    o = 0
                    if order_type == 'MOC':
                        o = self.of.generate_moc_order(quantity, symbol)
                    time.sleep(.05)
                    if o:
                        return '1'
                    else:
                        return '0'
                if inp == 'b':
                    return 'b'
                else:
                    self.print2('order not submitted: {}'.format(order_string))
                    sys.stdout.flush()
                return ''
            else:
                self.print2('Load sheet first. (cmd = load sheet)')
                sys.stdout.flush()
                return 'b'
        except Exception as e:
            self.print2('row {} failed to submit: {}'.format(r + 1, e))
            sys.stdout.flush()
示例#23
0
文件: cv7seg.py 项目: 12019/cv7seg.py
class LoggingUI(TimedFrame):
    u'''ロギング用UI'''
    def __init__(self, *args, **kwargs):
        TimedFrame.__init__(self, *args, **kwargs)
        self.pack()
        self.init()
        self.startTimer()
    
    def init(self):
        if not config.normalize.points:
            self._label = tk.Label(self, text = u'まだ正規化が済んでいません。\n正規化を行ってください。')
            self._label.pack()
            return

        if not config.template.images or len(config.template.images) < 10 or not all(config.template.images):
            self._label = tk.Label(self, text = u'まだ学習が済んでいません。\n学習を行ってください。')
            self._label.pack()
            return
        
        # テンプレートの読み込み
        self.loadTemplates()
        
        # カメラの準備
        self._camera = cv.CaptureFromCAM(config.camera.id)
        
        # 左側UI
        frame1 = tk.Frame(self)
        frame1.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)
        
        # カメラ画像表示用Canvasなどの準備
        self._cvmat = None
        self._image = tk.PhotoImage(width = config.canvas.width, height = config.canvas.height)
        self._canvas = tk.Canvas(frame1, width = config.canvas.width, height = config.canvas.height)
        self._canvas.create_image(config.canvas.width / 2, config.canvas.height / 2, image = self._image, tags = 'image')
        self._canvas.pack(expand = True, fill = tk.BOTH)
        
        # ボタン
        self._main_button = tk.Button(frame1)
        self._main_button.pack(side = tk.LEFT)
        self.logStop()
        self._reset_button = tk.Button(frame1, text = u'リセット', command = self.reset)
        self._reset_button.pack(side = tk.RIGHT)
        
        # 生データ表示領域
        self._textarea = ScrolledText(self, width = 6, height = 18)
        self._textarea.pack(side = tk.LEFT, expand = True)
        
        # 右側UI
        frame2 = tk.Frame(self)
        frame2.pack(side = tk.LEFT, expand = True, fill = tk.BOTH)
        
        # ログデータ表示領域
        self._graph = tk.Canvas(frame2, width = config.canvas.width, height = config.canvas.height, bg = 'white')
        self._graph.pack(expand = True, fill = tk.BOTH)
        self._bar_graph = BarGraph(A(width = config.canvas.width, height = config.canvas.height), config.logging.graph_max_count)
        
        # ボタン
        self._out_button = tk.Button(frame2, text = u'生データをコピー', command = self.datacopy)
        self._out_button.pack(side = tk.LEFT)
        self._gchart_button = tk.Button(frame2, text = u'Google Chart URLをコピー', command = self.gchart)
        self._gchart_button.pack(side = tk.RIGHT)
        
        # 画像をフィルタするための変数
        self._clip_rect, self._perspective_points = Points2Rect(config.normalize.points)
        
        # ロギング開始、停止のフラグ
        self._take_log = False
        
        # ログ
        self._log = []
        
        # カメラ画像の更新を1秒間隔にする
        self.addTiming(self.showImage, 1)
    
    def setValue(self, value):
        if value is None: value = 0
        self._bar_graph.setValue(value)
        
        self._graph.delete('bar')
        for bar in self._bar_graph.getAllBars():
            self._graph.create_rectangle(
                bar.p1.x, bar.p1.y,
                bar.p2.x, bar.p2.y,
                fill = 'green', stipple = 'gray25',
                tags = 'bar'
            )
    
    def loadTemplates(self):
        u'''テンプレート画像の読み込み'''
        self._templates = []
        for i, cvimageinfo in enumerate(config.template.images):
            cvmat = cv.CreateMatHeader(cvimageinfo.rows, cvimageinfo.cols, cvimageinfo.type)
            cv.SetData(cvmat, cvimageinfo.data)
            self._templates.append(A(
                image = cv.GetImage(cvmat),
                number = i,
                result = None,
            ))
    
    def showImage(self):
        u'''カメラ画像の表示'''
        captured = cv.QueryFrame(self._camera)
        self._cvmat = self.filter(captured)
        self._image = CvMat2TkImage(self._cvmat)
        self._canvas.itemconfigure('image', image = self._image)
        if self._take_log:
            self.logging()
    
    def logging(self):
        u'''ログを取る'''
        target = self._cvmat
        digits_sieve = DigitsSieve()
        for template in self._templates:
            if not template.result:
                # マッチング結果保存用領域の準備
                template.result = cv.CreateImage(
                    (target.width - template.image.width + 1, target.height - template.image.height + 1),
                    cv.IPL_DEPTH_32F, 1,
                )
            
            cv.MatchTemplate(target, template.image, template.result, config.logging.match_method)

            # 数値の読み取り
            minVal, maxVal, minLoc, maxLoc = cv.MinMaxLoc(template.result)
            while maxVal > config.logging.match_threshold:
                # 検出された数値情報の保持
                digits_sieve.push(A(
                    number = template.number,
                    x = maxLoc[0],
                    y = maxLoc[1],
                    width = template.image.width,
                    height = template.image.height,
                    score = maxVal,
                ))
                
                # 現在の位置周辺のスコアをクリアし、次にスコアの高い位置を取得する
                SetReal2DAround(template.result, maxLoc, config.logging.match_exclusion_size, 0.0)
                minVal, maxVal, minLoc, maxLoc = cv.MinMaxLoc(template.result)
        
        value = digits_sieve.getValue()
        if value is not None:
            self._log.append(value)
            self.setValue(value)
            self._textarea.insert(tk.END, '%d\n' % value)
            self._textarea.see(tk.END)

    def logStart(self):
        u'''ロギングを開始する'''
        self._main_button.configure(text = u'ストップ', command = self.logStop)
        self._take_log = True
        
    def logStop(self):
        u'''ロギングを停止する'''
        self._main_button.configure(text = u'スタート', command = self.logStart)
        self._take_log = False
    
    def reset(self):
        u'''リセット'''
        self._bar_graph.init()
        self.setValue(0)
        self._log = []
        self._textarea.delete('1.0', tk.END)
    
    def datacopy(self):
        u'''生データをクリップボードにコピーする'''
        text = self._textarea.get('1.0', tk.END)
        self.clipboard_clear()
        self.clipboard_append(text)
    
    def gchart(self):
        u'''Google Chart API用のURLをクリップボードにコピーする'''
        if  self._log \
            and len(self._log) > 0 \
            and max(self._log) > 0:
                
                unit = float(4095) / max(self._log)
                url = gExtendedUrl(
                    map(lambda x: unit * x, self._log),
                    cht = 'bvs', # 棒グラフ
                    chxt = 'y', # y軸の目盛り表示
                    chxr = '0,0,%d' % max(self._log), # y軸の最小最大値
                    chg = '0,10,3,2', # 補助線
                    chbh = '%d,1' % (480 / len(self._log) - 1), # 棒グラフの棒の幅
                )
                self.clipboard_clear()
                self.clipboard_append(url)
        
    def filter(self, cvmat):
        u'''画像をフィルタする'''
        # サイズ調整
        thumbnail = cv.CreateMat(config.canvas.height, config.canvas.width, cv.CV_8UC3)
        cv.Resize(cvmat, thumbnail)
        return NormalizeImage(thumbnail, self._clip_rect, self._perspective_points)
示例#24
0
class TermWindow(Frame):
    ##
    # constructor method
    def __init__(self, master = None, **cnf):
        apply(Frame.__init__, (self, master), cnf)
        self.__create_widgets__()
        self.rxThread = None
        self.rxWaitEvent = threading.Event()
        self.rxWaitPattern = ""
        self.localEcho = False
        self.logFile = None
        self.textQueue = Queue.Queue()
        self.update_thread_safe()

    def update_thread_safe(self):
        try:
            while 1:
                element = self.textQueue.get_nowait()
                if element is not None:
                    msg,tag = element
                    self.__display__(msg,tag)
                self.st_trm.update_idletasks()
        except Queue.Empty:
            pass
        self.st_trm.after(100, self.update_thread_safe)

    ##
    # worker function for threaded reading from the input of
    # the assigned device
    #
    def __thrd_reader__(self):
        self.waitbuf = ""
        while 1:
            try:
                x = self.device.read()
                if len(x):
                    cmd = self.cmdVar.get()
                    if len(cmd):
                        self.cmdVar.set("")
                    self.write(x)
                    if self.rxWaitEvent.isSet():
                        self.waitbuf += x
                        if self.waitbuf.find(self.rxWaitPattern) > -1:
                            self.rxWaitEvent.clear()
                            while not self.rxWaitEvent.isSet():
                                pass
                            self.rxWaitEvent.clear()
            except:
                traceback.print_exc()
                time.sleep(1)
            else:
                # this infinitesimal sleep keeps the GUI update alive
                time.sleep(.01)

    def waitfor(self, pattern, maxwait=10):
        self.waitbuf = ""
        self.rxWaitPattern = pattern
        self.rxWaitEvent.set()
        self.maxwait = 10
        while self.rxWaitEvent.isSet() and self.maxwait > 0:
            time.sleep(1)
            self.maxwait -= 1
        if self.maxwait == 0:
            self.message("PatternNotFound")
        self.rxWaitEvent.set()

    ##
    #
    def __create_widgets__(self):
        dfl_font = 'Courier 10'

        # the title frame of the terminal
        self.f_title = Frame(self)
        self.f_title.pack(fill=BOTH)
        self.f_title.configure(FRAMEBORDER)
        self.shVar = StringVar()
        # show/hide button
        self.b_sh = Button(self.f_title, textvariable=self.shVar, font=dfl_font)
        self.b_sh.pack(side=RIGHT)
        self.b_sh['command'] = self.show_hide_cont
        # clear screen button
        self.b_cls = Button(self.f_title, text="CLS", font=dfl_font, underline=0)
        self.b_cls.pack(side=RIGHT)
        self.b_cls['command'] = self.clear_screen
        # echo on/off button
        self.al_echo = Label(self.f_title, text = "ECHO", relief = RAISED,
                             font = dfl_font, padx='3m', pady='1m', underline=0)
        self.al_echo.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_echo.bind("<Button-1>", self.__echo_handler__)
        # log on/off button
        self.al_log = Label(self.f_title, text = "LOG", relief = RAISED,
                            font = dfl_font, padx='3m', pady='1m', underline=0)
        self.al_log.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_log.bind("<Button-1>", self.__log_handler__)
        # device connect button
        self.al_connect = Label(self.f_title, text = "CONNECT", relief = RAISED,
                                font = dfl_font, padx='3m', pady='1m', underline=1)
        self.al_connect.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_connect.bind("<Button-1>", self.__connect_handler__)

        self.mb_macros = Menubutton(self.f_title, text = "Macros", relief=RAISED)
        self.mb_macros.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.mb_macros.menu = Menu(self.mb_macros, tearoff = 0)
        self.mb_macros["menu"] = self.mb_macros.menu


        # title of terminal window
        self.tVar = StringVar()
        self.l_title = Label(self.f_title, text="foo", font=dfl_font)
        self.l_title['textvariable'] = self.tVar
        self.l_title.pack(side=LEFT, expand=1, fill=X)
        self.l_title['width'] = 42
        self.update_title("------ XXX ------")
        # frame for scrolled text window
        # (this frame handle needs to be kept fo show_hide_cont())
        self.f_cont = Frame(self)
        # IO data scrolled text window
        self.st_trm = ScrolledText(self.f_cont, height=10, state=DISABLED, wrap=NONE)
        self.st_trm.pack(expand=1,fill=BOTH)
        self.st_trm['font'] = dfl_font
        self.st_trm.tag_config('E', foreground="blue")
        self.st_trm.tag_config('M', foreground="magenta")


        tframe = Frame(self.f_cont)
        tframe.pack(expand = 0, fill = X)
        self.cmdVar = StringVar()
        self.ent_trm = Entry(tframe, textvariable=self.cmdVar, font=dfl_font)
        self.ent_trm.pack(side=LEFT, expand =1, fill = X)
        self.ent_trm.bind("<Control-l>", self.__log_handler__)
        self.ent_trm.bind("<Control-e>", self.__echo_handler__)
        self.ent_trm.bind("<Control-o>", self.__connect_handler__)
        self.ent_trm.bind("<Control-c>", self.clear_screen)
        self.ent_trm.bind("<Control-x>", self.show_hide_cont)
        self.ent_trm.bind("<Control-m>", lambda *args: self.do_macro("M"))
        self.ent_trm.bind("<KeyPress>", self.__input_handler__)

        self.gui_elements = [ self.b_sh,
                              self.b_cls,
                              self.al_echo,
                              self.al_log,
                              self.al_connect,
                              self.mb_macros,
                              self.l_title,
                              self.st_trm,
                              self.ent_trm]
        self.show_cont()

    def add_macro(self, id, title, text = None, function = None, params = None):
        if text:
            cmd = lambda *args: self.do_macro(text)
        if function:
            user_func = eval(function)
            params = eval(str(params))
            cmd = lambda *args: user_func(DEVICES, **params)
        mb = self.mb_macros.menu.add_command(label = title, command = cmd)

    def _configure_(self,**args):
        for e in self.gui_elements:
            e.configure(args)

    def __input_handler__(self, *args):
        for i in args:
            if self.localEcho:
                self.display(i.char, "E")
            if len(i.char):
                if i.char == "\r":
                    self.device.write("\r\n")
                    self.cmdVar.set("")
                else:
                    self.device.write(i.char)

    def __echo_handler__(self, *args):
        if self.localEcho:
            self.localEcho = False
            self.al_echo['relief'] = RAISED
            self.message("Local Echo OFF")
        else:
            self.localEcho = True
            self.al_echo['relief'] = SUNKEN
            self.message("Local Echo ON")

    def __log_handler__(self, *args):
        try:
            do_open = self.logFile.closed
            logname = self.logFile.name
        except:
            do_open = True
            logname = ""
        if do_open:
            if self.device.logname:
                logname = self.device.logname
                self.message("logfile from config file %s " % logname)
            else:
                fd = FileDialog(self)
                logname = fd.go(logname)
            try:
                if self.device.logmode not in "wa":
                    self.device.logmode = "a"
                    print "force _a_ppend"
                self.logFile = open(logname, self.device.logmode)
                self.al_log['relief'] = SUNKEN
                self.message("Logging ON: %s" % self.logFile.name)
            except:
                self.message("Error open logfile: %s" % logname)

        else:
            self.message("Logging OFF: %s" % self.logFile.name)
            self.logFile.flush()
            self.logFile.close()
            self.al_log['relief'] = RAISED

    def __connect_handler__(self, *args):
        if self.device.isConnected:
            self.device.disconnect()
            self.al_connect['relief'] = RAISED
            self.message("Disconnected")
        else:
            try:
                self.device.connect()
                self.al_connect['relief'] = SUNKEN
                self.message("Connected")
                self.al_connect['fg'] = "black"
            except:
                self.device.isConnected = False
                self.message( str(sys.exc_info()[1]) )
                self.al_connect['fg'] = "red"

    def clear_screen(self, *args):
        self.st_trm['state'] = NORMAL
        self.st_trm.delete("0.0",END)
        self.st_trm['state'] = DISABLED

    def set_device(self,device):
        self.device = device
        self.rxThread = threading.Thread(target = self.__thrd_reader__)
        # if a thread is not a daemon, the program needs to join all
        self.rxThread.setDaemon(1)
        print "**",self.device, self.device.name
        self.rxThread.setName("GUI_RX_%s" % self.device.name)
        self.rxThread.start()
        self.update_title(self.device)
        #
        if self.device.echo:
            self.localEcho = 0
            self.__echo_handler__()
        if self.device.log:
            self.__log_handler__()
        if self.device.auto_connect:
            self.__connect_handler__()

    def update_title(self, title):
        self.tVar.set(title)

    def show_cont(self):
        self.shVar.set("X")
        self.f_cont.pack(expand=1,fill=BOTH)

    def hide_cont(self):
        self.shVar.set("+")
        self.f_cont.pack_forget()

    def show_hide_cont(self, *args):
        if self.shVar.get() == "X":
            self.hide_cont()
        else:
            self.show_cont()

    def do_macro(self, *args):
        if self.localEcho:
            self.display(args[0] + "\n", "E")
        self.device.write(args[0]+ "\n")

    def write(self, data):
        self.textQueue.put((data, None))

    def message(self, text, tag='M'):
        msg = "[%s:%s:%s]\n" % (time.asctime(),self.device.name, text)
        if self.st_trm.index(AtInsert()).find(".0")  < 1:
            msg = "\n" + msg
        self.textQueue.put((msg, tag))

    def display(self, text, tag = None):
        self.textQueue.put((text, tag))

    def __display__(self, msg, tag = None):
        self.st_trm['state'] = NORMAL
        here =  self.st_trm.index(AtInsert())
        for d in re.split("([\r\v\t\n])", msg):
            if len(d):
                if d != '\r':
                    self.st_trm.insert(END, d)
        if tag:
            self.st_trm.tag_add(tag, here, AtInsert())
        self.st_trm.see(END)
        self.st_trm['state'] = DISABLED
        try:
            self.logFile.write(msg)
            self.logFile.flush()
        except:
            pass
示例#25
0
class ExportApp(Frame):
    """GUI version of the Phoshare tool."""

    def __init__(self, master=None):
        """Initialize the app, setting up the UI."""
        Frame.__init__(self, master, padding=10)

        top = self.winfo_toplevel()
        menu_bar = Menu(top)
        top["menu"] = menu_bar

        apple = Menu(menu_bar, name='apple')
        menu_bar.add_cascade(label='Phoshare', menu=apple)
        apple.add_command(label="About Phoshare", command=self.__aboutHandler)

        sub_menu = Menu(menu_bar, name='help')
        menu_bar.add_cascade(label="Help", menu=sub_menu)
        sub_menu.add_command(label="Phoshare Help", command=self.help_buttons)

        self.thread_queue = Queue.Queue(maxsize=100)
        self.active_library = None

        top.columnconfigure(0, weight=1)
        top.rowconfigure(0, weight=1)
        self.grid(sticky=N+S+E+W)

        self.valid_library = False
        self.exiftool = False

        self.iphoto_library = StringVar()
        self.iphoto_library_status = StringVar()
        self.browse_library_button = None
        self.export_folder = StringVar()

        self.library_status = None
        self.dryrun_button = None
        self.export_button = None
        self.text = None

        self.events = StringVar()
        self.albums = StringVar()
        self.smarts = StringVar()

        self.foldertemplate = StringVar()
        self.nametemplate = StringVar()
        self.captiontemplate = StringVar()

        self.update_var = IntVar()
        self.delete_var = IntVar()
        self.originals_var = IntVar()
        self.link_var = IntVar()
        self.folder_hints_var = IntVar()
        self.faces_box = None
        self.faces_var = IntVar()
        self.face_keywords_box = None
        self.face_keywords_var = IntVar()
        self.face_albums_var = IntVar()
        self.face_albums_text = StringVar()

        self.iptc_box = None
        self.iptc_all_box = None
        self.iptc_var = IntVar()
        self.iptc_all_var = IntVar()

        self.gps_box = None
        self.gps_var = IntVar()
        self.verbose_var = IntVar()

        self.info_icon = PhotoImage(file="info-b16.gif")

        self.create_widgets()

        # Set up logging so it gets redirected to the text area in the app.
        self.logging_handler = logging.StreamHandler(self)
        self.logging_handler.setLevel(logging.WARN)
        _logger.addHandler(self.logging_handler)

    def __aboutHandler(self):
        HelpDialog(self, """%s %s

  Copyright 2010 Google Inc.

http://code.google.com/p/phoshare""" % (phoshare_version.PHOSHARE_VERSION,
	phoshare_version.PHOSHARE_BUILD),
                   title="About Phoshare")

    def init(self):
        """Initializes processing by launching background thread checker and
           initial iPhoto library check."""
        self.thread_checker()
        if exiftool.check_exif_tool(sys.stdout):
            self.exiftool = True
            self.faces_box.configure(state=NORMAL)
            self.face_keywords_box.configure(state=NORMAL)
            self.iptc_box.configure(state=NORMAL)
            self.iptc_all_box.configure(state=NORMAL)
            self.gps_box.configure(state=NORMAL)

        options = self.Options()
        options.load()
        self.init_from_options(options)
        self.check_iphoto_library()

    def init_from_options(self, options):
        """Populates the UI from options."""
        self.iphoto_library.set(options.iphoto)
        self.export_folder.set(options.export)
        self.albums.set(su.fsdec(options.albums))
        self.events.set(su.fsdec(options.events))
        self.smarts.set(su.fsdec(options.smarts))
        self.foldertemplate.set(su.unicode_string(options.foldertemplate))
        self.nametemplate.set(su.unicode_string(options.nametemplate))
        self.captiontemplate.set(su.unicode_string(options.captiontemplate))
        self.update_var.set(_int_from_bool(options.update))
        self.delete_var.set(_int_from_bool(options.delete))
        self.originals_var.set(_int_from_bool(options.originals))
        self.link_var.set(_int_from_bool(options.link))
        self.folder_hints_var.set(_int_from_bool(options.folderhints))
        self.faces_var.set(_int_from_bool(options.faces) and self.exiftool)
        self.face_keywords_var.set(_int_from_bool(options.face_keywords) and
                                   self.exiftool)
        self.face_albums_var.set(_int_from_bool(options.facealbums))
        self.face_albums_text.set(options.facealbum_prefix)
        if options.iptc and self.exiftool:
            self.iptc_var.set(1)
            if options.iptc == 2:
                self.iptc_all_var.set(1)
        self.gps_var.set(_int_from_bool(options.gps) and self.exiftool)

    def _add_section(self, container, text, help_command):
        """Adds a new UI section with a bold label and an info button.

        Args:
          container: UI element that will contain this new item
          row: row number in grid. Uses two rows.
          text: label frame text.
          help_command: command to run when the info button is pressed.
        Returns: tuple of new section and content frames.
        """
        section_frame = Frame(container)
        section_frame.columnconfigure(0, weight=1)
        label = Label(section_frame, text=text)
        label.config(font=_BOLD_FONT)
        label.grid(row=0, column=0, sticky=W, pady=5)
        Button(section_frame, image=self.info_icon,
               command=help_command).grid(row=0, column=1, sticky=E)

        content_frame = Frame(section_frame)
        content_frame.grid(row= 1, column=0, columnspan=2, sticky=N+S+E+W, pady=5)

        return (section_frame, content_frame)

    def _create_button_bar(self, container, row):
        """Creates the button bar with the Dry Run and Export buttons.

        Args:
          row: row number in grid.
        Returns: next row number in grid.
        """
        button_bar = Frame(container)
        button_bar.grid(row=row, column=0, sticky=E+W, padx=10)
        button_bar.columnconfigure(0, weight=1)
        verbose_box = Checkbutton(button_bar, text="Show debug output", var=self.verbose_var)
        verbose_box.grid(row=0, column=0, sticky=E)
        self.dryrun_button = Button(button_bar, text="Dry Run",
                                    command=self.do_dryrun, state=DISABLED)
        self.dryrun_button.grid(row=0, column=1, sticky=E, pady=5)
        self.export_button = Button(button_bar, text="Export",
                                    command=self.do_export, state=DISABLED)
        self.export_button.grid(row=0, column=2, pady=5)
        return row + 1

    def _create_library_tab(self, library_tab):
        library_tab.columnconfigure(0, weight=1)
        row = 0

        f = Frame(library_tab)
        f.grid(row=row, columnspan=2, stick=E+W, padx=5, pady=5)
        row += 1
        f.columnconfigure(1, weight=1)

        Label(f, text="iPhoto Library:").grid(sticky=E)
        iphoto_library_entry = Entry(f, textvariable=self.iphoto_library)
        iphoto_library_entry.grid(row=0, column=1, sticky=E+W)
        self.browse_library_button = Button(f, text="Browse...",
                                            command=self.browse_library)
        self.browse_library_button.grid(row=0, column=2)

        self.library_status = Label(f, textvariable=self.iphoto_library_status)
        self.library_status.grid(row=1, column=1, sticky=W)

        (cf, lf) = self._add_section(library_tab, "Events, Albums and Smart Albums",
                                     self.help_events)
        cf.grid(row=row, columnspan=2, stick=E+W)
        row += 1
        lf.columnconfigure(1, weight=1)
        Label(lf, text="Events:").grid(sticky=E)
        events_entry = Entry(lf, textvariable=self.events)
        events_entry.grid(row=0, column=1, sticky=EW)

        Label(lf, text="Albums:").grid(sticky=E)
        albums_entry = Entry(lf, textvariable=self.albums)
        albums_entry.grid(row=1, column=1, sticky=EW)

        Label(lf, text="Smart Albums:").grid(sticky=E)
        smarts_entry = Entry(lf, textvariable=self.smarts)
        smarts_entry.grid(row=2, column=1, columnspan=3, sticky=EW)

    def _create_files_tab(self, files_tab):
        files_tab.columnconfigure(0, weight=1)
        # Export folder and options
        row = 0
        (cf, lf) = self._add_section(files_tab, "Export Folder and Options", self.help_export)
        cf.grid(row=row, columnspan=2, stick=E+W)
        row += 1
        lf.columnconfigure(1, weight=1)
        label = Label(lf, text="Export Folder:")
        label.grid(sticky=E)
        export_folder_entry = Entry(lf, textvariable=self.export_folder)
        export_folder_entry.grid(row=0, column=1, columnspan=2, sticky=E+W)
        Button(lf, text="Browse...",
               command=self.browse_export).grid(row=0, column=3)

        update_box = Checkbutton(lf, text="Overwrite changed pictures",
                                 var=self.update_var)
        update_box.grid(row=1, column=1, sticky=W)
        originals_box = Checkbutton(lf, text="Export originals",
                                    var=self.originals_var)
        originals_box.grid(row=2, column=1, sticky=W)
        hint_box = Checkbutton(lf, text="Use folder hints",
                               var=self.folder_hints_var)
        hint_box.grid(row=3, column=1, sticky=W)

        delete_box = Checkbutton(lf, text="Delete obsolete pictures",
                                 var=self.delete_var)
        delete_box.grid(row=4, column=1, sticky=W)
        link_box = Checkbutton(lf, text="Use file links", var=self.link_var)
        link_box.grid(row=5, column=1, sticky=W)

        # Templates ----------------------------------------
        (cf, lf) = self._add_section(files_tab, "Name Templates", self.help_templates)
        cf.grid(row=row, columnspan=2, stick=E+W)
        row += 1
        lf.columnconfigure(1, weight=1)
        Label(lf, text="Folder names:").grid(sticky=E)
        foldertemplate_entry = Entry(lf, textvariable=self.foldertemplate)
        foldertemplate_entry.grid(row=0, column=1, sticky=EW)

        Label(lf, text="File names:").grid(sticky=E)
        nametemplate_entry = Entry(lf, textvariable=self.nametemplate)
        nametemplate_entry.grid(row=1, column=1, sticky=EW)

        Label(lf, text="Captions:").grid(sticky=E)
        captiontemplate_entry = Entry(lf, textvariable=self.captiontemplate)
        captiontemplate_entry.grid(row=2, column=1, sticky=EW)

    def _create_metadata_tab(self, metadata_tab):
        metadata_tab.columnconfigure(0, weight=1)
        row = 0
        # Metadata --------------------------------------------
        (cf, lf) = self._add_section(metadata_tab, "Metadata", self.help_metadata)
        cf.grid(row=row, columnspan=2, stick=E+W)
        row += 1
        self.iptc_box = Checkbutton(lf,
                                    text=("Export metadata (descriptions, "
                                          "keywords, ratings, dates)"),
                                    var=self.iptc_var, state=DISABLED,
                                    command=self.change_iptc_box)
        self.iptc_box.grid(row=0, column=0, columnspan=2, sticky=W)

        self.iptc_all_box = Checkbutton(lf,
                                        text="Check previously exported images",
                                        var=self.iptc_all_var,
                                        command=self.change_metadata_box,
                                        state=DISABLED)
        self.iptc_all_box.grid(row=1, column=0, sticky=W)

        self.gps_box = Checkbutton(lf,
                                   text="Export GPS data",
                                   var=self.gps_var,
                                   command=self.change_metadata_box,
                                   state=DISABLED)
        self.gps_box.grid(row=2, column=0, sticky=W)

        # Faces ---------------------------------------------------
        (cf, lf) = self._add_section(metadata_tab, "Faces", self.help_faces)
        cf.grid(row=row, columnspan=2, stick=E+W)
        row += 1
        lf.columnconfigure(2, weight=1)
        self.faces_box = Checkbutton(lf, text="Copy faces into metadata",
                                     var=self.faces_var, state=DISABLED,
                                     command=self.change_metadata_box)
        self.faces_box.grid(row=0, column=0, sticky=W)

        self.face_keywords_box = Checkbutton(
            lf,
            text="Copy face names into keywords",
            var=self.face_keywords_var,
            command=self.change_metadata_box,
            state=DISABLED)
        self.face_keywords_box.grid(row=1, column=0, sticky=W)

        checkbutton = Checkbutton(lf, text="Export faces into folders",
                                  var=self.face_albums_var)
        checkbutton.grid(row=2, column=0, sticky=W)
        label = Label(lf, text="Faces folder prefix:")
        label.grid(row=2, column=1, sticky=E)
        entry = Entry(lf, textvariable=self.face_albums_text)
        entry.grid(row=2, column=2, sticky=E+W)

    def create_widgets(self):
        """Builds the UI."""
        self.columnconfigure(0, weight=1)
        n = Notebook(self)
        n.grid(row=0, sticky=E+W+N+S)

        library_tab = Frame(n)
        n.add(library_tab, text='Library')
        self._create_library_tab(library_tab)

        files_tab = Frame(n)
        n.add(files_tab, text='Files')
        self._create_files_tab(files_tab)

        metadata_tab = Frame(n)
        n.add(metadata_tab, text='Metadata')
        self._create_metadata_tab(metadata_tab)

        self._create_button_bar(self, 1)

        self.text = ScrolledText(self, borderwidth=4, relief=RIDGE, padx=4,
                                 pady=4)
        self.text.grid(row=2, column=0, sticky=E+W+N+S)
        self.rowconfigure(2, weight=1)

    def change_iptc_box(self):
        """Clears some options that depend on the metadata export option."""
        mode = self.iptc_var.get()
        if not mode:
            self.faces_var.set(0)
            self.face_keywords_var.set(0)
            self.iptc_all_var.set(0)
            self.gps_var.set(0)

    def change_metadata_box(self):
        """Sets connected options if an option that needs meta data is changed.
        """
        mode = (self.faces_var.get() or self.face_keywords_var.get() or
                self.iptc_all_var.get() or self.gps_var.get())
        if mode:
            self.iptc_var.set(1)

    def help_events(self):
        HelpDialog(self, """Events, Albums and Smart Albums

Selects which events, albums, or smart albums to export.

Each field is a regular expression, and at least one must be filled in.
Matches are done against the beginning of the event or album name. An
entry in Events of
    Family
will export all events that start with "Family", including "Family 2008"
and "Family 2009". "|" separates alternate patterns, so
    Family|Travel
will export all events that start with either "Family" or "Travel".

"." matches any character, and therefore,
    .
will export all events. To export all events with "2008" in the name, use
    .*2008

For more details on regular expressions, see
    http://en.wikipedia.org/wiki/Regular_expression""")

    def help_templates(self):
        HelpDialog(self, """Folder, file, and image caption templates.

Templates are strings with place holders for values. The place holders have
the format "{name}". Everything else in the template will be copied. Examples:
  {title}
  {yyyy}/{mm}/{dd} {title} - generates "2010/12/31 My Birthday" if the date
      of the pictures is Dec 31, 2010, and the title is "My Birthday".
  {yyyy} Event: {event} - generates "2010 Event: Birthday" for an event with
      any date in 2010 and the name "Birthday".

Available place holders for folder names:
  {name} - name of the album or event.
  {hint} - folder hint (taken from line event or album description starting with
           @).
  {yyyy} - year of album or event date.
  {mm} - month of album or event date.
  {dd} - date of album or event date.

Available place holders for file names:
  {album} - name of album (or in the case of an event, the name of the event).
  {index} - number of image in album, starting at 1.
  {index0} - number of image in album, padded with 0s, so that all numbers have
             the same length.
  {event} - name of the event. In the case of an album, the name of the event
            to which the image belongs.
  {event_index} - number of image in the event, starting at 1. If the case of an
                  album, this number will be based on the event to which the
                  image belongs.
  {event_index0} - same as {event_index}, but padded with leading 0s so that all
                   values have the same length.
  {title} - image title.
  {yyyy} - year of image.
  {mm} - month of image (01 - 12).
  {dd} - day of image (01 - 31).

  If you are using {album}/{index}/{index0} place holders, the image will be
  named based on whatever album or event it is contained. That means an image
  in two albums will be exported with different names, even so the files are
  identical. If you want to use the same name for each image, regardless of
  which album it is in, use {event}, {event_index}, and {event_index0} instead.

Available place holders for captions:
  {title} - image title.
  {description} - image description.
  {title_description} - concatenated image title and description, separated by a
                        : if both are set.
  {yyyy} - year of image.
  {mm} - month of image (01 - 12).
  {dd} - day of image (01 - 31).
""")

    def help_buttons(self):
        HelpDialog(self, """Export modes.

Click on "Dry Run" to see what Phoshare would do without actually modifying any
files.

Click on "Export" to export your files using the current settings.

All your settings will be saved when you click either Dry Run and Export, and
re-loaded if you restart Phoshare.

Check "Show debug output" to generate additional output message that can assist
in debugging Phoshare problems.
""")

    def help_export(self):
        HelpDialog(self, """Export Settings

Export Folder: path to the folder for exporting images.

Overwrite changed pictures: If set, pictures that already exist in the export
                            folder will be overriden if an different version
                            exist in iPhoto. Any edits made to previously
                            exported images in the export folder will be lost!
                            Use Dry Run to see which files would be overwritten.

Export originals: If set, and an image has been modified in iPhoto, both the
                  original and the edited version will be exported. The original
                  will be stored in a sub-folder called "Originals".

Use folder hints: By default, each exported event or album will become a folder
                  in the export folder. With folder hints, a sub-folder name can
                  be given in the event or album description by adding a line
                  starting with a @ character. Example:
                      Family Vacation
                      @Vacation
                  would export all images in that event into a sub-folder called
                  "Vacation".

Delete obsolete pictures: If set, any image, movie file or folder in the export
                          folder that does not exist in the iPhoto library will
                          be deleted. Use Dry Run to see which files would be
                          deleted.

Use file links: Don't copy images during export, but make a link to the files
                in the iPhoto library instead. This option is only available
                if the export folder is on the same drive as the iPhoto library.
                This option will save a lot of disk space because it avoids
                making copies of all your images and videos. Using this option
                causes the metadata of the images IN YOUR IPHOTO LIBRARY to be
                modified. While phoshare should not cause any problems to your
                images, it is best to use this option only if you have a backup
                of your iPhoto library, and you know how to restore your library
                from the backup. For more details on link mode, see
                https://sites.google.com/site/phosharedoc/Home#TOC-link-mode""")

    def help_faces(self):
        HelpDialog(self, """Faces options.

Copy faces into metadata: faces tags and face regions will be copied into the
                          image metadata using the Microsoft Photo Region
                          Schema:
               http://msdn.microsoft.com/en-us/library/ee719905(VS.85).aspx

Copy faces names into keywords: If set, face names will be merged into image
                                keywords. Requires "Export metadata" checked.

Export faces into folders: If checked, folders will be created for each face
                           tag, each containing all the images tagged with
                           that person.

Faces folder prefix: If set, the string will be used as a prefix for the
                     face export folders if "Exported faces into folders"
                     is checked. This can be just a value like "Face: ", or
                     a sub-folder name like "Faces/" if it ends with a "/"

Metadata options will be disabled if exiftool is not available.
""")

    def help_metadata(self):
        HelpDialog(self, """Metadata options.

Export metadata: sets the description, keywords, rating and date metadata in the
                 exported images to match the iPhoto settings.

Check previously exported images: If not checked, metadata will only be set for new or
                        updated images. If checked, metadata will be checked in
                        all images, including ones that were previously
                        exported. This is much slower.

Export GPS data: export the GPS coordinates into the image metadata.

Metadata options will be disabled if exiftool is not available.""")

    def check_iphoto_library(self):
        self.valid_library = False
        self.enable_buttons()
        self.iphoto_library_status.set("Checking library location...")
        self.launch_export("library")

    def set_library_status(self, good, message):
        if good:
            self.valid_library = True
        self.enable_buttons()
        self.iphoto_library_status.set(message)

    def write_progress(self, text):
        self.text.insert(END, text)
        self.text.see(END)

    def enable_buttons(self):
        if self.valid_library:
            self.dryrun_button.config(state=NORMAL)
            self.export_button.config(state=NORMAL)
        else:
            self.dryrun_button.config(state=DISABLED)
            self.export_button.config(state=DISABLED)
        self.browse_library_button.config(state=NORMAL)

    def browse_library(self):
        path = tkFileDialog.askopenfilename(title="Locate iPhoto Library")
        self.iphoto_library.set(path)
        self.check_iphoto_library()

    def browse_export(self):
        path = tkFileDialog.askdirectory(title="Locate Export Folder")
        self.export_folder.set(path)

    def do_export(self):
        if self.active_library:
            self.stop_thread()
            return
        if not self.can_export():
            return
        self.export_button.config(text="Stop Export")
        self.dryrun_button.config(state=DISABLED)
        self.run_export(False)

    def do_dryrun(self):
        if self.active_library:
            self.stop_thread()
            return
        if not self.can_export():
            return
        self.dryrun_button.config(text="Stop Dry Run")
        self.export_button.config(state=DISABLED)
        self.run_export(True)

    def stop_thread(self):
        if self.active_library:
            self.active_library.abort()

    def export_done(self):
        self.active_library = None
        self.dryrun_button.config(text="Dry Run")
        self.export_button.config(text="Export")
        self.enable_buttons()

    class Options(object):
        """Simple helper to create an object compatible with the OptionParser
        output in Phoshare.py."""

        def __init__(self):
            self.iphoto = '~/Pictures/iPhoto Library'
            self.export = '~/Pictures/Album'
            self.albums = ''
            self.events = '.'
            self.smarts = ''
            self.ignore = []
            self.delete = False
            self.update = False
            self.link = False
            self.dryrun = False
            self.folderhints = False
            self.captiontemplate = u'{description}'
            self.foldertemplate = u'{name}'
            self.nametemplate = u'{title}'
            self.aperture = False # TODO
            self.size = ''  # TODO
            self.picasa = False  # TODO
            self.movies = True  # TODO
            self.originals = False
            self.iptc = 0
            self.gps = False
            self.faces = False
            self.facealbums = False
            self.facealbum_prefix = ''
            self.face_keywords = False
            self.verbose = False

        def load(self):
            """Attempts to load saved options. Returns True if saved options
            were available."""
            if not os.path.exists(_CONFIG_PATH):
                return False
            config = ConfigParser.SafeConfigParser()
            config.read(_CONFIG_PATH)
            s = 'Export1'
            if config.has_option(s, 'iphoto'):
                self.iphoto = config.get(s, 'iphoto')
            if config.has_option(s, 'export'):
                self.export = config.get(s, 'export')
            if config.has_option(s, 'albums'):
                self.albums = config.get(s, 'albums')
            if config.has_option(s, 'events'):
                self.events = config.get(s, 'events')
            if config.has_option(s, 'smarts'):
                self.smarts = config.get(s, 'smarts')
            if config.has_option(s, 'foldertemplate'):
                self.foldertemplate = config.get(s, 'foldertemplate')
            if config.has_option(s, 'nametemplate'):
                self.nametemplate = config.get(s, 'nametemplate')
            if config.has_option(s, 'captiontemplate'):
                self.captiontemplate = config.get(s, 'captiontemplate')
            if config.has_option(s, 'delete'):
                self.delete = config.getboolean(s, 'delete')
            if config.has_option(s, 'update'):
                self.update = config.getboolean(s, 'update')
            if config.has_option(s, 'link'):
                self.link = config.getboolean(s, 'link')
            if config.has_option(s, 'folderhints'):
                self.folderhints = config.getboolean(s, 'folderhints')
            if config.has_option(s, 'captiontemplate'):
                self.nametemplate = unicode(config.get(s, 'captiontemplate'))
            if config.has_option(s, 'nametemplate'):
                self.nametemplate = unicode(config.get(s, 'nametemplate'))
            if config.has_option(s, 'size'):
                self.size = config.get(s, 'size')
            if config.has_option(s, 'picasa'):
                self.picasa = config.getboolean(s, 'picasa')
            if config.has_option(s, 'movies'):
                self.movies = config.getboolean(s, 'movies')
            if config.has_option(s, 'originals'):
                self.originals = config.getboolean(s, 'originals')
            if config.has_option(s, 'iptc'):
                self.iptc = config.getint(s, 'iptc')
            if config.has_option(s, 'gps'):
                self.gps = config.getboolean(s, 'gps')
            if config.has_option(s, 'faces'):
                self.faces = config.getboolean(s, 'faces')
            if config.has_option(s, 'facealbums'):
                self.facealbums = config.getboolean(s, 'facealbums')
            if config.has_option(s, 'facealbum_prefix'):
                self.facealbum_prefix = config.get(s, 'facealbum_prefix')
            if config.has_option(s, 'face_keywords'):
                self.face_keywords = config.getboolean(s, 'face_keywords')
            return True

        def save(self):
            """Saves the current options into a file."""
            config = ConfigParser.RawConfigParser()
            s = 'Export1'
            config.add_section(s)
            config.set(s, 'iphoto', self.iphoto)
            config.set(s, 'export', self.export)
            config.set(s, 'albums', su.fsenc(self.albums))
            config.set(s, 'events', su.fsenc(self.events))
            config.set(s, 'smarts', su.fsenc(self.smarts))
            config.set(s, 'foldertemplate', su.fsenc(self.foldertemplate))
            config.set(s, 'nametemplate', su.fsenc(self.nametemplate))
            config.set(s, 'captiontemplate', su.fsenc(self.captiontemplate))
            config.set(s, 'delete', self.delete)
            config.set(s, 'update', self.update)
            config.set(s, 'link', self.link)
            config.set(s, 'dryrun', self.dryrun)
            config.set(s, 'folderhints', self.folderhints)
            config.set(s, 'captiontemplate', self.captiontemplate)
            config.set(s, 'nametemplate', self.nametemplate)
            config.set(s, 'size', self.size)
            config.set(s, 'picasa', self.picasa)
            config.set(s, 'movies', self.movies)
            config.set(s, 'originals', self.originals)
            config.set(s, 'iptc', self.iptc)
            config.set(s, 'gps', self.gps)
            config.set(s, 'faces', self.faces)
            config.set(s, 'facealbums', self.facealbums)
            config.set(s, 'facealbum_prefix', self.facealbum_prefix)
            config.set(s, 'face_keywords', self.face_keywords)

            config_folder = os.path.split(_CONFIG_PATH)[0]
            if not os.path.exists(config_folder):
                os.makedirs(config_folder)
            configfile = open(_CONFIG_PATH, 'wb')
            config.write(configfile)
            configfile.close()

    def can_export(self):
        if (not self.albums.get() and not self.events.get() and
            not self.smarts.get()):
            tkMessageBox.showerror(
                "Export Error",
                ("Need to specify at least one event, album, or smart album "
                 "for exporting."))
            return False
        return True

    def run_export(self, dry_run):
        mode = "export"
        if dry_run:
            mode = "dry_run"
        self.launch_export(mode)

    def launch_export(self, mode):
        """Launch an export operation in a new thread, to not block the UI.

        Args:
            mode - name of operation to run, "library", "dry_run", or "export".
        """
        self.text.delete('1.0', END)
        self.browse_library_button.config(state=DISABLED)
        export_thread = threading.Thread(target=self.export_thread,
                                         args=(mode,))
        export_thread.start()

    def export_thread(self, mode):
        """Run an export operation in a thread, to not block the UI.

        Args:
            mode - name of operation to run, "library", "dry_run", or "export".
        """
        try:
            # First, load the iPhoto library.
            library_path = su.expand_home_folder(self.iphoto_library.get())
            album_xml_file = iphotodata.get_album_xmlfile(library_path)
            data = iphotodata.get_iphoto_data(album_xml_file)
            msg = "Version %s library with %d images" % (
                data.applicationVersion, len(data.images))
            self.write(msg + '\n')
            if mode == "library":
                # If we just need to check the library, we are done here.
                self.thread_queue.put(("done", (True, mode, msg)))
                return

            # Do the actual export.
            export_folder = su.expand_home_folder(self.export_folder.get())
            args = ['Phoshare.py', '--export', '"' + export_folder + '"']

            options = self.Options()
            options.iphoto = self.iphoto_library.get()
            args.extend(['--iphoto', '"' + options.iphoto + '"'])
            options.export = self.export_folder.get()
            options.dryrun = mode == "dry_run"
            options.albums = self.albums.get()
            if options.albums:
                args.extend(['--albums', '"' + options.albums + '"'])
            options.events = self.events.get()
            if options.events:
                args.extend(['--events', '"' + options.events + '"'])
            options.smarts = self.smarts.get()
            if options.smarts:
                args.extend(['--smarts', '"' + options.smarts + '"'])
            options.foldertemplate = unicode(self.foldertemplate.get())
            if options.foldertemplate:
                args.extend(['--foldertemplate', '"' +
                             options.foldertemplate + '"'])
            options.nametemplate = unicode(self.nametemplate.get())
            if options.nametemplate:
                args.extend(['--nametemplate', '"' +
                             options.nametemplate + '"'])
            options.captiontemplate = unicode(self.captiontemplate.get())
            if options.captiontemplate:
                args.extend(['--captiontemplate', '"' +
                             options.captiontemplate + '"'])
            options.ignore = []  # TODO
            options.update = self.update_var.get() == 1
            if options.update:
                args.append('--update')
            options.delete = self.delete_var.get() == 1
            if options.delete:
                args.append('--delete')
            options.originals = self.originals_var.get() == 1
            if options.originals:
                args.append('--originals')
            options.link = self.link_var.get() == 1
            if options.link:
                args.append('--link')
            options.folderhints = self.folder_hints_var.get() == 1
            if options.folderhints:
                args.append('--folderhints')
            options.faces = self.faces_var.get() == 1
            if options.faces:
                args.append('--faces')
            options.face_keywords = self.face_keywords_var.get() == 1
            if options.face_keywords:
                args.append('--face_keywords')
            if self.iptc_all_var.get() == 1:
                options.iptc = 2
                args.append('--iptcall')
            elif self.iptc_var.get() == 1:
                options.iptc = 1
                args.append('--iptc')
            else:
                options.iptc = 0
            options.gps = self.gps_var.get()
            if options.gps:
                args.append('--gps')
            options.facealbums = self.face_albums_var.get() == 1
            if options.facealbums:
                args.append('--facealbums')
            options.facealbum_prefix = self.face_albums_text.get()
            if options.facealbum_prefix:
                args.append('--facealbum_prefix')

            exclude = None # TODO

            options.save()
            print " ".join(args)

            self.logging_handler.setLevel(logging.DEBUG if self.verbose_var.get() else logging.INFO)
            self.active_library = phoshare_main.ExportLibrary(export_folder)
            phoshare_main.export_iphoto(self.active_library, data, exclude,
                                        options)
            self.thread_queue.put(("done", (True, mode, '')))
        except Exception, e:  # IGNORE:W0703
            self.thread_queue.put(("done",
                                   (False, mode,
                                    str(e) + '\n\n' + traceback.format_exc())))
示例#26
0
class LoggerDialog(Toplevel):
    def __init__(self, master, customers, payments, refresh):
        Toplevel.__init__(self,master)

        self.root = master
        self.refresh = refresh

        self.title("Check In")
        self.iconname = "Check In"

        self.name = StringVar() # variable for customer
        self.customers = customers # customers object
        self.payments = payments
        self.names = []
        self.workout = StringVar()
        self.workouts = []
        self.workouts_form = []
        self.date = StringVar()
        self.date.set(strftime("%m/%d/%Y"))
        self.refresh_time = 15 # in minutes
        self.output = '' # for the output label at the bottom
        self.schedule = Schedule()

        self.logger = Logger() #throws IOError if file is open

        inf = Frame(self)
        inf.pack(padx=10,pady=10,side='top')
        Label(inf, text="Name:").grid(row=0,column=0,sticky=E,ipady=2,pady=2,padx=10)
        Label(inf, text='Date:').grid(row=1,column=0,sticky=E,ipady=2,pady=2,padx=10)
        Label(inf, text="Workout:").grid(row=2,column=0,sticky=E,ipady=2,pady=2,padx=10)

        self.name_cb = Combobox(inf, textvariable=self.name, width=30,
                                values=self.names)
        self.name_cb.grid(row=0,column=1,sticky=W,columnspan=2)
        self.date_ent = Entry(inf, textvariable=self.date)
        self.date_ent.grid(row=1,column=1,sticky=W)
        self.date_ent.bind('<FocusOut>', self.update_workouts)
        Button(inf,text='Edit', command=self.enable_date_ent).grid(row=1,column=2,sticky=E)
        self.workout_cb = Combobox(inf, textvariable=self.workout, width=30,
                                   values=self.workouts_form,state='readonly')
        self.workout_cb.grid(row=2,column=1,sticky=W,columnspan=2)

        self.log_btn=Button(inf,text="Log Workout",command=self.log,width=12)
        self.log_btn.grid(row=3,column=1,columnspan=2,pady=4,sticky='ew')
        
        stf = Frame(self)
        stf.pack(padx=10,pady=10,fill='x',side='top')
        self.scrolled_text = ScrolledText(stf,height=15,width=50,wrap='word',state='disabled')
        self.scrolled_text.pack(expand=True,fill='both')

        self.update_workouts()
        self.update_names()

        self.bind('<Return>',self.log)
        self.name_cb.focus_set()  # set the focus here when created

        #disable the date field
        self.disable_date_ent()

        #start time caller
        self.time_caller()

    def output_text(self,outstr):
        self.scrolled_text['state'] = 'normal'
        self.scrolled_text.insert('end',outstr)
        self.scrolled_text.see('end')
        self.scrolled_text['state'] = 'disabled'

    def log(self, e=None):
        #check to see if name is blank
        logged = False
        if self.name.get() == '':
            self.output_text("! - Please select your name.\n")
        elif self.workout.get() not in self.workouts_form:
            self.output_text("! - Select valid workout.\n")
        elif self.name.get() not in self.names: # new customer
            self.new_customer_error()
        else: # log the workout
            name = self.name.get().split(' ',2)
            (line, r) = self.customers.find(name[2],name[0],name[1])
            name_str = str(self.name.get())
            date = datetime.strptime(str(self.date.get()),'%m/%d/%Y')

            if not line:
                self.output_text("!! - No record: " + self.name.get() + ".\n")

            while (not logged):
                try:
                    self.logger.log(self.workouts[self.workout_cb.current()][0],
                                    self.workouts[self.workout_cb.current()][1],
                                    name_str, day=date)
                    logged = True
                except IOError:
                    showerror("Error writting to file", "Please close " + self.logger.filename + " and press OK.")


            if logged:
                self.output_text(self.name.get() + " - " + line[3] + "\n")
                logged_payment = False
                while(not logged_payment):
                    try:
                        if line[3] == 'Monthly':
                            payment_due = self.payments.next_payment_due(name_str)
                            if payment_due < datetime.today():
                                self.output_text("$ - Please pay your monthly dues.\n")
                            else:
                                self.output_text("$ - Next payment due: " + payment_due.strftime("%B %d, %Y\n"))
                        elif line[3] == 'Punch Card':
                            punch = self.payments.punch(name_str)
                            if punch == 0:
                                self.output_text("$ - Last punch on card, please purchase another.\n")
                            elif not punch:
                                self.output_text("$ - Please purchase another punch card.\n")
                            else:
                                self.output_text("$ - You have " + str(punch) + " remaining workouts on your card.\n")
                        elif line[3] == 'Drop In':
                            self.payments.drop_in(name_str, date)
                            self.output_text("$ - Drop In payment logged.\n")
                        logged_payment = True
                    except IOError:
                        # this is bad, you logged a workout and you failed to log payment
                        showerror("Error writting to file", "Please close " + self.payments.filename + " and press OK.")
                    else:
                        #exception not raised
                        try: #accessing log file here
                            workout_count = str(workouts_this_month(name_str,self.logger.filename,date.strftime("%B"))) 
                            self.output_text("Workouts you've completed this month: " + workout_count + "\n")
                        except IOError:
                            showerror("Error reading from file", "Please close " + self.logger.filename + " and press OK.")

                self.refresh()
            
    def new_customer_error(self):
        self.ncd = NewCustomerDialog(self,self.customers,self.refresh)
        if askquestion(title="New Customer?",
            message="Add new customer: " + self.name.get(),
            parent = self) == 'yes':

            temp = self.name.get().split(' ')
            self.ncd.fname.set(temp[0])
            if len(temp) == 2:
                self.ncd.lname.set(temp[1])
            elif len(temp) == 3:
                self.ncd.mname.set(temp[1])
                self.ncd.lname.set(temp[2])
            elif len(temp) > 3:
                self.ncd.mname.set(temp[1])
                self.ncd.lname.set(' '.join(temp[2:4]))

            self.ncd.show()

        if self.ncd.new_customer_name:
            self.add_name(self.ncd.new_customer_name)
            self.output_text("+ - " + self.ncd.new_customer_name + " added.\n")

    def disable_date_ent(self, e=None):
        self.date_ent['state'] = 'disabled'

    def enable_date_ent(self, e=None):
        self.date_ent['state'] = 'normal'
        
    def time_caller(self):
        #updates every 15 min automatically
        msec = self.refresh_time * 6000

        self.update_time_now() #update time to current time
        self.set_workout_now()
        self.update_workouts() #update the workouts
        
        self.after(msec, self.time_caller) #call again

    def update_time_now(self):
        self.enable_date_ent()
        self.date.set(strftime("%m/%d/%Y"))

    def set_workout_now(self):
        #set workout field
        if len(self.workouts) == 0:
            self.disable_date_ent()
            return #no workouts
        index = 0
        now = datetime.today()
        for i, workout in enumerate(self.workouts):
            test = datetime.combine(date.today(),workout[0])
            if now < (test - timedelta(minutes=15)):
                index = i
                break
        self.workout_cb.current(index)
        self.disable_date_ent()
            
    def update_workouts(self, e=None):
        try:
            self.populate_workouts()
            self.workout_cb['values'] = self.workouts_form
        except ValueError:
            self.workout.set(' Enter Valid Date ')
        if len(self.workouts) > 0 and e:
            self.workout_cb.current(0)
            
    def populate_workouts(self):
        today = datetime.strptime(str(self.date.get()), "%m/%d/%Y") #get date
        dow = self.schedule.weekday_to_str(today.weekday()) #get dow string

        self.workouts = self.schedule.get_wkday(dow)
        self.workouts_form = []
        for w in self.workouts:
            self.workouts_form.append(w[0].strftime("%H:%M") + ' - ' + w[1])
        if len(self.workouts) == 0:
            self.workout.set(' No workouts today ')

    def update_names(self):
        self.populate_names()
        if len(self.names) == 0: self.names = ['']
        self.name_cb['values'] = self.names
        self.name_cb.set(' ')

    def add_name(self, name):
        self.names.append(name)
        split_names = [x.split(' ') for x in self.names]
        split_names.sort(key = lambda x: ' '.join([x[2],x[0],x[1]]))
        self.names = [' '.join(x) for x in split_names]
        self.name_cb['values'] = self.names
        self.name.set(name)
        
    def populate_names(self):
        try:
            clist = self.customers.get_list()
        except IOError:
            self.output_text("! - " + self.customers.filename + " open in another application.\n")
            return
        clist.sort(key = lambda x: ', '.join(x[0:3]).lower())
        self.names = []
        for line in clist:
            self.names.append(' '.join([line[1],line[2],line[0]]))

    def find_line(self, name):
        [fname, mname, lname] = name.split(' ')
        try:
            return self.customers.find(lname, fname, mname)
        except IOError:
            self.output_text("! - " + self.customers.filename + " open in another application.\n")
            return None
示例#27
0
文件: gui.py 项目: Jaymon/reached
class Dialog(ui.Dialog):
    def __init__(self, frame=None):
        self.parent_frame = frame  # set the parent frame
        self.confirm_frame = None
        self.make_change = False
        self.new_line = u""
        self.status_text = u""
        self.make_silent = False
        self.cancel = False

        # set screen position...
        x = 0
        y = 0
        ##x = config.get('status_x',0)
        ##y = config.get('status_y',0)
        ##if x and y:
        ##    self.parent_frame.geometry("+%d+%d" % (int(x),int(y)))

        # create a status message widget and bind it to the parent...
        # self.status_text = ScrolledText(self.parent_frame, height=20, width=80, state=DISABLED)
        # self.status_text.pack()
        self.status_text = ScrolledText(self.parent_frame, wrap=WORD, pady=2, padx=3, state=DISABLED)
        self.status_text.pack(fill=BOTH, expand=Y)
        self.parent_frame.protocol("WM_DELETE_WINDOW", self.destroy)
        self.parent_frame.bind("<Escape>", self.destroy)
        self.parent_frame.bind("<Configure>", self.save_pos)
        self.status_text.update()

    def confirm_change(self, old_line, new_line, old_tuple=(), new_tuple=(), filepath=""):
        self.confirm_frame = Tkinter.Toplevel(self.parent_frame, padx=10, pady=10)
        # self.confirm_frame.grid(padx=10,pady=10)

        self.confirm_frame.protocol("WM_DELETE_WINDOW", self.confirm_decline)

        # set screen position...
        ##x = config.get('dialog_x', (self.parent_frame.winfo_rootx() + 50))
        ##y = config.get('dialog_y', (self.parent_frame.winfo_rooty() + 50))
        x = self.parent_frame.winfo_rootx() + 50
        y = self.parent_frame.winfo_rooty() + 50
        if x and y:
            self.confirm_frame.geometry("+%s+%s" % (x, y))

        # bind enter to ok and escape to cancel buttons...
        self.confirm_frame.bind("<Return>", self.confirm_accept)
        self.confirm_frame.bind("<Escape>", self.confirm_decline)
        self.confirm_frame.bind("<Configure>", self.save_pos)
        # make the new dialog a part of the parent...
        self.confirm_frame.transient(self.parent_frame)
        # focus onto the dialog...
        self.confirm_frame.focus_set()

        label = Tkinter.Label(self.confirm_frame, text=filepath)
        label.pack()

        label = Tkinter.Label(self.confirm_frame, text="Change:")
        # label.grid(row=row_i, column=0, sticky=W)
        label.pack()

        # entry = Tkinter.Text(self.confirm_frame, width=75, height=5)
        # entry = ScrolledText(self.confirm_frame, width=75, height=5)
        entry = ScrolledText(self.confirm_frame, height=5, wrap=WORD, pady=2, padx=3)
        entry.insert(Tkinter.INSERT, old_line.encode("utf-8"))
        # highlight the text to be changed...
        if len(old_tuple) == 2:
            entry.tag_add("found", "1.%s" % (old_tuple[0]), "1.%s+%sc" % (old_tuple[0], old_tuple[1] - old_tuple[0]))
            entry.tag_config("found", foreground="red")

        entry.config(state=DISABLED)
        entry.pack(fill=BOTH, expand=Y)

        label = Tkinter.Label(self.confirm_frame, text="To:")
        label.pack()

        self.new_entry = ScrolledText(self.confirm_frame, height=5, wrap=WORD, pady=2, padx=3)
        self.new_entry.insert(Tkinter.INSERT, new_line.encode("utf-8"))
        # highlight the text to be changed...
        if len(new_tuple) == 2:
            self.new_entry.tag_add(
                "found", "1.%s" % (new_tuple[0]), "1.%s+%sc" % (new_tuple[0], new_tuple[1] - new_tuple[0])
            )
            self.new_entry.tag_config("found", foreground="red")

        self.new_entry.config(state=DISABLED)
        self.new_entry.pack(fill=BOTH, expand=Y)

        btnDisplay = Tkinter.Button(self.confirm_frame, text="Yes", command=self.confirm_accept, default=ACTIVE)
        # btnDisplay.grid(row=row_i, column=0)
        btnDisplay.pack(side=LEFT, padx=5, pady=5)

        btnDisplay = Tkinter.Button(self.confirm_frame, text="No", command=self.confirm_decline)
        # btnDisplay.grid(row=row_i, column=1)
        btnDisplay.pack(side=LEFT, padx=5, pady=5)

        btnDisplay = Tkinter.Button(self.confirm_frame, text="Cancel", command=self.confirm_cancel)
        # btnDisplay.grid(row=row_i, column=1)
        btnDisplay.pack(side=LEFT, padx=5, pady=5)

        btnDisplay = Tkinter.Button(self.confirm_frame, text="Yes to All", command=self.confirm_silence)
        # btnDisplay.grid(row=row_i, column=1)
        btnDisplay.pack(side=LEFT, padx=5, pady=5)

        self.confirm_frame.update()
        try:
            self.parent_frame.wait_window(self.confirm_frame)
        except Tkinter.TclError:
            # sometimes the wait_window fails, I'm not sure why, but it seems to be
            # safe to just ignore it *shrug*
            pass

        self.confirm_frame = None

    def confirm_silence(self):
        self.make_change = True
        self.make_silent = True
        self.clean_up()

    def confirm_cancel(self):
        self.make_change = False
        self.cancel = True
        self.clean_up()

    def confirm_accept(self):
        # self.new_line = self.new_entry.get(1.0, END)
        self.make_change = True
        self.clean_up()

    def confirm_decline(self):
        self.make_change = False
        self.clean_up()

    def clean_up(self, event=None):
        self.save_pos()
        # print self.screen_pos_x,self.screen_pos_y
        self.parent_frame.focus_set()
        self.confirm_frame.destroy()

    def destroy(self, event=None):
        self.parent_frame.destroy()

    def save_pos(self, event=None):
        return
        ## save the screen position of the dialog box
        # if self.confirm_frame:
        # try:
        # config.add('dialog_x',(self.confirm_frame.winfo_rootx() - 4))
        # config.add('dialog_y',(self.confirm_frame.winfo_rooty() - 30))
        # except:
        # pass

        ## save the status box's position
        # if self.parent_frame:
        # try:
        # config.add('status_x',self.parent_frame.winfo_rootx() - 4)
        # config.add('status_y',self.parent_frame.winfo_rooty() - 30)
        # except:
        # pass

    def update(self, msg):
        # if the window no longer exists, its text can't be updated
        try:
            self.status_text.config(state=NORMAL)
            # Add the new message
            self.status_text.insert(END, msg.encode("utf-8") + os.linesep)
            # Scroll down to the bottom again
            self.status_text.see(END)
            # Make the display uneditable
            self.status_text.config(state=DISABLED)
            self.status_text.update()
        except:
            pass
示例#28
0
class LogHandler(object):
    '''
	Logging and warnings
	'''
    def __init__(self, app):
        self.app = app
        self.enabled = True  # enabling or disabling logging

        # get package loggers
        self.loggers = []
        self.pkgName = __name__.split('.')[0]
        for name in logging.Logger.manager.loggerDict.keys():
            if self.pkgName in name:
                self.loggers.append(logging.getLogger(name))

        self.font = tkFont.Font(family='Courier New', size=12)
        # make text for normal logs
        self.logFrame = tk.Frame(self.app.root)
        self.logScroll = ScrolledText(self.app.root,
                                      bd=0,
                                      highlightthickness=0,
                                      font=self.font,
                                      bg=COL_PRIM,
                                      fg=COL_HL,
                                      width=80)
        self.logScroll.pack(side=tk.RIGHT, fill=tk.Y)

        # make warning panel
        self.alert = tk.Label(self.app.graphEditor.bg,
                              cursor='X_cursor',
                              font=self.font,
                              bg=COL_HL,
                              fg=COL_BG)
        self.alert.bind('<Button-1>', lambda _: self.resetWarning())
        self.alert.pack(side=tk.TOP)
        self.alert.pack_forget()  # initially not visible

        self.enableLog(False)  # initially, disable normal logs

    def enableLog(self, enable):
        '''
		Enables/Disables logging and shows/hides the log scroll
		'''
        self.enabled = enable
        if enable:
            # slow, but comprehensive logging
            self.logScroll.pack(side=tk.RIGHT, fill=tk.Y)
            self.setLogLevel(logging.DEBUG)
        else:
            # only alerts can occur now
            self.clear()
            self.logScroll.pack_forget()
            self.setLogLevel(logging.WARNING)

    def setLogLevel(self, level):
        '''
		Sets all package related loggers to a new level.
		This results in better performance, but other log handlers 
		won't see messages below level too of course.
		'''
        for logger in self.loggers:
            logger.setLevel(level)

    def warn(self, warning):
        '''
		Shows a warning
		'''
        # append linefeed to current text
        curText = self.alert.cget('text')
        if curText and not curText.endswith('\n'):
            curText += '\n'
        # add warning to current text and show
        self.alert.config(text=curText + warning)
        self.alert.pack()

    def resetWarning(self):
        '''
		Resets the warnings in the alert panel
		'''
        self.alert.config(text='')
        self.alert.pack_forget()

    def write(self, msg):
        '''
		This method is called from the logging module for each message
		'''
        if any(lvl in msg for lvl in ('WARNING', 'ERROR', 'CRITICAL')):
            # user needs attention
            self.warn(msg)

        if self.enabled:
            # normal logging
            self.logScroll.insert(tk.END, msg)

    def flush(self):
        '''
		This method might be called from the logging module
		'''
        pass

    def tail(self):
        '''
		Scrolls down to the last messages
		'''
        if self.enabled:
            self.logScroll.see(tk.END)  # super useful but super slow

    def clear(self):
        self.logScroll.delete(1.0, tk.END)
示例#29
0
文件: help.py 项目: cyenglish3/stars
class MyThing (Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def createWidgets(self):
        self.textBox = ScrolledText(self, height=30, width=85)
        self.textBox.pack()
        self.addText()

    def leftMouseClick(self,event):
        print "got a click"
        mouseIndex =  "@%d,%d" % (event.x, event.y)
        current = self.textBox.index(mouseIndex)
        row = current.split(".")[0] + ".0"
        rowFl = float(row)+1.0
        row = str(rowFl)
        target = self.rowIndex[row]
        target = float(target)+12.0
        target = str(target)
        print "moving to target",target
        self.textBox.see(target)

    def rightMouseClick(self,event):
        self.textBox.see("0.0")



    def addText(self):
        f=open("help.txt",'r')
        lines = f.readlines()
        f.close()
        flag = 1
        i=0
        sectionOrder = {}
        sectionHeads = {}
        outlines = {} 
        targetId = 0
        defaultTarget = ""
        tocEntries = []
        lineId=0
        for line in lines:
            if line[0:1] =="#":
                tocEntries.append(line)
                if flag:
                    top = lineId
                    flag = 0
            lineId+=1



        self.tocEntries = tocEntries
        # header text
        header = lines[0:top]

        for line in header:
            hid=self.textBox.insert(END,line,"header")
            self.textBox.tag_config("header",foreground=FGCOLOR)
            self.textBox.tag_config("header",background=BGCOLOR)

        

        self.textBox.insert(END,"Table of Contents\n","toc")
        self.textBox.tag_config("toc",foreground="red")
        self.textBox.tag_config("toc",background=BGCOLOR)
        self.textBox.insert(END,
            "(Left-click entry to navigate, right-click to return)\n\n","directions")
        self.textBox.tag_config("directions",background=BGCOLOR)
        self.textBox.tag_config("directions",foreground="purple")



        sectionDict = {}
        rowIndex = {}
        for tocEntry in tocEntries:
            if tocEntry[0:2] == "##":
                line = "\t"+tocEntry[2:]
            else:
                line = tocEntry[1:]
            rowPosition = self.textBox.index(END).split(".")[0] + ".0"
            rowIndex[rowPosition] = "0.0"
            sectionDict[tocEntry] = rowPosition
            self.textBox.insert(END,line,"tocEntry")

        self.textBox.tag_bind("tocEntry",'<ButtonRelease-1>',
                               self.leftMouseClick)
        self.textBox.tag_config("tocEntry",background=BGCOLOR)
        self.textBox.tag_config("tocEntry",foreground=hfg)
        for i in range(50):
            self.textBox.insert(END,"\n","regular")

        lines = lines[top:]
        for line in lines:
            if sectionDict.has_key(line):
                print "section id",line
                position = self.textBox.index(END)
                tocPosition = sectionDict[line]
                rowIndex[tocPosition] = position
                line = line.replace("#","")

            self.textBox.insert(END,line,"regular")

        self.rowIndex = rowIndex

        self.sectionDict = sectionDict

        self.textBox.see("0.0")

        self.textBox.bind_all('<ButtonRelease-3>',
                              self.rightMouseClick)
        self.textBox.tag_config("regular",background=BGCOLOR)
        self.textBox.tag_config("regular",foreground="black")
class GUI_hcheck:

    # do everything!
	def __init__(self):
		self.top = Tk()
		self.top.title('Health Check Tool')
		self.top.geometry('1400x800')

		#------- Label,Entry defination ----------#
		self.l1 = Label(self.top, text="IP:").grid(row=1, column=1, sticky="w")
		self.e1 = Entry(self.top)
		self.e1.grid(row=1, column=2,sticky="ew")
		self.l2 = Label(self.top, text="User:"******"w")
		self.e2 = Entry(self.top)
		self.e2.grid(row=2, column=2,sticky="ew")
		self.l3 = Label(self.top, text="Passwd:").grid(row=3, column=1, sticky="w")
		self.e3 = Entry(self.top)
		self.e3['show'] = '*'
		self.e3.grid(row=3, column=2,sticky="ew")
		self.l4 = Label(self.top, text="Command pool:").grid(row=4, column=1, sticky="e")
		self.l5 = Label(self.top, text="To be run command:").grid(row=4, column=5, sticky="e")
		self.e4 = Entry(self.top, width=30)
		self.e4.grid(row=16, column=0, columnspan=3, sticky="ew")

		#------- Checkbutton defination ----------#
		self.cb1State = IntVar()
		self.cb1 = Checkbutton(self.top, variable=self.cb1State, text = "Always Yes", command=self.callCheckbutton)
		self.cb1.grid(row=21, column=16)

		#------- Listbox defination ----------#
		self.cmdfm = Frame(self.top)
		self.cmdsb = Scrollbar(self.cmdfm)
		self.cmdsb_x = Scrollbar(self.cmdfm,orient = HORIZONTAL)
		self.cmdsb.pack(side=RIGHT, fill=Y)
		self.cmdsb_x.pack(side=BOTTOM, fill=X)
		self.cmdls = Listbox(self.cmdfm, selectmode=EXTENDED, height=25, width=40, xscrollcommand=self.cmdsb_x.set, yscrollcommand=self.cmdsb.set)
		self.cmdsb.config(command=self.cmdls.yview)
		self.cmdsb_x.config(command=self.cmdls.xview)
		self.cmdls.pack(side=LEFT, fill=BOTH)
		self.cmdfm.grid(row=5, rowspan=10, column=0,columnspan=4,sticky="ew")
		self.db_file = os.path.join(os.getcwd(),'%s' % constants.DB_NAME)
		flist = utility.load_file(self.db_file)
		if flist != None:
			log.debug ("db file found, start load command")
			for element in flist:
				element = element.strip('\n')
				if element == '' or element.startswith('#'):
					continue
				self.cmdls.insert(END, element)
		else:
			log.debug ("db file doesn't existed, initail cmd")
			for element in constants.CMD_LIST_COMM:
				self.cmdls.insert(END, element)

		self.dirfm = Frame(self.top)
		self.dirsb = Scrollbar(self.dirfm)
		self.dirsb_x = Scrollbar(self.dirfm,orient = HORIZONTAL)
		self.dirsb.pack(side=RIGHT, fill=Y)
		self.dirsb_x.pack(side=BOTTOM, fill=X)
		self.dirs = Listbox(self.dirfm, selectmode=EXTENDED, height=25, width=40, xscrollcommand=self.dirsb_x.set,yscrollcommand=self.dirsb.set)
		self.dirsb.config(command=self.dirs.yview)
		self.dirsb_x.config(command=self.dirs.xview)
		self.dirs.pack(side=LEFT, fill=BOTH)
		self.dirfm.grid(row=5, rowspan=10, column=5,columnspan=4,sticky="ew")

		#------- Buttion defination ----------#
		# add command button
		self.b1 = Button(self.top,text=">>",width=6,borderwidth=3,relief=RAISED, command=self.move_cmd)
		self.b1.grid(row=7, column=4)
		# del command button
		self.b2 = Button(self.top,text="<<",width=6,borderwidth=3,relief=RAISED, command=self.del_cmd)
		self.b2.grid(row=8, column=4)
		# move up command button
		self.b3 = Button(self.top,text="up",width=6,borderwidth=3,relief=RAISED, command=self.up_cmd)
		self.b3.grid(row=7, column=10)
		# move down command button
		self.b4 = Button(self.top,text="down",width=6,borderwidth=3,relief=RAISED, command=self.down_cmd)
		self.b4.grid(row=8, column=10)
		# start command button
		self.b5 = Button(self.top,text="Start",bg='red',width=10,borderwidth=3,relief=RAISED, command=self.start_process)
		self.b5.grid(row=2, column=11)
		# yes button
		self.b6 = Button(self.top,text="Yes",width=6,borderwidth=3,relief=RAISED, command=self.set_confirm_yes)
		self.b6.grid(row=21, column=13)
		# No button
		self.b7 = Button(self.top,text="No",width=6,borderwidth=3,relief=RAISED, command=self.set_confirm_no)
		self.b7.grid(row=21, column=14)
		# Skip button
		self.b8 = Button(self.top,text="Skip",width=6,borderwidth=3,relief=RAISED, command=self.set_confirm_skip)
		self.b8.grid(row=21, column=15)
		# Add button
		self.b9 = Button(self.top,text="add cmd",width=10,borderwidth=3,relief=RAISED, command=self.add_command)
		self.b9.grid(row=15, column=1)
		# Del button
		self.b10 = Button(self.top,text="del cmd",width=10,borderwidth=3,relief=RAISED, command=self.del_command)
		self.b10.grid(row=15, column=2)
		# Manual button
		self.manual = False
		self.b11 = Button(self.top,text="Manual model",width=10,borderwidth=3,relief=RAISED, command=self.manual_mode)
		self.b11.grid(row=2, column=12)

		#------- ScrolledText defination ----------#
		self.sfm = Frame(self.top)
		self.console = ScrolledText(self.sfm,height=45, width=86,bg='black',fg='green',insertbackground='green')
		self.console['font'] = ('lucida console','10')
		self.console.bind("<Return>", self.process_input)
		self.console.pack()
		self.sfm.grid(row=4, rowspan=15, column=11,columnspan=10,sticky="ew")

		self.redir = redirect(self.console)
		sys.stdout = self.redir
		sys.stderr = self.redir
		self.fconsole = logging.StreamHandler(sys.stdout)
		self.fconsole.setLevel(logging.INFO)
		logging.getLogger('').addHandler(self.fconsole)

		#------- Menu defination ----------#
		self.menubar = Menu()
		# file menu
		self.fmenu = Menu()
		#self.fmenu.add_command(label = 'New',command=self.new_win)
		self.fmenu.add_command(label = 'Import cmd',command=self.load_cmd)
		self.fmenu.add_command(label = 'Export cmd',command=self.export_cmd)
		self.menubar.add_cascade(label = 'File', menu = self.fmenu)
		# edit menu
		self.emenu = Menu()
		self.cmenu = Menu()
		self.cvar = StringVar()
		for item in ['white/black', 'black/white', 'green/black']:
			self.cmenu.add_radiobutton(label = item, variable=self.cvar, value=item, command=self.sel_color_style)
		self.emenu.add_cascade(label = 'console style', menu = self.cmenu)
		self.emenu.add_command(label = 'reset cmd pool',command=self.reset_cmd_pool)
		self.menubar.add_cascade(label = 'Edit', menu = self.emenu)

		self.top['menu'] = self.menubar

	def new_win(self):
		#GUI_hcheck()
		pass

	def sel_color_style(self):
		log.debug ("select console color style: %s " % self.cvar.get())
		color = self.cvar.get()
		if color == 'white/black':
			self.console.config(bg='black',fg='white',insertbackground='white')
		elif color == 'black/white':
			self.console.config(bg='white',fg='black',insertbackground='black')
		elif color == 'green/black':
			self.console.config(bg='black',fg='green',insertbackground='green')

	def move_cmd(self):
		if self.cmdls.curselection() != ():
			for i in self.cmdls.curselection():
				if utility.elemet_exists(self.dirs.get(0,END), self.cmdls.get(i)) == None:
					self.dirs.insert(END,self.cmdls.get(i))
					log.debug ("move command %s" % self.cmdls.get(i))
		else:
			tkMessageBox.showwarning('Message', 'Please select at lease one item')

	def load_cmd(self):
		file = tkFileDialog.askopenfilename()
		flist = utility.load_file(file)
		if flist != None:
			self.dirs.delete(0,END)
			for element in flist:
				element = element.strip('\n')
				if element == '' or element.startswith('#'):
					continue
				if utility.elemet_exists(self.dirs.get(0,END), element) == None:
					self.dirs.insert(END, element)
		else:
			tkMessageBox.showerror('Message', 'import failed')

	def export_cmd(self):
		file = tkFileDialog.askopenfilename()
		if utility.export_file(self.dirs.get(0,END), file) == True:
			tkMessageBox.showinfo('Message', 'export finish')
		else:
			tkMessageBox.showerror('Message', 'export failed')

	def del_cmd(self):
		if self.dirs.curselection() != ():
			for i in self.dirs.curselection():
				self.dirs.delete(i)
		else:
			tkMessageBox.showwarning('Message', 'Please select at lease one item')

	def up_cmd(self):
		select = self.dirs.curselection()
		if (len(select)) >= 2:
			tkMessageBox.showwarning('Message', 'Only one select is supported')
			return
		log.debug ("move up select pos: %s" % str(select))
		if select != () and select != (0,):
			element = self.dirs.get(select)
			self.dirs.delete(select)
			self.dirs.insert((select[0] - 1), element)
			self.dirs.select_set(select[0] - 1)

	def down_cmd(self):
		select = self.dirs.curselection()
		if (len(select)) >= 2:
			tkMessageBox.showwarning('Message', 'Only one select is supported')
			return
		log.debug ("move down select pos: %s" % str(select))
		if select != () and select != (END,):
			element = self.dirs.get(select)
			self.dirs.delete(select)
			self.dirs.insert((select[0] + 1), element)
			self.dirs.select_set(select[0] + 1)

	def start_process(self):
		log.debug ("current thread total numbers: %d" % threading.activeCount())
		response = tkMessageBox.askokcancel('Message', 'Will start healthcheck, please click OK to continue, or cancel')
		if response == False:
			return
		th = threading.Thread(target=self.start_cmd)
		th.setDaemon(True)
		th.start()

	def start_cmd(self):
		self.manual = False
		cmd = list(self.dirs.get(0,END))
		if len(cmd) == 0:
			log.info ("To be run cmd numbers none, quit...")
			return
		log.debug ("fetch cmd list from GUI: %s" % cmd)
		(ip, port) = utility.getipinfo(self.e1.get())
		log.debug ("get ip infor-> ip: %s, port:%s" % (ip,port))
		if ip == False:
			log.error ("Given ip infor is wrong! The right ip address: xxx.xxx.xxx.xxx or IP:port ")
			return
		self.b5.config(state=DISABLED)
		self.b11.config(state=DISABLED)
		self.console.delete('1.0',END)
		try:
			self.wf = Workflow(cmd, ip, self.e2.get(), self.e3.get(), port)
			self.wf.start()
		except:
			pass
		self.b5.config(state=NORMAL)
		self.b11.config(state=NORMAL)

	def manual_mode(self):
		cmd = []
		(ip, port) = utility.getipinfo(self.e1.get())
		log.debug ("get ip infor-> ip: %s, port:%s" % (ip,port))
		if ip == False:
			log.error ("Given ip infor is wrong! The right ip address: xxx.xxx.xxx.xxx or IP:port ")
			return
		self.wf_manual = Workflow(cmd, ip, self.e2.get(), self.e3.get(), port)
		if self.wf_manual.setup_ssh(self.wf_manual.hostip) == False:
			log.error ("\nssh setup error! please check ip/user/passwd and network is okay")
			del self.wf_manual
			return
		self.console.delete('1.0',END)
		self.console.insert(END, "Switch to manual mode...\n\
Please input command directly after \">>> \"\n\n")
		self.prompt = ">>> "
		self.insert_prompt()
		self.manual = True
		self.b5.config(state=DISABLED)
		self.b11.config(state=DISABLED)

	def set_confirm_yes(self):
		try:
			self.wf.set_confirm('Yes')
		except AttributeError:
			log.debug("wf doesn't existed")
	def set_confirm_no(self):
		try:
			self.wf.set_confirm('No')
		except AttributeError:
			log.debug("wf doesn't existed")
	def set_confirm_skip(self):
		try:
			self.wf.set_confirm('Skip')
		except AttributeError:
			log.debug("wf doesn't existed")

	def callCheckbutton(self):
		try:
			if self.cb1State.get() == 1:
				self.wf.set_automatic(5)
			else:
				self.wf.set_automatic(None)
		except AttributeError:
			log.debug("wf doesn't existed")
			self.cb1.deselect()
			tkMessageBox.showwarning('Message', 'please press start button first')

	def saveinfo(self):
		pass

	def add_command(self):
		item = self.e4.get()
		if item != '':
			if utility.elemet_exists(self.cmdls.get(0,END), item) == None:
				self.cmdls.insert(END,item)
				self.cmdls.see(END)
				log.debug ("add new command %s" % item)
				self.save_command()
		else:
			tkMessageBox.showwarning('Message', 'entry can not empty')

	def del_command(self):
		if self.cmdls.curselection() != ():
			for i in self.cmdls.curselection():
				self.cmdls.delete(i)
				self.save_command()
		else:
			tkMessageBox.showwarning('Message', 'Please select at lease one item')

	def save_command(self):
		if utility.export_file(self.cmdls.get(0,END), self.db_file) != True:
			log.error ("save command pool failed")

	def reset_cmd_pool(self):
		log.debug ("start to reset command pool list")
		self.cmdls.delete(0,END)
		for element in constants.CMD_LIST_COMM:
			self.cmdls.insert(END, element)
		self.save_command()

	def insert_prompt(self):
		c = self.console.get("end-2c")
		if c != "\n":
			self.console.insert("end", "\n")
		self.console.insert("end", self.prompt, ("prompt",))
		#self.text.insert("end", self.prompt)
		# this mark lets us find the end of the prompt, and thus
		# the beggining of the user input
		self.console.mark_set("end-of-prompt", "end-1c")
		self.console.mark_gravity("end-of-prompt", "left")

	def process_input(self,event):
		index = self.console.index("end-1c linestart")
		line = self.console.get(index,'end-1c')
		log.debug ("last line: %s" % line)
		if self.manual == True:
			self.console.insert("end", "\n")
			command = self.console.get("end-of-prompt", "end-1c")
			command = command.strip()
			if command != '':
				if command == 'bye' or command == 'exit':
					log.info ("quit from manual mode...")
					self.wf_manual.ssh.close()
					self.manual = False
					self.b5.config(state=NORMAL)
					self.b11.config(state=NORMAL)
					return
				elif command == 'help':
					log.info ("This is used for run command on target server by ssh, for example: >>> df -h, >>> svcs -xv")
				elif self.wf_manual.remote_cmd(command) == 1:
					log.error ("command %s execute failed" % command)
			self.insert_prompt()
			self.console.see("end")
			# this prevents the class binding from firing, since we 
			# inserted the newline in this method
			return "break"
		else:
			if line == 'Yes' or line == 'y' or line == 'yes': 
				self.set_confirm_yes()
			elif line == 'No' or line == 'n' or line == 'no':
				self.set_confirm_no()
			elif line == 'Skip' or line == 's' or line == 'skip':
				self.set_confirm_skip()
			else:
				pass
示例#31
0
class SigBridgeUI(Tk):
    server = None
    server_thread = None

    def __init__(self):
        Tk.__init__(self)

        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)

        # 2 rows: firts with settings, second with registrar data
        self.main_frame = Frame(self)
        # Commands row doesn't expands
        self.main_frame.rowconfigure(0, weight=0)
        # Logs row will grow
        self.main_frame.rowconfigure(1, weight=1)
        # Main frame can enlarge
        self.main_frame.columnconfigure(0, weight=1)
        self.main_frame.columnconfigure(1, weight=1)
        self.main_frame.grid(row=0, column=0)

        # Run/Stop button
        self.server_button = Button(self.main_frame, text="Connect", command=self.start_server)
        self.server_button.grid(row=0, column=0)

        # Clear button
        self.clear_button = Button(self.main_frame, text="Clear Log", command=self.clear_log)
        self.clear_button.grid(row=0, column=1)

        # Logs Widget
        self.log_widget = ScrolledText(self.main_frame)
        self.log_widget.grid(row=1, column=0, columnspan=2)
        # made not editable
        self.log_widget.config(state='disabled')

        # Queue where the logging handler will write
        self.log_queue = Queue.Queue()

        # Setup the logger
        self.uilogger = logging.getLogger('SigBridgeUI')
        self.uilogger.setLevel(logging.INFO)
        formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')

        # Use the QueueLogger as Handler
        hl = QueueLogger(queue=self.log_queue)
        hl.setFormatter(formatter)
        self.uilogger.addHandler(hl)

        # self.log_widget.update_idletasks()
        self.set_geometry()

        # Setup the update_widget callback reading logs from the queue
        self.start_log()

    def clear_log(self):
        self.log_widget.config(state='normal')
        self.log_widget.delete(0.0, END)
        self.log_widget.config(state='disabled')

    def start_log(self):
        self.uilogger.info("SigBridge Started.")
        self.update_widget()
        # self.control_log_button.configure(text="Pause Log", command=self.stop_log)

    def update_widget(self):
        self.log_widget.config(state='normal')
        # Read from the Queue and add to the log widger
        while not self.log_queue.empty():
            line = self.log_queue.get()
            tag = "error" if " ERROR " in line else 'info'
            self.log_widget.insert(END, line, tag)
            self.log_widget.see(END)  # Scroll to the bottom
            self.log_widget.update_idletasks()
        self.log_widget.tag_config('error', foreground="red")
        self.log_widget.config(state='disabled')
        self.log_widget.after(10, self.update_widget)

    def set_geometry(self):
        # set position in window
        w = 600  # width for the Tk
        h = 300  # height for the Tk

        # get screen width and height
        ws = self.winfo_screenwidth()   # width of the screen
        hs = self.winfo_screenheight()  # height of the screen

        # calculate x and y coordinates for the Tk window
        x = (ws/2) - (w/2)
        y = (hs/2) - (h/2)

        # set the dimensions of the screen 
        # and where it is placed
        self.geometry('%dx%d+%d+%d' % (w, h, x, y))

    def start_server(self):
        try:
            self.server = SigServer(('0.0.0.0', 25), None, self.uilogger)
            self.server_thread = threading.Thread(name='server', target=self.server.run)
            self.server_thread.daemon = True
            self.server_thread.start()
            self.server_button.configure(text="Disconnect", command=self.stop_server)
        except Exception as err:
            self.uilogger("Cannot start the server: %s" % err.message)

        # self.label_variable.set(self.entry_variable.get()+"(Started Signal Server)")
        # self.entry.focus_set()
        # self.entry.selection_range(0, END)

    def stop_server(self):
        self.server.shutdown()
        self.server_button.configure(text="Connect", command=self.start_server)
        self.server = None
示例#32
0
class TermWindow(Frame):
    EOL = None

    ##
    # constructor method
    def __init__(self, master=None, **cnf):
        apply(Frame.__init__, (self, master), cnf)
        self.__create_widgets__()
        self.rxWaitPattern = ""
        self.localEcho = False
        self.logFile = None
        self.inQueue = Queue.Queue()
        self.outQueue = Queue.Queue()
        self.update_thread_safe()

    def update_thread_safe(self):
        while not self.inQueue.empty():
            element = self.inQueue.get_nowait()
            if element is not None:
                msg, tag = element
                self.__display__(msg, tag)
            self.st_trm.update_idletasks()
        self.st_trm.after(100, self.update_thread_safe)

    ##
    #
    def __create_widgets__(self):
        dfl_font = 'Courier 10'

        # the title frame of the terminal
        self.f_title = Frame(self)
        self.f_title.pack(fill=BOTH)
        self.f_title.configure(FRAMEBORDER)
        self.shVar = StringVar()
        # show/hide button
        self.b_sh = Button(self.f_title,
                           textvariable=self.shVar,
                           font=dfl_font)
        self.b_sh.pack(side=RIGHT)
        self.b_sh['command'] = self.show_hide_cont
        # clear screen button
        self.b_cls = Button(self.f_title,
                            text="CLS",
                            font=dfl_font,
                            underline=0)
        self.b_cls.pack(side=RIGHT)
        self.b_cls['command'] = self.clear_screen
        # echo on/off button
        self.al_echo = Label(self.f_title,
                             text="ECHO",
                             relief=RAISED,
                             font=dfl_font,
                             padx='3m',
                             pady='1m',
                             underline=0)
        self.al_echo.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_echo.bind("<Button-1>", self.__echo_handler__)
        # log on/off button
        self.al_log = Label(self.f_title,
                            text="LOG",
                            relief=RAISED,
                            font=dfl_font,
                            padx='3m',
                            pady='1m',
                            underline=0)
        self.al_log.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_log.bind("<Button-1>", self.__log_handler__)
        # device connect button
        self.al_connect = Label(self.f_title,
                                text="CONNECT",
                                relief=RAISED,
                                font=dfl_font,
                                padx='3m',
                                pady='1m',
                                underline=1)
        self.al_connect.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.al_connect.bind("<Button-1>", self.__connect_handler__)

        self.mb_macros = Menubutton(self.f_title, text="Macros", relief=RAISED)
        self.mb_macros.pack(side=RIGHT, padx=1, pady=1, fill=BOTH)
        self.mb_macros.menu = Menu(self.mb_macros, tearoff=0)
        self.mb_macros["menu"] = self.mb_macros.menu

        # title of terminal window
        self.tVar = StringVar()
        self.l_title = Label(self.f_title, text="foo", font=dfl_font)
        self.l_title['textvariable'] = self.tVar
        self.l_title.pack(side=LEFT, expand=1, fill=X)
        self.l_title['width'] = 42
        self.update_title("------ XXX ------")
        # frame for scrolled text window
        # (this frame handle needs to be kept fo show_hide_cont())
        self.f_cont = Frame(self)
        # IO data scrolled text window
        self.st_trm = ScrolledText(self.f_cont,
                                   height=10,
                                   state=DISABLED,
                                   wrap=NONE)
        self.st_trm.pack(expand=1, fill=BOTH)
        self.st_trm['font'] = dfl_font
        self.st_trm.tag_config('E', foreground="blue")
        self.st_trm.tag_config('M', foreground="magenta")

        tframe = Frame(self.f_cont)
        tframe.pack(expand=0, fill=X)
        self.cmdVar = StringVar()
        self.ent_trm = Entry(tframe, textvariable=self.cmdVar, font=dfl_font)
        self.ent_trm.pack(side=LEFT, expand=1, fill=X)
        self.ent_trm.bind("<Control-l>", self.__log_handler__)
        self.ent_trm.bind("<Control-e>", self.__echo_handler__)
        self.ent_trm.bind("<Control-o>", self.__connect_handler__)
        self.ent_trm.bind("<Control-c>", self.clear_screen)
        self.ent_trm.bind("<Control-x>", self.show_hide_cont)
        self.ent_trm.bind("<Control-m>", lambda *args: self.do_macro("M"))
        self.ent_trm.bind("<KeyPress>", self.__input_handler__)

        self.gui_elements = [
            self.b_sh, self.b_cls, self.al_echo, self.al_log, self.al_connect,
            self.mb_macros, self.l_title, self.st_trm, self.ent_trm
        ]
        self.show_cont()

    def add_macro(self, id, title, text=None, function=None, params=None):
        if text:
            cmd = lambda *args: self.do_macro(text)
        if function:
            user_func = eval(function)
            if params:
                params = eval(str(params))
            else:
                params = {}
            cmd = lambda *args: user_func(self, DEVICES, **params)
        mb = self.mb_macros.menu.add_command(label=title, command=cmd)

    def _configure_(self, **args):
        for e in self.gui_elements:
            e.configure(args)

    def __input_handler__(self, *args):
        for i in args:
            self.terminal_device_write(i.char)

    def terminal_device_write(self, *args):
        for i in args:
            if self.localEcho:
                self.display(i, "E")
            if len(i):
                if i == "\r" or i == "\n":
                    self.device.write(self.EOL)
                    self.display(self.EOL, "E")
                    self.cmdVar.set("")
                else:
                    self.device.write(i)
        self.st_trm.update_idletasks()

    def __echo_handler__(self, *args):
        if self.localEcho:
            self.localEcho = False
            self.al_echo['relief'] = RAISED
            self.message("Local Echo OFF")
        else:
            self.localEcho = True
            self.al_echo['relief'] = SUNKEN
            self.message("Local Echo ON")

    def __log_handler__(self, *args):
        try:
            do_open = self.logFile.closed
            logname = self.logFile.name
        except:
            do_open = True
            logname = ""
        if do_open:
            if self.device.logname:
                logname = self.device.logname
                self.message("logfile from config file %s " % logname)
            else:
                fd = FileDialog(self)
                logname = fd.go(logname)
            try:
                if self.device.logmode not in "wa":
                    self.device.logmode = "a"
                    _print(3, "force _a_ppend")
                self.logFile = open(logname, self.device.logmode)
                self.al_log['relief'] = SUNKEN
                self.message("Logging ON: %s" % self.logFile.name)
            except:
                self.message("Error open logfile: %s" % logname)

        else:
            self.message("Logging OFF: %s" % self.logFile.name)
            self.logFile.flush()
            self.logFile.close()
            self.al_log['relief'] = RAISED

    def __connect_handler__(self, *args):
        if self.device.isConnected:
            self.device.disconnect()
            self.al_connect['relief'] = RAISED
            self.message("Disconnected")
        else:
            try:
                self.device.connect()
                self.al_connect['relief'] = SUNKEN
                self.message("Connected")
                self.al_connect['fg'] = "black"
            except:
                self.device.isConnected = False
                self.message(str(sys.exc_info()[1]))
                self.al_connect['fg'] = "red"

    def clear_screen(self, *args):
        self.st_trm['state'] = NORMAL
        self.st_trm.delete("0.0", END)
        self.st_trm['state'] = DISABLED

    def set_device(self, device):
        self.device = device
        self.device.configure(TxQueue=self.outQueue, RxQueue=self.inQueue)
        self.update_title(self.device)

        if self.device.log:
            self.__log_handler__()
        if self.device.auto_connect:
            self.__connect_handler__()

    def update_title(self, title):
        self.tVar.set(title)

    def show_cont(self):
        self.shVar.set("X")
        self.f_cont.pack(expand=1, fill=BOTH)

    def hide_cont(self):
        self.shVar.set("+")
        self.f_cont.pack_forget()

    def show_hide_cont(self, *args):
        if self.shVar.get() == "X":
            self.hide_cont()
        else:
            self.show_cont()

    def do_macro(self, *args):
        if self.localEcho:
            self.display(args[0] + "\n", "E")
        self.device.write(args[0] + "\n")

    def write(self, data):
        self.outQueue.put((data, None))

    def message(self, text, tag='M'):
        msg = "[%s:%s:%s]\n" % (time.asctime(), self.device.name, text)
        if self.st_trm.index(AtInsert()).find(".0") < 1:
            msg = "\n" + msg
        self.inQueue.put((msg, tag))

    def display(self, text, tag=None):
        self.inQueue.put((text, tag))

    def __display__(self, msg, tag=None):
        self.st_trm['state'] = NORMAL
        here = self.st_trm.index(AtInsert())
        for d in re.split("([\r\v\t\n])", msg):
            if len(d):
                if d != '\r':
                    self.st_trm.insert(END, d)
        if tag:
            self.st_trm.tag_add(tag, here, AtInsert())
        self.st_trm.see(END)
        self.st_trm['state'] = DISABLED
        try:
            self.logFile.write(msg)
            self.logFile.flush()
        except:
            pass
示例#33
0
class UploadWizard(Wizard):
    def __init__(self, root, data):
        self.root = root
        self.data = data
        self.secure = False
        super(UploadWizard, self).__init__(
            width=450,
            height=300,
            cancelcommand=self._handle_cancel,
            finishcommand=self._handle_finish,
        )
        self.servers = ServerList()
        self.server_lbox = None
        self.upthread = None
        self.old_upload_state = None
        self.setup_gui()

    def setup_gui(self):
        self.title("Upload Wizard")
        self.protocol("WM_DELETE_WINDOW", self._handle_cancel)
        self.setup_gui_server_pane()
        self.setup_gui_user_pane()
        self.setup_gui_program_pane()
        self.setup_gui_upload_pane()

    def setup_gui_server_pane(self):
        fr = self.add_pane(
            'server', 'Select Server',
            entrycommand=self._enter_server_pane
        )
        fr.config(padx=20, pady=20)
        self.ssl_enable = IntVar()
        lbox_lbl = Label(fr, text="Select a Server to upload to:")
        self.server_lbox = ScrolledListbox(
            fr, horiz_scroll=False, width=20, highlightthickness=1)
        muck_lbl = Label(fr, text="Name")
        host_lbl = Label(fr, text="Host")
        port_lbl = Label(fr, text="Port")
        svalid = (self.register(self._serv_validate))
        pvalid = (self.register(self._port_validate), '%P')
        self.muck_entry = Entry(
            fr, width=30, validate=ALL, validatecommand=svalid)
        self.host_entry = Entry(
            fr, width=30, validate=ALL, validatecommand=svalid)
        self.port_entry = Entry(
            fr, width=10, validate=ALL, validatecommand=pvalid)
        self.port_entry.insert(END, '8888')
        self.ssl_cb = Checkbutton(
            fr, text="SSL",
            variable=self.ssl_enable,
            highlightthickness=3,
            command=self._update_server_buttons,
        )
        self.serv_del = Button(fr, text="-", width=1, command=self._del_server)
        self.serv_add = Button(fr, text="+", width=1, command=self._add_server)
        self.serv_save = Button(fr, text="Save", command=self._save_server)
        ToolTip(self.serv_del, "Delete selected Favorite Server")
        ToolTip(self.serv_add, "Enter a new Server")
        ToolTip(self.serv_save, "Save as a Favorite Server")
        self.server_lbox.bind('<<ListboxSelect>>', self._server_listbox_select)
        lbox_lbl.grid(row=0, column=0, sticky=N+W)
        self.server_lbox.grid(
            row=1, column=0, rowspan=8, padx=5, sticky=N+S+E+W)
        muck_lbl.grid(row=1, column=1, sticky=W, padx=5)
        self.muck_entry.grid(row=2, column=1, columnspan=3, sticky=E+W, padx=5)
        host_lbl.grid(row=3, column=1, sticky=W, padx=5)
        self.host_entry.grid(row=4, column=1, columnspan=3, sticky=E+W, padx=5)
        port_lbl.grid(row=5, column=1, sticky=W, padx=5)
        self.port_entry.grid(row=6, column=1, columnspan=2, sticky=E+W, padx=5)
        self.ssl_cb.grid(row=6, column=3, sticky=E, padx=5)
        self.serv_del.grid(row=8, column=1, sticky=N+W, padx=5)
        self.serv_add.grid(row=8, column=2, sticky=N+W, padx=5)
        self.serv_save.grid(row=8, column=3, sticky=N+E, padx=5)
        fr.grid_columnconfigure(2, weight=1, minsize=50)
        fr.grid_rowconfigure(7, weight=1)
        self.server_lbox.focus()
        return fr

    def setup_gui_user_pane(self):
        fr = self.add_pane(
            'user', 'Select a user',
            entrycommand=self._enter_user_pane
        )
        fr.config(padx=20, pady=20)
        lbox_lbl = Label(fr, text="Select a User to upload to:")
        self.user_lbox = ScrolledListbox(fr, horiz_scroll=False, width=20)
        user_lbl = Label(fr, text="UserName")
        pass_lbl = Label(fr, text="Password")
        uvalid = (self.register(self._user_validate))
        self.user_entry = Entry(
            fr, width=30, validate=ALL, validatecommand=uvalid)
        self.pass_entry = Entry(
            fr, width=30, show="*", validate=ALL, validatecommand=uvalid)
        self.user_del = Button(fr, text="-", width=1, command=self._del_user)
        self.user_add = Button(fr, text="+", width=1, command=self._add_user)
        self.user_save = Button(fr, text="Save", command=self._save_user)
        ToolTip(self.user_del, "Delete selected User")
        ToolTip(self.user_add, "Enter a new User")
        ToolTip(self.user_save, "Save User Info")
        self.user_lbox.bind('<<ListboxSelect>>', self._user_listbox_select)
        lbox_lbl.grid(row=0, column=0, sticky=N+W)
        self.user_lbox.grid(row=1, column=0, rowspan=8, padx=5, sticky=N+S+E+W)
        user_lbl.grid(row=1, column=1, sticky=W, padx=5)
        self.user_entry.grid(row=2, column=1, columnspan=3, sticky=E+W, padx=5)
        pass_lbl.grid(row=3, column=1, sticky=W, padx=5)
        self.pass_entry.grid(row=4, column=1, columnspan=3, sticky=E+W, padx=5)
        self.user_del.grid(row=6, column=1, sticky=N+W, padx=5)
        self.user_add.grid(row=6, column=2, sticky=N+W, padx=5)
        self.user_save.grid(row=6, column=3, sticky=N+E, padx=5)
        fr.grid_columnconfigure(2, weight=1, minsize=50)
        fr.grid_rowconfigure(5, weight=1)
        return fr

    def setup_gui_program_pane(self):
        fr = self.add_pane(
            'program', 'Program Info',
            entrycommand=self._enter_program_pane
        )
        pvalid = (self.register(self._program_validate))
        fr.config(padx=20, pady=20)
        prog_lbl = Label(fr, text="Program Name or DBRef")
        self.prog_entry = Entry(
            fr, width=30, validate=ALL, validatecommand=pvalid)
        global previous_progname
        self.prog_entry.insert(END, previous_progname)
        prog_lbl.grid(row=0, column=0, sticky=W+S)
        self.prog_entry.grid(row=1, column=0, sticky=N+E+W)
        fr.grid_columnconfigure(0, weight=1)
        fr.grid_rowconfigure(2, weight=1)
        return fr

    def setup_gui_upload_pane(self):
        fr = self.add_pane(
            'upload', 'Uploading',
            entrycommand=self._enter_upload_pane
        )
        fr.config(padx=20, pady=20)
        self.upload_lbl = Label(
            fr, text="", justify=LEFT, anchor=W, wraplength=400)
        self.progressbar = ProgressBar(
            fr, length=300,
            value=10.0, maximum=100.0,
            mode=INDETERMINATE,
        )
        self.console_log = ScrolledText(
            fr, font='TkFixedFont',
            relief=SUNKEN,
            borderwidth=2,
            background="black",
            foreground="white",
            width=1,
            height=1,
            insertontime=0,
            takefocus=0,
            cursor='arrow',
        )
        ro_binds = [
            "<Key>",
            "<<Cut>>",
            "<<Clear>>",
            "<<Paste>>",
            "<<PasteSelection>>",
            "<Double-Button-1>",
        ]
        for bind in ro_binds:
            self.console_log.bind(bind, lambda e: "break")
        self.upload_lbl.grid(row=0, column=0, sticky=W+S)
        self.progressbar.grid(row=1, column=0, sticky=N+E+W, padx=15, pady=5)
        self.console_log.grid(row=2, column=0, sticky=N+S+E+W)
        fr.grid_columnconfigure(0, weight=1)
        fr.grid_rowconfigure(2, weight=1)
        return fr

    def _enter_server_pane(self):
        self.set_finish_enabled(False)
        self.set_next_enabled(False)
        self.set_next_text()
        self.set_default_button("next")
        self.set_finish_text("Done")
        self._populate_server_listbox()
        if self.server_lbox.size() > 0:
            self.server_lbox.focus()
        else:
            self.muck_entry.focus()
        self._update_server_buttons()

    def _enter_user_pane(self):
        self.set_finish_enabled(False)
        self.set_next_enabled(False)
        self.set_next_text()
        self.set_default_button("next")
        self._populate_user_listbox()
        if self.user_lbox.size() > 0:
            self.user_lbox.focus()
        else:
            self.user_entry.focus()
        self._update_user_buttons()

    def _enter_program_pane(self):
        self.set_finish_enabled(False)
        self.set_next_enabled(False)
        self.set_next_text("Upload")
        self.set_default_button("next")
        self.prog_entry.focus()

    def _enter_upload_pane(self):
        self.set_default_button("finish")
        self.set_next_text()
        self.set_prev_enabled(False)
        self.set_finish_enabled(False)
        self._upload_start()
        global previous_progname
        previous_progname = self.prog_entry.get()

    def _populate_server_listbox(self):
        self.server_lbox.delete(0, END)
        for serv in self.servers.get_servers():
            self.server_lbox.insert(END, str(serv))

    def _update_server_listbox(self):
        sel = self.server_lbox.curselection()
        self._populate_server_listbox()
        if sel:
            self.server_lbox.selection_set(sel[0])
        self._update_server_buttons()

    def _server_listbox_select(self, event=None):
        try:
            sel = int(self.server_lbox.curselection()[0])
            servers = self.servers.get_servers()
            serv = servers[sel]
            self.muck_entry.delete(0, END)
            self.host_entry.delete(0, END)
            self.port_entry.delete(0, END)
            self.muck_entry.insert(END, serv.name)
            self.host_entry.insert(END, serv.host)
            self.port_entry.insert(END, serv.port)
            self.ssl_enable.set(serv.ssl)
            self._update_server_buttons()
        except (ValueError, IndexError):
            return

    def _update_server_buttons(self, event=None):
        add_state = 'normal'
        del_state = 'normal'
        save_state = 'normal'
        items = self.server_lbox.curselection()
        if not items:
            del_state = 'disabled'
            if not self.muck_entry.get():
                if not self.host_entry.get():
                    if self.port_entry.get() == '8888':
                        if not self.ssl_enable.get():
                            add_state = 'disabled'
        if not self.host_entry.get() or not self.port_entry.get():
            save_state = 'disabled'
        self.serv_del.config(state=del_state)
        self.serv_add.config(state=add_state)
        self.serv_save.config(state=save_state)
        self.set_next_enabled(
            bool(items or (self.host_entry.get() and self.port_entry.get()))
        )

    def _serv_validate(self):
        self.after_idle(self._update_server_buttons)
        return True

    def _port_validate(self, val):
        self.after_idle(self._update_server_buttons)
        if val == '':
            return True
        try:
            val = int(val)
            return True
        except ValueError:
            self.bell()
        return False

    def _add_server(self):
        self.server_lbox.selection_clear(0, END)
        self.muck_entry.delete(0, END)
        self.host_entry.delete(0, END)
        self.port_entry.delete(0, END)
        self.port_entry.insert(END, '8888')
        self.ssl_enable.set('0')
        self.muck_entry.focus()
        self._update_server_buttons()

    def _del_server(self):
        del_confirmed = askyesno(
            "Delete Server",
            "Are you sure you want to delete this server?",
            parent=self
        )
        if del_confirmed:
            try:
                sel = int(self.server_lbox.curselection()[0])
                self.servers.del_server(sel)
                self.servers.save()
                self._update_server_listbox()
            except (ValueError, IndexError):
                self.bell()

    def _save_server(self):
        sel = -1
        try:
            sel = int(self.server_lbox.curselection()[0])
            self.servers.del_server(sel)
            self._update_server_listbox()
        except (ValueError, IndexError):
            pass
        server = ServerInfo(
            name=self.muck_entry.get(),
            host=self.host_entry.get(),
            port=self.port_entry.get(),
            use_ssl=self.ssl_enable.get()
        )
        self.servers.add_server(server)
        self.servers.save()
        self._update_server_listbox()
        if sel >= 0:
            self.server_lbox.selection_set(sel)
        self._server_listbox_select()
        self._update_server_buttons()

    def _populate_user_listbox(self):
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        serv = self.servers.find_by_host_and_port(host, port)
        self.user_lbox.delete(0, END)
        if not serv:
            return
        for user in serv.get_users():
            self.user_lbox.insert(END, user.user)

    def _update_user_listbox(self):
        sel = self.user_lbox.curselection()
        self._populate_user_listbox()
        if sel:
            self.user_lbox.selection_set(sel[0])
        self._update_user_buttons()

    def _user_listbox_select(self, event=None):
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        serv = self.servers.find_by_host_and_port(host, port)
        if not serv:
            return
        try:
            sel = int(self.user_lbox.curselection()[0])
            users = serv.get_users()
            user = users[sel]
            self.user_entry.delete(0, END)
            self.pass_entry.delete(0, END)
            self.user_entry.insert(END, user.user)
            self.pass_entry.insert(END, user.password)
            self._update_server_buttons()
        except (ValueError, IndexError):
            return

    def _update_user_buttons(self, event=None):
        add_state = 'normal'
        del_state = 'normal'
        save_state = 'normal'
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        serv = self.servers.find_by_host_and_port(host, port)
        if not serv:
            del_state = 'disabled'
            add_state = 'disabled'
            save_state = 'disabled'
        items = self.user_lbox.curselection()
        if not items:
            del_state = 'disabled'
            if not self.user_entry.get():
                if not self.pass_entry.get():
                    add_state = 'disabled'
        if not self.user_entry.get():
            save_state = 'disabled'
        self.user_del.config(state=del_state)
        self.user_add.config(state=add_state)
        self.user_save.config(state=save_state)
        self.set_next_enabled(
            bool(items or (self.user_entry.get() and self.pass_entry.get()))
        )

    def _user_validate(self):
        self.after_idle(self._update_user_buttons)
        return True

    def _add_user(self):
        self.user_lbox.selection_clear(0, END)
        self.user_entry.delete(0, END)
        self.pass_entry.delete(0, END)
        self._update_user_buttons()
        self.user_entry.focus()

    def _del_user(self):
        del_confirmed = askyesno(
            "Delete User",
            "Are you sure you want to delete this user?",
            parent=self
        )
        if del_confirmed:
            host = self.host_entry.get()
            port = int(self.port_entry.get())
            serv = self.servers.find_by_host_and_port(host, port)
            if not serv:
                return
            try:
                sel = int(self.server_lbox.curselection()[0])
                serv.del_user(sel)
                self.servers.save()
                self._update_user_listbox()
            except (ValueError, IndexError):
                self.bell()

    def _save_user(self):
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        serv = self.servers.find_by_host_and_port(host, port)
        if not serv:
            return
        serv.add_user(
            user=self.user_entry.get(),
            password=self.pass_entry.get(),
        )
        self.servers.save()
        self._update_user_listbox()

    def _update_program_buttons(self, event=None):
        self.set_next_enabled(bool(self.prog_entry.get()))

    def _program_validate(self):
        self.after_idle(self._update_program_buttons)
        return True

    def _upload_start(self):
        force_ssl = bool(self.ssl_enable.get())
        host = self.host_entry.get()
        port = int(self.port_entry.get())
        user = self.user_entry.get()
        password = self.pass_entry.get()
        progname = self.prog_entry.get()
        self.upload_lbl.config(text="Connecting to %s:%s..." % (host, port))
        self.progressbar.start()
        self.upthread = UploadThread(
            host, port, force_ssl,
            user, password, progname,
            self.data,
        )
        self.upthread.start()
        self.old_upload_state = ''
        self._update_upload_state()

    def _update_upload_state(self):
        logtxt = self.upthread.get_log_text()
        if logtxt:
            self.console_log.insert(END, logtxt)
            self.console_log.see(END)
        state = self.upthread.state
        self.upload_lbl.config(text=self.upthread.status)
        if state in [UPLOAD_FAIL, UPLOAD_SUCCESS]:
            self.set_finish_enabled(True)
            self.set_cancel_enabled(False)
        else:
            self.after(100, self._update_upload_state)
        if state == UPLOADING:
            uploaded = self.upthread.bytes_uploaded
            total = self.upthread.total_bytes
            pcnt = float(uploaded) / total
            self.progressbar.config(value=pcnt)
        if state == self.old_upload_state:
            return
        self.old_upload_state = state
        if state == UPLOADING:
            self.progressbar.stop()
            self.progressbar.config(mode=DETERMINATE)
        elif state == UPLOAD_FAIL:
            self.progressbar.stop()
            self.progressbar.grid_forget()
        elif state == UPLOAD_SUCCESS:
            self.progressbar.stop()
            self.progressbar.config(mode=DETERMINATE)
            self.progressbar.config(value=100.0)

    def _handle_cancel(self):
        self.destroy()

    def _handle_finish(self):
        self.destroy()
示例#34
0
class facades_main(Tkinter.Tk):
    
    def __init__(self, parent):
        Tkinter.Tk.__init__(self, parent)
        self.parent = parent

        self.initialize()
        self.clock_tick()

    def update_val_from_entry(self):
          global G_RUN_STATUS
          global G_SHUTDOWN_DELAY
          global G_WAKEUP_AFTER
          global G_LOOP_NUMBER
          global G_LONGRUN_ACTION
          G_SHUTDOWN_DELAY = int(self.entry_second.get(), base=10)
          G_WAKEUP_AFTER = int(self.entry_wakeafter.get(), base=10)
          G_LOOP_NUMBER = int(self.entry_loop.get(), base=10)
          G_LONGRUN_ACTION = self.var_action.get()

    def reset_rtcdata(self):
        efiapi = WinApiEfiVariables()
        rtcdata = efiapi.read(UEFI_VAR_NAME, UEFI_VAR_GUID)
        data = RtcWakeData(*struct.unpack_from(RTC_WAKE_DATA_FORMAT, rtcdata))
        #just reset to not wake up
        data2 = data._replace(Alarm_Wake=3,Alarm_Week=0, \
                          RtcWakeTime_Hour= 0, \
                          RtcWakeTime_Minute= 0, \
                          RtcWakeTime_Second= 0
                          )
        rtcdata = data2.packstring()
        efiapi.write(UEFI_VAR_NAME, UEFI_VAR_GUID, rtcdata)
        
    def func_shutdown(self):
        global G_CURRENT_LOOPNUM 
        G_CURRENT_LOOPNUM += 1
        self.confighandle.set_config('run_status', 'True')
        self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
        self.confighandle.update_file()
        
        if (G_LONGRUN_ACTION == 4):
          print "reboot"
          Hour = int(time.strftime("%H"), 10)
          Minute = int(time.strftime("%M"), 10)
          Second = int(time.strftime("%S"), 10)
          self.logger.info("reboot time: %d:%d:%d" %(Hour, Minute, Second))
          os.system('shutdown /r /f /t 0')
          while(1):
            pass

        efiapi = WinApiEfiVariables()
        rtcdata = efiapi.read(UEFI_VAR_NAME, UEFI_VAR_GUID)
        data = RtcWakeData(*struct.unpack_from(RTC_WAKE_DATA_FORMAT, rtcdata))

        (Hour, Minute, Second) = self.CalAlarmTimer()
        data2 = data._replace(Alarm_Wake=1,Alarm_Week=0, \
                          RtcWakeTime_Hour= Hour, \
                          RtcWakeTime_Minute= Minute, \
                          RtcWakeTime_Second= Second
                          )
        rtcdata = data2.packstring()
        efiapi.write(UEFI_VAR_NAME, UEFI_VAR_GUID, rtcdata)

        
        if (G_LONGRUN_ACTION == 3):
          print "shutdown"
          os.system('shutdown /s /f /t 0')
          
        if (G_LONGRUN_ACTION == 2):
          print "suspend"
          os.system('rundll32.exe PowrProf.dll,SetSuspendState')
        if (G_LONGRUN_ACTION == 1):
          print "sleep"
          os.system('rundll32.exe powrprof.dll,SetSuspendState 0,1,0')
        
    def CalAlarmTimer(self):
        Hour = int(time.strftime("%H"), 10)
        Minute = int(time.strftime("%M"), 10)
        Second = int(time.strftime("%S"), 10)
        print "current time:", Hour, Minute, Second
        print "wake after:", G_WAKEUP_AFTER
        self.logger.info("current time: %d:%d:%d" %(Hour, Minute, Second))
        #
        total_secs = Hour*3600 + Minute*60 + Second
        total_secs += G_WAKEUP_AFTER
        total_secs += G_SHUTDOWN_DELAY
        #
        Hour = total_secs / 3600
        Minute = (total_secs % 3600) / 60
        Second = (total_secs % 3600) % 60
        if Hour >= 24:
            Hour = 0
        print "wake time: %d:%d:%d" %(Hour, Minute, Second)
        self.logger.info("wake time: %d:%d:%d" %(Hour, Minute, Second))
        return (Hour,Minute,Second)

    def clock_tick(self):
        now = time.strftime("%H:%M:%S")
        self.label_ticker.configure(text=now)
        self.label_ticker.after(200, self.clock_tick)

    def clock_timeout(self):
        count = self.entry_second.get()
        #print count
        count = int(count, 10)
        print count
        if (G_RUN_STATUS):
          if (count > 0):
            self.count_second.set(count - 1)
            self._job = self.entry_second.after(1000, self.clock_timeout)
        if (count == 0):
            print "function to action!"
            self.func_shutdown()
        
    def initialize(self):
        global G_RUN_STATUS
        global G_SHUTDOWN_DELAY
        global G_WAKEUP_AFTER
        global G_LOOP_NUMBER
        global G_CURRENT_LOOPNUM
        global G_LONGRUN_ACTION
        self.geometry("400x450+300+100")
        self.minsize(350,250)
        self.grid()

        self._job = None
        self.confighandle = lrConfigParser(configfn)
        
        self.count_second = Tkinter.IntVar()
        self.str_action = Tkinter.StringVar()
        self.var_action = Tkinter.IntVar()
        self.loop_number = Tkinter.IntVar()
        self.current_loop = Tkinter.IntVar()
        self.wake_after = Tkinter.IntVar()
        self.str_start = Tkinter.StringVar()
              
        self.var_action.set(G_LONGRUN_ACTION )
        self.count_second.set(G_SHUTDOWN_DELAY)
        self.loop_number.set(G_LOOP_NUMBER)
        self.current_loop.set(G_CURRENT_LOOPNUM)
        self.wake_after.set(G_WAKEUP_AFTER)
        if (G_LONGRUN_ACTION == 4):
          self.str_action.set("reboot  ")
        if (G_LONGRUN_ACTION == 3):
          self.str_action.set("Shutdown")
        self.log_queue = Queue.Queue()
        
        self.label_blank = Tkinter.Label(self, text='')
        self.label_ticker = Tkinter.Label(self, text="test",anchor='e',font=('times', 20, 'bold'), bg='green')
        self.entry_second = Tkinter.Entry(self, text=self.count_second, font=('times', 20, 'bold'),width=5)
        self.label_str1 = Tkinter.Label(self, text='seconds to',font=('times', 20, 'bold'))
        self.label_str2 = Tkinter.Label(self, text='Loop',font=('times', 20, 'bold'))
        self.label_str3 = Tkinter.Label(self, text='seconds to',font=('times', 20, 'bold'))
        self.label_str4 = Tkinter.Label(self, text='wakeup', font=('times', 20, 'bold'))
        self.entry_wakeafter = Tkinter.Entry(self, text=self.wake_after, font=('times', 20, 'bold'),width=5)
        self.label_str_action = Tkinter.Label(self, textvariable=self.str_action, font=('times', 20, 'bold'))
        self.radiobtn_s3 = Tkinter.Radiobutton(self, text='S3',variable=self.var_action, value=1, command=self.radiobtn_callback, state='disabled')
        self.radiobtn_s4 = Tkinter.Radiobutton(self, text='S4',variable=self.var_action, value=2, command=self.radiobtn_callback, state='disabled')
        self.radiobtn_s5 = Tkinter.Radiobutton(self, text='S5',variable=self.var_action, value=3, command=self.radiobtn_callback)
        self.radiobtn_reboot = Tkinter.Radiobutton(self, text='reboot',variable=self.var_action, value=4, command=self.radiobtn_callback)
        self.entry_loop = Tkinter.Entry(self, text=self.loop_number, font=('times', 20, 'bold'),width=5)
        self.btn_start = Tkinter.Button(self, text="Start",bg="green",font=('times', 20, 'bold'), command=self.btn_start_callback)
        self.btn_edit = Tkinter.Button(self, text="Edit", font=('times', 20, 'bold'), state="disabled", command=self.btn_edit_callback)
        self.label_current_loop = Tkinter.Label(self, textvariable=self.current_loop, font=('times', 20, 'bold'))
        self.btn_clrlog = Tkinter.Button(self, text="Clear Log",font=('times', 15, 'bold'), command=self.btn_clearlog_callback)
        self.log_widget = ScrolledText(self, width = 50, heigh = 15)
        
        
        self.label_blank.grid(row=0,column=0,ipadx=20)
        self.label_ticker.grid(row=0,column=2,sticky='w')
        self.entry_second.grid(row=1,column=0)
        self.label_str1.grid(row=1,column=1,sticky='w')
        self.label_str_action.grid(row=1,column=2,sticky='w')
        self.entry_loop.grid(row=2,column=0)
        self.label_str2.grid(row=2, column=1,sticky='w')
        self.radiobtn_s3.grid(row=2,column=2,sticky='w')
        self.radiobtn_s4.grid(row=2,column=2,sticky='w', padx=40)
        self.radiobtn_s5.grid(row=2,column=2,sticky='w', padx=80)
        self.radiobtn_reboot.grid(row=2,column=2,sticky='w',padx=120)
        self.entry_wakeafter.grid(row=3, column=0)
        self.label_str3.grid(row=3, column=1)
        self.label_str4.grid(row=3, column=2,sticky='w')
        self.label_blank.grid(row=4,column=0)
        self.btn_start.grid(row=5, column=0)
        self.btn_edit.grid(row=5, column=1)
        self.btn_clrlog.grid(row=5,column=2,sticky='w')
        self.label_current_loop.grid(row=5, column=2,sticky='w',padx=120)
        self.log_widget.grid(row=6, column=0, columnspan=3, sticky='w')

        #init log queue
        self.logger = logging.getLogger(logfn)
        self.logger.setLevel(logging.INFO)
        logformat = logging.Formatter(LOG_FORMAT)
        hl = QueueLogger(queue=self.log_queue)
        hl.setFormatter(logformat)
        self.logger.addHandler(hl)

        self.start_logwidget()

        if G_CURRENT_LOOPNUM <= G_LOOP_NUMBER:
          if G_RUN_STATUS:
              print "auto run loop %d" %(G_CURRENT_LOOPNUM)
              self.logger.info("\ncurrent loop: %d" %(G_CURRENT_LOOPNUM))
              self.btn_start_callback()
        else:
          print "loop pass!"
          self.current_loop.set(G_CURRENT_LOOPNUM-1)
          
          if G_RUN_STATUS:
            print "reset run status here"
            G_RUN_STATUS = False
            G_CURRENT_LOOPNUM -= 1
            self.current_loop.set(str(G_CURRENT_LOOPNUM))
            self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
            self.confighandle.update_file()
            self.reset_rtcdata()

    def radiobtn_callback(self):
        global G_LONGRUN_ACTION
        seltmp = self.var_action.get()
        G_LONGRUN_ACTION = seltmp
        if (seltmp == 4):
            self.str_action.set("reboot")
        if (seltmp == 3):
            self.str_action.set("Shutdown")
        if (seltmp == 2):
            self.str_action.set("Suspend ")
        if (seltmp == 1):
            self.str_action.set("Sleep   ")

    def btn_clearlog_callback(self):
        global G_CURRENT_LOOPNUM
        self.log_widget.config(state='normal')
        self.log_widget.delete(0.0, Tkinter.END)
        self.log_widget.config(state='disabled')

        if os.path.isfile(logfn):
            with open(logfn, 'w'):
                pass
        #reset current loop to zero
        if G_CURRENT_LOOPNUM != 0:
          G_CURRENT_LOOPNUM = 0
          self.confighandle.set_config('current_loop', str(G_CURRENT_LOOPNUM))
          self.confighandle.update_file()
          self.current_loop.set(G_CURRENT_LOOPNUM)


    def btn_start_callback(self):
        global G_RUN_STATUS
        global G_EDITABLE
        if G_EDITABLE:
          G_EDITABLE = False
          print "set get from entry"
          self.update_val_from_entry()
          self.confighandle.set_config('shutdown_delay', str(G_SHUTDOWN_DELAY))
          self.confighandle.set_config('loop_number', str(G_LOOP_NUMBER))
          self.confighandle.set_config('wake_after', str(G_WAKEUP_AFTER))
          self.confighandle.set_config('longrun_action', str(G_LONGRUN_ACTION))
          self.confighandle.update_file()
        
        self.btn_start.config(text='Stop ', bg = "red", command=self.btn_stop_callback)
        self.entry_second.config(state='disabled')
        self.entry_loop.config(state='disabled')
        self.btn_edit.config(state='disabled')
        self.entry_wakeafter.config(state='disabled')
        G_EDITABLE = False

        if not G_RUN_STATUS:
          G_RUN_STATUS = True
        self.clock_timeout()
        

    def btn_stop_callback(self):
        global G_RUN_STATUS
        G_RUN_STATUS = False
        self.btn_start.config(text="Start", bg = "green", command=self.btn_start_callback)
        self.btn_edit.config(state='normal')
        
        self.confighandle.set_config('run_status', str(G_RUN_STATUS))
        self.confighandle.update_file()

        self.reset_rtcdata()


    def btn_edit_callback(self):
        global G_EDITABLE
        print "edit callback, to enable change variables"
        self.btn_edit.config(text="Apply", command=self.btn_apply_callback)
        self.entry_second.config(state='normal')
        self.entry_loop.config(state='normal')
        self.entry_wakeafter.config(state='normal')
        G_EDITABLE = True

    def btn_apply_callback(self):
        global G_EDITABLE
        print "apply callback, save changes to cfg file after edit"
        self.btn_edit.config(text="Edit", command=self.btn_edit_callback)
        self.entry_second.config(state='disabled')
        self.entry_loop.config(state='disabled')
        self.entry_wakeafter.config(state='disabled')
        G_EDITABLE = False
        
        self.update_val_from_entry()
        ##update into cfg file
        self.confighandle.set_config('shutdown_delay', str(G_SHUTDOWN_DELAY))
        self.confighandle.set_config('loop_number', str(G_LOOP_NUMBER))
        self.confighandle.set_config('wake_after', str(G_WAKEUP_AFTER))
        self.confighandle.set_config('longrun_action', str(G_LONGRUN_ACTION))
        self.confighandle.update_file()

    def start_logwidget(self):
        if os.path.isfile(logfn):
            self.log_widget.config(state='normal')
            print "read log file into log widget"
            with open(logfn) as fin:
                for line in fin:
                    self.log_widget.insert(Tkinter.END, line)
                    self.log_widget.see(Tkinter.END)
                    self.log_widget.update_idletasks()
            self.log_widget.config(state='disabled')

        self.update_logwidget(self.log_widget, self.log_queue)

    def update_logwidget(self, widget, queue):
        widget.config(state='normal')
        while not queue.empty():
            line = queue.get()
            widget.insert(Tkinter.END, line)
            widget.see(Tkinter.END)
            widget.update_idletasks()
        widget.config(state='disabled')
        self.logger_alarm = widget.after(10, self.update_logwidget, widget, queue)
示例#35
0
class myPanel(tkinter.Tk):
    def __init__(self):
        tkinter.Tk.__init__(self, 'lsx')

        try:
            self.ss = self.clipboard_get()
        except:
            self.ss = ''
        self.cnt = 0
        self.slices = paragraph(self.ss, qrlen)
        self.string = None

        if not os.path.exists('config.ini'):
            x = - 100 + 0.2 * self.winfo_screenwidth() # 100: 补偿初始Tk界面为200x200
            y = - 100 + 0.7 * self.winfo_screenheight()
            xy = '+%d+%d'%(x,y)
            with open('config.ini','w') as f:
                f.write(xy)
        with open('config.ini','r') as f:
            xy = f.read()
        self.geometry(xy)
        self.minsize(450,206)

        self.qrc = tkinter.Label(self)
        self.ent = ScrolledText(self, width=1, height=15)
        self.ent.insert(1.0, self.ss)
        self.ent.mark_set('insert','0.0') # 程序首次运行时不使用see函数,否则会有未知原因半行内容沉没在Text窗体上面一点点
        self.ent.focus()

        text = self.slices[self.cnt]
        basic = (len(self.slices),len(self.ss))
        info = 'Page: %s, Length: %s'%basic
        if zh_cn:
            info = '共%s页, %s字'%basic

        self.withdraw() # withdraw/deiconify 阻止页面闪烁
        self.update_idletasks()
        self.ent.pack(padx=2, pady=2, fill='both', expand=True, side='right') # RIGHT为了在Label隐藏再显示后所在位置一致
        self.qrc.pack()
        self.setQrcode(text, info)
        self.deiconify()

        self.qrc.bind('<Button-2>',self.onExit)
        self.qrc.bind('<Button-1>',self.fliping)
        self.qrc.bind('<Button-3>',self.fliping)
        self.qrc.bind('<Double-Button-1>',self.setting)
        self.qrc.bind('<Double-ButtonRelease-3>',self.openFile) # 没有Release会在窗口打开之后的鼠标抬起时唤起右键菜单

        self.ent.bind('<Escape>',self.onExit)
        self.ent.bind('<F1>',self.openFile)
        self.ent.bind('<F2>',self.fliping)
        self.ent.bind('<F3>',self.fliping)
        self.ent.bind('<F4>',self.setting)

        self.ent.bind('<KeyRelease>',self.refresh)
        self.ent.bind('<ButtonRelease-1>',self.selected)
        self.bind('<Destroy>',lambda evt:self.onExit(evt,close=True))

    def setQrcode(self, string, info):
        if self.string != string:
            self.string = string
            if string == '':
                self.qrc.forget()
            else:
                global img
                img = qrmake(string)
                self.qrc.config(image=img)
                self.qrc.pack()
        log(string, info)
        self.title('Text Helper v1.06 (%s)'%info)
        if zh_cn:
            self.title('文本助手v1.06 (%s)'%info)

    def refresh(self, evt):
        if evt.keysym in ['Control_L', 'Return', 'BackSpace']:
            ss2 = self.ent.get('0.0', 'end')[:-1]
            if self.ss != ss2:
                self.ss = ss2
                self.cnt = 0
                self.slices = paragraph(self.ss, qrlen)

            text = self.slices[self.cnt]
            basic = (len(self.slices),len(self.ss))
            info = 'Page: %s, Length: %s'%basic
            if zh_cn:
                info = '共%s页, %s字'%basic
            self.setQrcode(text, info)

    def fliping(self, evt):
        if evt.num == 1 or evt.keysym == 'F3':
            self.cnt = min(self.cnt+1,len(self.slices)-1)
        else:
            self.cnt = max(self.cnt-1,0)
        cur1 = getIndex(''.join(self.slices[:self.cnt]))
        cur2 = getIndex(''.join(self.slices[:self.cnt+1]))
        self.setCursor(cur1, cur2)

        text = self.slices[self.cnt]
        basic = (self.cnt+1,len(self.slices),len(text),len(self.ss))
        info = 'Page: %s/%s, Sel: %s/%s'%basic
        if zh_cn:
            info = '第%s/%s页, 共%s/%s字'%basic
        self.setQrcode(text, info)

    def selected(self, evt):
        if self.ent.tag_ranges('sel'):
            text = self.ent.selection_get()
            info = 'Sel: %s/%s'%(len(text),len(self.ss))
            if zh_cn:
                info = '选中%s/%s字'%(len(text),len(self.ss))
            self.setQrcode(text, info)

    def setCursor(self, cur1, cur2):
        self.ent.mark_set('insert', cur1)
        self.ent.tag_remove('sel','0.0','end')
        self.ent.tag_add('sel',cur1,cur2)
        self.ent.see(cur1)

    def setting(self, evt):
        max_page = len(self.slices)
        num = tkinter.simpledialog.askinteger('Goto','Go to page (1-%s):'%max_page, initialvalue=self.cnt+1)
        self.ent.focus()
        if num:
            self.cnt = max(1,min(max_page,num)) - 1

            text = self.slices[self.cnt]
            basic = (self.cnt+1,len(self.slices),len(text),len(self.ss))
            info = 'Page: %s/%s, Sel: %s/%s'%basic
            if zh_cn:
                info = '第%s/%s页, 共%s/%s字'%basic
            self.setQrcode(text, info)

    def openFile(self, evt):
        path = tkinter.filedialog.askopenfilename()
        if path != '':
            filename = os.path.basename(path)
            with open(path,'rb') as f:
                s = f.read()
            try:
                try:
                    res = s.decode()
                except:
                    try:
                        res = s.decode('gbk')
                    except:
                        raise
            except:
                s = base64.urlsafe_b64encode(filename.encode()+b'\n'+s).decode()
                total = int((len(s)-1)/(qrlen-10)+1)
                res = ''
                for i in range(total):
                    res += '%04d%04d.%s,'%(total, i+1, s[(qrlen-10)*i:(qrlen-10)*(i+1)])

            self.ss = res
            self.cnt = 0
            self.slices = paragraph(self.ss, qrlen)
            self.ent.delete(1.0, 'end')
            self.ent.insert(1.0, res)

            text = self.slices[self.cnt]
            basic = (len(self.slices),len(self.ss))
            info = 'Page: %s, Length: %s'%basic
            if zh_cn:
                info = '共%s页, %s字'%basic
            self.setQrcode(text, info)

    def onExit(self, evt, close=False):
        xy = '+%d+%d'%(self.winfo_x(),self.winfo_y())
        with open('config.ini','w') as f:
            f.write(xy)
        if not close:
            self.destroy()
示例#36
0
class client_GUI(Thread):

    alias = None
    room = None
    flag = False
    in_room = False
    client = socket()
    IP = raw_input("IP Address: ")
    if not IP:
        IP = 'localhost'
    try:
        client.connect((IP, 9000))
    except Exception as e:
        print "Could not connect to IP"
        logging.exception(e)
        exit()

    def __init__(self, master):
        Thread.__init__(self)
        frame = Frame(master)
        frame.pack()
        self.setAlias()

    #creates the thread for listening to the Server
    def run(self):
        Recieve(self.client)

    def clearWindow(self):
        for widget in root.winfo_children():
            widget.destroy()

    def assemble_packet(self, msg, code):
        parser = Parser()
        if code == utils.codes["send_msg"]:
            date = datetime.datetime.now().strftime(utils.DATE_FORMAT)
            packet = parser.assemble(utils.codes["send_msg"], self.alias,
                                     self.room, date, msg)
        elif code == utils.codes["set_alias"]:
            packet = parser.assemble(utils.codes["set_alias"], msg, "", "", "")
        elif code == utils.codes["set_room"]:
            packet = parser.assemble(utils.codes["set_room"], self.alias, msg,
                                     "", "")
        elif code == utils.codes["get_roomlist"]:
            packet = parser.assemble(utils.codes["get_roomlist"], self.alias,
                                     self.room, "", "")
        logging.info("Sending packet %s" % (packet))
        return packet

    def breakdown_packet(self, packet):
        parser = Parser()
        parser.breakdown(packet)
        if parser.code == utils.codes["recv_msg"]:
            return parser.body
        elif parser.code == utils.codes["recv_roomlist"]:
            return parser.body
        elif parser.code == utils.codes["alias_success"]:
            self.alias = parser.alias
            return parser.body
        elif parser.code == utils.codes["alias_invalid"]:
            return parser.alias
        elif parser.code == utils.codes["room_success"]:
            self.room = parser.room
            return parser.room
        elif parser.code == utils.codes["room_invalid"]:
            return parser.room
        else:
            logging.info("Invalid packet recieved")
            return

    def setAlias(self):
        def setRoom():
            aliasCheck = None
            self.alias = self.aliasInfo.get().translate(None, '\\')
            self.alias = self.alias.translate(None, ' ')
            if len(self.alias) > 20:
                self.alias = self.alias[:19]
            packet = self.assemble_packet(self.alias, utils.codes["set_alias"])
            try:
                self.client.send(packet)
            except Exception as e:
                logging.exception(e)
            time.sleep(1)
            if not inputQueue.empty():
                aliasCheck = str(inputQueue.get())
                if aliasCheck.startswith(utils.codes["alias_success"]):
                    roomList = self.breakdown_packet(aliasCheck)
                    self.clearWindow()
                    self.changeRoom(roomList)
                else:
                    self.flag = True
                    self.clearWindow()
                    self.setAlias()
            else:
                self.flag = True
                self.clearWindow()
                self.setAlias()

        self.intro = Label(root,
                           text="Welcome to TrashTalk",
                           width=600,
                           font=8000,
                           fg="red",
                           pady=100)
        self.intro.pack(anchor=CENTER)
        self.aliasLabel = Label(root, text="Set Your Alias:", pady=10)
        self.aliasLabel.pack(anchor=CENTER)
        self.aliasInfo = Entry(root, width=40)
        self.aliasInfo.pack(anchor=CENTER)
        self.spacing = Label(root, text="", pady=70)
        if self.flag:
            self.spacing.config(text="Invalid, please try again", fg="red")
        self.spacing.pack(anchor=CENTER)
        self.login = Button(root,
                            height=2,
                            width=10,
                            text="Pick A Room",
                            command=setRoom)
        self.login.pack(anchor=CENTER)

    def changeRoom(self, roomList):
        def enterRoom():
            self.clearWindow()
            chosenRoom = self.v.get()
            if not chosenRoom:
                chosenRoom = firstRoom
            packet = self.assemble_packet(chosenRoom, utils.codes["set_room"])
            try:
                self.client.send(packet)
            except Exception as e:
                logging.exception(e)
            time.sleep(1)
            if not inputQueue.empty():
                roomCheck = str(inputQueue.get())
                if roomCheck.startswith(utils.codes["room_success"]):
                    self.room = chosenRoom
                    self.in_room = True
                    self.inRoom(chosenRoom)
            else:
                self.changeRoom(roomList)

        root.title("TrashTalk")
        rooms = roomList.split()
        firstRoom = rooms[0]
        self.v = StringVar(value=firstRoom)
        self.roomLabel = Label(
            root,
            text="Select which Chat Room You Would Like to Join",
            pady=70,
            font=800)
        self.roomLabel.pack(anchor=CENTER)
        for room in rooms:
            self.b = Radiobutton(root, text=room, variable=self.v, value=room)
            self.b.pack(anchor=CENTER)
        self.b.deselect()
        self.login = Button(root,
                            height=2,
                            width=20,
                            text="Enter Chosen Room",
                            command=enterRoom)
        self.login.place(relx=0.5, y=400, anchor=CENTER)

    def inRoom(self, room):
        def newMessage():
            message = self.entryBox.get()
            if message:
                self.entryBox.delete(0, 'end')
                message = message.translate(None, '\\')
                if len(message) > 900:
                    message = message[:899]
                packet = self.assemble_packet(message, utils.codes["send_msg"])
                try:
                    self.client.send(packet)
                except Exception as e:
                    logging.exception(e)

        def changingRoom():
            packet = self.assemble_packet("", utils.codes["get_roomlist"])
            try:
                self.client.send(packet)
            except Exception as e:
                logging.exception(e)
            time.sleep(1)
            if not inputQueue.empty():
                roomCheck = str(inputQueue.get())
                if roomCheck.startswith(utils.codes["recv_roomlist"]):
                    in_room = False
                    roomList = self.breakdown_packet(roomCheck)
                    self.clearWindow()
                    self.changeRoom(roomList)

        def exitProgram():
            self.client.close()
            os._exit(1)

        root.title("TrashTalk - " + room)
        self.messageHistory = ScrolledText(root, undo=True)
        self.messageHistory.bind("<Key>", lambda e: "break")
        self.messageHistory.pack(anchor=W)
        self.messageHistory.insert(
            END, "Welcome " + self.alias + " to the " + room + " chat room!")
        self.entryBox = Entry(root, width=85)
        self.entryBox.place(x=0, y=400, anchor=W)
        self.sendButton = Button(root,
                                 height=2,
                                 width=19,
                                 text="Send Message",
                                 command=newMessage)
        self.sendButton.place(x=518, y=388, anchor=NW)
        self.sendButton = Button(root,
                                 height=4,
                                 width=25,
                                 text="Change Room",
                                 command=changingRoom)
        self.sendButton.place(x=725, y=300, anchor=NW)
        self.sendButton = Button(root,
                                 height=4,
                                 width=25,
                                 text="Quit",
                                 command=exitProgram)
        self.sendButton.place(x=725, y=400, anchor=NW)

        def update_chat():
            if not buildQueue.empty():
                MYINFO = buildQueue.get()
                if MYINFO.startswith(utils.codes["leave_room"]):
                    changingRoom()
                elif self.in_room:
                    msg = self.breakdown_packet(MYINFO)
                    endOfBox = self.messageHistory.vbar.get()
                    self.messageHistory.insert(END, "\n" + msg)
                    if endOfBox[1] == 1.0:
                        endOfBox = self.messageHistory.see("end")
            root.after(100, update_chat)

        root.after(100, update_chat)