mirror of
				https://github.com/python/cpython.git
				synced 2025-10-26 11:14:33 +00:00 
			
		
		
		
	 f260e443ac
			
		
	
	
		f260e443ac
		
	
	
	
	
		
			
			Updated documentation to use new name. Merged revisions 63077 via svnmerge from svn+ssh://pythondev@svn.python.org/python/trunk ........ r63077 | alexandre.vassalotti | 2008-05-11 15:39:48 -0400 (Sun, 11 May 2008) | 3 lines Added stub for the Queue module to be renamed in 3.0. Use the 3.0 module name to avoid spurious warnings. ........
		
			
				
	
	
		
			240 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			240 lines
		
	
	
	
		
			6.9 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #! /usr/bin/env python
 | |
| 
 | |
| """Tkinter-based GUI for websucker.
 | |
| 
 | |
| Easy use: type or paste source URL and destination directory in
 | |
| their respective text boxes, click GO or hit return, and presto.
 | |
| """
 | |
| 
 | |
| from Tkinter import *
 | |
| import websucker
 | |
| import os
 | |
| import threading
 | |
| import queue
 | |
| import time
 | |
| 
 | |
| VERBOSE = 2
 | |
| 
 | |
| 
 | |
| try:
 | |
|     class Canceled(Exception):
 | |
|         "Exception used to cancel run()."
 | |
| except (NameError, TypeError):
 | |
|     Canceled = __name__ + ".Canceled"
 | |
| 
 | |
| 
 | |
| class SuckerThread(websucker.Sucker):
 | |
| 
 | |
|     stopit = 0
 | |
|     savedir = None
 | |
|     rootdir = None
 | |
| 
 | |
|     def __init__(self, msgq):
 | |
|         self.msgq = msgq
 | |
|         websucker.Sucker.__init__(self)
 | |
|         self.setflags(verbose=VERBOSE)
 | |
|         self.urlopener.addheaders = [
 | |
|             ('User-agent', 'websucker/%s' % websucker.__version__),
 | |
|         ]
 | |
| 
 | |
|     def message(self, format, *args):
 | |
|         if args:
 | |
|             format = format%args
 | |
|         ##print format
 | |
|         self.msgq.put(format)
 | |
| 
 | |
|     def run1(self, url):
 | |
|         try:
 | |
|             try:
 | |
|                 self.reset()
 | |
|                 self.addroot(url)
 | |
|                 self.run()
 | |
|             except Canceled:
 | |
|                 self.message("[canceled]")
 | |
|             else:
 | |
|                 self.message("[done]")
 | |
|         finally:
 | |
|             self.msgq.put(None)
 | |
| 
 | |
|     def savefile(self, text, path):
 | |
|         if self.stopit:
 | |
|             raise Canceled
 | |
|         websucker.Sucker.savefile(self, text, path)
 | |
| 
 | |
|     def getpage(self, url):
 | |
|         if self.stopit:
 | |
|             raise Canceled
 | |
|         return websucker.Sucker.getpage(self, url)
 | |
| 
 | |
|     def savefilename(self, url):
 | |
|         path = websucker.Sucker.savefilename(self, url)
 | |
|         if self.savedir:
 | |
|             n = len(self.rootdir)
 | |
|             if path[:n] == self.rootdir:
 | |
|                 path = path[n:]
 | |
|                 while path[:1] == os.sep:
 | |
|                     path = path[1:]
 | |
|                 path = os.path.join(self.savedir, path)
 | |
|         return path
 | |
| 
 | |
|     def XXXaddrobot(self, *args):
 | |
|         pass
 | |
| 
 | |
|     def XXXisallowed(self, *args):
 | |
|         return 1
 | |
| 
 | |
| 
 | |
| class App:
 | |
| 
 | |
|     sucker = None
 | |
|     msgq = None
 | |
| 
 | |
|     def __init__(self, top):
 | |
|         self.top = top
 | |
|         top.columnconfigure(99, weight=1)
 | |
|         self.url_label = Label(top, text="URL:")
 | |
|         self.url_label.grid(row=0, column=0, sticky='e')
 | |
|         self.url_entry = Entry(top, width=60, exportselection=0)
 | |
|         self.url_entry.grid(row=0, column=1, sticky='we',
 | |
|                     columnspan=99)
 | |
|         self.url_entry.focus_set()
 | |
|         self.url_entry.bind("<Key-Return>", self.go)
 | |
|         self.dir_label = Label(top, text="Directory:")
 | |
|         self.dir_label.grid(row=1, column=0, sticky='e')
 | |
|         self.dir_entry = Entry(top)
 | |
|         self.dir_entry.grid(row=1, column=1, sticky='we',
 | |
|                     columnspan=99)
 | |
|         self.go_button = Button(top, text="Go", command=self.go)
 | |
|         self.go_button.grid(row=2, column=1, sticky='w')
 | |
|         self.cancel_button = Button(top, text="Cancel",
 | |
|                         command=self.cancel,
 | |
|                                     state=DISABLED)
 | |
|         self.cancel_button.grid(row=2, column=2, sticky='w')
 | |
|         self.auto_button = Button(top, text="Paste+Go",
 | |
|                       command=self.auto)
 | |
|         self.auto_button.grid(row=2, column=3, sticky='w')
 | |
|         self.status_label = Label(top, text="[idle]")
 | |
|         self.status_label.grid(row=2, column=4, sticky='w')
 | |
|         self.top.update_idletasks()
 | |
|         self.top.grid_propagate(0)
 | |
| 
 | |
|     def message(self, text, *args):
 | |
|         if args:
 | |
|             text = text % args
 | |
|         self.status_label.config(text=text)
 | |
| 
 | |
|     def check_msgq(self):
 | |
|         while not self.msgq.empty():
 | |
|             msg = self.msgq.get()
 | |
|             if msg is None:
 | |
|                 self.go_button.configure(state=NORMAL)
 | |
|                 self.auto_button.configure(state=NORMAL)
 | |
|                 self.cancel_button.configure(state=DISABLED)
 | |
|                 if self.sucker:
 | |
|                     self.sucker.stopit = 0
 | |
|                 self.top.bell()
 | |
|             else:
 | |
|                 self.message(msg)
 | |
|         self.top.after(100, self.check_msgq)
 | |
| 
 | |
|     def go(self, event=None):
 | |
|         if not self.msgq:
 | |
|             self.msgq = queue.Queue(0)
 | |
|             self.check_msgq()
 | |
|         if not self.sucker:
 | |
|             self.sucker = SuckerThread(self.msgq)
 | |
|         if self.sucker.stopit:
 | |
|             return
 | |
|         self.url_entry.selection_range(0, END)
 | |
|         url = self.url_entry.get()
 | |
|         url = url.strip()
 | |
|         if not url:
 | |
|             self.top.bell()
 | |
|             self.message("[Error: No URL entered]")
 | |
|             return
 | |
|         self.rooturl = url
 | |
|         dir = self.dir_entry.get().strip()
 | |
|         if not dir:
 | |
|             self.sucker.savedir = None
 | |
|         else:
 | |
|             self.sucker.savedir = dir
 | |
|             self.sucker.rootdir = os.path.dirname(
 | |
|                 websucker.Sucker.savefilename(self.sucker, url))
 | |
|         self.go_button.configure(state=DISABLED)
 | |
|         self.auto_button.configure(state=DISABLED)
 | |
|         self.cancel_button.configure(state=NORMAL)
 | |
|         self.message( '[running...]')
 | |
|         self.sucker.stopit = 0
 | |
|         t = threading.Thread(target=self.sucker.run1, args=(url,))
 | |
|         t.start()
 | |
| 
 | |
|     def cancel(self):
 | |
|         if self.sucker:
 | |
|             self.sucker.stopit = 1
 | |
|         self.message("[canceling...]")
 | |
| 
 | |
|     def auto(self):
 | |
|         tries = ['PRIMARY', 'CLIPBOARD']
 | |
|         text = ""
 | |
|         for t in tries:
 | |
|             try:
 | |
|                 text = self.top.selection_get(selection=t)
 | |
|             except TclError:
 | |
|                 continue
 | |
|             text = text.strip()
 | |
|             if text:
 | |
|                 break
 | |
|         if not text:
 | |
|             self.top.bell()
 | |
|             self.message("[Error: clipboard is empty]")
 | |
|             return
 | |
|         self.url_entry.delete(0, END)
 | |
|         self.url_entry.insert(0, text)
 | |
|         self.go()
 | |
| 
 | |
| 
 | |
| class AppArray:
 | |
| 
 | |
|     def __init__(self, top=None):
 | |
|         if not top:
 | |
|             top = Tk()
 | |
|             top.title("websucker GUI")
 | |
|             top.iconname("wsgui")
 | |
|             top.wm_protocol('WM_DELETE_WINDOW', self.exit)
 | |
|         self.top = top
 | |
|         self.appframe = Frame(self.top)
 | |
|         self.appframe.pack(fill='both')
 | |
|         self.applist = []
 | |
|         self.exit_button = Button(top, text="Exit", command=self.exit)
 | |
|         self.exit_button.pack(side=RIGHT)
 | |
|         self.new_button = Button(top, text="New", command=self.addsucker)
 | |
|         self.new_button.pack(side=LEFT)
 | |
|         self.addsucker()
 | |
|         ##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")
 | |
| 
 | |
|     def addsucker(self):
 | |
|         self.top.geometry("")
 | |
|         frame = Frame(self.appframe, borderwidth=2, relief=GROOVE)
 | |
|         frame.pack(fill='x')
 | |
|         app = App(frame)
 | |
|         self.applist.append(app)
 | |
| 
 | |
|     done = 0
 | |
| 
 | |
|     def mainloop(self):
 | |
|         while not self.done:
 | |
|             time.sleep(0.1)
 | |
|             self.top.update()
 | |
| 
 | |
|     def exit(self):
 | |
|         for app in self.applist:
 | |
|             app.cancel()
 | |
|             app.message("[exiting...]")
 | |
|         self.done = 1
 | |
| 
 | |
| 
 | |
| def main():
 | |
|     AppArray().mainloop()
 | |
| 
 | |
| if __name__ == '__main__':
 | |
|     main()
 |