#! /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 Tkinter
import string
import websucker
import sys
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 = string.strip(url)
        if not url:
            self.top.bell()
            self.message("[Error: No URL entered]")
            return
        self.rooturl = url
        dir = string.strip(self.dir_entry.get())
        if not dir:
            self.sucker.savedir = None
        else:
            self.sucker.savedir = dir
            self.sucker.rootdir = os.path.dirname(
                websucker.Sucker.savefilename(self, 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 = string.strip(text)
            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()
