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