Kaydet (Commit) b77a68e6 authored tarafından Guido van Rossum's avatar Guido van Rossum

Rewrite to support multiple suckers, each with their own thread.

üst 125700ad
...@@ -12,12 +12,11 @@ import string ...@@ -12,12 +12,11 @@ import string
import websucker import websucker
import sys import sys
import os import os
try: import threading
import threading import Queue
except ImportError: import time
threading = None
VERBOSE = 1 VERBOSE = 2
try: try:
...@@ -27,27 +26,74 @@ except: ...@@ -27,27 +26,74 @@ except:
Canceled = __name__ + ".Canceled" Canceled = __name__ + ".Canceled"
class App(websucker.Sucker): class SuckerThread(websucker.Sucker):
def __init__(self, top=None): stopit = 0
savedir = None
rootdir = None
def __init__(self, msgq):
self.msgq = msgq
websucker.Sucker.__init__(self) websucker.Sucker.__init__(self)
self.setflags(verbose=VERBOSE) self.setflags(verbose=VERBOSE)
self.urlopener.addheaders = [ self.urlopener.addheaders = [
('User-agent', 'websucker/%s' % websucker.__version__), ('User-agent', 'websucker/%s' % websucker.__version__),
##('Accept', 'text/html'),
##('Accept', 'text/plain'),
##('Accept', 'text/*'),
##('Accept', 'image/gif'),
##('Accept', 'image/jpeg'),
##('Accept', 'image/*'),
##('Accept', '*/*'),
] ]
def message(self, format, *args):
if args:
format = format%args
##print format
self.msgq.put(format)
if not top: def run1(self, url):
top = Tk() try:
top.title("websucker GUI") try:
top.iconname("wsgui") self.reset()
top.wm_protocol('WM_DELETE_WINDOW', self.exit) 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 self.top = top
top.columnconfigure(99, weight=1) top.columnconfigure(99, weight=1)
self.url_label = Label(top, text="URL:") self.url_label = Label(top, text="URL:")
...@@ -56,13 +102,12 @@ class App(websucker.Sucker): ...@@ -56,13 +102,12 @@ class App(websucker.Sucker):
self.url_entry.grid(row=0, column=1, sticky='we', self.url_entry.grid(row=0, column=1, sticky='we',
columnspan=99) columnspan=99)
self.url_entry.focus_set() self.url_entry.focus_set()
self.url_entry.bind("<Key-Return>", self.go)
self.dir_label = Label(top, text="Directory:") self.dir_label = Label(top, text="Directory:")
self.dir_label.grid(row=1, column=0, sticky='e') self.dir_label.grid(row=1, column=0, sticky='e')
self.dir_entry = Entry(top) self.dir_entry = Entry(top)
self.dir_entry.grid(row=1, column=1, sticky='we', self.dir_entry.grid(row=1, column=1, sticky='we',
columnspan=99) 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 = Button(top, text="Go", command=self.go)
self.go_button.grid(row=2, column=1, sticky='w') self.go_button.grid(row=2, column=1, sticky='w')
self.cancel_button = Button(top, text="Cancel", self.cancel_button = Button(top, text="Cancel",
...@@ -74,41 +119,35 @@ class App(websucker.Sucker): ...@@ -74,41 +119,35 @@ class App(websucker.Sucker):
self.auto_button.grid(row=2, column=3, sticky='w') self.auto_button.grid(row=2, column=3, sticky='w')
self.status_label = Label(top, text="[idle]") self.status_label = Label(top, text="[idle]")
self.status_label.grid(row=2, column=4, sticky='w') self.status_label.grid(row=2, column=4, sticky='w')
sys.stdout = self
self.top.update_idletasks() self.top.update_idletasks()
self.top.grid_propagate(0) 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): def message(self, text, *args):
if args: if args:
text = text % args text = text % args
self.status_label.config(text=text) self.status_label.config(text=text)
stopit = 0
def go(self): def check_msgq(self):
if self.stopit: 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 return
self.url_entry.selection_range(0, END) self.url_entry.selection_range(0, END)
url = self.url_entry.get() url = self.url_entry.get()
...@@ -120,42 +159,22 @@ class App(websucker.Sucker): ...@@ -120,42 +159,22 @@ class App(websucker.Sucker):
self.rooturl = url self.rooturl = url
dir = string.strip(self.dir_entry.get()) dir = string.strip(self.dir_entry.get())
if not dir: if not dir:
self.savedir = None self.sucker.savedir = None
else: else:
self.savedir = dir self.sucker.savedir = dir
self.rootdir = os.path.dirname( self.sucker.rootdir = os.path.dirname(
websucker.Sucker.savefilename(self, url)) websucker.Sucker.savefilename(self, url))
self.go_button.configure(state=DISABLED) self.go_button.configure(state=DISABLED)
self.auto_button.configure(state=DISABLED) self.auto_button.configure(state=DISABLED)
self.cancel_button.configure(state=NORMAL) self.cancel_button.configure(state=NORMAL)
self.status_label['text'] = '[running...]' self.message( '[running...]')
self.top.update_idletasks() self.sucker.stopit = 0
if threading: t = threading.Thread(target=self.sucker.run1, args=(url,))
t = threading.Thread(target=self.run1, args=(url,)) t.start()
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): def cancel(self):
self.stopit = 1 if self.sucker:
self.sucker.stopit = 1
self.message("[canceling...]") self.message("[canceling...]")
def auto(self): def auto(self):
...@@ -175,32 +194,51 @@ class App(websucker.Sucker): ...@@ -175,32 +194,51 @@ class App(websucker.Sucker):
return return
self.url_entry.delete(0, END) self.url_entry.delete(0, END)
self.url_entry.insert(0, text) self.url_entry.insert(0, text)
self.top.update_idletasks()
self.go() 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 savefile(self, text, path): def exit(self):
self.top.update() for app in self.applist:
if self.stopit: app.cancel()
raise Canceled app.message("[exiting...]")
websucker.Sucker.savefile(self, text, path) self.done = 1
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
def main():
AppArray().mainloop()
if __name__ == '__main__': if __name__ == '__main__':
App().mainloop() main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment