source: vendor/python/2.5/Tools/webchecker/wsgui.py

Last change on this file was 3225, checked in by bird, 18 years ago

Python 2.5

File size: 6.9 KB
Line 
1#! /usr/bin/env python
2
3"""Tkinter-based GUI for websucker.
4
5Easy use: type or paste source URL and destination directory in
6their respective text boxes, click GO or hit return, and presto.
7"""
8
9from Tkinter import *
10import Tkinter
11import websucker
12import sys
13import os
14import threading
15import Queue
16import time
17
18VERBOSE = 2
19
20
21try:
22 class Canceled(Exception):
23 "Exception used to cancel run()."
24except (NameError, TypeError):
25 Canceled = __name__ + ".Canceled"
26
27
28class 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
89class 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
198class 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
238def main():
239 AppArray().mainloop()
240
241if __name__ == '__main__':
242 main()
Note: See TracBrowser for help on using the repository browser.