def unread(self): conn = imaplib2.IMAP4_SSL('imap.gmail.com', 993) conn.login(self.username, self.password) conn.list() conn.select('inbox') statuscode, uids = conn.search(None, '(UNSEEN)') emails = [] unread = False for uid in sorted(uids[0].split()): unread = True if int(uid) <= self.last_uid: continue statuscode, data = conn.fetch(uid, '(BODY[HEADER.FIELDS (SUBJECT FROM)])') conn.store(uid, '-FLAGS','\\Seen') header = data[0][1] msg = email.message_from_string(header) msg_from = msg.get("From") msg_subject = msg.get("Subject") data, encoding = email.header.decode_header(msg_subject)[0] if encoding != None: msg_subject = data.decode(encoding) data, encoding = email.header.decode_header(msg_from)[0] if encoding != None: msg_from = data.decode(encoding) emails.append((msg_from, msg_subject)) self.last_uid = max(int(uid), self.last_uid) conn.close() conn.logout() return unread, emails
def __init__(self): threading.Thread.__init__(self) # setup logger self.logger = logging.getLogger('mailFVAT') self.logger.setLevel(logging.DEBUG) handler = logging.handlers.RotatingFileHandler('/tmp/mailfv.log', maxBytes=1048576, backupCount=10) handler.setLevel(logging.DEBUG) formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s') handler.setFormatter(formatter) self.logger.addHandler(handler) # create logger for errors errLogger = logging.getLogger('stdErr') errLogger.setLevel(logging.ERROR) errHandler = logging.handlers.RotatingFileHandler( '/tmp/mailfv_error.log', maxBytes=1048576, backupCount=10) errHandler.setLevel(logging.ERROR) errFormatter = logging.Formatter('%(asctime)s - %(message)s') errHandler.setFormatter(errFormatter) errLogger.addHandler(errHandler) # redirect stderr sys.stderr = stdErrWriter(errLogger, logging.ERROR) self.M = imaplib2.IMAP4_SSL('imap.gmail.com')
def startListening(username, password, newMailCallback, retry=False): logger.info("IMAP listening") # Had to do this stuff in a try-finally, since some testing # went a little wrong..... try: # Set the following two lines to your creds and server M = imaplib2.IMAP4_SSL("imap.gmail.com") M.login(username, password) # We need to get out of the AUTH state, so we just select # the INBOX. M.select("INBOX") # Start the Idler thread idler = Idler(M, newMailCallback) idler.start() # Because this is just an example, exit after 1 minute. while True: # Let this sit in an infinite loop time.sleep(0.1) finally: # Clean up. idler.stop() idler.join() M.close() # This is important! M.logout() if retry: logger.info("connection closed, retrying...") startListening(username, password, newMailCallback, True)
def open_connections(verbose=False): # Read from config file config = ConfigParser.ConfigParser() #config.read('config.ini') config.read([os.path.expanduser('~/.chumbpush')]) # Connect to IMAP server imap_server = config.get('imap', 'server') if verbose: print 'Connecting to', imap_server imap_connection = imaplib2.IMAP4_SSL(imap_server) # Login to our account imap_username = config.get('imap', 'username') imap_password = config.get('imap', 'password') if verbose: print 'Logging in as', imap_username imap_connection.login(imap_username, imap_password) # Set up Twitter API twitter_consumer_key = config.get('twitter', 'consumer_key') twitter_consumer_secret = config.get('twitter', 'consumer_secret') twitter_access_token_key = config.get('twitter', 'access_token_key') twitter_access_token_secret = config.get('twitter', 'access_token_secret') twitter_api = twitter.Api(consumer_key=twitter_consumer_key, consumer_secret=twitter_consumer_secret, access_token_key=twitter_access_token_key, access_token_secret=twitter_access_token_secret) # Set up Bitify API bitly_login = config.get('bitly', 'login') bitly_apikey = config.get('bitly', 'apikey') bitify = bitly.Api(login=bitly_login, apikey=bitly_apikey) return imap_connection, twitter_api, bitify
def parseraw(id): # Connect to the IMAP serverimap imap = imaplib2.IMAP4_SSL(server) imap.LOGIN(username, password) imap.SELECT(mailbox) typ, data = imap.fetch(id, '(RFC822)' ) body = data[0][1] splitmsg = body.split('\n') command = splitmsg[len(splitmsg)-2] module = command[0:command.find(' ')].lower() parameters = command[command.find(' '):-1] path = os.path.dirname(sys.executable) fromline = splitmsg[len(splitmsg)-6] splitfrom = fromline.split('\"') numbers = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] fromphonel = [] for i in splitfrom[1]: if i in numbers: fromphonel.append(i) fromphone = '' fromphone = fromphone.join(fromphonel) finalcmd = '%s/python2 modules/%s/__main__.py %s' % (path, module, parameters) os.system(finalcmd) returnmessage(fromphone) imap.CLOSE() imap.LOGOUT()
def imap_connection(self): if not self._imap_conn: if self._options.get('use_ssl', True): self._imap_conn = imaplib2.IMAP4_SSL(self._options['hostname']) else: self._imap_conn = imaplib2.IMAP4(self._options['hostname']) return self._imap_conn
def ensure_connection_open(m): if m and m.state != 'LOGOUT': return m, False logging.info('Opening connection') m = imaplib2.IMAP4_SSL('imap.gmail.com', timeout=timeout) if m: return m, True else: raise AttributeError('IMAP4_SSL() returned %s' % (m, ))
def _login(self): """(Re-)Initialize `self._m`. `self._m` is set to a logged in instance of `imaplib2.IMAP4_SSL` corresponding to this mailbox. """ self._m = imaplib2.IMAP4_SSL(self._host) self._m.login(self._username, os.environ[self._pass_var]) self._m.select()
def _login(self): try: self.imapSession = imaplib.IMAP4_SSL('imap.gmail.com') typ, accountDetails = self.imapSession.login( self.credential.username, self.credential.password) if typ != 'OK': raise imaplib.IMAP4.error( "Could not login to the email account.") self.imapSession.select('[Gmail]/All Mail') except: raise imaplib.IMAP4.error("Could not login to the email account.")
def connect(): global last_connect # Don't connect twice in 5 minutes, since the server probably overloaded, wait half hour before trying again if last_connect is not None and ( datetime.datetime.now() - datetime.timedelta(0, 60 * 5)) < last_connect: print "Tried to connect twice in 5 minutes, going to sleep..." time.sleep(60 * 30) last_connect = datetime.datetime.now() M = imaplib2.IMAP4_SSL(config.HOST, config.PORT) M.login(config.USER, config.PASS) M.select("INBOX") return M
def TestImapAuthentication(user, auth_string): """Authenticates to IMAP with the given auth_string. Prints a debug trace of the attempted IMAP connection. Args: user: The Gmail username (full email address) auth_string: A valid OAuth2 string, as returned by GenerateOAuth2String. Must not be base64-encoded, since imaplib does its own base64-encoding. """ print imap_conn = imaplib.IMAP4_SSL('imap.gmail.com') imap_conn.debug = 4 imap_conn.authenticate('XOAUTH2', lambda x: auth_string) imap_conn.select('INBOX')
def _login(self): if self.imap_SSLEnable and self._imap_ssl_port > 0: self._imap = imaplib2.IMAP4_SSL(self._imap_server, port=self._imap_ssl_port) else: self._imap = imaplib2.IMAP4(self._imap_server, port=self._imap_port) try: t, d = self._imap.login(self._imap_user, self._imap_pass) if t == 'OK': return True else: return False except Exception, e: print e return False
def connect_and_wait(): server = config_get("imap_server") logging.info("Connecting to %s" % server) mail = imaplib.IMAP4_SSL(server) mail.login(config_get("imap_user"), config_get("imap_password")) mail.select(config_get("imap_folder", "INBOX")) # Maybe there's something already. search_messages(mail) if config_get("imap_debug_message"): mail.logout() exit(0) while HAVE_IDLE: mail.idle() search_messages(mail)
class Idler(threading.Thread): imap = imaplib2.IMAP4_SSL( "imap.gmail.com") # can be changed to another server if needed stopWaitingEvent = threading.Event() #Now, this stopWaitingEvent thing -- it really does make the whole thing work. Basically, #it holds a boolean value which is set and cleared using, oddly enough, the methods set() and #clear(). But, the good thing about it is that it has another method, wait(), which holds #execution until it has been set(). I cannot thank threading.Event() enough, I really couldn't #have done it without you! knownAboutMail = [] # will be a list of IDs of messages in the inbox killNow = False # stops execution of thread to allow propper closing of conns. """ Initialise (sorry, I'm from the UK) everything to get ready for PUSHed mail. """ def __init__(self, GMailUsername, GMailPassword): # os.system('clear') debugMsg('DEBUG is ENABLED') debugMsg('__init__() entered') try: #establish connection to IMAP Server self.imap.LOGIN(GMailUsername, GMailPassword) self.imap.SELECT("INBOX") #get the IDs of all messages in the inbox and put in knowAboutMail typ, data = self.imap.SEARCH(None, 'ALL') self.knownAboutMail = data[0].split() #now run the inherited __init__ method to create thread threading.Thread.__init__(self) except Exception, e: #Uh Oh, something went wrong print 'ERROR: IMAP Issue. It could be one (or more) of the following:' print '- The impalib2.py file needs to be in the same directory as this file' print '- You\'re not connected to the internet' print '- Google\'s mail server(s) is/are down' print '- Your username and/or password is incorrect' print e.message sys.exit(1) debugMsg('__init__() exited')
def start_mail_thread(): print "Starting mail thread!" # Set the following two lines to your creds and server mail = imaplib2.IMAP4_SSL(IMAP_SERVER) mail.login(MAIL_USER, MAIL_PASSWORD) mail.select("[Gmail]/All Mail", readonly=True) result, data = mail.search(None, "ALL") ids = data[0] id_list = ids.split() latest_email_id = id_list[-1] idler = Idler(mail, latest_email_id) idler.start() print "Client started on {}, waiting for emails.".format(MAIL_USER)
def __init__(self, server, username, password, mailbox): self.imap = imaplib2.IMAP4_SSL(server) # Log into the IMAP server try: self.imap.LOGIN(username, password) except: print 'There was an error logging into the IMAP server' sys.exit() # Select the appropriate mailbox and disregard messages already there currentmail = [] self.imap.SELECT(mailbox) typ, data = self.imap.SEARCH(None, 'ALL') self.currentmail = data[0].split() # Start the threading event threading.Thread.__init__(self)
def run(self): self.connection = imaplib2.IMAP4_SSL(self.host) if self.config.get('credential'): password = get_credential(self.config['credential']) else: password = subprocess.check_output(self.config['passcmd'], shell=True, encoding='utf-8').strip() self.connection.login(self.login, password) # TODO handle login failure while not self.to_stop: self.connection.select(self.folder) LOGGER.info('watching server %r user %r folder %r', self.host, self.login, self.folder) self.connection.idle() self.activity.emit()
def doCheckNewEmail(self): timegap = 0 t1 = datetime.now() print "T1: ", t1 while True: logDtm = (datetime.now() + timedelta(hours=7)).strftime('%Y-%m-%d %H:%M:%S') if timegap == 0 or timegap > 14400 or self.idleStatus == "idle_error": self.response = self.RefreshToken(self.client_id, self.client_secret, self.refresh_token) self.auth_string = 'user=%s\1auth=Bearer %s\1\1' % ( '*****@*****.**', self.response['access_token']) self.imap = imaplib2.IMAP4_SSL("imap.gmail.com") try: self.imap.authenticate('XOAUTH2', lambda x: self.auth_string) self.imap.SELECT("INBOX") except: print 'ERROR: IMAP Issue. Exit...' sys.exit(1) print "New Token: ", self.response[ 'access_token'], logDtm, timegap, self.idleStatus self.initCheck() self.waitForServer() t2 = datetime.now() delta = t2 - t1 timegap = delta.total_seconds() print "T2: ", t2, timegap logDtm = (datetime.now() + timedelta(hours=7)).strftime('%Y-%m-%d %H:%M:%S') if timegap > 14400 or self.idleStatus == "idle_error": t1 = t2 try: self.imap.CLOSE() self.imap.LOGOUT() except: print "CLOSE IMAP ERROR", logDtm, timegap, self.idleStatus time.sleep(2) print "imap logout", logDtm, timegap, self.idleStatus
def main(): global M thread = Thread(target=queuing) thread.start() email = "*****@*****.**" password = "******" print "connecting to server" # Make a SSL connection to gmail M = imaplib2.IMAP4_SSL("imap.gmail.com") # Login to gmail ("email","password") M.login(email, password) # Select the folder you want to check M.select("Inbox") # Start a thread with the idler running print "connected" idler = Idler(M) idler.start()
def authenticate_connect_imap(): refresh_token = keyring.get_password('moneyplot', 'refresh_token') access_token = None if refresh_token is None: response = request_access() print response refresh_token = response[u'refresh_token'] access_token = response[u'access_token'] keyring.set_password('moneyplot', 'refresh_token', refresh_token) if access_token is None: response = oauth2.RefreshToken(CLIENT_ID, CLIENT_SECRET, refresh_token) access_token = response[u'access_token'] auth_string = oauth2.GenerateOAuth2String('*****@*****.**', access_token, False) imap_conn = imaplib.IMAP4_SSL('imap.gmail.com') imap_conn.authenticate('XOAUTH2', lambda x: auth_string) return imap_conn
def get_password(account, is_account_to=False): """Store the validated password for the given account in `passwords[account['pass_var']]`.""" m = imaplib2.IMAP4_SSL(account['host']) while True: password = getpass.getpass( 'Please enter the password for host %s and username %s: ' % (account['host'], account['username'])) try: m.login(account['username'], password) except imaplib2.IMAP4.error: print 'Incorrect username/password. To change your username or host, you can run setup_accounts.py again or change the accounts.json file directly and then rerun this. Try again.' continue if not is_account_to: m.select() if m.search(None, 'ALL')[1][0] != '': print 'Warning: the inbox for this account is not empty. When setup is complete, all messages in the inbox will be imported and will then be deleted.' if not ask_continue(): sys.exit(0) passwords[account['pass_var']] = password return
def open_connection(config): #Connect to server hostname = config['server']['hostname'] port = config['server']['port'] print ("Connecting to " + hostname) try: connection = imaplib.IMAP4_SSL(host=hostname) except: raise SystemExit("Couldn't connect to server.") print("Succesfully connected.") #Login to account username = config['account']['username'] password = config['account']['password'] if username is None or password is None: raise SystemExit("Please set account details in config.txt") print("Logging in as " + username) try: connection.login(username, password) except: raise SystemExit("Couldn't log in.") print("Logged in succesfully.") return connection
def login(self): M = imaplib2.IMAP4_SSL(host=self.host, port=993) try: logging.info("Logging in as %s " % {self.userName}) M.login(self.userName, self.password) logging.info("Login successful") except: logging.error("Could not log in", exc_info=True) raise M.select("INBOX") idler = self.Idler(M, self.getIdsBySubject, self.markAsRead, self.pushTodB, self.parseEmails) try: idler.start() logging.debug("Idler activated.") except Exception as e: logging.exception("Could not start idler. Exception occured") raise time.sleep(60 * 60) idler.stop() idler.join() M.close() M.logout()
def connectAndIdle(monitoredFolder, highestUid): idler = None M = None #logInfo( monitoredFolder, 'Connecting' ) imaplib2DebugLevel = max(Verbosity - 2, 0) try: M = imaplib2.IMAP4_SSL(host=monitoredFolder['server'], debug=imaplib2DebugLevel) except Exception as e: logInfo(monitoredFolder, "ERROR connecting") logException(e) return highestUid try: M.login(monitoredFolder['user'], monitoredFolder['password']) except Exception as e: logInfo(monitoredFolder, "ERROR logging in") logException(e) try: M.close() except: pass return highestUid try: logImap(monitoredFolder, 'Sending -- SELECT ' + monitoredFolder['folder']) selectResponse = M.select(monitoredFolder['folder']) logImap(monitoredFolder, 'Received -- ' + str(selectResponse)) (typ, resp) = selectResponse if typ != "OK": logInfo(monitoredFolder, "Bad select") return highestUid if highestUid == 0: highestSeq = resp[0] if highestSeq != b'0': uidResponse = M.fetch(highestSeq, "UID") highestUid = int( uidResponse[1][0].split()[-1][:-1].decode('utf-8')) with ThreadPoolExecutor(max_workers=1) as executor: highestUid = syncMonitoredFolder(monitoredFolder, M, highestUid) idler = Idler(M, monitoredFolder, highestUid) executor.submit(idler.idle()) highestUid = idler.highestUid logInfo(monitoredFolder, "IDLE Done") return highestUid except Exception as e: logInfo(monitoredFolder, 'ERROR setting up IDLE') logException(e) return highestUid finally: try: if idler != None: idler.stop() idler.join() if M != None: M.close() M.logout() logInfo(monitoredFolder, 'Logged out') except: pass
def dosync(self): print "You\'ve Got Mail." did_except = True while did_except: try: _, data = self.mail.search(None, "ALL") did_except = False except: # Attempt reconnect did_except = True print "Disconnected, attempting reconnect." self.mail = imaplib2.IMAP4_SSL(IMAP_SERVER) self.mail.login(MAIL_USER, MAIL_PASSWORD) self.mail.select("inbox", readonly=True) ids = data[0] id_list = ids.split() new_mail_ids = [] if id_list[-1] < self.last_id: new_mail_ids = [] else: for i in xrange(len(id_list) - 1, 0, -1): if id_list[i] == self.last_id: break else: new_mail_ids.append(id_list[i]) self.last_id = id_list[-1] for mail_id in new_mail_ids: _, data = self.mail.fetch(mail_id, "(RFC822)") raw_email = "null" for d in data: if type(d) is tuple: if "RFC822" in d[0]: raw_email = d[1] if raw_email == "null": continue email_message = email.message_from_string(raw_email) flanker_msg = mime.from_string(raw_email) body = "null" try: for part in flanker_msg.parts: pp = part.body.encode('ascii', 'ignore') if start_trigger(pp, TRIGGERS): body = pp break except Exception as _: pass # If body is still null, just look for this stuff if body == "null": for l in raw_email.split('\n'): if start_trigger(l, TRIGGERS): body = l # CR-LF ugh body = body.replace('\r', '') tos = email_message.get_all('to', []) ccs = email_message.get_all('cc', []) all_recipients = getaddresses(tos + ccs) + [ parseaddr(email_message["Reply-To"] or email_message["From"]) ] reply_object = { 'subject': email_message["Subject"], 'all_recipients': all_recipients, 'raw_email': raw_email, 'msg_id': email_message["Message-ID"] } if "In-Reply-To" in email_message: reply_object["reply_to"] = email_message["In-Reply-To"] trigger = start_trigger(body, TRIGGERS) if trigger and "From" in email_message and is_whitelisted( raw_email): print "Request from {} for subject {}.".format( email_message["From"], email_message["Subject"]) # Extra parsing since our trigger word can include spaces due to gmail autocomplete body = body.replace(trigger, '') argv = [x.strip() for x in body.split()] argv = [trigger] + argv callbacks.triggered_email(body, argv, reply_object) else: callbacks.raw_email(flanker_msg, raw_email, reply_object)
def main(self): self.log.debug("Mail: Running!") waited = False while True: try: self.log.debug("Mail: Connecting to IMAP server...") self.imap = imaplib2.IMAP4_SSL(self.config.imap_server) self.log.debug("Mail: Logging in...") self.imap.login(self.config.username, self.config.password) self.log.debug("Mail: Success") self.reconnects = 0 self.log.debug("Mail: Selecting INBOX") self.imap.select("INBOX") self.reconnects = 0 while True: self.log.debug("Mail: Fetching emails...") type, emails = self.imap.search(None, "ALL") for num in emails[0].split(" "): if num: self.log.debug("Mail: Retrieving message %s..." % num) response = self.imap.fetch(num, "(RFC822)") if waited: # Don't dump our entire INBOX into callback(). # We only post messages after having imap.idle()d once self.process_mail(response) self.log.debug( "Mail: Flagging %s for deletion..." % num) self.imap.store(num, '+FLAGS', '\\Deleted') self.log.debug("Mail: Now calling imap.expunge()...") self.imap.expunge() self.log.debug("Mail: Now calling imap.idle() ... ") self.imap.sock.settimeout(600) self.imap.idle() self.imap.sock.settimeout(60) self.log.debug("Mail: Wait finished; now looping - " \ "searching for msgs...") waited = True except (imaplib2.IMAP4.abort, socket.error): self.log.notice("Mail: Error caught:") self.log.info("".join(traceback.format_exc())) self.reconnects += 1 self.log.info("Mail: Reconnects is %i" % self.reconnects) proposed_wait = 2**self.reconnects if proposed_wait < self.config.max_reconnect_wait: self.log.info("Mail: Sleeping for %i seconds" % proposed_wait) time.sleep(proposed_wait) else: self.log.info("Mail: Sleeping for %i seconds (max)" \ % self.config.max_reconnect_wait) time.sleep(self.config.max_reconnect_wait)
def collect_data(): """Messy code to download training data. """ c = load_config('templates') templates = c['templates'] training_data = [] mail = imaplib2.IMAP4_SSL(IMAP_SERVER) mail.login(MAIL_USER, MAIL_PASSWORD) mail.select("[Gmail]/All Mail", readonly=True) result, data = mail.search(None, '(BODY "%s")' % ("@faqbot")) ids = data[0] id_list = ids.split() for idx, r_id in enumerate(id_list): _, data = mail.fetch(r_id, "(RFC822)") print "%i / %i (%i%%)" % (idx, len(id_list), int(float(idx) / len(id_list) * 100)) raw_email = "null" for d in data: if type(d) is tuple: if "RFC822" in d[0]: raw_email = d[1] flanker_msg = mime.from_string(raw_email) body = "null" try: for part in flanker_msg.parts: if str(part) == "(text/plain)": pp = part.body.encode('ascii', 'ignore') body = pp except Exception as _: pass if body == "null": continue parsed_body = EmailReplyParser.read(body) if len(parsed_body.fragments) >= 2: if parsed_body.fragments[0].content.split()[0] == "@faqbot": fb = parsed_body.fragments[0].content.split()[1] original = parsed_body.fragments[1].content lines = [] for l in original.split('\n'): if l.startswith('> '): tl = l.replace('>', '').strip() if tl != '' and not (tl.startswith('On')): lines.append(l.replace('>', '')) key = fb original = '\n'.join(lines) # Now that we have this, let's make sure it's # valid and stuff and then save it. if key in templates: training_data.append((key, original)) save_config(training_data, 'smartreply_data')
self.M.idle(callback=callback) self.event.wait() if self.needsync: self.event.clear() self.dosync() def dosync(self): #Call a event from here print("Got an event!") try: #Authentication for Mail M = imaplib2.IMAP4_SSL("imap.gmail.com") M.login("UserName", "Password") # Select Mail folder from where event should manage i.e inbox,sent M.select("INBOX") emailChecker = EmailChecker(M) emailChecker.start() # Stop checking Mail after sometime time.sleep(120 * 60) finally: emailChecker.stop() emailChecker.join() M.close() M.logout()
class Idler(threading.Thread): imap = imaplib2.IMAP4_SSL( "imap.gmail.com") # can be changed to another server if needed stopWaitingEvent = threading.Event() #Now, this stopWaitingEvent thing -- it really does make the whole thing work. Basically, #it holds a boolean value which is set and cleared using, oddly enough, the methods set() and #clear(). But, the good thing about it is that it has another method, wait(), which holds #execution until it has been set(). I cannot thank threading.Event() enough, I really couldn't #have done it without you! knownAboutMail = [] # will be a list of IDs of messages in the inbox killNow = False # stops execution of thread to allow propper closing of conns. """ Initialise (sorry, I'm from the UK) everything to get ready for PUSHed mail. """ def __init__(self, GMailUsername, GMailPassword): os.system('clear') debugMsg('DEBUG is ENABLED') debugMsg('__init__() entered') try: #establish connection to IMAP Server self.imap.LOGIN(GMailUsername, GMailPassword) self.imap.SELECT( "Voice" ) # I have set a gmail filter to put messages from myself to myself into a folder named "Voice" #get the IDs of all messages in the inbox and put in knowAboutMail typ, data = self.imap.SEARCH(None, 'ALL') self.knownAboutMail = data[0].split() #now run the inherited __init__ method to create thread threading.Thread.__init__(self) except: #Uh Oh, something went wrong print 'ERROR: IMAP Issue. It could be one (or more) of the following:' print '- The impalib2.py file needs to be in the same directory as this file' print '- You\'re not connected to the internet' print '- Google\'s mail server(s) is/are down' print '- Your username and/or password is incorrect' sys.exit(1) debugMsg('__init__() exited') """ The method invoked when the thread id start()ed. Enter a loop executing waitForServer() untill kill()ed. waitForServer() can, and should, be continuously executed to be alerted of new mail. """ def run(self): debugMsg('run() entered') #loop until killNow is set by kill() method while not self.killNow: self.waitForServer() debugMsg('run() exited') """ Run notify script, if installed, use it; if not, just use regular old print. """ def notify(self, title, message, body): debugMsg('notify() entered') #if notify script is installed, send notification if os.path.isfile('/home/pi/notify.py'): #The command string - os.system()ed to use notify cmd = '/home/pi/notify.py -f "' + title + '" -s "' + message + '" -m "' + body + '"' print cmd debugMsg('notify cmd string:') debugMsg(cmd, 0) os.system(cmd) #if not, just print it out else: debugMsg('WARNING: notify script not installed.') print ' ' print 'NEW MAIL:' print '--', title print '--', message print '--', body debugMsg('notify() exited') """ The main def for displaying messages. It draws on getMessageHeaderFieldsById() and growlnotify() to do so. """ def showNewMailMessages(self): debugMsg('showNewMailMessages() entered') #get IDs of all UNSEEN messages typ, data = self.imap.SEARCH(None, 'UNSEEN') debugMsg('data - new mail IDs:') debugMsg(data, 0) for id in data[0].split(): if not id in self.knownAboutMail: #get the entire message etyp, edata = self.imap.FETCH(id, '(RFC822)') raw = edata[0][1] #puts message from list into string msg = email.message_from_string( raw ) # converts string to instance of message msg is an email message so multipart and walk work on it. body = '' #Finds the plain text version of the body of the message. if msg.get_content_maintype( ) == 'multipart': #If message is multi part we only want the text version of the body, this walks the message and gets the body. for part in msg.walk(): if part.get_content_type() == "text/plain": body = part.get_payload(decode=True) regex = re.compile( "\\A.{0,}\\s") # First line of plain text body matchArray = regex.findall(body) body = str(matchArray[0]) body = ''.join(body.splitlines()) #notify self.notify( email.utils.parseaddr(msg['From'])[1], msg['Subject'][:64], body[:64]) #add this message to the list of known messages self.knownAboutMail.append(id) debugMsg('showNewMailMessages() exited') """ Called to stop the script. It stops the continuous while loop in run() and therefore stops the thread's execution. """ def kill(self): self.killNow = True # to stop while loop in run() self.timeout = True # keeps waitForServer() nice self.stopWaitingEvent.set( ) # to let wait() to return and let execution continue """ This is the block of code called by the run() method of the therad. It is what does all the waiting for new mail (well, and timeouts). """ def waitForServer(self): debugMsg('waitForServer() entered') #init self.newMail = False self.timeout = False self.IDLEArgs = '' self.stopWaitingEvent.clear() def _IDLECallback(args): self.IDLEArgs = args self.stopWaitingEvent.set() #_IDLECallack() is entered when the IMAP server responds to the IDLE command when new #mail is received. The self.stopWaitingEvent.set() allows the .wait() to return and #therefore the rest of waitForServer(). #attach callback function, and let server know it should tell us when new mail arrives self.imap.idle(timeout=60 * ServerTimeout, callback=_IDLECallback) #execution will stay here until either: # - a new message is received; or # - the timeout has happened # - we set the timout -- the RFC says the server has the right to forget about # us after 30 mins of inactivity (i.e. not communicating with server for 30 mins). # By sending the IDLE command every 29 mins, we won't be forgotten. # - Alternatively, the kill() method has been invoked. self.stopWaitingEvent.wait() #self.IDLEArgs has now been filled (if not kill()ed) if not self.killNow: # skips a chunk of code to sys.exit() more quickly. if self.IDLEArgs[0][1][0] == ('IDLE terminated (Success)'): # This (above) is sent when either: there has been a timeout (server sends); or, there # is new mail. We have to check manually to see if there is new mail. typ, data = self.imap.SEARCH( None, 'UNSEEN') # like before, get UNSEEN message IDs debugMsg('Data: ') debugMsg(data, 0) #see if each ID is new, and, if it is, make newMail True for id in data[0].split(): if not id in self.knownAboutMail: self.newMail = self.newMail or True else: self.timeout = True # gets executed if there are UNSEEN messages that we have been notified of, # but we haven't yet read. In this case, it response was just a timeout. if data[0] == '': # no IDs, so it was a timeout (but no notified but UNSEEN mail) self.timeout = True #now there has either been a timeout or a new message -- Do something... if self.newMail: debugMsg('INFO: New Mail Received') self.showNewMailMessages() elif self.timeout: debugMsg('INFO: A Timeout Occurred') debugMsg('waitForServer() exited')
host, urllib2.quote(user), urllib2.quote(folder)) password = getpass.getpass('IMAP Password: '******'(RFC822)') req = urllib2.Request(url, data[0][1]) req.add_header('Content-Type', 'message/rfc822') f = urllib2.urlopen(req) out = '{0} {1}'.format(f.getcode(), f.read(100)) print out while True: M = imaplib2.IMAP4_SSL('secure.emailsrvr.com') M.login(user, password) M.select(folder.replace('&', '&-')) typ, data = M.search(None, 'RECENT') if data[0]: migrate_set(data[0]) else: M.idle() typ, data = M.search(None, 'RECENT') if data[0]: migrate_set(data[0]) M.close() M.logout() # vim:et:fdm=marker:sts=4:sw=4:ts=4