Welcome, guest | Sign In | My Account | Store | Cart
#!/usr/bin/torify /usr/bin/python
import Tkinter
import tkFont
import requests
import html2text
import urllib2

class TkDND(object):

   
def __init__(self, master):
        master
.tk.eval('package require tkdnd')
       
self.master = master
       
self.tk = master.tk
       
self._subst_format = ('%A', '%a', '%b', '%D', '%d', '%m', '%T',
               
'%W', '%X', '%Y', '%x', '%y')
       
self._subst_format_str = " ".join(self._subst_format)

   
def bindtarget(self, window, callback, dndtype, event='<Drop>', priority=50):
        cmd
= self._prepare_tkdnd_func(callback)
       
return self.tk.call('dnd', 'bindtarget', window, dndtype, event,
                cmd
, priority)
               
   
def _prepare_tkdnd_func(self, callback):
        funcid
= self.master.register(callback, self._dndsubstitute)
        cmd
= ('%s %s' % (funcid, self._subst_format_str))
       
return cmd              

   
def _dndsubstitute(self, *args):
       
if len(args) != len(self._subst_format):
           
return args

       
def try_int(x):
            x
= str(x)
           
try:
               
return int(x)
           
except ValueError:
               
return x

        A
, a, b, D, d, m, T, W, X, Y, x, y = args

       
event = Tkinter.Event()
       
event.action = A       # Current action of the drag and drop operation.
       
event.action_list = a  # Action list supported by the drag source.
       
event.mouse_button = b # Mouse button pressed during the drag and drop.
       
event.data = D         # The data that has been dropped.
       
event.descr = d        # The list of descriptions.
       
event.modifier = m     # The list of modifier keyboard keys pressed.
       
event.dndtype = T
       
event.widget = self.master.nametowidget(W)
       
event.x_root = X       # Mouse pointer x coord, relative to the root win.
       
event.y_root = Y
       
event.x = x            # Mouse pointer x coord, relative to the widget.
       
event.y = y
       
event.action_list = str(event.action_list).split()

       
for name in ('mouse_button', 'x', 'y', 'x_root', 'y_root'):
            setattr
(event, name, try_int(getattr(event, name)))
       
return (event, )

class TextPlus(Tkinter.Text):
   
def __init__(self, *args, **kwargs):
       
Tkinter.Text.__init__(self, *args, **kwargs)
        _rc_menu_install
(self)
       
# overwrite default class binding so we don't need to return "break"
       
self.bind_class("Text", "<Control-a>", self.event_select_all)  
       
self.bind("<Button-3><ButtonRelease-3>", self.show_menu)

   
def event_select_all(self, *args):
       
self.focus_force()        
       
self.tag_add("sel","1.0","end")

   
def show_menu(self, e):
       
self.tk.call("tk_popup", self.menu, e.x_root, e.y_root)

class EntryPlus(Tkinter.Entry):
   
def __init__(self, *args, **kwargs):
       
Tkinter.Entry.__init__(self, *args, **kwargs)
        _rc_menu_install
(self, go=True)
       
# overwrite default class binding so we don't need to return "break"
       
self.bind_class("Entry", "<Control-a>", self.event_select_all)  
       
self.bind("<Button-3><ButtonRelease-3>", self.show_menu)

   
def event_select_all(self, *args):
       
self.focus_force()
       
self.selection_range(0, Tkinter.END)

   
def event_paste_and_go(self, *args):
       
self.delete(0,Tkinter.END)
       
self.focus_force()
       
self.event_generate("<<Paste>>")
        handlereturn
(self)

   
def show_menu(self, e):
       
self.tk.call("tk_popup", self.menu, e.x_root, e.y_root)

def _rc_menu_install(w, go = False):
    w
.menu = Tkinter.Menu(w, tearoff=0)
    w
.menu.add_command(label="Cut")
    w
.menu.add_command(label="Copy")
    w
.menu.add_command(label="Paste")
   
if go:
        w
.menu.add_command(label="Paste & Go")
    w
.menu.add_separator()
    w
.menu.add_command(label="Select all")        

    w
.menu.entryconfigure("Cut", command=lambda: w.focus_force() or w.event_generate("<<Cut>>"))
    w
.menu.entryconfigure("Copy", command=lambda: w.focus_force() or w.event_generate("<<Copy>>"))
    w
.menu.entryconfigure("Paste", command=lambda: w.focus_force() or w.event_generate("<<Paste>>"))
   
if go:
        w
.menu.entryconfigure("Paste & Go", command=w.event_paste_and_go)
    w
.menu.entryconfigure("Select all", command=w.event_select_all)

def handle(event):
   
event.widget.delete(0,Tkinter.END)
    url
= event.data.strip()
   
event.widget.insert(0,url)
    textwindow
(url)

def handlereturn(entry):
    p
= entry.get().splitlines()[0]
   
if not p.startswith('http'):
        p
= 'file://'+ p
    textwindow
(p)
   
def convert65536(s):
   
#convert out-of-range characters
    res
= []
   
for c in s:
        k
= ord(c)
       
if k < 65536:
            res
.append(c)
       
else:
            res
.append("{"+str(k)+"?}")
   
return "".join(res)
   
def gethtml(link):
    user_agent
= "Mozilla/5.0 (Windows NT 6.1; rv:38.0) Gecko/20100101 Firefox/38.0"
    headers
={'user-agent':user_agent}
    s
= requests.Session()
   
try:
        res
= s.get(link,headers=headers).text
   
except requests.exceptions.InvalidSchema:
        req
=urllib2.Request(link,None,headers)
        r
= urllib2.urlopen(req)
        res
= r.read().decode('utf8')
   
return res

def textwindow(url):
    title
= url
    h
= html2text.HTML2Text()
    h
.ignore_links = True
    h
.ignore_images = True
    s
= gethtml(url)
    s
= h.handle(s)
    s
= h.unescape(s)
    text
= convert65536(s)
    top
= Tkinter.Toplevel()
    top
.geometry("+200+100")
    top
.title(title)
    top
.bind("<Escape>", lambda _ : top.destroy())
    S
= Tkinter.Scrollbar(top)
    customFont
= tkFont.Font(family="Arial", size=16)
    T
= TextPlus(top,height=20,width=78,font=customFont,bg="lightgrey")
    S
.pack(side=Tkinter.RIGHT,fill=Tkinter.Y)
    T
.pack(side=Tkinter.LEFT,fill=Tkinter.Y)
    S
.config(command=T.yview)
    T
.config(yscrollcommand=S.set)
    T
.insert(Tkinter.END,text)

def main():
    root
= Tkinter.Tk()
    root
.geometry("950x32+200+32")
    root
.title('markdown')
    dnd
= TkDND(root)
    customFont
= tkFont.Font(family="Arial", size=14)
    entry
= EntryPlus(font=customFont,bg="lightgrey")
    entry
.pack(expand=1,fill='both')
    dnd
.bindtarget(entry,handle,'text/plain')
    entry
.bind("<Return>", lambda _ : handlereturn(entry))
    root
.mainloop()

if __name__=="__main__":
    main
()

Diff to Previous Revision

--- revision 3 2015-11-15 12:21:52
+++ revision 4 2015-11-18 14:02:19
@@ -82,9 +82,10 @@
 
     
def event_select_all(self, *args):
         
self.focus_force()
-        self.selection_range(0, tk.END)
+        self.selection_range(0, Tkinter.END)
 
     
def event_paste_and_go(self, *args):
+        self.delete(0,Tkinter.END)
         
self.focus_force()
         
self.event_generate("<<Paste>>")
         handlereturn
(self)

History