#! /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 Tkinter import string import websucker import sys import os try: import threading except ImportError: threading = None VERBOSE = 1 try: class Canceled(Exception): "Exception used to cancel run()." except: Canceled = __name__ + ".Canceled" class App(websucker.Sucker): def __init__(self, top=None): websucker.Sucker.__init__(self) self.setflags(verbose=VERBOSE) self.urlopener.addheaders = [ ('User-agent', 'websucker/%s' % websucker.__version__), ##('Accept', 'text/html'), ##('Accept', 'text/plain'), ##('Accept', 'text/*'), ##('Accept', 'image/gif'), ##('Accept', 'image/jpeg'), ##('Accept', 'image/*'), ##('Accept', '*/*'), ] if not top: top = Tk() top.title("websucker GUI") top.iconname("wsgui") top.wm_protocol('WM_DELETE_WINDOW', self.exit) 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.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.exit_button = Button(top, text="Exit", command=self.exit) self.exit_button.grid(row=2, column=0, sticky='w') 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') sys.stdout = self self.top.update_idletasks() self.top.grid_propagate(0) def mainloop(self): self.top.mainloop() def exit(self): self.stopit = 1 self.message("[exiting...]") self.top.update_idletasks() self.top.quit() buffer = "" def write(self, text): self.top.update() if self.stopit: raise Canceled sys.stderr.write(text) lines = string.split(text, "\n") if len(lines) > 1: self.buffer = "" self.buffer = self.buffer + lines[-1] if string.strip(self.buffer): self.message(self.buffer) def message(self, text, *args): if args: text = text % args self.status_label.config(text=text) stopit = 0 def go(self): if self.stopit: return self.url_entry.selection_range(0, END) url = self.url_entry.get() url = string.strip(url) if not url: self.top.bell() self.message("[Error: No URL entered]") return self.rooturl = url dir = string.strip(self.dir_entry.get()) if not dir: self.savedir = None else: self.savedir = dir self.rootdir = os.path.dirname( websucker.Sucker.savefilename(self, url)) self.go_button.configure(state=DISABLED) self.auto_button.configure(state=DISABLED) self.cancel_button.configure(state=NORMAL) self.status_label['text'] = '[running...]' self.top.update_idletasks() if threading: t = threading.Thread(target=self.run1, args=(url,)) t.start() else: self.run1(url) def run1(self, url): self.reset() self.addroot(url) self.stopit = 0 try: try: self.run() except Canceled: self.message("[canceled]") else: self.message("[done]") self.top.bell() finally: self.go_button.configure(state=NORMAL) self.auto_button.configure(state=NORMAL) self.cancel_button.configure(state=DISABLED) self.stopit = 0 def cancel(self): self.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 = string.strip(text) 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.top.update_idletasks() self.go() def savefile(self, text, path): self.top.update() if self.stopit: raise Canceled websucker.Sucker.savefile(self, text, path) def getpage(self, url): self.top.update() 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 if __name__ == '__main__': App().mainloop()