diff options
Diffstat (limited to 'Tools/webchecker/wcgui.py')
-rwxr-xr-x | Tools/webchecker/wcgui.py | 456 |
1 files changed, 0 insertions, 456 deletions
diff --git a/Tools/webchecker/wcgui.py b/Tools/webchecker/wcgui.py deleted file mode 100755 index b0c69d3..0000000 --- a/Tools/webchecker/wcgui.py +++ /dev/null @@ -1,456 +0,0 @@ -#! /usr/bin/env python3 - -"""GUI interface to webchecker. - -This works as a Grail applet too! E.g. - - <APPLET CODE=wcgui.py NAME=CheckerWindow></APPLET> - -Checkpoints are not (yet??? ever???) supported. - -User interface: - -Enter a root to check in the text entry box. To enter more than one root, -enter them one at a time and press <Return> for each one. - -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 -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. - -A series of checkbuttons determines whether the corresponding output panel -is shown. List panels are also automatically shown or hidden when their -status changes between empty to non-empty. There are six panels: - -Log -- raw output from the checker (-v, -q affect this) -To check -- links discovered but not yet checked -Checked -- links that have been checked -Bad links -- links that failed upon checking -Errors -- pages containing at least one bad link -Details -- details about one URL; double click on a URL in any of - the above list panels (not in Log) will show details - for that URL - -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 --t root -- specify root dir which should be treated as internal (can repeat) --a -- don't check name anchors - -Command line arguments: - -rooturl -- URL to start checking - (default %(DEFROOT)s) - -XXX The command line options (-m, -q, -v) should be GUI accessible. - -XXX The roots should be visible as a list (?). - -XXX The multipanel user interface is clumsy. - -""" - -# ' Emacs bait - - -import sys -import getopt -from Tkinter import * -import tktools -import webchecker - -def main(): - try: - opts, args = getopt.getopt(sys.argv[1:], 't:m:qva') - except getopt.error as msg: - sys.stdout = sys.stderr - print(msg) - print(__doc__%vars(webchecker)) - sys.exit(2) - webchecker.verbose = webchecker.VERBOSE - webchecker.nonames = webchecker.NONAMES - webchecker.maxpage = webchecker.MAXPAGE - extra_roots = [] - for o, a in opts: - if o == '-m': - webchecker.maxpage = int(a) - if o == '-q': - webchecker.verbose = 0 - if o == '-v': - webchecker.verbose = webchecker.verbose + 1 - if o == '-t': - extra_roots.append(a) - if o == '-a': - webchecker.nonames = not webchecker.nonames - root = Tk(className='Webchecker') - root.protocol("WM_DELETE_WINDOW", root.quit) - c = CheckerWindow(root) - c.setflags(verbose=webchecker.verbose, maxpage=webchecker.maxpage, - nonames=webchecker.nonames) - if args: - for arg in args[:-1]: - c.addroot(arg) - c.suggestroot(args[-1]) - # 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) - root.mainloop() - - -class CheckerWindow(webchecker.Checker): - - def __init__(self, parent, root=webchecker.DEFROOT): - 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") - 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) - self.__details = LogPanel(mp, "Details") - self.root_seed = None - webchecker.Checker.__init__(self) - if root: - root = str(root).strip() - if root: - self.suggestroot(root) - self.newstatus() - - def reset(self): - webchecker.Checker.reset(self) - for p in self.__todo, self.__done, self.__bad, self.__errors: - p.clear() - if self.root_seed: - self.suggestroot(self.root_seed) - - def suggestroot(self, root): - self.__rootentry.delete(0, END) - self.__rootentry.insert(END, root) - self.__rootentry.select_range(0, END) - self.root_seed = root - - def enterroot(self, event=None): - root = self.__rootentry.get() - root = root.strip() - 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) - - def start(self): - self.__start.config(state=DISABLED, relief=SUNKEN) - self.__stop.config(state=NORMAL) - self.__step.config(state=DISABLED) - self.enterroot() - self.__running = 1 - self.go() - - def stop(self): - self.__stop.config(state=DISABLED, relief=SUNKEN) - self.__running = 0 - - def step(self): - self.__start.config(state=DISABLED) - self.__step.config(state=DISABLED, relief=SUNKEN) - self.enterroot() - self.__running = 0 - self.dosomething() - - def go(self): - 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) - - __busy = 0 - - def dosomething(self): - 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] - self.__checking.config(text="Checking "+self.format_url(url)) - self.__parent.update() - self.dopage(url) - else: - self.stop() - self.__busy = 0 - self.go() - - def showinfo(self, url): - d = self.__details - d.clear() - d.put("URL: %s\n" % self.format_url(url)) - if url in self.bad: - d.put("Error: %s\n" % str(self.bad[url])) - if url in self.roots: - d.put("Note: This is a root URL\n") - if url in self.done: - d.put("Status: checked\n") - o = self.done[url] - elif url in self.todo: - d.put("Status: to check\n") - o = self.todo[url] - else: - d.put("Status: unknown (!)\n") - o = [] - if (not url[1]) and url[0] in self.errors: - d.put("Bad links from this page:\n") - for triple in self.errors[url[0]]: - link, rawlink, msg = triple - d.put(" HREF %s" % self.format_url(link)) - if self.format_url(link) != rawlink: d.put(" (%s)" %rawlink) - d.put("\n") - d.put(" error %s\n" % str(msg)) - self.__mp.showpanel("Details") - for source, rawlink in o: - d.put("Origin: %s" % source) - if rawlink != self.format_url(url): - d.put(" (%s)" % rawlink) - d.put("\n") - d.text.yview("1.0") - - def setbad(self, url, msg): - webchecker.Checker.setbad(self, url, msg) - self.__bad.insert(url) - self.newstatus() - - def setgood(self, url): - webchecker.Checker.setgood(self, url) - self.__bad.remove(url) - self.newstatus() - - def newlink(self, url, origin): - webchecker.Checker.newlink(self, url, origin) - if url in self.done: - self.__done.insert(url) - elif url in self.todo: - self.__todo.insert(url) - self.newstatus() - - def markdone(self, url): - webchecker.Checker.markdone(self, url) - self.__done.insert(url) - self.__todo.remove(url) - self.newstatus() - - def seterror(self, url, triple): - webchecker.Checker.seterror(self, url, triple) - self.__errors.insert((url, '')) - self.newstatus() - - def newstatus(self): - self.__status.config(text="Status: "+self.status()) - self.__parent.update() - - def update_checkext(self): - self.checkext = self.__cv.get() - - -class ListPanel: - - def __init__(self, mp, name, checker, showinfo=None): - self.mp = mp - self.name = name - self.showinfo = showinfo - self.checker = checker - 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 = [] - - def clear(self): - self.items = [] - self.list.delete(0, END) - self.mp.hidepanel(self.name) - - def doubleclick(self, event): - l = self.selectedindices() - if l: - self.showinfo(self.items[l[0]]) - - def selectedindices(self): - l = self.list.curselection() - if not l: return [] - return list(map(int, l)) - - def insert(self, url): - 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) - self.list.insert(i, self.checker.format_url(url)) - self.list.yview(i) - self.items.insert(i, url) - - def remove(self, url): - 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) - - -class LogPanel: - - def __init__(self, mp, name): - 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) - - def clear(self): - self.text.delete("1.0", END) - self.text.yview("1.0") - - def put(self, s): - self.text.insert(END, s) - if '\n' in s: - self.text.yview(END) - - def write(self, s): - self.text.insert(END, s) - if '\n' in s: - self.text.yview(END) - self.panel.update() - - -class MultiPanel: - - def __init__(self, parent): - 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 = {} - - def addpanel(self, name, on=0): - 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 - - def showpanel(self, name): - v, check, panel = self.panels[name] - v.set(name) - panel.pack(expand=1, fill=BOTH) - - def hidepanel(self, name): - v, check, panel = self.panels[name] - v.set("") - panel.pack_forget() - - def checkpanel(self): - 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) - - -if __name__ == '__main__': - main() |