Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b77a68e

Browse files
committed
Rewrite to support multiple suckers, each with their own thread.
1 parent 125700a commit b77a68e

1 file changed

Lines changed: 140 additions & 102 deletions

File tree

Tools/webchecker/wsgui.py

Lines changed: 140 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@
1212
import websucker
1313
import sys
1414
import os
15-
try:
16-
import threading
17-
except ImportError:
18-
threading = None
15+
import threading
16+
import Queue
17+
import time
1918

20-
VERBOSE = 1
19+
VERBOSE = 2
2120

2221

2322
try:
@@ -27,27 +26,74 @@ class Canceled(Exception):
2726
Canceled = __name__ + ".Canceled"
2827

2928

30-
class App(websucker.Sucker):
29+
class SuckerThread(websucker.Sucker):
3130

32-
def __init__(self, top=None):
31+
stopit = 0
32+
savedir = None
33+
rootdir = None
34+
35+
def __init__(self, msgq):
36+
self.msgq = msgq
3337
websucker.Sucker.__init__(self)
3438
self.setflags(verbose=VERBOSE)
3539
self.urlopener.addheaders = [
3640
('User-agent', 'websucker/%s' % websucker.__version__),
37-
##('Accept', 'text/html'),
38-
##('Accept', 'text/plain'),
39-
##('Accept', 'text/*'),
40-
##('Accept', 'image/gif'),
41-
##('Accept', 'image/jpeg'),
42-
##('Accept', 'image/*'),
43-
##('Accept', '*/*'),
4441
]
42+
43+
def message(self, format, *args):
44+
if args:
45+
format = format%args
46+
##print format
47+
self.msgq.put(format)
4548

46-
if not top:
47-
top = Tk()
48-
top.title("websucker GUI")
49-
top.iconname("wsgui")
50-
top.wm_protocol('WM_DELETE_WINDOW', self.exit)
49+
def run1(self, url):
50+
try:
51+
try:
52+
self.reset()
53+
self.addroot(url)
54+
self.run()
55+
except Canceled:
56+
self.message("[canceled]")
57+
else:
58+
self.message("[done]")
59+
finally:
60+
self.msgq.put(None)
61+
62+
def savefile(self, text, path):
63+
if self.stopit:
64+
raise Canceled
65+
websucker.Sucker.savefile(self, text, path)
66+
67+
def getpage(self, url):
68+
if self.stopit:
69+
raise Canceled
70+
return websucker.Sucker.getpage(self, url)
71+
72+
def savefilename(self, url):
73+
path = websucker.Sucker.savefilename(self, url)
74+
if self.savedir:
75+
n = len(self.rootdir)
76+
if path[:n] == self.rootdir:
77+
path = path[n:]
78+
while path[:1] == os.sep:
79+
path = path[1:]
80+
path = os.path.join(self.savedir, path)
81+
return path
82+
83+
def XXXaddrobot(self, *args):
84+
pass
85+
86+
def XXXisallowed(self, *args):
87+
return 1
88+
89+
90+
91+
class App:
92+
93+
sucker = None
94+
msgq = None
95+
96+
def __init__(self, top):
5197
self.top = top
5298
top.columnconfigure(99, weight=1)
5399
self.url_label = Label(top, text="URL:")
@@ -56,13 +102,12 @@ def __init__(self, top=None):
56102
self.url_entry.grid(row=0, column=1, sticky='we',
57103
columnspan=99)
58104
self.url_entry.focus_set()
105+
self.url_entry.bind("<Key-Return>", self.go)
59106
self.dir_label = Label(top, text="Directory:")
60107
self.dir_label.grid(row=1, column=0, sticky='e')
61108
self.dir_entry = Entry(top)
62109
self.dir_entry.grid(row=1, column=1, sticky='we',
63110
columnspan=99)
64-
self.exit_button = Button(top, text="Exit", command=self.exit)
65-
self.exit_button.grid(row=2, column=0, sticky='w')
66111
self.go_button = Button(top, text="Go", command=self.go)
67112
self.go_button.grid(row=2, column=1, sticky='w')
68113
self.cancel_button = Button(top, text="Cancel",
@@ -74,41 +119,35 @@ def __init__(self, top=None):
74119
self.auto_button.grid(row=2, column=3, sticky='w')
75120
self.status_label = Label(top, text="[idle]")
76121
self.status_label.grid(row=2, column=4, sticky='w')
77-
sys.stdout = self
78122
self.top.update_idletasks()
79123
self.top.grid_propagate(0)
80124

81-
def mainloop(self):
82-
self.top.mainloop()
83-
84-
def exit(self):
85-
self.stopit = 1
86-
self.message("[exiting...]")
87-
self.top.update_idletasks()
88-
self.top.quit()
89-
90-
buffer = ""
91-
92-
def write(self, text):
93-
self.top.update()
94-
if self.stopit:
95-
raise Canceled
96-
sys.stderr.write(text)
97-
lines = string.split(text, "\n")
98-
if len(lines) > 1:
99-
self.buffer = ""
100-
self.buffer = self.buffer + lines[-1]
101-
if string.strip(self.buffer):
102-
self.message(self.buffer)
103-
104125
def message(self, text, *args):
105126
if args:
106127
text = text % args
107-
self.status_label.config(text=text)
108-
stopit = 0
128+
self.status_label.config(text=text)
109129

110-
def go(self):
111-
if self.stopit:
130+
def check_msgq(self):
131+
while not self.msgq.empty():
132+
msg = self.msgq.get()
133+
if msg is None:
134+
self.go_button.configure(state=NORMAL)
135+
self.auto_button.configure(state=NORMAL)
136+
self.cancel_button.configure(state=DISABLED)
137+
if self.sucker:
138+
self.sucker.stopit = 0
139+
self.top.bell()
140+
else:
141+
self.message(msg)
142+
self.top.after(100, self.check_msgq)
143+
144+
def go(self, event=None):
145+
if not self.msgq:
146+
self.msgq = Queue.Queue(0)
147+
self.check_msgq()
148+
if not self.sucker:
149+
self.sucker = SuckerThread(self.msgq)
150+
if self.sucker.stopit:
112151
return
113152
self.url_entry.selection_range(0, END)
114153
url = self.url_entry.get()
@@ -120,42 +159,22 @@ def go(self):
120159
self.rooturl = url
121160
dir = string.strip(self.dir_entry.get())
122161
if not dir:
123-
self.savedir = None
162+
self.sucker.savedir = None
124163
else:
125-
self.savedir = dir
126-
self.rootdir = os.path.dirname(
164+
self.sucker.savedir = dir
165+
self.sucker.rootdir = os.path.dirname(
127166
websucker.Sucker.savefilename(self, url))
128167
self.go_button.configure(state=DISABLED)
129168
self.auto_button.configure(state=DISABLED)
130169
self.cancel_button.configure(state=NORMAL)
131-
self.status_label['text'] = '[running...]'
132-
self.top.update_idletasks()
133-
if threading:
134-
t = threading.Thread(target=self.run1, args=(url,))
135-
t.start()
136-
else:
137-
self.run1(url)
138-
139-
def run1(self, url):
140-
self.reset()
141-
self.addroot(url)
142-
self.stopit = 0
143-
try:
144-
try:
145-
self.run()
146-
except Canceled:
147-
self.message("[canceled]")
148-
else:
149-
self.message("[done]")
150-
self.top.bell()
151-
finally:
152-
self.go_button.configure(state=NORMAL)
153-
self.auto_button.configure(state=NORMAL)
154-
self.cancel_button.configure(state=DISABLED)
155-
self.stopit = 0
170+
self.message( '[running...]')
171+
self.sucker.stopit = 0
172+
t = threading.Thread(target=self.sucker.run1, args=(url,))
173+
t.start()
156174

157175
def cancel(self):
158-
self.stopit = 1
176+
if self.sucker:
177+
self.sucker.stopit = 1
159178
self.message("[canceling...]")
160179

161180
def auto(self):
@@ -175,32 +194,51 @@ def auto(self):
175194
return
176195
self.url_entry.delete(0, END)
177196
self.url_entry.insert(0, text)
178-
self.top.update_idletasks()
179197
self.go()
198+
199+
200+
class AppArray:
201+
202+
def __init__(self, top=None):
203+
if not top:
204+
top = Tk()
205+
top.title("websucker GUI")
206+
top.iconname("wsgui")
207+
top.wm_protocol('WM_DELETE_WINDOW', self.exit)
208+
self.top = top
209+
self.appframe = Frame(self.top)
210+
self.appframe.pack(fill='both')
211+
self.applist = []
212+
self.exit_button = Button(top, text="Exit", command=self.exit)
213+
self.exit_button.pack(side=RIGHT)
214+
self.new_button = Button(top, text="New", command=self.addsucker)
215+
self.new_button.pack(side=LEFT)
216+
self.addsucker()
217+
##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")
218+
219+
def addsucker(self):
220+
self.top.geometry("")
221+
frame = Frame(self.appframe, borderwidth=2, relief=GROOVE)
222+
frame.pack(fill='x')
223+
app = App(frame)
224+
self.applist.append(app)
225+
226+
done = 0
227+
228+
def mainloop(self):
229+
while not self.done:
230+
time.sleep(0.1)
231+
self.top.update()
180232

181-
def savefile(self, text, path):
182-
self.top.update()
183-
if self.stopit:
184-
raise Canceled
185-
websucker.Sucker.savefile(self, text, path)
186-
187-
def getpage(self, url):
188-
self.top.update()
189-
if self.stopit:
190-
raise Canceled
191-
return websucker.Sucker.getpage(self, url)
192-
193-
def savefilename(self, url):
194-
path = websucker.Sucker.savefilename(self, url)
195-
if self.savedir:
196-
n = len(self.rootdir)
197-
if path[:n] == self.rootdir:
198-
path = path[n:]
199-
while path[:1] == os.sep:
200-
path = path[1:]
201-
path = os.path.join(self.savedir, path)
202-
return path
233+
def exit(self):
234+
for app in self.applist:
235+
app.cancel()
236+
app.message("[exiting...]")
237+
self.done = 1
238+
203239

240+
def main():
241+
AppArray().mainloop()
204242

205243
if __name__ == '__main__':
206-
App().mainloop()
244+
main()

0 commit comments

Comments
 (0)