python-2.5.2/win32/Tools/webchecker/wsgui.py
changeset 0 ae805ac0140d
equal deleted inserted replaced
-1:000000000000 0:ae805ac0140d
       
     1 #! /usr/bin/env python
       
     2 
       
     3 """Tkinter-based GUI for websucker.
       
     4 
       
     5 Easy use: type or paste source URL and destination directory in
       
     6 their respective text boxes, click GO or hit return, and presto.
       
     7 """
       
     8 
       
     9 from Tkinter import *
       
    10 import Tkinter
       
    11 import websucker
       
    12 import sys
       
    13 import os
       
    14 import threading
       
    15 import Queue
       
    16 import time
       
    17 
       
    18 VERBOSE = 2
       
    19 
       
    20 
       
    21 try:
       
    22     class Canceled(Exception):
       
    23         "Exception used to cancel run()."
       
    24 except (NameError, TypeError):
       
    25     Canceled = __name__ + ".Canceled"
       
    26 
       
    27 
       
    28 class SuckerThread(websucker.Sucker):
       
    29 
       
    30     stopit = 0
       
    31     savedir = None
       
    32     rootdir = None
       
    33 
       
    34     def __init__(self, msgq):
       
    35         self.msgq = msgq
       
    36         websucker.Sucker.__init__(self)
       
    37         self.setflags(verbose=VERBOSE)
       
    38         self.urlopener.addheaders = [
       
    39             ('User-agent', 'websucker/%s' % websucker.__version__),
       
    40         ]
       
    41 
       
    42     def message(self, format, *args):
       
    43         if args:
       
    44             format = format%args
       
    45         ##print format
       
    46         self.msgq.put(format)
       
    47 
       
    48     def run1(self, url):
       
    49         try:
       
    50             try:
       
    51                 self.reset()
       
    52                 self.addroot(url)
       
    53                 self.run()
       
    54             except Canceled:
       
    55                 self.message("[canceled]")
       
    56             else:
       
    57                 self.message("[done]")
       
    58         finally:
       
    59             self.msgq.put(None)
       
    60 
       
    61     def savefile(self, text, path):
       
    62         if self.stopit:
       
    63             raise Canceled
       
    64         websucker.Sucker.savefile(self, text, path)
       
    65 
       
    66     def getpage(self, url):
       
    67         if self.stopit:
       
    68             raise Canceled
       
    69         return websucker.Sucker.getpage(self, url)
       
    70 
       
    71     def savefilename(self, url):
       
    72         path = websucker.Sucker.savefilename(self, url)
       
    73         if self.savedir:
       
    74             n = len(self.rootdir)
       
    75             if path[:n] == self.rootdir:
       
    76                 path = path[n:]
       
    77                 while path[:1] == os.sep:
       
    78                     path = path[1:]
       
    79                 path = os.path.join(self.savedir, path)
       
    80         return path
       
    81 
       
    82     def XXXaddrobot(self, *args):
       
    83         pass
       
    84 
       
    85     def XXXisallowed(self, *args):
       
    86         return 1
       
    87 
       
    88 
       
    89 class App:
       
    90 
       
    91     sucker = None
       
    92     msgq = None
       
    93 
       
    94     def __init__(self, top):
       
    95         self.top = top
       
    96         top.columnconfigure(99, weight=1)
       
    97         self.url_label = Label(top, text="URL:")
       
    98         self.url_label.grid(row=0, column=0, sticky='e')
       
    99         self.url_entry = Entry(top, width=60, exportselection=0)
       
   100         self.url_entry.grid(row=0, column=1, sticky='we',
       
   101                     columnspan=99)
       
   102         self.url_entry.focus_set()
       
   103         self.url_entry.bind("<Key-Return>", self.go)
       
   104         self.dir_label = Label(top, text="Directory:")
       
   105         self.dir_label.grid(row=1, column=0, sticky='e')
       
   106         self.dir_entry = Entry(top)
       
   107         self.dir_entry.grid(row=1, column=1, sticky='we',
       
   108                     columnspan=99)
       
   109         self.go_button = Button(top, text="Go", command=self.go)
       
   110         self.go_button.grid(row=2, column=1, sticky='w')
       
   111         self.cancel_button = Button(top, text="Cancel",
       
   112                         command=self.cancel,
       
   113                                     state=DISABLED)
       
   114         self.cancel_button.grid(row=2, column=2, sticky='w')
       
   115         self.auto_button = Button(top, text="Paste+Go",
       
   116                       command=self.auto)
       
   117         self.auto_button.grid(row=2, column=3, sticky='w')
       
   118         self.status_label = Label(top, text="[idle]")
       
   119         self.status_label.grid(row=2, column=4, sticky='w')
       
   120         self.top.update_idletasks()
       
   121         self.top.grid_propagate(0)
       
   122 
       
   123     def message(self, text, *args):
       
   124         if args:
       
   125             text = text % args
       
   126         self.status_label.config(text=text)
       
   127 
       
   128     def check_msgq(self):
       
   129         while not self.msgq.empty():
       
   130             msg = self.msgq.get()
       
   131             if msg is None:
       
   132                 self.go_button.configure(state=NORMAL)
       
   133                 self.auto_button.configure(state=NORMAL)
       
   134                 self.cancel_button.configure(state=DISABLED)
       
   135                 if self.sucker:
       
   136                     self.sucker.stopit = 0
       
   137                 self.top.bell()
       
   138             else:
       
   139                 self.message(msg)
       
   140         self.top.after(100, self.check_msgq)
       
   141 
       
   142     def go(self, event=None):
       
   143         if not self.msgq:
       
   144             self.msgq = Queue.Queue(0)
       
   145             self.check_msgq()
       
   146         if not self.sucker:
       
   147             self.sucker = SuckerThread(self.msgq)
       
   148         if self.sucker.stopit:
       
   149             return
       
   150         self.url_entry.selection_range(0, END)
       
   151         url = self.url_entry.get()
       
   152         url = url.strip()
       
   153         if not url:
       
   154             self.top.bell()
       
   155             self.message("[Error: No URL entered]")
       
   156             return
       
   157         self.rooturl = url
       
   158         dir = self.dir_entry.get().strip()
       
   159         if not dir:
       
   160             self.sucker.savedir = None
       
   161         else:
       
   162             self.sucker.savedir = dir
       
   163             self.sucker.rootdir = os.path.dirname(
       
   164                 websucker.Sucker.savefilename(self.sucker, url))
       
   165         self.go_button.configure(state=DISABLED)
       
   166         self.auto_button.configure(state=DISABLED)
       
   167         self.cancel_button.configure(state=NORMAL)
       
   168         self.message( '[running...]')
       
   169         self.sucker.stopit = 0
       
   170         t = threading.Thread(target=self.sucker.run1, args=(url,))
       
   171         t.start()
       
   172 
       
   173     def cancel(self):
       
   174         if self.sucker:
       
   175             self.sucker.stopit = 1
       
   176         self.message("[canceling...]")
       
   177 
       
   178     def auto(self):
       
   179         tries = ['PRIMARY', 'CLIPBOARD']
       
   180         text = ""
       
   181         for t in tries:
       
   182             try:
       
   183                 text = self.top.selection_get(selection=t)
       
   184             except TclError:
       
   185                 continue
       
   186             text = text.strip()
       
   187             if text:
       
   188                 break
       
   189         if not text:
       
   190             self.top.bell()
       
   191             self.message("[Error: clipboard is empty]")
       
   192             return
       
   193         self.url_entry.delete(0, END)
       
   194         self.url_entry.insert(0, text)
       
   195         self.go()
       
   196 
       
   197 
       
   198 class AppArray:
       
   199 
       
   200     def __init__(self, top=None):
       
   201         if not top:
       
   202             top = Tk()
       
   203             top.title("websucker GUI")
       
   204             top.iconname("wsgui")
       
   205             top.wm_protocol('WM_DELETE_WINDOW', self.exit)
       
   206         self.top = top
       
   207         self.appframe = Frame(self.top)
       
   208         self.appframe.pack(fill='both')
       
   209         self.applist = []
       
   210         self.exit_button = Button(top, text="Exit", command=self.exit)
       
   211         self.exit_button.pack(side=RIGHT)
       
   212         self.new_button = Button(top, text="New", command=self.addsucker)
       
   213         self.new_button.pack(side=LEFT)
       
   214         self.addsucker()
       
   215         ##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")
       
   216 
       
   217     def addsucker(self):
       
   218         self.top.geometry("")
       
   219         frame = Frame(self.appframe, borderwidth=2, relief=GROOVE)
       
   220         frame.pack(fill='x')
       
   221         app = App(frame)
       
   222         self.applist.append(app)
       
   223 
       
   224     done = 0
       
   225 
       
   226     def mainloop(self):
       
   227         while not self.done:
       
   228             time.sleep(0.1)
       
   229             self.top.update()
       
   230 
       
   231     def exit(self):
       
   232         for app in self.applist:
       
   233             app.cancel()
       
   234             app.message("[exiting...]")
       
   235         self.done = 1
       
   236 
       
   237 
       
   238 def main():
       
   239     AppArray().mainloop()
       
   240 
       
   241 if __name__ == '__main__':
       
   242     main()