Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
from Tkinter import *
root = Tk()
w = Label(root, text="Hello, world!")
w.pack()
root.mainloop()

There may be the remembering of the 'overview' interface: it displays current tasks in submitted, active and aborted states from a server.

...

Queue module shall then be used to deal with the asynchronous aspect.

A contextual menu is added to display task manual, script, job, or output, when available.

Code Block
themeEmacs
languagepython
titleOverview
collapsetrue
import Tkinter as tk
import ecflow  as ec
from threading import Thread
import Queue
import sys
PROGRAM_NAME =  "ecflowview-overview"
BUTTON_FONT  =  ('times', 12)
MONO_FONT    =  ('lucidatypewriter', 14, 'bold')
class MenuBar(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        self.__helpButton = self.__createHelp()
        self.__helpButton.grid(row=0, column=3)
        self.__updateButton = tk.Button(self, text='Update',
                                        font= BUTTON_FONT,
                                        command= parent.update)
        self.__updateButton.grid(row=0, column=2)
        self.__quitButton = tk.Button(
            self, text='Quit',
            font= BUTTON_FONT, command= self.quit)
        self.__quitButton.grid(row=0, column=0)
        
    def __createHelp(self):
        mb = tk.Menubutton(self, font=BUTTON_FONT,
                        relief= tk.RAISED,
                        text= 'Help')
        menu = tk.Menu(mb)
        mb['menu'] = menu
        return mb
from scrolledlist import ScrolledList
class TaskList(tk.Frame):
    NAME_WIDTH = 80
    NAME_LINES = 22
    def __init__(self, parent, kind):
        tk.Frame.__init__(self, parent)
        self.__kind = kind
        self.__callback = None
        self.__label = tk.Label(self, font=BUTTON_FONT,
                                text= kind)
        rowx = 0
        self.__label.grid(row=rowx, column=0, sticky= tk.W)
        rowx += 1
        self.__scrolledList = ScrolledList(
            self, 
            width= self.NAME_WIDTH,
            height= self.NAME_LINES,
            callback= self.__callback)
        self.__scrolledList.grid(row=rowx, column=0)
    def insert(self, node):
        self.__scrolledList.append(node.get_abs_node_path())
    def clear(self): 
        self.__scrolledList.clear()
running = [True]
class PaceKeeper():
    PACE = 60
    def __init__(self, item, queue): 
        thr = Thread(target=self.process, 
               args=(queue, running))
        self._item = item
        thr.start()
        
    def process(self, queue, running):
        import time
        while running:
            queue.put(self._item.update)
            time.sleep(self.PACE)
    def run(self): self.update()
    def update(self, verbose=False): 
        import time
        while True:
            print time.clock()
            self._item.update()
            time.sleep(self.PACE)
    
class Application(tk.Frame):
    def __init__(self, master=None, client=None, queue=None):
        tk.Frame.__init__(self, master)
        self.__client = client
        self.__queue = queue
        # if client is None: self.__client = ec.Client("localhost", 31415)
        width = 400
        height = 300
        self.canvas = tk.Canvas(width=width, height=height, bg='black')
        self.grid()
        self.createWidgets()
        self.canvas.after(50, self.check_queue)
    def createWidgets(self):
        if 0:
            self.quitButton = tk.Button(self, text='Quit',
                                        command=self.quit)
            self.quitButton.grid(row=1, column=1)
        self.__menuBar = MenuBar(self)
        self.__menuBar.grid(row=0, column=0, columnspan=3,
                            sticky=tk.W)
        self.__wins = dict()
        rowx = 1
        colx = 0
        for kind in ("active", "aborted", "submitted"):
            self.__wins[kind] = TaskList(self, kind)
            self.__wins[kind].grid(row=rowx, column= colx)
            colx += 1
        self.update()
    def check_queue(self):
        try: 
            self.__queue.get(block=False)
        except Queue.Empty: 
            pass
        else: 
            self.update()
        self.canvas.after(50, self.check_queue)
    def process_node(self, node):
        for kind, win in self.__wins.items():
            status = "%s" % node.get_state()
            if status != kind: continue
            win.insert(node)
            print node.get_abs_node_path(), status
    def process_nc(self, node):
        for node in node.nodes:
            if not isinstance(node, ec.Task):
                self.process_nc(node)
            else:
                self.process_node(node)
    def update(self):
        self.__client.sync_local() # get changes, 
        defs = self.__client.get_defs()
        if defs is None: raise BaseException("empty content")
        for kind, win in self.__wins.items(): 
            win.clear()
        print 
        for suite in defs.suites: 
            self.process_nc(suite)
def get_username():
    return pwd.getpwuid( os.getuid() )[ 0 ]

if __name__ == '__main__':
    host = "localhost"
    port = 31415
    if len(sys.argv) > 2:
        host = sys.argv[1]
        port = int(sys.argv[2])
    print "# " + PROGRAM_NAME + ": contact is %s %d" % ( host, port)
    queue = Queue.Queue()
    if port < 65535 or sys.argv[-1] != "sms":
        client = ec.Client(host, port)
        app = Application(client=client, queue=queue)
    else: app = AppSms(host, port, queue)
    app.master.title(PROGRAM_NAME)
    PaceKeeper(app, queue)
    app.mainloop()

...