3 """Tkinter-based GUI for websucker.
5 Easy use: type or paste source URL and destination directory in
6 their respective text boxes, click GO or hit return, and presto.
20 class Canceled(Exception):
21 "Exception used to cancel run()."
22 except (NameError, TypeError):
23 Canceled
= __name__
+ ".Canceled"
26 class SuckerThread(websucker
.Sucker
):
32 def __init__(self
, msgq
):
34 websucker
.Sucker
.__init
__(self
)
35 self
.setflags(verbose
=VERBOSE
)
36 self
.urlopener
.addheaders
= [
37 ('User-agent', 'websucker/%s' % websucker
.__version
__),
40 def message(self
, format
, *args
):
53 self
.message("[canceled]")
55 self
.message("[done]")
59 def savefile(self
, text
, path
):
62 websucker
.Sucker
.savefile(self
, text
, path
)
64 def getpage(self
, url
):
67 return websucker
.Sucker
.getpage(self
, url
)
69 def savefilename(self
, url
):
70 path
= websucker
.Sucker
.savefilename(self
, url
)
73 if path
[:n
] == self
.rootdir
:
75 while path
[:1] == os
.sep
:
77 path
= os
.path
.join(self
.savedir
, path
)
80 def XXXaddrobot(self
, *args
):
83 def XXXisallowed(self
, *args
):
92 def __init__(self
, top
):
94 top
.columnconfigure(99, weight
=1)
95 self
.url_label
= Label(top
, text
="URL:")
96 self
.url_label
.grid(row
=0, column
=0, sticky
='e')
97 self
.url_entry
= Entry(top
, width
=60, exportselection
=0)
98 self
.url_entry
.grid(row
=0, column
=1, sticky
='we',
100 self
.url_entry
.focus_set()
101 self
.url_entry
.bind("<Key-Return>", self
.go
)
102 self
.dir_label
= Label(top
, text
="Directory:")
103 self
.dir_label
.grid(row
=1, column
=0, sticky
='e')
104 self
.dir_entry
= Entry(top
)
105 self
.dir_entry
.grid(row
=1, column
=1, sticky
='we',
107 self
.go_button
= Button(top
, text
="Go", command
=self
.go
)
108 self
.go_button
.grid(row
=2, column
=1, sticky
='w')
109 self
.cancel_button
= Button(top
, text
="Cancel",
112 self
.cancel_button
.grid(row
=2, column
=2, sticky
='w')
113 self
.auto_button
= Button(top
, text
="Paste+Go",
115 self
.auto_button
.grid(row
=2, column
=3, sticky
='w')
116 self
.status_label
= Label(top
, text
="[idle]")
117 self
.status_label
.grid(row
=2, column
=4, sticky
='w')
118 self
.top
.update_idletasks()
119 self
.top
.grid_propagate(0)
121 def message(self
, text
, *args
):
124 self
.status_label
.config(text
=text
)
126 def check_msgq(self
):
127 while not self
.msgq
.empty():
128 msg
= self
.msgq
.get()
130 self
.go_button
.configure(state
=NORMAL
)
131 self
.auto_button
.configure(state
=NORMAL
)
132 self
.cancel_button
.configure(state
=DISABLED
)
134 self
.sucker
.stopit
= 0
138 self
.top
.after(100, self
.check_msgq
)
140 def go(self
, event
=None):
142 self
.msgq
= queue
.Queue(0)
145 self
.sucker
= SuckerThread(self
.msgq
)
146 if self
.sucker
.stopit
:
148 self
.url_entry
.selection_range(0, END
)
149 url
= self
.url_entry
.get()
153 self
.message("[Error: No URL entered]")
156 dir = self
.dir_entry
.get().strip()
158 self
.sucker
.savedir
= None
160 self
.sucker
.savedir
= dir
161 self
.sucker
.rootdir
= os
.path
.dirname(
162 websucker
.Sucker
.savefilename(self
.sucker
, url
))
163 self
.go_button
.configure(state
=DISABLED
)
164 self
.auto_button
.configure(state
=DISABLED
)
165 self
.cancel_button
.configure(state
=NORMAL
)
166 self
.message( '[running...]')
167 self
.sucker
.stopit
= 0
168 t
= threading
.Thread(target
=self
.sucker
.run1
, args
=(url
,))
173 self
.sucker
.stopit
= 1
174 self
.message("[canceling...]")
177 tries
= ['PRIMARY', 'CLIPBOARD']
181 text
= self
.top
.selection_get(selection
=t
)
189 self
.message("[Error: clipboard is empty]")
191 self
.url_entry
.delete(0, END
)
192 self
.url_entry
.insert(0, text
)
198 def __init__(self
, top
=None):
201 top
.title("websucker GUI")
202 top
.iconname("wsgui")
203 top
.wm_protocol('WM_DELETE_WINDOW', self
.exit
)
205 self
.appframe
= Frame(self
.top
)
206 self
.appframe
.pack(fill
='both')
208 self
.exit_button
= Button(top
, text
="Exit", command
=self
.exit
)
209 self
.exit_button
.pack(side
=RIGHT
)
210 self
.new_button
= Button(top
, text
="New", command
=self
.addsucker
)
211 self
.new_button
.pack(side
=LEFT
)
213 ##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")
216 self
.top
.geometry("")
217 frame
= Frame(self
.appframe
, borderwidth
=2, relief
=GROOVE
)
220 self
.applist
.append(app
)
230 for app
in self
.applist
:
232 app
.message("[exiting...]")
237 AppArray().mainloop()
239 if __name__
== '__main__':