import  poplib
from email import parser
from email import utils
import Tkinter
import threading
import time

class msg_transfer(object):
    def __init__(self):
        self.lock=threading.Lock()
        self._msg=[]
        pass
    def g_msg(self):
        self.lock.acquire()
        if len(self._msg)>0:
            res=self._msg.pop(0)
        else:
            res=""
        self.lock.release()
        return res
    def s_msg(self,value):
        self.lock.acquire()
        self._msg.append(value)
        self.lock.release()
    msg=property(g_msg,s_msg)
class mail_checker(threading.Thread):
    def get_mail_client(self):
##        M = poplib.POP3_SSL('pop.mail.yahoo.com',995)
##        M.user("")
##        M.pass_("")
        M = poplib.POP3_SSL(self.p_server[0],self.p_server[1])
        M.user(self.p_user)
        M.pass_(self.p_password)
        return M
    def __init__(self,pop_server_address,username,password,request,eve_list,eve_header,eve_mail,eve_error):
        threading.Thread.__init__(self)
        self.p_server=pop_server_address
        self.p_user=username
        self.p_password=password

        
        self.request=request
        self.eve_list=eve_list
        self.eve_header=eve_header
        self.eve_mail=eve_mail
        self.eve_error=eve_error


        
        self.parser=parser.Parser()
        self.mails=[]
        self.headers=[]
        self.m1=None

        
    def for_ever(self):
        self.start()
    def run(self):
        self.m1=self.get_mail_client()
        while True:
##            print self.request.msg
##            time.sleep(1)
            req=self.request.msg
            if req=="list":
                self.get_list()
                self.eve_list(self._list)
            elif req=="header":
                self.get_header(5)
                self.eve_header(self._header)
            elif req=="mail":
                self.get_mail(5)
                self.eve_mail(self._mail)
            elif req=="exit":
                break
            else:
                try:
                    self.m1.noop();
                except Exception as e:
                    self.eve_error(str(e))
                    self.m1=self.get_mail_client()
            time.sleep(0.5)
    def get_list(self):
        try:
            self._list=self.m1.list()[1]
        except Exception as e:
            self.eve_error(str(e))
            self._list=[]
            self.m1=self.get_mail_client()
    def parse(self,msg_str):
        return  self.parser.parsestr(msg_str)
    def get_header(self,number):
        try:
            mssg=self.m1.top(number,0)
        except Exception as e:
            self.eve_error(str(e))
            mssg=[""]
            self.m1=self.get_mail_client()
        mssg="\n".join(mssg[1])
        self._header=self.parse(mssg)
    def get_mail(self,number):
        try:
            mssg=self.m1.retr(number,0)
        except Exception as e:
            self.eve_error(str(e))
            mssg=[""]
            self.m1=self.get_mail_client()
        mssg="\n".join(mssg[1])
        self._mail=pself.parse(mssg)
class App:
    def __init__(self):
        self.root=Tkinter.Tk()
        self.txt_error  = Tkinter.Text(self.root, width=50, height=10, highlightthickness=2)
        self.txt_error.pack(expand=1, fill="both")
        self.txt_no  = Tkinter.Text(self.root, width=50, height=1, highlightthickness=2)
        self.txt_no.pack(expand=1, fill="both")
        button = Tkinter.Button(self.root, text="check mail")
        button.bind("<ButtonPress>",self.keypress)
        button.pack()
        self.txt_list  = Tkinter.Text(self.root, width=50, height=30, highlightthickness=2)
        self.txt_list.pack(expand=1, fill="both")
        self.request=msg_transfer()
        self.pop_check=mail_checker(('pop.mail.yahoo.com',995),
                                    "",
                                    "",
                                    self.request,
                                    self.eve_list,
                                    self.eve_header,
                                    self.eve_mail,
                                    self.eve_error)
        self.lock=threading.Lock()
        self.pop_check.for_ever()
        self.period=5000
        self.root.after(1,self.seconds_check)
        self.sate=True
    def eve_error(self,_message):
##        self.txt_error.delete(1.0,Tkinter.END)
        self.lock.acquire()
        if(self.sate):
            self.txt_error.insert(Tkinter.END,str(_message))
            self.txt_error.insert(Tkinter.END,"\n")
        self.lock.release()
    def eve_list(self,_list):
        
        self.lock.acquire()
        if(self.sate):
            self.txt_no.delete(1.0,Tkinter.END)
            self.txt_no.insert(Tkinter.END,str(len(_list)))
        self.lock.release()
    def eve_header(self,_header):
        self.lock.acquire()
        if(self.sate):
            self.txt_list.delete(1.0,Tkinter.END)
            self.txt_list.insert(Tkinter.END,str(_header))
            self.txt_list.insert(Tkinter.END,"\n")
##        for msg in msg_list:
##            self.txt_list.insert(Tkinter.END,msg["FROM"])
        self.lock.release()
    def eve_mail(self,_mail):
        self.lock.acquire()
        if(self.sate):
            self.txt_list.delete(1.0,Tkinter.END)
            self.txt_list.insert(Tkinter.END,str(_mail))
            self.txt_list.insert(Tkinter.END,"\n")
        self.lock.release()
        
    def seconds_check(self):
        self.request.msg="list"
        self.root.after(self.period,self.seconds_check)
        
        
        
    def keypress(self,event):
        self.request.msg="mail"
    def mainloop(self):
        res=self.root.mainloop()
        self.sate=False
        self.request.msg="exit"
        print "exit"
        self.pop_check.join()
        return res
if __name__ == '__main__':
    app = App()
    app.mainloop()