blob: c23e87cbe0449b81c08bec920d9fdb8201ca6baf [file] [log] [blame]
Guido van Rossume3bd8211998-06-15 12:35:19 +00001#! /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 string
12import websucker
13import sys
14import os
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000015try:
16 import threading
17except ImportError:
18 threading = None
Guido van Rossume3bd8211998-06-15 12:35:19 +000019
20VERBOSE = 1
Guido van Rossume3bd8211998-06-15 12:35:19 +000021
22
23try:
24 class Canceled(Exception):
25 "Exception used to cancel run()."
26except:
27 Canceled = __name__ + ".Canceled"
28
29
30class App(websucker.Sucker):
31
32 def __init__(self, top=None):
33 websucker.Sucker.__init__(self)
34 self.setflags(verbose=VERBOSE)
35 self.urlopener.addheaders = [
36 ('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', '*/*'),
44 ]
45
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)
51 self.top = top
52 top.columnconfigure(99, weight=1)
53 self.url_label = Label(top, text="URL:")
54 self.url_label.grid(row=0, column=0, sticky='e')
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000055 self.url_entry = Entry(top, width=60, exportselection=0)
56 self.url_entry.grid(row=0, column=1, sticky='we',
57 columnspan=99)
58 self.url_entry.focus_set()
Guido van Rossume3bd8211998-06-15 12:35:19 +000059 self.dir_label = Label(top, text="Directory:")
60 self.dir_label.grid(row=1, column=0, sticky='e')
61 self.dir_entry = Entry(top)
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000062 self.dir_entry.grid(row=1, column=1, sticky='we',
63 columnspan=99)
Guido van Rossume3bd8211998-06-15 12:35:19 +000064 self.exit_button = Button(top, text="Exit", command=self.exit)
65 self.exit_button.grid(row=2, column=0, sticky='w')
66 self.go_button = Button(top, text="Go", command=self.go)
67 self.go_button.grid(row=2, column=1, sticky='w')
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000068 self.cancel_button = Button(top, text="Cancel",
69 command=self.cancel,
Guido van Rossume3bd8211998-06-15 12:35:19 +000070 state=DISABLED)
71 self.cancel_button.grid(row=2, column=2, sticky='w')
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000072 self.auto_button = Button(top, text="Paste+Go",
73 command=self.auto)
Guido van Rossume3bd8211998-06-15 12:35:19 +000074 self.auto_button.grid(row=2, column=3, sticky='w')
75 self.status_label = Label(top, text="[idle]")
76 self.status_label.grid(row=2, column=4, sticky='w')
77 sys.stdout = self
78 self.top.update_idletasks()
79 self.top.grid_propagate(0)
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000080
81 def mainloop(self):
82 self.top.mainloop()
Guido van Rossume3bd8211998-06-15 12:35:19 +000083
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):
Guido van Rossum0a13f7f1998-06-15 14:49:16 +000093 self.top.update()
94 if self.stopit:
95 raise Canceled
Guido van Rossume3bd8211998-06-15 12:35:19 +000096 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)
Guido van Rossume3bd8211998-06-15 12:35:19 +0000103
104 def message(self, text, *args):
105 if args:
106 text = text % args
107 self.status_label.config(text=text)
108 stopit = 0
109
110 def go(self):
111 if self.stopit:
112 return
113 self.url_entry.selection_range(0, END)
114 url = self.url_entry.get()
115 url = string.strip(url)
116 if not url:
117 self.top.bell()
118 self.message("[Error: No URL entered]")
119 return
120 self.rooturl = url
121 dir = string.strip(self.dir_entry.get())
122 if not dir:
123 self.savedir = None
124 else:
125 self.savedir = dir
126 self.rootdir = os.path.dirname(
127 websucker.Sucker.savefilename(self, url))
128 self.go_button.configure(state=DISABLED)
129 self.auto_button.configure(state=DISABLED)
130 self.cancel_button.configure(state=NORMAL)
131 self.status_label['text'] = '[running...]'
132 self.top.update_idletasks()
Guido van Rossum0a13f7f1998-06-15 14:49:16 +0000133 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):
Guido van Rossume3bd8211998-06-15 12:35:19 +0000140 self.reset()
141 self.addroot(url)
Guido van Rossume3bd8211998-06-15 12:35:19 +0000142 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
156
157 def cancel(self):
158 self.stopit = 1
159 self.message("[canceling...]")
160
161 def auto(self):
Guido van Rossum0a13f7f1998-06-15 14:49:16 +0000162 tries = ['PRIMARY', 'CLIPBOARD']
163 text = ""
164 for t in tries:
165 try:
166 text = self.top.selection_get(selection=t)
167 except TclError:
168 continue
169 text = string.strip(text)
170 if text:
171 break
Guido van Rossume3bd8211998-06-15 12:35:19 +0000172 if not text:
173 self.top.bell()
174 self.message("[Error: clipboard is empty]")
175 return
176 self.url_entry.delete(0, END)
177 self.url_entry.insert(0, text)
178 self.top.update_idletasks()
179 self.go()
Guido van Rossume3bd8211998-06-15 12:35:19 +0000180
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
203
204
205if __name__ == '__main__':
206 App().mainloop()