forked from kaylee/uvgotmail
		
	finished, but buggy
This commit is contained in:
		
							parent
							
								
									ad6b6281b3
								
							
						
					
					
						commit
						757eba1c6c
					
				
							
								
								
									
										132
									
								
								uvgotmail.py
									
									
									
									
									
								
							
							
						
						
									
										132
									
								
								uvgotmail.py
									
									
									
									
									
								
							@ -2,6 +2,7 @@
 | 
				
			|||||||
import argparse
 | 
					import argparse
 | 
				
			||||||
import sys
 | 
					import sys
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
 | 
					import atexit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def parseYN(s, default = False):
 | 
					def parseYN(s, default = False):
 | 
				
			||||||
    if default == False:
 | 
					    if default == False:
 | 
				
			||||||
@ -34,7 +35,7 @@ def parseConfig(args=None,config_path=None):
 | 
				
			|||||||
                    if type(config[kv[0]]) == type(True):
 | 
					                    if type(config[kv[0]]) == type(True):
 | 
				
			||||||
                        config[kv[0]] = (kv[1] == 'True') # cast to boolean
 | 
					                        config[kv[0]] = (kv[1] == 'True') # cast to boolean
 | 
				
			||||||
                    elif type(config[kv[0]]) == type(1):
 | 
					                    elif type(config[kv[0]]) == type(1):
 | 
				
			||||||
                        config[kv[0]] = parseInt(kv[1])
 | 
					                        config[kv[0]] = int(kv[1])
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        config[kv[0]] = kv[1]
 | 
					                        config[kv[0]] = kv[1]
 | 
				
			||||||
                except:
 | 
					                except:
 | 
				
			||||||
@ -88,7 +89,6 @@ def parseConfig(args=None,config_path=None):
 | 
				
			|||||||
    # make sure at least a server and a username are set
 | 
					    # make sure at least a server and a username are set
 | 
				
			||||||
    if config["server"] == "" or config["user"] == "":
 | 
					    if config["server"] == "" or config["user"] == "":
 | 
				
			||||||
        print("uvgotmail: failed to start. no imap server or username specified.")
 | 
					        print("uvgotmail: failed to start. no imap server or username specified.")
 | 
				
			||||||
    print(config)
 | 
					 | 
				
			||||||
    return config
 | 
					    return config
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def createConfig(config_path, config,args):
 | 
					def createConfig(config_path, config,args):
 | 
				
			||||||
@ -145,12 +145,16 @@ def main():
 | 
				
			|||||||
    parser.add_argument("--config", help="specify config file (default: ~/.uvgotmail/config)", default="~/.uvgotmail/config")
 | 
					    parser.add_argument("--config", help="specify config file (default: ~/.uvgotmail/config)", default="~/.uvgotmail/config")
 | 
				
			||||||
    parser.add_argument("--mutt", help="use existing mutt configuration (experimental)", action="store_true")
 | 
					    parser.add_argument("--mutt", help="use existing mutt configuration (experimental)", action="store_true")
 | 
				
			||||||
    parser.add_argument("--check", help="run in check mode (put this in PS1)", action="store_true")
 | 
					    parser.add_argument("--check", help="run in check mode (put this in PS1)", action="store_true")
 | 
				
			||||||
    parser.add_argument("--no-count", help="don't display how many unread messages there are", action="store_false")
 | 
					    parser.add_argument("--no-count", help="don't display how many unread messages there are", action="store_true")
 | 
				
			||||||
    parser.add_argument("--mailbox-symbol", help="specify a string instead of the mailbox emoji",default="")
 | 
					    parser.add_argument("--mailbox-symbol", help="specify a string instead of the mailbox emoji",default="")
 | 
				
			||||||
 | 
					    parser.add_argument("--debug", help="print errors",action="store_true")
 | 
				
			||||||
    args = parser.parse_args()
 | 
					    args = parser.parse_args()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    config_settings = parseConfig(args);
 | 
					    global config
 | 
				
			||||||
 | 
					    config = parseConfig(args);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    config["debug"] = args.debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if(args.daemon == args.check):
 | 
					    if(args.daemon == args.check):
 | 
				
			||||||
        parser.print_help()
 | 
					        parser.print_help()
 | 
				
			||||||
@ -164,17 +168,126 @@ def check():
 | 
				
			|||||||
    filename = os.path.expanduser('~/.uvgotmail/unread')
 | 
					    filename = os.path.expanduser('~/.uvgotmail/unread')
 | 
				
			||||||
    if os.path.exists(filename):
 | 
					    if os.path.exists(filename):
 | 
				
			||||||
        with open(filename) as f:
 | 
					        with open(filename) as f:
 | 
				
			||||||
            unread = int(f.read());
 | 
					            unread = f.read();
 | 
				
			||||||
 | 
					            if unread != '':
 | 
				
			||||||
 | 
					                unread = int(unread)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                unread = 0
 | 
				
			||||||
        if unread == 0:
 | 
					        if unread == 0:
 | 
				
			||||||
            sys.exit(0)
 | 
					            sys.exit(0)
 | 
				
			||||||
        pre = ""
 | 
					        pre = ""
 | 
				
			||||||
        if(unread > 1 and countmail == True):
 | 
					        if(unread > 1 and config["no_count"] == False):
 | 
				
			||||||
            pre = "("+str(unread)+") "
 | 
					            pre = "("+str(unread)+") "
 | 
				
			||||||
        print(pre+mailchar,end=' ')
 | 
					        print(pre+config["mailbox_symbol"],end=' ')
 | 
				
			||||||
    # if there's no unread count file, just exit quietly
 | 
					    # if there's no unread count file, just exit quietly
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def writeUnreadFile(unseen):
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        with open(os.path.expanduser('~/.uvgotmail/unread'),'w') as f:
 | 
				
			||||||
 | 
					            f.write(str(len(unseen)))
 | 
				
			||||||
 | 
					    except Exception as e:
 | 
				
			||||||
 | 
					        if config["debug"]: print(e)
 | 
				
			||||||
 | 
					        print("uvgotmail: could not write to unread file")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# we're implementing this in a disgusting way. i'm sorry.
 | 
				
			||||||
 | 
					import time
 | 
				
			||||||
 | 
					import socket
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def idleFunction(s,unseen):
 | 
				
			||||||
 | 
					    s._startIdle = time.time()
 | 
				
			||||||
 | 
					    if 'IDLE' not in s.capabilities:
 | 
				
			||||||
 | 
					        raise s.error('Server does not support IDLE')
 | 
				
			||||||
 | 
					    idle_tag = s._command('IDLE')  # start idling
 | 
				
			||||||
 | 
					    s._get_response()
 | 
				
			||||||
 | 
					    while line := s._get_line():
 | 
				
			||||||
 | 
					        if b'FETCH' in line:
 | 
				
			||||||
 | 
					            l = str(line)
 | 
				
			||||||
 | 
					            msg = re.findall(r'\d+',l)[0]
 | 
				
			||||||
 | 
					            if config["debug"]: print(msg, unseen)
 | 
				
			||||||
 | 
					            if "seen" in l.lower():
 | 
				
			||||||
 | 
					                unseen.remove(msg)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                unseen.append(msg)
 | 
				
			||||||
 | 
					            print(unseen)
 | 
				
			||||||
 | 
					            writeUnreadFile(unseen)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            # we only want to idle for ten minutes maximum. we will use the keep-alive messages to keep track in a single thread.
 | 
				
			||||||
 | 
					            if(time.time() - s.start > 600):
 | 
				
			||||||
 | 
					                s.send(b'DONE' + imaplib.CRLF)
 | 
				
			||||||
 | 
					                return s._command_complete('IDLE', idle_tag)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# thanks to trentbuck on github for this awful idea
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def daemon():
 | 
					def daemon():
 | 
				
			||||||
    import imaplib
 | 
					    import imaplib
 | 
				
			||||||
 | 
					    imaplib.Commands['IDLE'] = ('AUTH', 'SELECTED')
 | 
				
			||||||
 | 
					    class IMAP4_SSL_plus_IDLE(imaplib.IMAP4_SSL):
 | 
				
			||||||
 | 
					        def idle(self, unseen):
 | 
				
			||||||
 | 
					            idleFunction(self,unseen)
 | 
				
			||||||
 | 
					    class IMAP4_plus_IDLE(imaplib.IMAP4):
 | 
				
			||||||
 | 
					        def idle(self, unseen):
 | 
				
			||||||
 | 
					            idleFunction(self,unseen)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    IMAP4_SSL = IMAP4_SSL_plus_IDLE
 | 
				
			||||||
 | 
					    IMAP4 = IMAP4_plus_IDLE
 | 
				
			||||||
 | 
					    socket.setdefaulttimeout(120)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # first check if daemon is already running
 | 
				
			||||||
 | 
					    pidfile = os.path.expanduser('~/.uvgotmail/.run.pid')
 | 
				
			||||||
 | 
					    if os.path.exists(pidfile):
 | 
				
			||||||
 | 
					        with open(pidfile) as f:
 | 
				
			||||||
 | 
					            pid = f.read()
 | 
				
			||||||
 | 
					            if pid != '':
 | 
				
			||||||
 | 
					                pid = int(pid)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                pid = 0
 | 
				
			||||||
 | 
					            running_cmd = os.popen("ps -p" + str(pid) +" -o command").read()
 | 
				
			||||||
 | 
					            current_cmd = os.popen("ps -p" + str(os.getpid()) +" -o command").read()
 | 
				
			||||||
 | 
					            if running_cmd == current_cmd or os.path.basename(sys.argv[0]) in running_cmd:
 | 
				
			||||||
 | 
					                # the process is running; we don't need to start up at all
 | 
				
			||||||
 | 
					                exit(0)
 | 
				
			||||||
 | 
					    try:
 | 
				
			||||||
 | 
					        with open(pidfile,'w') as f:
 | 
				
			||||||
 | 
					            f.write(str(os.getpid()))
 | 
				
			||||||
 | 
					        def delPid(pidfile):
 | 
				
			||||||
 | 
					            os.remove(pidfile)
 | 
				
			||||||
 | 
					        atexit.register(delPid,pidfile)
 | 
				
			||||||
 | 
					    except:
 | 
				
			||||||
 | 
					        print("uvgotmail: failed to write to PID file")
 | 
				
			||||||
 | 
					        exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # main loop
 | 
				
			||||||
 | 
					    import time
 | 
				
			||||||
 | 
					    start_time = time.time();
 | 
				
			||||||
 | 
					    IMAP4_func = IMAP4_SSL if config["ssl"] else IMAP4
 | 
				
			||||||
 | 
					    while True:
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            with IMAP4_func(config["server"],config["port"]) as conn:
 | 
				
			||||||
 | 
					                conn.login(user=config["user"],password=config["password"])
 | 
				
			||||||
 | 
					                conn.select(mailbox='INBOX',readonly=True)
 | 
				
			||||||
 | 
					                typ,msgnums = conn.search(None, "UNSEEN");
 | 
				
			||||||
 | 
					                unseen = [n.decode() for n in msgnums if n != b''][0].split(' ')
 | 
				
			||||||
 | 
					                if config["debug"]: print(unseen)
 | 
				
			||||||
 | 
					                writeUnreadFile(unseen)
 | 
				
			||||||
 | 
					                #try:
 | 
				
			||||||
 | 
					                resp = conn.idle(unseen)
 | 
				
			||||||
 | 
					                #except Exception as e:
 | 
				
			||||||
 | 
					                if config["debug"]: print(e)
 | 
				
			||||||
 | 
					                if time.time() - start_time <= 10:
 | 
				
			||||||
 | 
					                    print("uvgotmail: too many imap errors. exiting.")
 | 
				
			||||||
 | 
					                    sys.exit(1)
 | 
				
			||||||
 | 
					                start_time = time.time();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        except Exception as e:
 | 
				
			||||||
 | 
					            if config["debug"]:
 | 
				
			||||||
 | 
					                print(e)
 | 
				
			||||||
 | 
					            print("uvgotmail: failed to log in to server. dumping config.")
 | 
				
			||||||
 | 
					            print(config);
 | 
				
			||||||
 | 
					            exit(1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# handle ctrl+c gracefully
 | 
					# handle ctrl+c gracefully
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
@ -182,8 +295,5 @@ if __name__ == '__main__':
 | 
				
			|||||||
        main()
 | 
					        main()
 | 
				
			||||||
    except KeyboardInterrupt:
 | 
					    except KeyboardInterrupt:
 | 
				
			||||||
        print('Interrupted')
 | 
					        print('Interrupted')
 | 
				
			||||||
        try:
 | 
					        exit(130)
 | 
				
			||||||
            sys.exit(130)
 | 
					 | 
				
			||||||
        except SystemExit:
 | 
					 | 
				
			||||||
            os._exit(130)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user