#! /usr/bin/env python

"""Tkinter-based GUI for websucker.

Easy use: type or paste source URL and destination directory in
their respective text boxes, click GO or hit return, and presto.
"""

from Tkinter import *
import websucker
import os
import threading
import Queue
import time

VERBOSE = 2


try:
    class Canceled(Exception):
        "Exception used to cancel run()."
except (NameError, TypeError):
    Canceled = __name__ + ".Canceled"


class SuckerThread(websucker.Sucker):

    stopit = 0
    savedir = None
    rootdir = None

    def __init__(self, msgq):
        self.msgq = msgq
        websucker.Sucker.__init__(self)
        self.setflags(verbose=VERBOSE)
        self.urlopener.addheaders = [
            ('User-agent', 'websucker/%s' % websucker.__version__),
        ]

    def message(self, format, *args):
        if args:
            format = format%args
        ##print format
        self.msgq.put(format)

    def run1(self, url):
        try:
            try:
                self.reset()
                self.addroot(url)
                self.run()
            except Canceled:
                self.message("[canceled]")
            else:
                self.message("[done]")
        finally:
            self.msgq.put(None)

    def savefile(self, text, path):
        if self.stopit:
            raise Canceled
        websucker.Sucker.savefile(self, text, path)

    def getpage(self, url):
        if self.stopit:
            raise Canceled
        return websucker.Sucker.getpage(self, url)

    def savefilename(self, url):
        path = websucker.Sucker.savefilename(self, url)
        if self.savedir:
            n = len(self.rootdir)
            if path[:n] == self.rootdir:
                path = path[n:]
                while path[:1] == os.sep:
                    path = path[1:]
                path = os.path.join(self.savedir, path)
        return path

    def XXXaddrobot(self, *args):
        pass

    def XXXisallowed(self, *args):
        return 1


class App:

    sucker = None
    msgq = None

    def __init__(self, top):
        self.top = top
        top.columnconfigure(99, weight=1)
        self.url_label = Label(top, text="URL:")
        self.url_label.grid(row=0, column=0, sticky='e')
        self.url_entry = Entry(top, width=60, exportselection=0)
        self.url_entry.grid(row=0, column=1, sticky='we',
                    columnspan=99)
        self.url_entry.focus_set()
        self.url_entry.bind("<Key-Return>", self.go)
        self.dir_label = Label(top, text="Directory:")
        self.dir_label.grid(row=1, column=0, sticky='e')
        self.dir_entry = Entry(top)
        self.dir_entry.grid(row=1, column=1, sticky='we',
                    columnspan=99)
        self.go_button = Button(top, text="Go", command=self.go)
        self.go_button.grid(row=2, column=1, sticky='w')
        self.cancel_button = Button(top, text="Cancel",
                        command=self.cancel,
                                    state=DISABLED)
        self.cancel_button.grid(row=2, column=2, sticky='w')
        self.auto_button = Button(top, text="Paste+Go",
                      command=self.auto)
        self.auto_button.grid(row=2, column=3, sticky='w')
        self.status_label = Label(top, text="[idle]")
        self.status_label.grid(row=2, column=4, sticky='w')
        self.top.update_idletasks()
        self.top.grid_propagate(0)

    def message(self, text, *args):
        if args:
            text = text % args
        self.status_label.config(text=text)

    def check_msgq(self):
        while not self.msgq.empty():
            msg = self.msgq.get()
            if msg is None:
                self.go_button.configure(state=NORMAL)
                self.auto_button.configure(state=NORMAL)
                self.cancel_button.configure(state=DISABLED)
                if self.sucker:
                    self.sucker.stopit = 0
                self.top.bell()
            else:
                self.message(msg)
        self.top.after(100, self.check_msgq)

    def go(self, event=None):
        if not self.msgq:
            self.msgq = Queue.Queue(0)
            self.check_msgq()
        if not self.sucker:
            self.sucker = SuckerThread(self.msgq)
        if self.sucker.stopit:
            return
        self.url_entry.selection_range(0, END)
        url = self.url_entry.get()
        url = url.strip()
        if not url:
            self.top.bell()
            self.message("[Error: No URL entered]")
            return
        self.rooturl = url
        dir = self.dir_entry.get().strip()
        if not dir:
            self.sucker.savedir = None
        else:
            self.sucker.savedir = dir
            self.sucker.rootdir = os.path.dirname(
                websucker.Sucker.savefilename(self.sucker, url))
        self.go_button.configure(state=DISABLED)
        self.auto_button.configure(state=DISABLED)
        self.cancel_button.configure(state=NORMAL)
        self.message( '[running...]')
        self.sucker.stopit = 0
        t = threading.Thread(target=self.sucker.run1, args=(url,))
        t.start()

    def cancel(self):
        if self.sucker:
            self.sucker.stopit = 1
        self.message("[canceling...]")

    def auto(self):
        tries = ['PRIMARY', 'CLIPBOARD']
        text = ""
        for t in tries:
            try:
                text = self.top.selection_get(selection=t)
            except TclError:
                continue
            text = text.strip()
            if text:
                break
        if not text:
            self.top.bell()
            self.message("[Error: clipboard is empty]")
            return
        self.url_entry.delete(0, END)
        self.url_entry.insert(0, text)
        self.go()


class AppArray:

    def __init__(self, top=None):
        if not top:
            top = Tk()
            top.title("websucker GUI")
            top.iconname("wsgui")
            top.wm_protocol('WM_DELETE_WINDOW', self.exit)
        self.top = top
        self.appframe = Frame(self.top)
        self.appframe.pack(fill='both')
        self.applist = []
        self.exit_button = Button(top, text="Exit", command=self.exit)
        self.exit_button.pack(side=RIGHT)
        self.new_button = Button(top, text="New", command=self.addsucker)
        self.new_button.pack(side=LEFT)
        self.addsucker()
        ##self.applist[0].url_entry.insert(END, "http://www.python.org/doc/essays/")

    def addsucker(self):
        self.top.geometry("")
        frame = Frame(self.appframe, borderwidth=2, relief=GROOVE)
        frame.pack(fill='x')
        app = App(frame)
        self.applist.append(app)

    done = 0

    def mainloop(self):
        while not self.done:
            time.sleep(0.1)
            self.top.update()

    def exit(self):
        for app in self.applist:
            app.cancel()
            app.message("[exiting...]")
        self.done = 1


def main():
    AppArray().mainloop()

if __name__ == '__main__':
    main()
