blob: 59b71c09c78460f1bf1b1ba5401f73be257304b2 [file] [log] [blame]
Guido van Rossumdfa70a91995-01-10 17:05:37 +00001#! /usr/local/bin/python
2
3# www11.py -- display the contents of a URL in a Text widget
4# - set window title
5# - make window resizable
6# - update display while reading
7# - vertical scroll bar
8# - rewritten as class
9# - editable url entry and reload button
10# - error dialog
11
12import sys
13import urllib
14from Tkinter import *
15import Dialog
16
17def main():
18 if len(sys.argv) != 2 or sys.argv[1][:1] == '-':
19 print "Usage:", sys.argv[0], "url"
20 sys.exit(2)
21 url = sys.argv[1]
22 viewer = Viewer()
23 viewer.load(url)
24 viewer.go()
25
26class Viewer:
27
28 def __init__(self):
29 # Create root window
30 self.root = Tk()
31 self.root.minsize(1, 1)
32
33 # Create topframe for the entry and button
34 self.topframe = Frame(self.root)
35 self.topframe.pack({'fill': 'x'})
36
37 # Create a label in front of the entry
38 self.urllabel = Label(self.topframe, {'text': 'URL:'})
39 self.urllabel.pack({'side': 'left'})
40
41 # Create the entry containing the URL
42 self.entry = Entry(self.topframe,
43 {'relief': 'sunken', 'border': 2})
44 self.entry.pack({'side': 'left', 'fill': 'x', 'expand': 1})
45 self.entry.bind('<Return>', self.loadit)
46
47 # Create the button
48 self.reload = Button(self.topframe,
49 {'text': 'Reload',
50 'command': self.reload})
51 self.reload.pack({'side': 'right'})
52
53 # Create botframe for the text and scrollbar
54 self.botframe = Frame(self.root)
55 self.botframe.pack({'fill': 'both', 'expand': 1})
56
57 # The Scrollbar *must* be created first
58 self.vbar = Scrollbar(self.botframe)
59 self.vbar.pack({'fill': 'y', 'side': 'right'})
60 self.text = Text(self.botframe)
61 self.text.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
62
63 # Link Text widget and Scrollbar
64 self.text['yscrollcommand'] = (self.vbar, 'set')
65 self.vbar['command'] = (self.text, 'yview')
66
67 self.url = None
68
69 def load(self, url):
70 # Load a new URL into the window
71 fp, url = self.urlopen(url)
72 if not fp:
73 return
74
75 self.url = url
76
77 self.root.title(url)
78
79 self.entry.delete('0', 'end')
80 self.entry.insert('end', url)
81
82 self.text.delete('0.0', 'end')
83
84 while 1:
85 line = fp.readline()
86 if not line: break
87 if line[-2:] == '\r\n': line = line[:-2] + '\n'
88 self.text.insert('end', line)
89 self.root.update_idletasks()
90
91 fp.close()
92
93 def urlopen(self, url):
94 # Open a URL --
95 # return (fp, url) if successful
96 # display dialog and return (None, url) for errors
97 try:
98 fp = urllib.urlopen(url)
99 except IOError, msg:
100 import types
101 if type(msg) == types.TupleType and len(msg) == 4:
102 if msg[1] == 302:
103 m = msg[3]
104 if m.has_key('location'):
105 url = m['location']
106 return self.urlopen(url)
107 elif m.has_key('uri'):
108 url = m['uri']
109 return self.urlopen(url)
110 self.errordialog(IOError, msg)
111 fp = None
112 return fp, url
113
114 def errordialog(self, exc, msg):
115 # Display an error dialog -- return when the user clicks OK
116 Dialog.Dialog(self.root, {
117 'text': str(msg),
118 'title': exc,
119 'bitmap': 'error',
120 'default': 0,
121 'strings': ('OK',),
122 })
123
124 def go(self):
125 # Start Tk main loop
126 self.root.mainloop()
127
128 def reload(self, *args):
129 # Callback for Reload button
130 if self.url:
131 self.load(self.url)
132
133 def loadit(self, *args):
134 # Callback for <Return> event in entry
135 self.load(self.entry.get())
136
137main()