#! /usr/bin/env python

"""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, 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 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 = []
        if (not url[1]) and self.errors.has_key(url[0]):
            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 self.done.has_key(url):
            self.__done.insert(url)
        elif self.todo.has_key(url):
            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 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()
