def process_rulz(): # make a timestamp for the run rundt = datetime.datetime.now() runlog.append(str(rundt) + " - processing rules...") # Get the list of "to folders" from database. Will move emails in bulk sql = "Select distinct ToFolder, Field from Rulz;" try: cursor.execute(sql) ToFolders = cursor.fetchall() except Exception as e: runlog.append("!!! ERROR - Could not get list of ToFolders. Error=" + str(e)) return for row in ToFolders: # For every To Folder/Keyword.... ToFolder = row[0] ToFolderVerbose = SubfolderPrefix + ToFolder actionField = row[1] sql = "select criteria from rulz where tofolder='" + ToFolder + "' AND field='" + actionField + "';" cursor.execute(sql) CriteriaSet = cursor.fetchall() Criteria = [] for row2 in CriteriaSet: Criteria.append(row2[0].replace( '"', '')) # drop any double quotes in the criteria # Pull the emails that have the criteria # for msg in mailbox.fetch(OR(from_=['little', 'newegg', 'drafthouse.com']), mark_seen=False): status = "Processing '" + actionField + "' rules for '" + ToFolder + "' folder..." # Criteria=" + str(Criteria) runlog.append(status) numrecs = 0 try: mailbox.folder.set('INBOX') if actionField.lower() == "from": numrecs = mailbox.move( mailbox.fetch(OR(from_=Criteria), mark_seen=False), ToFolderVerbose) if actionField.lower() == "subject": numrecs = mailbox.move( mailbox.fetch(OR(subject=Criteria), mark_seen=False), ToFolderVerbose) if actionField.lower() == "body": numrecs = mailbox.move( mailbox.fetch(OR(body=Criteria), mark_seen=False), ToFolderVerbose) runlog.append("..." + str(str(numrecs).count('UID')) + " messages moved to folder '" + ToFolder + "'.") except Exception as e: runlog.append("!!!FAILED rule for folder '" + ToFolder + "'. Criteria=" + str(Criteria)) runlog.append(str(e)) continue # end for each keyword (from, subject, body...) # end for each ToFolder runlog.append("Rules processing completed.") return # end of process_rulz()
def generate_search_query(time_to_fetch_from: Optional[datetime], permitted_from_addresses: str, permitted_from_domains: str, uid_to_fetch_from: int) -> list: """ Generates a search query for the IMAP client 'search' method. with the permitted domains, email addresses and the starting date from which mail should be fetched. Input example: time_to_fetch_from: datetime.datetime(2020, 8, 7, 12, 14, 32, 918634, tzinfo=datetime.timezone.utc) permitted_from_addresses: ['*****@*****.**', '*****@*****.**'] permitted_from_domains: ['test1.com', 'domain2.com'] output example: ['OR', 'OR', 'OR', 'FROM', '*****@*****.**', 'FROM', '*****@*****.**', 'FROM', 'test1.com', 'FROM', 'domain2.com', 'SINCE', datetime.datetime(2020, 8, 7, 12, 14, 32, 918634, tzinfo=datetime.timezone.utc)] Args: time_to_fetch_from: The greatest incident created_time we fetched from last fetch permitted_from_addresses: A string representation of list of mail addresses to fetch from permitted_from_domains: A string representation list of domains to fetch from uid_to_fetch_from: The email message UID to start the fetch from as offset Returns: A list with arguments for the email search query """ permitted_from_addresses_list = argToList(permitted_from_addresses) permitted_from_domains_list = argToList(permitted_from_domains) messages_query = '' if permitted_from_addresses_list + permitted_from_domains_list: messages_query = OR(from_=permitted_from_addresses_list + permitted_from_domains_list).format() # Removing Parenthesis and quotes messages_query = messages_query.strip('()').replace('"', '') # Creating a list of the OR query words messages_query_list = messages_query.split() if time_to_fetch_from: messages_query_list += ['SINCE', time_to_fetch_from] # type: ignore[list-item] if uid_to_fetch_from: messages_query_list += ['UID', f'{uid_to_fetch_from}:*'] return messages_query_list
def getUnseenMails(self, limit=100): today = date.today() mailbox = self.serverStart() # subjects = [msg for msg in mailbox.fetch(AND(all=True))] unseen_mails = mailbox.fetch(OR(date=today)) return unseen_mails
# python to prefix steps 1. OR(1=11, 2=22, 3=33) -> "(OR OR FROM "11" TO "22" TEXT "33")" 2. AND("(OR OR FROM "11" TO "22" TEXT "33")", cc='44', bcc='55') -> "AND(OR(from_='11', to='22', text='33'), cc='44', bcc='55')" 3. NOT("AND(OR(from_='11', to='22', text='33'), cc='44', bcc='55')") -> "NOT (((OR OR FROM "1" TO "22" TEXT "33") CC "44" BCC "55"))" """ import datetime as dt from imap_tools import AND, OR, NOT, A, H # date in the date list (date=date1 OR date=date3 OR date=date2) q1 = OR( date=[dt.date(2019, 10, 1), dt.date(2019, 10, 10), dt.date(2019, 10, 15)]) # "(OR OR ON 1-Oct-2019 ON 10-Oct-2019 ON 15-Oct-2019)" # date not in the date list (NOT(date=date1 OR date=date3 OR date=date2)) q2 = NOT( OR(date=[ dt.date(2019, 10, 1), dt.date(2019, 10, 10), dt.date(2019, 10, 15) ])) # "NOT ((OR OR ON 1-Oct-2019 ON 10-Oct-2019 ON 15-Oct-2019))" # subject contains "hello" AND date greater than or equal dt.date(2019, 10, 10) q3 = A(subject='hello', date_gte=dt.date(2019, 10, 10)) # "(SUBJECT "hello" SINCE 10-Oct-2019)"
def _get_messages_by_email(self, folder: str, recepient_email: str) -> list: with MailBox('smtp.gmail.com').login(self.email_address, self.password, f'{folder}') as mailbox: message_list = [(msg.date, msg.text or msg.html) for msg in mailbox.fetch(OR(A(from_=f'{recepient_email}'), A(to=f'{recepient_email}')))] return message_list
def getbysearch(self,text): if self.authuser(): return self.Mb_main.fetch(OR(subject=text))