annotate Tools/webchecker/webchecker.py @ 5817:48b94de85bf3 legacy-trunk

Extensive changes by AMK.
author Guido van Rossum <guido@python.org>
date Thu, 17 Jul 1997 16:29:42 +0000
parents bccb8d742964
children 9ed9eb4a7f23
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
1 #! /usr/bin/env python
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
2
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
3 """Web tree checker.
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
4
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
5 This utility is handy to check a subweb of the world-wide web for
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
6 errors. A subweb is specified by giving one or more ``root URLs''; a
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
7 page belongs to the subweb if one of the root URLs is an initial
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
8 prefix of it.
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
9
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
10 File URL extension:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
11
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
12 In order to easy the checking of subwebs via the local file system,
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
13 the interpretation of ``file:'' URLs is extended to mimic the behavior
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
14 of your average HTTP daemon: if a directory pathname is given, the
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
15 file index.html in that directory is returned if it exists, otherwise
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
16 a directory listing is returned. Now, you can point webchecker to the
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 document tree in the local file system of your HTTP daemon, and have
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 most of it checked. In fact the default works this way if your local
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
19 web tree is located at /usr/local/etc/httpd/htdpcs (the default for
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 the NCSA HTTP daemon and probably others).
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
21
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
22 Report printed:
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
23
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
24 When done, it reports pages with bad links within the subweb. When
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
25 interrupted, it reports for the pages that it has checked already.
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
26
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 In verbose mode, additional messages are printed during the
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 information gathering phase. By default, it prints a summary of its
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
29 work status every 50 URLs (adjustable with the -r option), and it
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 reports errors as they are encountered. Use the -q option to disable
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 this output.
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
32
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
33 Checkpoint feature:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
34
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
35 Whether interrupted or not, it dumps its state (a Python pickle) to a
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
36 checkpoint file and the -R option allows it to restart from the
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
37 checkpoint (assuming that the pages on the subweb that were already
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
38 processed haven't changed). Even when it has run till completion, -R
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 can still be useful -- it will print the reports again, and -Rq prints
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
40 the errors only. In this case, the checkpoint file is not written
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
41 again. The checkpoint file can be set with the -d option.
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
42
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
43 The checkpoint file is written as a Python pickle. Remember that
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
44 Python's pickle module is currently quite slow. Give it the time it
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
45 needs to load and save the checkpoint file. When interrupted while
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
46 writing the checkpoint file, the old checkpoint file is not
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
47 overwritten, but all work done in the current run is lost.
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
48
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
49 Miscellaneous:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
50
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
51 - You may find the (Tk-based) GUI version easier to use. See wcgui.py.
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
52
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
53 - Webchecker honors the "robots.txt" convention. Thanks to Skip
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
54 Montanaro for his robotparser.py module (included in this directory)!
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
55 The agent name is hardwired to "webchecker". URLs that are disallowed
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
56 by the robots.txt file are reported as external URLs.
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
57
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
58 - Because the SGML parser is a bit slow, very large SGML files are
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
59 skipped. The size limit can be set with the -m option.
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
60
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
61 - When the server or protocol does not tell us a file's type, we guess
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
62 it based on the URL's suffix. The mimetypes.py module (also in this
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
63 directory) has a built-in table mapping most currently known suffixes,
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
64 and in addition attempts to read the mime.types configuration files in
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
65 the default locations of Netscape and the NCSA HTTP daemon.
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
66
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
67 - We follows links indicated by <A>, <FRAME> and <IMG> tags. We also
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
68 honor the <BASE> tag.
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
69
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
70 - Checking external links is now done by default; use -x to *disable*
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
71 this feature. External links are now checked during normal
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
72 processing. (XXX The status of a checked link could be categorized
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
73 better. Later...)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
74
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
75
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
76 Usage: webchecker.py [option] ... [rooturl] ...
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
77
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
78 Options:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
79
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 -R -- restart from checkpoint file
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
81 -d file -- checkpoint filename (default %(DUMPFILE)s)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
82 -m bytes -- skip HTML pages larger than this size (default %(MAXPAGE)d)
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
83 -n -- reports only, no checking (use with -R)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 -q -- quiet operation (also suppresses external links report)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
85 -r number -- number of links processed per round (default %(ROUNDSIZE)d)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
86 -v -- verbose operation; repeating -v will increase verbosity
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
87 -x -- don't check external links (these are often slow to check)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
88
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
89 Arguments:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
90
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
91 rooturl -- URL to start checking
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
92 (default %(DEFROOT)s)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
93
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
94 """
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
95
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
96
5423
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
97 __version__ = "0.5"
5066
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
98
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
99
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
100 import sys
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
101 import os
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
102 from types import *
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
103 import string
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
104 import StringIO
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
105 import getopt
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
106 import pickle
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
107
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
108 import urllib
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
109 import urlparse
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
110 import sgmllib
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
111
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 import mimetypes
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
113 import robotparser
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
114
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
115
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
116 # Tunable parameters
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
117 DEFROOT = "file:/usr/local/etc/httpd/htdocs/" # Default root URL
5080
9a8adaf58ce8 Spin off checking of external page in a subroutine.
Guido van Rossum <guido@python.org>
parents: 5076
diff changeset
118 MAXPAGE = 150000 # Ignore files bigger than this
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
119 ROUNDSIZE = 50 # Number of links processed per round
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
120 DUMPFILE = "@webchecker.pickle" # Pickled checkpoint
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
121 AGENTNAME = "webchecker" # Agent name for robots.txt parser
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
122
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
123
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
124 # Global variables
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
125 verbose = 1
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
126 maxpage = MAXPAGE
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
127 roundsize = ROUNDSIZE
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
128
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
129
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
130 def main():
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
131 global verbose, maxpage, roundsize
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
132 dumpfile = DUMPFILE
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
133 restart = 0
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
134 checkext = 1
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
135 norun = 0
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
136
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
137 try:
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
138 opts, args = getopt.getopt(sys.argv[1:], 'Rd:m:nqr:vx')
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
139 except getopt.error, msg:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
140 sys.stdout = sys.stderr
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
141 print msg
5080
9a8adaf58ce8 Spin off checking of external page in a subroutine.
Guido van Rossum <guido@python.org>
parents: 5076
diff changeset
142 print __doc__%globals()
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
143 sys.exit(2)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
144 for o, a in opts:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
145 if o == '-R':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
146 restart = 1
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
147 if o == '-d':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
148 dumpfile = a
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
149 if o == '-m':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
150 maxpage = string.atoi(a)
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
151 if o == '-n':
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
152 norun = 1
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
153 if o == '-q':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
154 verbose = 0
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
155 if o == '-r':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
156 roundsize = string.atoi(a)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
157 if o == '-v':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
158 verbose = verbose + 1
5067
4aaca42a2a16 Added -x option to check external links. Slooooow!
Guido van Rossum <guido@python.org>
parents: 5066
diff changeset
159 if o == '-x':
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
160 checkext = not checkext
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
161
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
162 if verbose > 0:
5066
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
163 print AGENTNAME, "version", __version__
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
164
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
165 if restart:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
166 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
167 print "Loading checkpoint from %s ..." % dumpfile
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
168 f = open(dumpfile, "rb")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
169 c = pickle.load(f)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
170 f.close()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
171 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
172 print "Done."
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
173 print "Root:", string.join(c.roots, "\n ")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
174 else:
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
175 c = Checker(checkext)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
176 if not args:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
177 args.append(DEFROOT)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
178
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
179 for arg in args:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
180 c.addroot(arg)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
181
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
182 if not norun:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
183 try:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
184 c.run()
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
185 except KeyboardInterrupt:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
186 if verbose > 0:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
187 print "[run interrupted]"
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
188
5067
4aaca42a2a16 Added -x option to check external links. Slooooow!
Guido van Rossum <guido@python.org>
parents: 5066
diff changeset
189 try:
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
190 c.report()
5067
4aaca42a2a16 Added -x option to check external links. Slooooow!
Guido van Rossum <guido@python.org>
parents: 5066
diff changeset
191 except KeyboardInterrupt:
4aaca42a2a16 Added -x option to check external links. Slooooow!
Guido van Rossum <guido@python.org>
parents: 5066
diff changeset
192 if verbose > 0:
4aaca42a2a16 Added -x option to check external links. Slooooow!
Guido van Rossum <guido@python.org>
parents: 5066
diff changeset
193 print "[report interrupted]"
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
194
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
195 if not c.changed:
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
196 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
197 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
198 print "No need to save checkpoint"
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
199 elif not dumpfile:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
200 if verbose > 0:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
201 print "No dumpfile, won't save checkpoint"
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
202 else:
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
203 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
204 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
205 print "Saving checkpoint to %s ..." % dumpfile
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
206 newfile = dumpfile + ".new"
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
207 f = open(newfile, "wb")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
208 pickle.dump(c, f)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
209 f.close()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
210 try:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
211 os.unlink(dumpfile)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
212 except os.error:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
213 pass
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
214 os.rename(newfile, dumpfile)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
215 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
216 print "Done."
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
217 if dumpfile == DUMPFILE:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
218 print "Use ``%s -R'' to restart." % sys.argv[0]
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
219 else:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
220 print "Use ``%s -R -d %s'' to restart." % (sys.argv[0],
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
221 dumpfile)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
222
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
223
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
224 class Checker:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
225
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
226 def __init__(self, checkext=1):
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
227 self.reset()
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
228 self.checkext = checkext
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
229
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
230 def reset(self):
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
231 self.roots = []
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
232 self.todo = {}
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
233 self.done = {}
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
234 self.bad = {}
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
235 self.round = 0
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
236 # The following are not pickled:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
237 self.robots = {}
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
238 self.errors = {}
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
239 self.urlopener = MyURLopener()
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
240 self.changed = 0
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
241
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
242 def __getstate__(self):
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
243 return (self.roots, self.todo, self.done, self.bad, self.round)
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
244
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
245 def __setstate__(self, state):
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
246 (self.roots, self.todo, self.done, self.bad, self.round) = state
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
247 for root in self.roots:
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
248 self.addrobot(root)
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
249 for url in self.bad.keys():
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
250 self.markerror(url)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
251
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
252 def addroot(self, root):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
253 if root not in self.roots:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
254 self.roots.append(root)
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
255 self.addrobot(root)
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
256 self.newlink(root, ("<root>", root))
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
257
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
258 def addrobot(self, root):
5066
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
259 url = urlparse.urljoin(root, "/robots.txt")
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
260 self.robots[root] = rp = robotparser.RobotFileParser()
5066
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
261 if verbose > 2:
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
262 print "Parsing", url
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
263 rp.debug = verbose > 3
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
264 rp.set_url(url)
5066
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
265 try:
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
266 rp.read()
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
267 except IOError, msg:
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
268 if verbose > 1:
77616b3001ef Catch I/O errors when parsing robots.txt file.
Guido van Rossum <guido@python.org>
parents: 5064
diff changeset
269 print "I/O error parsing", url, ":", msg
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
270
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
271 def run(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
272 while self.todo:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
273 self.round = self.round + 1
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
274 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
275 print
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
276 print "Round %d (%s)" % (self.round, self.status())
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
277 print
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
278 urls = self.todo.keys()[:roundsize]
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
279 for url in urls:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
280 self.dopage(url)
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
281
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
282 def status(self):
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
283 return "%d total, %d to do, %d done, %d bad" % (
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
284 len(self.todo)+len(self.done),
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
285 len(self.todo), len(self.done),
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
286 len(self.bad))
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
287
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
288 def report(self):
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
289 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
290 if not self.todo: print "Final",
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
291 else: print "Interim",
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
292 print "Report (%s)" % self.status()
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
293 self.report_errors()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
294
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
295 def report_errors(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
296 if not self.bad:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
297 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
298 print "No errors"
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
299 return
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
300 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
301 print "Error Report:"
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
302 sources = self.errors.keys()
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
303 sources.sort()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
304 for source in sources:
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
305 triples = self.errors[source]
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
306 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
307 if len(triples) > 1:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
308 print len(triples), "Errors in", source
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
309 else:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
310 print "Error in", source
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
311 for url, rawlink, msg in triples:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
312 print " HREF", url,
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
313 if rawlink != url: print "(%s)" % rawlink,
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
314 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
315 print " msg", msg
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
316
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
317 def dopage(self, url):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
318 if verbose > 1:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
319 if verbose > 2:
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
320 show("Check ", url, " from", self.todo[url])
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
321 else:
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
322 print "Check ", url
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
323 page = self.getpage(url)
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
324 if page:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
325 for info in page.getlinkinfos():
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
326 link, rawlink = info
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
327 origin = url, rawlink
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
328 self.newlink(link, origin)
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
329 self.markdone(url)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
330
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
331 def newlink(self, url, origin):
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
332 if self.done.has_key(url):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
333 self.newdonelink(url, origin)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
334 else:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
335 self.newtodolink(url, origin)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
336
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
337 def newdonelink(self, url, origin):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
338 self.done[url].append(origin)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
339 if verbose > 3:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
340 print " Done link", url
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
341
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
342 def newtodolink(self, url, origin):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
343 if self.todo.has_key(url):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
344 self.todo[url].append(origin)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
345 if verbose > 3:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
346 print " Seen todo link", url
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
347 else:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
348 self.todo[url] = [origin]
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
349 if verbose > 3:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
350 print " New todo link", url
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
351
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
352 def markdone(self, url):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
353 self.done[url] = self.todo[url]
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
354 del self.todo[url]
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
355 self.changed = 1
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
356
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
357 def inroots(self, url):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
358 for root in self.roots:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
359 if url[:len(root)] == root:
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
360 return self.robots[root].can_fetch(AGENTNAME, url)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
361 return 0
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
362
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
363 def getpage(self, url):
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
364 if url[:7] == 'mailto:' or url[:5] == 'news:':
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
365 if verbose > 1: print " Not checking mailto/news URL"
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
366 return None
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
367 isint = self.inroots(url)
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
368 if not isint and not self.checkext:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
369 if verbose > 1: print " Not checking ext link"
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
370 return None
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
371 try:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
372 f = self.urlopener.open(url)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
373 except IOError, msg:
5068
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
374 msg = sanitize(msg)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
375 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
376 print "Error ", msg
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
377 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
378 show(" HREF ", url, " from", self.todo[url])
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
379 self.setbad(url, msg)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
380 return None
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
381 if not isint:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
382 if verbose > 1: print " Not gathering links from ext URL"
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
383 safeclose(f)
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
384 return None
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
385 nurl = f.geturl()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
386 info = f.info()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
387 if info.has_key('content-type'):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
388 ctype = string.lower(info['content-type'])
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
389 else:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
390 ctype = None
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
391 if nurl != url:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
392 if verbose > 1:
5064
7dded7851fca Added robots.txt support, using Skip Montanaro's parser.
Guido van Rossum <guido@python.org>
parents: 5062
diff changeset
393 print " Redirected to", nurl
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
394 if not ctype:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
395 ctype, encoding = mimetypes.guess_type(nurl)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
396 if ctype != 'text/html':
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
397 safeclose(f)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
398 if verbose > 1:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
399 print " Not HTML, mime type", ctype
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
400 return None
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
401 text = f.read()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
402 f.close()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
403 return Page(text, nurl)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
404
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
405 def setgood(self, url):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
406 if self.bad.has_key(url):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
407 del self.bad[url]
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
408 self.changed = 1
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
409 if verbose > 0:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
410 print "(Clear previously seen error)"
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
411
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
412 def setbad(self, url, msg):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
413 if self.bad.has_key(url) and self.bad[url] == msg:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
414 if verbose > 0:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
415 print "(Seen this error before)"
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
416 return
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
417 self.bad[url] = msg
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
418 self.changed = 1
5086
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
419 self.markerror(url)
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
420
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
421 def markerror(self, url):
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
422 try:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
423 origins = self.todo[url]
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
424 except KeyError:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
425 origins = self.done[url]
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
426 for source, rawlink in origins:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
427 triple = url, rawlink, self.bad[url]
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
428 self.seterror(source, triple)
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
429
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
430 def seterror(self, url, triple):
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
431 try:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
432 self.errors[url].append(triple)
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
433 except KeyError:
aa73da661cdf Restructured Checker class to get rid of 'ext' table.
Guido van Rossum <guido@python.org>
parents: 5083
diff changeset
434 self.errors[url] = [triple]
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
435
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
436
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
437 class Page:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
438
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
439 def __init__(self, text, url):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
440 self.text = text
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
441 self.url = url
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
442
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
443 def getlinkinfos(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
444 size = len(self.text)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
445 if size > maxpage:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
446 if verbose > 0:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
447 print "Skip huge file", self.url
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
448 print " (%.0f Kbytes)" % (size*0.001)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
449 return []
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
450 if verbose > 2:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
451 print " Parsing", self.url, "(%d bytes)" % size
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
452 parser = MyHTMLParser()
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
453 parser.feed(self.text)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
454 parser.close()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
455 rawlinks = parser.getlinks()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
456 base = urlparse.urljoin(self.url, parser.getbase() or "")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
457 infos = []
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
458 for rawlink in rawlinks:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
459 t = urlparse.urlparse(rawlink)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
460 t = t[:-1] + ('',)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
461 rawlink = urlparse.urlunparse(t)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
462 link = urlparse.urljoin(base, rawlink)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
463 infos.append((link, rawlink))
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
464 return infos
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
465
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
466
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
467 class MyStringIO(StringIO.StringIO):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
468
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
469 def __init__(self, url, info):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
470 self.__url = url
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
471 self.__info = info
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
472 StringIO.StringIO.__init__(self)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
473
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
474 def info(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
475 return self.__info
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
476
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
477 def geturl(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
478 return self.__url
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
479
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
480
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
481 class MyURLopener(urllib.FancyURLopener):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
482
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
483 http_error_default = urllib.URLopener.http_error_default
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
484
5069
fa31476a2786 Set proper User-agent header (Python-webchecker/<version>).
Guido van Rossum <guido@python.org>
parents: 5068
diff changeset
485 def __init__(*args):
fa31476a2786 Set proper User-agent header (Python-webchecker/<version>).
Guido van Rossum <guido@python.org>
parents: 5068
diff changeset
486 self = args[0]
fa31476a2786 Set proper User-agent header (Python-webchecker/<version>).
Guido van Rossum <guido@python.org>
parents: 5068
diff changeset
487 apply(urllib.FancyURLopener.__init__, args)
5423
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
488 self.addheaders = [
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
489 ('User-agent', 'Python-webchecker/%s' % __version__),
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
490 ]
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
491
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
492 def http_error_401(self, url, fp, errcode, errmsg, headers):
bccb8d742964 Avoid the fancy handler for error 401 (request authentication).
Guido van Rossum <guido@python.org>
parents: 5086
diff changeset
493 return None
5069
fa31476a2786 Set proper User-agent header (Python-webchecker/<version>).
Guido van Rossum <guido@python.org>
parents: 5068
diff changeset
494
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
495 def open_file(self, url):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
496 path = urllib.url2pathname(urllib.unquote(url))
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
497 if path[-1] != os.sep:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
498 url = url + '/'
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
499 if os.path.isdir(path):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
500 indexpath = os.path.join(path, "index.html")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
501 if os.path.exists(indexpath):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
502 return self.open_file(url + "index.html")
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
503 try:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
504 names = os.listdir(path)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
505 except os.error, msg:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
506 raise IOError, msg, sys.exc_traceback
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
507 names.sort()
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
508 s = MyStringIO("file:"+url, {'content-type': 'text/html'})
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
509 s.write('<BASE HREF="file:%s">\n' %
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
510 urllib.quote(os.path.join(path, "")))
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
511 for name in names:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
512 q = urllib.quote(name)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
513 s.write('<A HREF="%s">%s</A>\n' % (q, q))
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
514 s.seek(0)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
515 return s
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
516 return urllib.FancyURLopener.open_file(self, path)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
517
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
518
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
519 class MyHTMLParser(sgmllib.SGMLParser):
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
520
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
521 def __init__(self):
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
522 self.base = None
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
523 self.links = {}
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
524 sgmllib.SGMLParser.__init__ (self)
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
525
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
526 def start_a(self, attributes):
5083
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
527 self.link_attr(attributes, 'href')
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
528
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
529 def end_a(self): pass
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
530
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
531 def do_img(self, attributes):
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
532 self.link_attr(attributes, 'src', 'lowsrc')
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
533
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
534 def do_frame(self, attributes):
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
535 self.link_attr(attributes, 'src')
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
536
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
537 def link_attr(self, attributes, *args):
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
538 for name, value in attributes:
5083
7ab1aa08d348 Process <img> and <frame> tags. Don't bother skipping second href.
Guido van Rossum <guido@python.org>
parents: 5080
diff changeset
539 if name in args:
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
540 if value: value = string.strip(value)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
541 if value: self.links[value] = None
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
542
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
543 def do_base(self, attributes):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
544 for name, value in attributes:
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
545 if name == 'href':
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
546 if value: value = string.strip(value)
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
547 if value:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
548 if verbose > 1:
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
549 print " Base", value
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
550 self.base = value
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
551
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
552 def getlinks(self):
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
553 return self.links.keys()
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
554
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
555 def getbase(self):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
556 return self.base
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
557
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
558
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
559 def show(p1, link, p2, origins):
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
560 print p1, link
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
561 i = 0
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
562 for source, rawlink in origins:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
563 i = i+1
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
564 if i == 2:
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
565 p2 = ' '*len(p2)
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
566 print p2, source,
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
567 if rawlink != link: print "(%s)" % rawlink,
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
568 print
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
569
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
570
5068
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
571 def sanitize(msg):
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
572 if (type(msg) == TupleType and
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
573 len(msg) >= 4 and
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
574 msg[0] == 'http error' and
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
575 type(msg[3]) == InstanceType):
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
576 # Remove the Message instance -- it may contain
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
577 # a file object which prevents pickling.
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
578 msg = msg[:3] + msg[4:]
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
579 return msg
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
580
8ecf2d7c9fb1 Some refinements of the external-link checking code: insert the errors
Guido van Rossum <guido@python.org>
parents: 5067
diff changeset
581
5076
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
582 def safeclose(f):
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
583 url = f.geturl()
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
584 if url[:4] == 'ftp:' or url[:7] == 'file://':
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
585 # Apparently ftp connections don't like to be closed
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
586 # prematurely...
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
587 text = f.read()
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
588 f.close()
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
589
4edab474974c Many misc changes.
Guido van Rossum <guido@python.org>
parents: 5069
diff changeset
590
5062
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
591 if __name__ == '__main__':
d681631d992f web tree checker
Guido van Rossum <guido@python.org>
parents:
diff changeset
592 main()