| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | #! /usr/bin/env python | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | """GUI interface to webchecker.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This works as a Grail applet too!  E.g. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  |   <APPLET CODE=wcgui.py NAME=CheckerWindow></APPLET> | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | Checkpoints are not (yet???  ever???) supported. | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | User interface: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | Enter a root to check in the text entry box.  To enter more than one root, | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | enter them one at a time and press <Return> for each one. | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | Command buttons Start, Stop and "Check one" govern the checking process in | 
					
						
							|  |  |  | the obvious way.  Start and "Check one" also enter the root from the text | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | entry box if one is present.  There's also a check box (enabled by default) | 
					
						
							|  |  |  | to decide whether actually to follow external links (since this can slow | 
					
						
							|  |  |  | the checking down considerably).  Finally there's a Quit button. | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2004-07-18 06:16:08 +00:00
										 |  |  | A series of checkbuttons determines whether the corresponding output panel | 
					
						
							|  |  |  | is shown.  List panels are also automatically shown or hidden when their | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | status changes between empty to non-empty.  There are six panels: | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Log        -- raw output from the checker (-v, -q affect this) | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | To check   -- links discovered but not yet checked | 
					
						
							|  |  |  | Checked    -- links that have been checked | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | Bad links  -- links that failed upon checking | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | Errors     -- pages containing at least one bad link | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | Details    -- details about one URL; double click on a URL in any of | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  |               the above list panels (not in Log) will show details | 
					
						
							|  |  |  |               for that URL | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | Use your window manager's Close command to quit. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Command line options: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | -m bytes  -- skip HTML pages larger than this size (default %(MAXPAGE)d) | 
					
						
							|  |  |  | -q        -- quiet operation (also suppresses external links report) | 
					
						
							|  |  |  | -v        -- verbose operation; repeating -v will increase verbosity | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  | -t root   -- specify root dir which should be treated as internal (can repeat) | 
					
						
							|  |  |  | -a        -- don't check name anchors | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Command line arguments: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | rooturl   -- URL to start checking | 
					
						
							|  |  |  |              (default %(DEFROOT)s) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | XXX The command line options (-m, -q, -v) should be GUI accessible. | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | XXX The roots should be visible as a list (?). | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | XXX The multipanel user interface is clumsy. | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # ' Emacs bait | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import sys | 
					
						
							|  |  |  | import getopt | 
					
						
							|  |  |  | from Tkinter import * | 
					
						
							|  |  |  | import tktools | 
					
						
							| 
									
										
										
										
											1999-11-17 15:40:48 +00:00
										 |  |  | import webchecker | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | import random | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | # Override some for a weaker platform | 
					
						
							|  |  |  | if sys.platform == 'mac': | 
					
						
							|  |  |  |     webchecker.DEFROOT = "http://grail.cnri.reston.va.us/" | 
					
						
							|  |  |  |     webchecker.MAXPAGE = 50000 | 
					
						
							|  |  |  |     webchecker.verbose = 4 | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def main(): | 
					
						
							|  |  |  |     try: | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         opts, args = getopt.getopt(sys.argv[1:], 't:m:qva') | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  |     except getopt.error, msg: | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         sys.stdout = sys.stderr | 
					
						
							|  |  |  |         print msg | 
					
						
							|  |  |  |         print __doc__%vars(webchecker) | 
					
						
							|  |  |  |         sys.exit(2) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |     webchecker.verbose = webchecker.VERBOSE | 
					
						
							|  |  |  |     webchecker.nonames = webchecker.NONAMES | 
					
						
							|  |  |  |     webchecker.maxpage = webchecker.MAXPAGE | 
					
						
							|  |  |  |     extra_roots = [] | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  |     for o, a in opts: | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if o == '-m': | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |             webchecker.maxpage = int(a) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if o == '-q': | 
					
						
							|  |  |  |             webchecker.verbose = 0 | 
					
						
							|  |  |  |         if o == '-v': | 
					
						
							|  |  |  |             webchecker.verbose = webchecker.verbose + 1 | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         if o == '-t': | 
					
						
							|  |  |  |             extra_roots.append(a) | 
					
						
							|  |  |  |         if o == '-a': | 
					
						
							|  |  |  |             webchecker.nonames = not webchecker.nonames | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  |     root = Tk(className='Webchecker') | 
					
						
							|  |  |  |     root.protocol("WM_DELETE_WINDOW", root.quit) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  |     c = CheckerWindow(root) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |     c.setflags(verbose=webchecker.verbose, maxpage=webchecker.maxpage, | 
					
						
							|  |  |  |                nonames=webchecker.nonames) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  |     if args: | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         for arg in args[:-1]: | 
					
						
							|  |  |  |             c.addroot(arg) | 
					
						
							|  |  |  |         c.suggestroot(args[-1]) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |     # Usually conditioned on whether external links | 
					
						
							|  |  |  |     # will be checked, but since that's not a command | 
					
						
							|  |  |  |     # line option, just toss them in. | 
					
						
							|  |  |  |     for url_root in extra_roots: | 
					
						
							|  |  |  |         # Make sure it's terminated by a slash, | 
					
						
							|  |  |  |         # so that addroot doesn't discard the last | 
					
						
							|  |  |  |         # directory component. | 
					
						
							|  |  |  |         if url_root[-1] != "/": | 
					
						
							|  |  |  |             url_root = url_root + "/" | 
					
						
							|  |  |  |         c.addroot(url_root, add_to_do = 0) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  |     root.mainloop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class CheckerWindow(webchecker.Checker): | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  |     def __init__(self, parent, root=webchecker.DEFROOT): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__parent = parent | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.__topcontrols = Frame(parent) | 
					
						
							|  |  |  |         self.__topcontrols.pack(side=TOP, fill=X) | 
					
						
							|  |  |  |         self.__label = Label(self.__topcontrols, text="Root URL:") | 
					
						
							|  |  |  |         self.__label.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__rootentry = Entry(self.__topcontrols, width=60) | 
					
						
							|  |  |  |         self.__rootentry.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__rootentry.bind('<Return>', self.enterroot) | 
					
						
							|  |  |  |         self.__rootentry.focus_set() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.__controls = Frame(parent) | 
					
						
							|  |  |  |         self.__controls.pack(side=TOP, fill=X) | 
					
						
							|  |  |  |         self.__running = 0 | 
					
						
							|  |  |  |         self.__start = Button(self.__controls, text="Run", command=self.start) | 
					
						
							|  |  |  |         self.__start.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__stop = Button(self.__controls, text="Stop", command=self.stop, | 
					
						
							|  |  |  |                              state=DISABLED) | 
					
						
							|  |  |  |         self.__stop.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__step = Button(self.__controls, text="Check one", | 
					
						
							|  |  |  |                              command=self.step) | 
					
						
							|  |  |  |         self.__step.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__cv = BooleanVar(parent) | 
					
						
							|  |  |  |         self.__cv.set(self.checkext) | 
					
						
							|  |  |  |         self.__checkext = Checkbutton(self.__controls, variable=self.__cv, | 
					
						
							|  |  |  |                                       command=self.update_checkext, | 
					
						
							|  |  |  |                                       text="Check nonlocal links",) | 
					
						
							|  |  |  |         self.__checkext.pack(side=LEFT) | 
					
						
							|  |  |  |         self.__reset = Button(self.__controls, text="Start over", command=self.reset) | 
					
						
							|  |  |  |         self.__reset.pack(side=LEFT) | 
					
						
							|  |  |  |         if __name__ == '__main__': # No Quit button under Grail! | 
					
						
							|  |  |  |             self.__quit = Button(self.__controls, text="Quit", | 
					
						
							|  |  |  |                                  command=self.__parent.quit) | 
					
						
							|  |  |  |             self.__quit.pack(side=RIGHT) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         self.__status = Label(parent, text="Status: initial", anchor=W) | 
					
						
							|  |  |  |         self.__status.pack(side=TOP, fill=X) | 
					
						
							|  |  |  |         self.__checking = Label(parent, text="Idle", anchor=W) | 
					
						
							|  |  |  |         self.__checking.pack(side=TOP, fill=X) | 
					
						
							|  |  |  |         self.__mp = mp = MultiPanel(parent) | 
					
						
							|  |  |  |         sys.stdout = self.__log = LogPanel(mp, "Log") | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         self.__todo = ListPanel(mp, "To check", self, self.showinfo) | 
					
						
							|  |  |  |         self.__done = ListPanel(mp, "Checked", self, self.showinfo) | 
					
						
							|  |  |  |         self.__bad = ListPanel(mp, "Bad links", self, self.showinfo) | 
					
						
							|  |  |  |         self.__errors = ListPanel(mp, "Pages w/ bad links", self, self.showinfo) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__details = LogPanel(mp, "Details") | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         self.root_seed = None | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.__init__(self) | 
					
						
							|  |  |  |         if root: | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |             root = str(root).strip() | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |             if root: | 
					
						
							|  |  |  |                 self.suggestroot(root) | 
					
						
							|  |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def reset(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.reset(self) | 
					
						
							|  |  |  |         for p in self.__todo, self.__done, self.__bad, self.__errors: | 
					
						
							|  |  |  |             p.clear() | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         if self.root_seed: | 
					
						
							|  |  |  |             self.suggestroot(self.root_seed) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def suggestroot(self, root): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__rootentry.delete(0, END) | 
					
						
							|  |  |  |         self.__rootentry.insert(END, root) | 
					
						
							|  |  |  |         self.__rootentry.select_range(0, END) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         self.root_seed = root | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def enterroot(self, event=None): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         root = self.__rootentry.get() | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |         root = root.strip() | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if root: | 
					
						
							|  |  |  |             self.__checking.config(text="Adding root "+root) | 
					
						
							|  |  |  |             self.__checking.update_idletasks() | 
					
						
							|  |  |  |             self.addroot(root) | 
					
						
							|  |  |  |             self.__checking.config(text="Idle") | 
					
						
							|  |  |  |             try: | 
					
						
							|  |  |  |                 i = self.__todo.items.index(root) | 
					
						
							|  |  |  |             except (ValueError, IndexError): | 
					
						
							|  |  |  |                 pass | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 self.__todo.list.select_clear(0, END) | 
					
						
							|  |  |  |                 self.__todo.list.select_set(i) | 
					
						
							|  |  |  |                 self.__todo.list.yview(i) | 
					
						
							|  |  |  |         self.__rootentry.delete(0, END) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def start(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__start.config(state=DISABLED, relief=SUNKEN) | 
					
						
							|  |  |  |         self.__stop.config(state=NORMAL) | 
					
						
							|  |  |  |         self.__step.config(state=DISABLED) | 
					
						
							|  |  |  |         self.enterroot() | 
					
						
							|  |  |  |         self.__running = 1 | 
					
						
							|  |  |  |         self.go() | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def stop(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__stop.config(state=DISABLED, relief=SUNKEN) | 
					
						
							|  |  |  |         self.__running = 0 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def step(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__start.config(state=DISABLED) | 
					
						
							|  |  |  |         self.__step.config(state=DISABLED, relief=SUNKEN) | 
					
						
							|  |  |  |         self.enterroot() | 
					
						
							|  |  |  |         self.__running = 0 | 
					
						
							|  |  |  |         self.dosomething() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def go(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if self.__running: | 
					
						
							|  |  |  |             self.__parent.after_idle(self.dosomething) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.__checking.config(text="Idle") | 
					
						
							|  |  |  |             self.__start.config(state=NORMAL, relief=RAISED) | 
					
						
							|  |  |  |             self.__stop.config(state=DISABLED, relief=RAISED) | 
					
						
							|  |  |  |             self.__step.config(state=NORMAL, relief=RAISED) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     __busy = 0 | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def dosomething(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if self.__busy: return | 
					
						
							|  |  |  |         self.__busy = 1 | 
					
						
							|  |  |  |         if self.todo: | 
					
						
							|  |  |  |             l = self.__todo.selectedindices() | 
					
						
							|  |  |  |             if l: | 
					
						
							|  |  |  |                 i = l[0] | 
					
						
							|  |  |  |             else: | 
					
						
							|  |  |  |                 i = 0 | 
					
						
							|  |  |  |                 self.__todo.list.select_set(i) | 
					
						
							|  |  |  |             self.__todo.list.yview(i) | 
					
						
							|  |  |  |             url = self.__todo.items[i] | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |             self.__checking.config(text="Checking "+self.format_url(url)) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |             self.__parent.update() | 
					
						
							|  |  |  |             self.dopage(url) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             self.stop() | 
					
						
							|  |  |  |         self.__busy = 0 | 
					
						
							|  |  |  |         self.go() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def showinfo(self, url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         d = self.__details | 
					
						
							|  |  |  |         d.clear() | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         d.put("URL:    %s\n" % self.format_url(url)) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if self.bad.has_key(url): | 
					
						
							|  |  |  |             d.put("Error:  %s\n" % str(self.bad[url])) | 
					
						
							|  |  |  |         if url in self.roots: | 
					
						
							|  |  |  |             d.put("Note:   This is a root URL\n") | 
					
						
							|  |  |  |         if self.done.has_key(url): | 
					
						
							|  |  |  |             d.put("Status: checked\n") | 
					
						
							|  |  |  |             o = self.done[url] | 
					
						
							|  |  |  |         elif self.todo.has_key(url): | 
					
						
							|  |  |  |             d.put("Status: to check\n") | 
					
						
							|  |  |  |             o = self.todo[url] | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             d.put("Status: unknown (!)\n") | 
					
						
							|  |  |  |             o = [] | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         if (not url[1]) and self.errors.has_key(url[0]): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |             d.put("Bad links from this page:\n") | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |             for triple in self.errors[url[0]]: | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |                 link, rawlink, msg = triple | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |                 d.put("  HREF  %s" % self.format_url(link)) | 
					
						
							|  |  |  |                 if self.format_url(link) != rawlink: d.put(" (%s)" %rawlink) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |                 d.put("\n") | 
					
						
							|  |  |  |                 d.put("  error %s\n" % str(msg)) | 
					
						
							|  |  |  |         self.__mp.showpanel("Details") | 
					
						
							|  |  |  |         for source, rawlink in o: | 
					
						
							|  |  |  |             d.put("Origin: %s" % source) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |             if rawlink != self.format_url(url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |                 d.put(" (%s)" % rawlink) | 
					
						
							|  |  |  |             d.put("\n") | 
					
						
							|  |  |  |         d.text.yview("1.0") | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setbad(self, url, msg): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.setbad(self, url, msg) | 
					
						
							|  |  |  |         self.__bad.insert(url) | 
					
						
							|  |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def setgood(self, url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.setgood(self, url) | 
					
						
							|  |  |  |         self.__bad.remove(url) | 
					
						
							|  |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  |     def newlink(self, url, origin): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.newlink(self, url, origin) | 
					
						
							|  |  |  |         if self.done.has_key(url): | 
					
						
							|  |  |  |             self.__done.insert(url) | 
					
						
							|  |  |  |         elif self.todo.has_key(url): | 
					
						
							|  |  |  |             self.__todo.insert(url) | 
					
						
							|  |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def markdone(self, url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.markdone(self, url) | 
					
						
							|  |  |  |         self.__done.insert(url) | 
					
						
							|  |  |  |         self.__todo.remove(url) | 
					
						
							|  |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  |     def seterror(self, url, triple): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         webchecker.Checker.seterror(self, url, triple) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         self.__errors.insert((url, '')) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.newstatus() | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def newstatus(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.__status.config(text="Status: "+self.status()) | 
					
						
							|  |  |  |         self.__parent.update() | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1998-03-05 20:12:18 +00:00
										 |  |  |     def update_checkext(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.checkext = self.__cv.get() | 
					
						
							| 
									
										
										
										
											1998-03-05 20:12:18 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | class ListPanel: | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |     def __init__(self, mp, name, checker, showinfo=None): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.mp = mp | 
					
						
							|  |  |  |         self.name = name | 
					
						
							|  |  |  |         self.showinfo = showinfo | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |         self.checker = checker | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.panel = mp.addpanel(name) | 
					
						
							|  |  |  |         self.list, self.frame = tktools.make_list_box( | 
					
						
							|  |  |  |             self.panel, width=60, height=5) | 
					
						
							|  |  |  |         self.list.config(exportselection=0) | 
					
						
							|  |  |  |         if showinfo: | 
					
						
							|  |  |  |             self.list.bind('<Double-Button-1>', self.doubleclick) | 
					
						
							|  |  |  |         self.items = [] | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  |     def clear(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.items = [] | 
					
						
							|  |  |  |         self.list.delete(0, END) | 
					
						
							|  |  |  |         self.mp.hidepanel(self.name) | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  |     def doubleclick(self, event): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         l = self.selectedindices() | 
					
						
							|  |  |  |         if l: | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |             self.showinfo(self.items[l[0]]) | 
					
						
							| 
									
										
										
										
											1997-02-01 05:17:29 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def selectedindices(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         l = self.list.curselection() | 
					
						
							|  |  |  |         if not l: return [] | 
					
						
							| 
									
										
										
										
											2002-09-11 20:36:02 +00:00
										 |  |  |         return map(int, l) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def insert(self, url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         if url not in self.items: | 
					
						
							|  |  |  |             if not self.items: | 
					
						
							|  |  |  |                 self.mp.showpanel(self.name) | 
					
						
							|  |  |  |             # (I tried sorting alphabetically, but the display is too jumpy) | 
					
						
							|  |  |  |             i = len(self.items) | 
					
						
							| 
									
										
										
										
											1999-11-17 15:03:52 +00:00
										 |  |  |             self.list.insert(i, self.checker.format_url(url)) | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |             self.list.yview(i) | 
					
						
							|  |  |  |             self.items.insert(i, url) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def remove(self, url): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         try: | 
					
						
							|  |  |  |             i = self.items.index(url) | 
					
						
							|  |  |  |         except (ValueError, IndexError): | 
					
						
							|  |  |  |             pass | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             was_selected = i in self.selectedindices() | 
					
						
							|  |  |  |             self.list.delete(i) | 
					
						
							|  |  |  |             del self.items[i] | 
					
						
							|  |  |  |             if not self.items: | 
					
						
							|  |  |  |                 self.mp.hidepanel(self.name) | 
					
						
							|  |  |  |             elif was_selected: | 
					
						
							|  |  |  |                 if i >= len(self.items): | 
					
						
							|  |  |  |                     i = len(self.items) - 1 | 
					
						
							|  |  |  |                 self.list.select_set(i) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class LogPanel: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, mp, name): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.mp = mp | 
					
						
							|  |  |  |         self.name = name | 
					
						
							|  |  |  |         self.panel = mp.addpanel(name) | 
					
						
							|  |  |  |         self.text, self.frame = tktools.make_text_box(self.panel, height=10) | 
					
						
							|  |  |  |         self.text.config(wrap=NONE) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def clear(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.text.delete("1.0", END) | 
					
						
							|  |  |  |         self.text.yview("1.0") | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  |     def put(self, s): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.text.insert(END, s) | 
					
						
							|  |  |  |         if '\n' in s: | 
					
						
							|  |  |  |             self.text.yview(END) | 
					
						
							| 
									
										
										
										
											1997-02-02 23:30:32 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  |     def write(self, s): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.text.insert(END, s) | 
					
						
							|  |  |  |         if '\n' in s: | 
					
						
							|  |  |  |             self.text.yview(END) | 
					
						
							|  |  |  |             self.panel.update() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class MultiPanel: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     def __init__(self, parent): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         self.parent = parent | 
					
						
							|  |  |  |         self.frame = Frame(self.parent) | 
					
						
							|  |  |  |         self.frame.pack(expand=1, fill=BOTH) | 
					
						
							|  |  |  |         self.topframe = Frame(self.frame, borderwidth=2, relief=RAISED) | 
					
						
							|  |  |  |         self.topframe.pack(fill=X) | 
					
						
							|  |  |  |         self.botframe = Frame(self.frame) | 
					
						
							|  |  |  |         self.botframe.pack(expand=1, fill=BOTH) | 
					
						
							|  |  |  |         self.panelnames = [] | 
					
						
							|  |  |  |         self.panels = {} | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def addpanel(self, name, on=0): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         v = StringVar(self.parent) | 
					
						
							|  |  |  |         if on: | 
					
						
							|  |  |  |             v.set(name) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             v.set("") | 
					
						
							|  |  |  |         check = Checkbutton(self.topframe, text=name, | 
					
						
							|  |  |  |                             offvalue="", onvalue=name, variable=v, | 
					
						
							|  |  |  |                             command=self.checkpanel) | 
					
						
							|  |  |  |         check.pack(side=LEFT) | 
					
						
							|  |  |  |         panel = Frame(self.botframe) | 
					
						
							|  |  |  |         label = Label(panel, text=name, borderwidth=2, relief=RAISED, anchor=W) | 
					
						
							|  |  |  |         label.pack(side=TOP, fill=X) | 
					
						
							|  |  |  |         t = v, check, panel | 
					
						
							|  |  |  |         self.panelnames.append(name) | 
					
						
							|  |  |  |         self.panels[name] = t | 
					
						
							|  |  |  |         if on: | 
					
						
							|  |  |  |             panel.pack(expand=1, fill=BOTH) | 
					
						
							|  |  |  |         return panel | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def showpanel(self, name): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         v, check, panel = self.panels[name] | 
					
						
							|  |  |  |         v.set(name) | 
					
						
							|  |  |  |         panel.pack(expand=1, fill=BOTH) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def hidepanel(self, name): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         v, check, panel = self.panels[name] | 
					
						
							|  |  |  |         v.set("") | 
					
						
							|  |  |  |         panel.pack_forget() | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def checkpanel(self): | 
					
						
							| 
									
										
										
										
											1998-04-06 14:29:28 +00:00
										 |  |  |         for name in self.panelnames: | 
					
						
							|  |  |  |             v, check, panel = self.panels[name] | 
					
						
							|  |  |  |             panel.pack_forget() | 
					
						
							|  |  |  |         for name in self.panelnames: | 
					
						
							|  |  |  |             v, check, panel = self.panels[name] | 
					
						
							|  |  |  |             if v.get(): | 
					
						
							|  |  |  |                 panel.pack(expand=1, fill=BOTH) | 
					
						
							| 
									
										
										
										
											1997-01-31 18:58:12 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if __name__ == '__main__': | 
					
						
							|  |  |  |     main() |