Commit dfa70a9f authored by Guido van Rossum's avatar Guido van Rossum

initial checkin of www Tk examples

parent ca9b323c
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
# A parser for SGML, using the derived class as static DTD.
# XXX This only supports those SGML features used by HTML.
# XXX There should be a way to distinguish between PCDATA (parsed
# character data -- the normal case), RCDATA (replaceable character
# data -- only char and entity references and end tags are special)
# and CDATA (character data -- only end tags are special).
import regex
import string
# Regular expressions used for parsing
incomplete = regex.compile( \
'<!-?\|</[a-zA-Z][a-zA-Z0-9]*[ \t\n]*\|</?\|' + \
'&#[a-zA-Z0-9]*\|&[a-zA-Z][a-zA-Z0-9]*\|&')
entityref = regex.compile('&[a-zA-Z][a-zA-Z0-9]*[;.]')
charref = regex.compile('&#[a-zA-Z0-9]+;')
starttagopen = regex.compile('<[a-zA-Z]')
endtag = regex.compile('</[a-zA-Z][a-zA-Z0-9]*[ \t\n]*>')
commentopen = regex.compile('<!--')
# SGML parser base class -- find tags and call handler functions.
# Usage: p = SGMLParser(); p.feed(data); ...; p.close().
# The dtd is defined by deriving a class which defines methods
# with special names to handle tags: start_foo and end_foo to handle
# <foo> and </foo>, respectively, or do_foo to handle <foo> by itself.
# (Tags are converted to lower case for this purpose.) The data
# between tags is passed to the parser by calling self.handle_data()
# with some data as argument (the data may be split up in arbutrary
# chunks). Entity references are passed by calling
# self.handle_entityref() with the entity reference as argument.
class SGMLParser:
# Interface -- initialize and reset this instance
def __init__(self):
self.reset()
# Interface -- reset this instance. Loses all unprocessed data
def reset(self):
self.rawdata = ''
self.stack = []
self.nomoretags = 0
self.literal = 0
# For derived classes only -- enter literal mode (CDATA) till EOF
def setnomoretags(self):
self.nomoretags = self.literal = 1
# For derived classes only -- enter literal mode (CDATA)
def setliteral(self, *args):
self.literal = 1
# Interface -- feed some data to the parser. Call this as
# often as you want, with as little or as much text as you
# want (may include '\n'). (This just saves the text, all the
# processing is done by process() or close().)
def feed(self, data):
self.rawdata = self.rawdata + data
self.goahead(0)
# Interface -- handle the remaining data
def close(self):
self.goahead(1)
# Internal -- handle data as far as reasonable. May leave state
# and data to be processed by a subsequent call. If 'end' is
# true, force handling all data as if followed by EOF marker.
def goahead(self, end):
rawdata = self.rawdata
i = 0
n = len(rawdata)
while i < n:
if self.nomoretags:
self.handle_data(rawdata[i:n])
i = n
break
j = incomplete.search(rawdata, i)
if j < 0: j = n
if i < j: self.handle_data(rawdata[i:j])
i = j
if i == n: break
if rawdata[i] == '<':
if starttagopen.match(rawdata, i) >= 0:
if self.literal:
self.handle_data(rawdata[i])
i = i+1
continue
k = self.parse_starttag(i)
if k < 0: break
i = i + k
continue
k = endtag.match(rawdata, i)
if k >= 0:
j = i+k
self.parse_endtag(rawdata[i:j])
i = j
self.literal = 0
continue
if commentopen.match(rawdata, i) >= 0:
if self.literal:
self.handle_data(rawdata[i])
i = i+1
continue
k = self.parse_comment(i)
if k < 0: break
i = i+k
continue
elif rawdata[i] == '&':
k = charref.match(rawdata, i)
if k >= 0:
j = i+k
self.handle_charref(rawdata[i+2:j-1])
i = j
continue
k = entityref.match(rawdata, i)
if k >= 0:
j = i+k
self.handle_entityref(rawdata[i+1:j-1])
i = j
continue
else:
raise RuntimeError, 'neither < nor & ??'
# We get here only if incomplete matches but
# nothing else
k = incomplete.match(rawdata, i)
if k < 0: raise RuntimeError, 'no incomplete match ??'
j = i+k
if j == n: break # Really incomplete
self.handle_data(rawdata[i:j])
i = j
# end while
if end and i < n:
self.handle_data(rawdata[i:n])
i = n
self.rawdata = rawdata[i:]
# XXX if end: check for empty stack
# Internal -- parse comment, return length or -1 if not ternimated
def parse_comment(self, i):
rawdata = self.rawdata
if rawdata[i:i+4] <> '<!--':
raise RuntimeError, 'unexpected call to handle_comment'
try:
j = string.index(rawdata, '--', i+4)
except string.index_error:
return -1
self.handle_comment(rawdata[i+4: j])
j = j+2
n = len(rawdata)
while j < n and rawdata[j] in ' \t\n': j = j+1
if j == n: return -1 # Wait for final '>'
if rawdata[j] == '>':
j = j+1
else:
print '*** comment not terminated with >'
print repr(rawdata[j-5:j]), '*!*', repr(rawdata[j:j+5])
return j-i
# Internal -- handle starttag, return length or -1 if not terminated
def parse_starttag(self, i):
rawdata = self.rawdata
try:
j = string.index(rawdata, '>', i)
except string.index_error:
return -1
# Now parse the data between i+1 and j into a tag and attrs
attrs = []
tagfind = regex.compile('[a-zA-Z][a-zA-Z0-9]*')
attrfind = regex.compile( \
'[ \t\n]+\([a-zA-Z][a-zA-Z0-9]*\)' + \
'\([ \t\n]*=[ \t\n]*' + \
'\(\'[^\']*\';\|"[^"]*"\|[-a-zA-Z0-9./:+*%?!()_#]+\)\)?')
k = tagfind.match(rawdata, i+1)
if k < 0:
raise RuntimeError, 'unexpected call to parse_starttag'
k = i+1+k
tag = string.lower(rawdata[i+1:k])
while k < j:
l = attrfind.match(rawdata, k)
if l < 0: break
regs = attrfind.regs
a1, b1 = regs[1]
a2, b2 = regs[2]
a3, b3 = regs[3]
attrname = rawdata[a1:b1]
if '=' in rawdata[k:k+l]:
attrvalue = rawdata[a3:b3]
if attrvalue[:1] == '\'' == attrvalue[-1:] or \
attrvalue[:1] == '"' == attrvalue[-1:]:
attrvalue = attrvalue[1:-1]
else:
attrvalue = ''
attrs.append(string.lower(attrname), attrvalue)
k = k + l
j = j+1
try:
method = getattr(self, 'start_' + tag)
except AttributeError:
try:
method = getattr(self, 'do_' + tag)
except AttributeError:
self.unknown_starttag(tag, attrs)
return j-i
method(attrs)
return j-i
self.stack.append(tag)
method(attrs)
return j-i
# Internal -- parse endtag
def parse_endtag(self, data):
if data[:2] <> '</' or data[-1:] <> '>':
raise RuntimeError, 'unexpected call to parse_endtag'
tag = string.lower(string.strip(data[2:-1]))
try:
method = getattr(self, 'end_' + tag)
except AttributeError:
self.unknown_endtag(tag)
return
if self.stack and self.stack[-1] == tag:
del self.stack[-1]
else:
print '*** Unbalanced </' + tag + '>'
print '*** Stack:', self.stack
found = None
for i in range(len(self.stack)):
if self.stack[i] == tag: found = i
if found <> None:
del self.stack[found:]
method()
# Example -- handle character reference, no need to override
def handle_charref(self, name):
try:
n = string.atoi(name)
except string.atoi_error:
self.unknown_charref(name)
return
if not 0 <= n <= 255:
self.unknown_charref(name)
return
self.handle_data(chr(n))
# Definition of entities -- derived classes may override
entitydefs = \
{'lt': '<', 'gt': '>', 'amp': '&', 'quot': '"', 'apos': '\''}
# Example -- handle entity reference, no need to override
def handle_entityref(self, name):
table = self.__class__.entitydefs
name = string.lower(name)
if table.has_key(name):
self.handle_data(table[name])
else:
self.unknown_entityref(name)
return
# Example -- handle data, should be overridden
def handle_data(self, data):
pass
# Example -- handle comment, could be overridden
def handle_comment(self, data):
pass
# To be overridden -- handlers for unknown objects
def unknown_starttag(self, tag, attrs): pass
def unknown_endtag(self, tag): pass
def unknown_charref(self, ref): pass
def unknown_entityref(self, ref): pass
class TestSGML(SGMLParser):
def handle_data(self, data):
r = repr(data)
if len(r) > 72:
r = r[:35] + '...' + r[-35:]
print 'data:', r
def handle_comment(self, data):
r = repr(data)
if len(r) > 68:
r = r[:32] + '...' + r[-32:]
print 'comment:', r
def unknown_starttag(self, tag, attrs):
print 'start tag: <' + tag,
for name, value in attrs:
print name + '=' + '"' + value + '"',
print '>'
def unknown_endtag(self, tag):
print 'end tag: </' + tag + '>'
def unknown_entityref(self, ref):
print '*** unknown entity ref: &' + ref + ';'
def unknown_charref(self, ref):
print '*** unknown char ref: &#' + ref + ';'
def test():
file = 'test.html'
f = open(file, 'r')
x = TestSGML()
while 1:
line = f.readline()
if not line:
x.close()
break
x.feed(line)
#test()
# Tk backend -- unfinished
debug = 0
from fmt import *
class TkFormatter:
def __init__(self, text):
self.text = text # The text widget to draw in
self.nospace = 1
self.blanklines = 0
self.font = ''
# Methods called by htmllib.FormattingParser:
def setfont(self, font):
if 1 or debug: print "setfont(%s)" % `font`
self.font = font
def resetfont(self):
if debug: print "resetfont()"
self.font = ''
def flush(self):
if debug: print "flush()"
self.needvspace(1)
def setleftindent(self, n):
if debug: print "setleftindent(%d)" % n
def needvspace(self, n):
if debug: print "needvspace(%d)" % n
self.blanklines = max(n, self.blanklines)
self.nospace = 1
def addword(self, word, nspaces):
if debug: print "addword(%s, %d)" % (`word`, nspaces)
if self.nospace and not word:
return
if self.blanklines > 0:
word = '\n'*self.blanklines + word
self.blanklines = 0
self.nospace = 0
here = self.text.index('end')
self.text.insert('end', word + nspaces*' ')
if not self.font:
self.tag_remo
def setjust(self, c):
if debug: print "setjust(%s)" % `c`
def bgn_anchor(self):
if debug: print "bgn_anchor()"
def end_anchor(self):
if debug: print "end_anchor()"
def hrule(self):
if debug: print "hrule()"
self.flush()
self.addword('_'*60, 0)
self.flush()
#! /usr/local/bin/python
# www1.py -- print the contents of a URL on stdout
import sys
import urllib
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]
fp = urllib.urlopen(url)
while 1:
line = fp.readline()
if not line: break
print line,
main()
#! /usr/local/bin/python
# www10.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
import sys
import urllib
from Tkinter import *
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', 'side': 'top'})
# 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'})
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 = urllib.urlopen(url)
self.url = url
self.root.title(url)
self.entry.delete('0', 'end')
self.entry.insert('end', url)
self.text.delete('1.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 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()
#! /usr/local/bin/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()
#! /usr/local/bin/python
# www12.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
# - menu bar; added 'master' option to constructor
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]
tk = Tk()
tk.withdraw()
viewer = Viewer(tk)
viewer.load(url)
viewer.go()
class Viewer:
def __init__(self, master = None):
# Create root window
if master is None:
self.root = self.master = Tk()
else:
self.master = master
self.root = Toplevel(self.master)
self.root.minsize(1, 1)
# Create menu bar
self.mbar = Frame(self.root,
{'relief': 'raised',
'border': 2})
self.mbar.pack({'fill': 'x'})
# Create File menu
self.filebutton = Menubutton(self.mbar, {'text': 'File'})
self.filebutton.pack({'side': 'left'})
self.filemenu = Menu(self.filebutton)
self.filebutton['menu'] = self.filemenu
# Create Edit menu
self.editbutton = Menubutton(self.mbar, {'text': 'Edit'})
self.editbutton.pack({'side': 'left'})
self.editmenu = Menu(self.editbutton)
self.editbutton['menu'] = self.editmenu
# Magic so you can swipe from one button to the next
self.mbar.tk_menuBar(self.filebutton, self.editbutton)
# Populate File menu
self.filemenu.add('command', {'label': 'New',
'command': self.new_command})
self.filemenu.add('command', {'label': 'Open...',
'command': self.open_command})
self.filemenu.add('command', {'label': 'Clone',
'command': self.clone_command})
self.filemenu.add('separator')
self.filemenu.add('command', {'label': 'Close',
'command': self.close_command})
self.filemenu.add('command', {'label': 'Quit',
'command': self.quit_command})
# Populate Edit menu
pass
# 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())
def new_command(self):
# File/New...
Viewer(self.master)
def clone_command(self):
# File/Clone
v = Viewer(self.master)
v.load(self.url)
def open_command(self):
# File/Open...
print "File/Open...: Not implemented"
def close_command(self):
# File/Close
self.destroy()
def quit_command(self):
# File/Quit
self.root.quit()
def destroy(self):
# Destroy this window
self.root.destroy()
if self.master is not self.root and not self.master.children:
self.master.quit()
main()
#! /usr/local/bin/python
# www13.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
# - menu bar; added 'master' option to constructor
# - Added HTML parser
import sys
import urllib
from Tkinter import *
import Dialog
import tkfmt
import htmllib
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]
tk = Tk()
tk.withdraw()
viewer = Viewer(tk)
viewer.load(url)
viewer.go()
class Viewer:
def __init__(self, master = None):
# Create root window
if master is None:
self.root = self.master = Tk()
else:
self.master = master
self.root = Toplevel(self.master)
self.root.minsize(1, 1)
# Create menu bar
self.mbar = Frame(self.root,
{'relief': 'raised',
'border': 2})
self.mbar.pack({'fill': 'x'})
# Create File menu
self.filebutton = Menubutton(self.mbar, {'text': 'File'})
self.filebutton.pack({'side': 'left'})
self.filemenu = Menu(self.filebutton)
self.filebutton['menu'] = self.filemenu
# Create Edit menu
self.editbutton = Menubutton(self.mbar, {'text': 'Edit'})
self.editbutton.pack({'side': 'left'})
self.editmenu = Menu(self.editbutton)
self.editbutton['menu'] = self.editmenu
# Magic so you can swipe from one button to the next
self.mbar.tk_menuBar(self.filebutton, self.editbutton)
# Populate File menu
self.filemenu.add('command', {'label': 'New',
'command': self.new_command})
self.filemenu.add('command', {'label': 'Open...',
'command': self.open_command})
self.filemenu.add('command', {'label': 'Clone',
'command': self.clone_command})
self.filemenu.add('separator')
self.filemenu.add('command', {'label': 'Close',
'command': self.close_command})
self.filemenu.add('command', {'label': 'Quit',
'command': self.quit_command})
# Populate Edit menu
pass
# 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')
f = tkfmt.TkFormatter(self.text)
p = htmllib.FormattingParser(f, htmllib.X11Stylesheet)
while 1:
line = fp.readline()
if not line: break
if line[-2:] == '\r\n': line = line[:-2] + '\n'
p.feed(line)
self.root.update_idletasks()
p.close()
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())
def new_command(self):
# File/New...
Viewer(self.master)
def clone_command(self):
# File/Clone
v = Viewer(self.master)
v.load(self.url)
def open_command(self):
# File/Open...
print "File/Open...: Not implemented"
def close_command(self):
# File/Close
self.destroy()
def quit_command(self):
# File/Quit
self.root.quit()
def destroy(self):
# Destroy this window
self.root.destroy()
if self.master is not self.root and not self.master.children:
self.master.quit()
main()
#! /usr/local/bin/python
# www2.py -- print the contents of a URL on stdout
# - error checking
import sys
import urllib
import types
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]
fp = my_urlopen(url)
while 1:
line = fp.readline()
if not line: break
sys.stdout.write(line)
def my_urlopen(url):
try:
fp = urllib.urlopen(url)
return fp
except IOError, msg:
if type(msg) == types.TupleType and len(msg) == 4:
print msg[:3]
m = msg[3]
for line in m.headers:
sys.stdout.write(line)
else:
print msg
sys.exit(1)
main()
#! /usr/local/bin/python
# www3.py -- print the contents of a URL on stdout
# - error checking
# - Error 302 handling
import sys
import urllib
import types
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]
fp = my_urlopen(url)
while 1:
line = fp.readline()
if not line: break
sys.stdout.write(line)
def my_urlopen(url):
try:
fp = urllib.urlopen(url)
return fp
except IOError, msg:
if type(msg) == types.TupleType and len(msg) == 4:
m = msg[3]
if msg[1] == 302:
if m.has_key('location'):
url = m['location']
print 'Location:', url
return my_urlopen(url)
elif m.has_key('uri'):
url = m['uri']
print 'URI:', url
return my_urlopen(url)
print '(Error 302 w/o Location/URI header???)'
print msg[:3]
for line in m.headers:
sys.stdout.write(line)
else:
print msg
sys.exit(1)
main()
#! /usr/local/bin/python
# www4.py -- display the contents of a URL in a Text widget
import sys
import urllib
from Tkinter import *
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]
fp = urllib.urlopen(url)
text = Text() # Create text widget
text.pack() # Realize it
while 1:
line = fp.readline()
if not line: break
text.insert('end', line) # Append line to text widget
text.mainloop() # Start Tk main loop
main()
#! /usr/local/bin/python
# www5.py -- display the contents of a URL in a Text widget
# - set window title
import sys
import urllib
from Tkinter import *
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]
fp = urllib.urlopen(url)
root = Tk()
root.title(url) # Set window manager title
text = Text(root)
text.pack()
while 1:
line = fp.readline()
if not line: break
text.insert('end', line)
text.mainloop()
main()
#! /usr/local/bin/python
# www6.py -- display the contents of a URL in a Text widget
# - set window title
# - make window resizable
import sys
import urllib
from Tkinter import *
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]
fp = urllib.urlopen(url)
root = Tk()
root.title(url)
root.minsize(1, 1) # Set minimum size
text = Text(root)
text.pack({'expand': 1, 'fill': 'both'}) # Expand into available space
while 1:
line = fp.readline()
if not line: break
text.insert('end', line)
root.mainloop() # Start Tk main loop (for root!)
main()
#! /usr/local/bin/python
# www7.py -- display the contents of a URL in a Text widget
# - set window title
# - make window resizable
# - update display while reading
import sys
import urllib
from Tkinter import *
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]
fp = urllib.urlopen(url)
root = Tk()
root.title(url)
root.minsize(1, 1)
text = Text(root)
text.pack({'expand': 1, 'fill': 'both'})
while 1:
line = fp.readline()
if not line: break
text.insert('end', line)
root.update_idletasks() # Update display
root.mainloop()
main()
#! /usr/local/bin/python
# www8.py -- display the contents of a URL in a Text widget
# - set window title
# - make window resizable
# - update display while reading
# - vertical scroll bar
import sys
import urllib
from Tkinter import *
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]
fp = urllib.urlopen(url)
# Create root window
root = Tk()
root.title(url)
root.minsize(1, 1)
# The Scrollbar *must* be created first -- this is magic for me :-(
vbar = Scrollbar(root)
vbar.pack({'fill': 'y', 'side': 'right'})
text = Text(root, {'yscrollcommand': (vbar, 'set')})
text.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
# Link Text widget and Scrollbar -- this is magic for you :-)
##text['yscrollcommand'] = (vbar, 'set')
vbar['command'] = (text, 'yview')
while 1:
line = fp.readline()
if not line: break
text.insert('end', line)
root.update_idletasks()
root.mainloop()
main()
#! /usr/local/bin/python
# www9.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
import sys
import urllib
from Tkinter import *
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)
# The Scrollbar *must* be created first
self.vbar = Scrollbar(self.root)
self.vbar.pack({'fill': 'y', 'side': 'right'})
self.text = Text(self.root)
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')
def load(self, url):
# Load a new URL into the window
fp = urllib.urlopen(url)
self.root.title(url)
self.text.delete('0.0', 'end')
while 1:
line = fp.readline()
if not line: break
self.text.insert('end', line)
self.root.update_idletasks()
fp.close()
def go(self):
# Start Tk main loop
self.root.mainloop()
main()
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment