<gh_stars>1000+
#! /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 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=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()     


#! /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 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=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()
#! /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. ##print format ##self.applist[0].url_entry.insert(END,"http://www.python.org/doc/essays/")