blob: 836b5ac8bcf7d177188c117a6723468fc6e2c95e [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
15
16VERBOSE = 1
17DEFAULT_URL = "http://www.python.org/download/"
18
19
20try:
21 class Canceled(Exception):
22 "Exception used to cancel run()."
23except:
24 Canceled = __name__ + ".Canceled"
25
26
27class App(websucker.Sucker):
28
29 def __init__(self, top=None):
30 websucker.Sucker.__init__(self)
31 self.setflags(verbose=VERBOSE)
32 self.urlopener.addheaders = [
33 ('User-agent', 'websucker/%s' % websucker.__version__),
34 ##('Accept', 'text/html'),
35 ##('Accept', 'text/plain'),
36 ##('Accept', 'text/*'),
37 ##('Accept', 'image/gif'),
38 ##('Accept', 'image/jpeg'),
39 ##('Accept', 'image/*'),
40 ##('Accept', '*/*'),
41 ]
42
43 if not top:
44 top = Tk()
45 top.title("websucker GUI")
46 top.iconname("wsgui")
47 top.wm_protocol('WM_DELETE_WINDOW', self.exit)
48 self.top = top
49 top.columnconfigure(99, weight=1)
50 self.url_label = Label(top, text="URL:")
51 self.url_label.grid(row=0, column=0, sticky='e')
52 self.url_entry = Entry(top, width=60)
53 self.url_entry.insert(END, DEFAULT_URL)
54 self.url_entry.grid(row=0, column=1, sticky='we', columnspan=99)
55 self.dir_label = Label(top, text="Directory:")
56 self.dir_label.grid(row=1, column=0, sticky='e')
57 self.dir_entry = Entry(top)
58 self.dir_entry.grid(row=1, column=1, sticky='we', columnspan=99)
59 self.exit_button = Button(top, text="Exit", command=self.exit)
60 self.exit_button.grid(row=2, column=0, sticky='w')
61 self.go_button = Button(top, text="Go", command=self.go)
62 self.go_button.grid(row=2, column=1, sticky='w')
63 self.cancel_button = Button(top, text="Cancel", command=self.cancel,
64 state=DISABLED)
65 self.cancel_button.grid(row=2, column=2, sticky='w')
66 self.auto_button = Button(top, text="Paste+Go", command=self.auto)
67 self.auto_button.grid(row=2, column=3, sticky='w')
68 self.status_label = Label(top, text="[idle]")
69 self.status_label.grid(row=2, column=4, sticky='w')
70 sys.stdout = self
71 self.top.update_idletasks()
72 self.top.grid_propagate(0)
73
74 def exit(self):
75 self.stopit = 1
76 self.message("[exiting...]")
77 self.top.update_idletasks()
78 self.top.quit()
79
80 buffer = ""
81
82 def write(self, text):
83 sys.stderr.write(text)
84 lines = string.split(text, "\n")
85 if len(lines) > 1:
86 self.buffer = ""
87 self.buffer = self.buffer + lines[-1]
88 if string.strip(self.buffer):
89 self.message(self.buffer)
90 self.top.update()
91 if self.stopit:
92 raise Canceled
93
94 def message(self, text, *args):
95 if args:
96 text = text % args
97 self.status_label.config(text=text)
98 stopit = 0
99
100 def go(self):
101 if self.stopit:
102 return
103 self.url_entry.selection_range(0, END)
104 url = self.url_entry.get()
105 url = string.strip(url)
106 if not url:
107 self.top.bell()
108 self.message("[Error: No URL entered]")
109 return
110 self.rooturl = url
111 dir = string.strip(self.dir_entry.get())
112 if not dir:
113 self.savedir = None
114 else:
115 self.savedir = dir
116 self.rootdir = os.path.dirname(
117 websucker.Sucker.savefilename(self, url))
118 self.go_button.configure(state=DISABLED)
119 self.auto_button.configure(state=DISABLED)
120 self.cancel_button.configure(state=NORMAL)
121 self.status_label['text'] = '[running...]'
122 self.top.update_idletasks()
123 self.reset()
124 self.addroot(url)
125
126 self.stopit = 0
127 try:
128 try:
129 self.run()
130 except Canceled:
131 self.message("[canceled]")
132 else:
133 self.message("[done]")
134 self.top.bell()
135 finally:
136 self.go_button.configure(state=NORMAL)
137 self.auto_button.configure(state=NORMAL)
138 self.cancel_button.configure(state=DISABLED)
139 self.stopit = 0
140
141 def cancel(self):
142 self.stopit = 1
143 self.message("[canceling...]")
144
145 def auto(self):
146 text = self.top.selection_get(selection='CLIPBOARD')
147 text = string.strip(text)
148 if not text:
149 self.top.bell()
150 self.message("[Error: clipboard is empty]")
151 return
152 self.url_entry.delete(0, END)
153 self.url_entry.insert(0, text)
154 self.top.update_idletasks()
155 self.go()
156
157 def mainloop(self):
158 self.top.mainloop()
159
160 def savefile(self, text, path):
161 self.top.update()
162 if self.stopit:
163 raise Canceled
164 websucker.Sucker.savefile(self, text, path)
165
166 def getpage(self, url):
167 self.top.update()
168 if self.stopit:
169 raise Canceled
170 return websucker.Sucker.getpage(self, url)
171
172 def savefilename(self, url):
173 path = websucker.Sucker.savefilename(self, url)
174 if self.savedir:
175 n = len(self.rootdir)
176 if path[:n] == self.rootdir:
177 path = path[n:]
178 while path[:1] == os.sep:
179 path = path[1:]
180 path = os.path.join(self.savedir, path)
181 return path
182
183
184if __name__ == '__main__':
185 App().mainloop()