#! /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()
