Beispiel #1
0
    def __init__(self, username, password):
        print("------------------------------------------------------")
        print("-                    SIRI CONTROL                    -")
        print("-           Created by Sanjeet Chatterjee            -")
        print("-           Adapted by Pydathon                      -")
        print("-      Website: https://medium.com/@thesanjeetc      -")
        print("------------------------------------------------------")

        try:
            self.last_checked = -1
            self.mail = MailBox('imap.gmail.com')
            self.mail.login(username, password, initial_folder='Notes')

            # Gets last Note id to stop last command from executing
            uidlist = [msg.uid for msg in self.mail.fetch(AND(all=True))]
            subjects = [msg.subject for msg in self.mail.fetch(AND(all=True))]
            try:
                self.last_checked = uidlist[-1].split()[-1]
            except IndexError:
                pass
            self.load()
            self.handle()
        except imaplib.IMAP4.error:
            print("Your username and password is incorrect")
            print("Or IMAP is not enabled.")
Beispiel #2
0
def parse_email(imap, u, pw):
    # get list of email subjects from INBOX folder - equivalent verbose version
    mailbox = MailBox(imap)
    mailbox.login(
        u, pw, initial_folder='INBOX')  # or mailbox.folder.set instead 3d arg

    # for debugging, you can set mark_seen=False
    # texts = [msg.html for msg in mailbox.fetch(AND(all=True),mark_seen=False)]
    # sometimes html, sometimes text
    h = [msg.html for msg in mailbox.fetch(AND(all=True), mark_seen=False)]
    h += [msg.text for msg in mailbox.fetch(AND(all=True), mark_seen=False)]
    #print(h) # debugging
    mailbox.logout()
    return h
Beispiel #3
0
    def fetch_command(self):
        """Retrieve the last Note created if new id found"""
        uidlist = [msg.uid for msg in self.mail.fetch(AND(all=True))]
        subjects = [msg.subject for msg in self.mail.fetch(AND(all=True))]
        try:
            latest_email_id = uidlist[-1].split()[-1]
        except IndexError:
            return

        if latest_email_id == self.last_checked:
            return

        self.last_checked = latest_email_id
        data = subjects[-1]
        return data.lower().strip()
    def update(self):
        # at least return the mail with 'last_send' uid
        # if there is new mail, there will be more than
        # one uid
        query = AND(uid=UidRange(self._get_last_send(), '*'))
        mails = None
        try:
            with MailBox(self.config['host'],
                         port=self.config['imap_port'],
                         starttls=True).login(self.config['imap_user'],
                                              self.config['imap_pw'],
                                              'INBOX') as mailbox:
                mails = list(
                    map(
                        lambda msg:
                        (msg.uid,
                         email.message_from_bytes(msg.obj.as_bytes(),
                                                  policy=policy.default)),
                        mailbox.fetch(query, mark_seen=False)))
        except Exception as e:
            self.logger.error(f'fetch mail failed : {e}')

        if mails is None:
            time.sleep(16)
            return

        if len(mails) > 1:
            # ignore the first email which has been sent last time
            self._forward_email(mails[1:])
            # skip failed mails
            self._set_last_send(mails[-1][0])
        else:
            interval = self.config['update_interval']
            print(f'{time.time()}: start count down for {interval} seconds')
            time.sleep(interval)
Beispiel #5
0
 def _get_mails(self) -> List[MailMessage]:
     return list(
         self.mailbox.fetch(
             AND(to=config.target_mail,
                 date_gte=date.today() - self.mail_date_within),
             bulk=True,
         ))
def cleanup():

    #Clean out old log files.  Criteria:
    # 1.  From myself
    # 2.  Incremental logs
    # 3.  Older than 2 days (today and yesterday)
    # 4.  Unflagged (no errors)

    status = "Cleanup: delete old incremental log emails..."
    runlog.append(status)

    date_criteria = (datetime.datetime.now() -
                     datetime.timedelta(days=1)).date()
    #print("date_criteria-", date_criteria)

    try:
        mailbox.folder.set(autofilefolder)  #point mailbox to autofile folder
        numrecs = mailbox.delete(
            mailbox.fetch(AND(from_=[myemailaddress],
                              subject=["Rulz Log - Incremental @"],
                              date_lt=date_criteria,
                              flagged=False),
                          mark_seen=False))
        runlog.append(
            str(str(numrecs).count('UID')) + " log messages removed.")
    except Exception as e:
        runlog.append(
            "!!!FAILED to cleanup old log files from autofile folder.")
        runlog.append(str(e))
        return

    return  #end of cleanup
Beispiel #7
0
    def search_for_email_with_criteria(self, mailbox: MailBox, use_debug: bool, init_mail_download: bool = False):
        if init_mail_download:
            search_for_mail = mailbox.fetch()
            with open('/opt/mailer_daemon/config.json', 'r') as f:
                lines = f.readlines()
            with open("/opt/mailer_daemon/config.json", "w") as f:
                for line in lines:
                    if "mailbox_init_download" not in line:
                        f.write(line)
        else:
            search_for_mail = mailbox.fetch(AND(date=(date(
                year=self.current_date.year, month=self.current_date.month, day=self.current_date.day))))
        for message in search_for_mail:
            self.mail_json_loader[message.uid] = {
                'headers': message.headers,
                'subject': message.subject,
                'from': message.from_,
                'to': message.to,
                'content': message.text,
                'date': str(message.date.strftime('%Y-%-m-%d'))
            }

        if use_debug:
            self.logger.info(f"Debug is on, blob file is saved in {self.debug_file}")
            if path.isfile(self.debug_file):
                remove(self.debug_file)
            with open(self.debug_file, 'x') as f:
                json_file = loads(
                    dumps(self.mail_json_loader, sort_keys=True)
                        .replace('\\n', '')
                        .replace('\\r', '')
                        .replace('\\t', ''))
                dump(json_file, f)
def do_command():

    if not settings.FETCH_EMAILS:
        return

    HOST = settings.IMAP_HOST
    USER = settings.IMAP_USER
    PASSWORD = settings.IMAP_PWD
    PORT = settings.IMAP_PORT
    FROM = settings.IMAP_FROM

    with MailBox(HOST).login(USER, PASSWORD, 'INBOX') as mailbox:
        for message in mailbox.fetch(AND(
                seen=False,
                subject=_('invoices'),
        ),
                                     mark_seen=True):
            try:
                usr = User.objects.get(email=message.from_)
                if not usr.has_perm('accounting.add_csvinvoice'):
                    continue
            except:
                continue
            for att in message.attachments:  # list: [Attachment objects]
                file = SimpleUploadedFile(att.filename, att.payload,
                                          att.content_type)
                instance = CSVInvoice(csv=file)
                instance.save()
Beispiel #9
0
    def handle_mail_rule(self, M, rule):

        self.log('debug', f"Rule {rule}: Selecting folder {rule.folder}")

        try:
            M.folder.set(rule.folder)
        except MailboxFolderSelectError:
            raise MailError(f"Rule {rule}: Folder {rule.folder} "
                            f"does not exist in account {rule.account}")

        criterias = make_criterias(rule)

        self.log(
            'debug', f"Rule {rule}: Searching folder with criteria "
            f"{str(AND(**criterias))}")

        try:
            messages = M.fetch(criteria=AND(**criterias),
                               mark_seen=False,
                               charset='UTF-8')
        except Exception:
            raise MailError(
                f"Rule {rule}: Error while fetching folder {rule.folder}")

        post_consume_messages = []

        mails_processed = 0
        total_processed_files = 0

        for message in messages:
            try:
                processed_files = self.handle_message(message, rule)
                if processed_files > 0:
                    post_consume_messages.append(message.uid)

                total_processed_files += processed_files
                mails_processed += 1
            except Exception as e:
                self.log("error", f"Rule {rule}: Error while processing mail "
                         f"{message.uid}: {e}",
                         exc_info=True)

        self.log('debug',
                 f"Rule {rule}: Processed {mails_processed} matching mail(s)")

        self.log(
            'debug', f"Rule {rule}: Running mail actions on "
            f"{len(post_consume_messages)} mails")

        try:
            get_rule_action(rule).post_consume(M, post_consume_messages,
                                               rule.action_parameter)

        except Exception as e:
            raise MailError(
                f"Rule {rule}: Error while processing post-consume actions: "
                f"{e}")

        return total_processed_files
Beispiel #10
0
 def readMessages(self):
     with MailBox('imap.gmail.com').login(os.getenv("USER"), os.getenv("PASSWORD")) as mailbox:
         for msg in mailbox.fetch(AND(seen=False)):
             print(msg)
             code = msg.subject.split(":", 1)
             if code[0].lower() == "matprat":
                 print("matprat")
                 return code[0].lower(),  code[1]
             else:
                 return "no messages found"
def search_email_inbox(search_string, username, password):
    search_from_date = dt.date.today() - dt.timedelta(days=90)

    # get list of email subjects from INBOX folder
    with MailBox('imap.gmail.com').login(username, password) as mailbox:
        for message in mailbox.fetch(Q(
                AND(subject=search_string, date_gte=search_from_date)),
                                     miss_defect=False,
                                     miss_no_uid=False):
            yield message.subject
Beispiel #12
0
    def store_email_data(self):
        try:
            find_email = False
            login = self.conf['main']['login']
            password = self.conf['main']['password']
            store_dir = self.conf['other']['tmp_folder']
            prefix_email_subject = self.conf['main']['prefix_email_subject']

            self.logger.info(f'Login to {login}')  # логинимся
            try:
                with MailBox('imap.gmail.com').login(login,
                                                     password) as mailbox:
                    for msg in mailbox.fetch(
                            AND(subject=prefix_email_subject, seen=False)):
                        find_email = True
                        self.logger.info(
                            f'Find email with subjetc contains {prefix_email_subject}'
                        )
                        self.logger.info(f'Message subject: {msg.subject}')

                        # создаем папку для сохранения файлов
                        if not os.path.exists(
                                os.path.join(os.getcwd(), store_dir)):
                            os.makedirs(os.path.join(os.getcwd(), store_dir))

                        # сохраняем текст сообщения
                        path = os.path.join(store_dir, 'message_text.txt')
                        self.logger.info(f'Save message body: {path}')
                        with open(path, 'w') as f:
                            f.write(msg.text)

                        # сохраняем вложения
                        self.logger.info(
                            f'Find {len(msg.attachments)} attachments:')
                        for att in msg.attachments:
                            path = os.path.join(store_dir, att.filename)
                            self.logger.info(f'Save attachment: {path}')
                            with open(path, 'wb') as f:
                                f.write(att.payload)
                        return True

                    if not find_email:
                        self.logger.info(
                            f'Not found NEW email with subjetc contains {prefix_email_subject}'
                        )
                        return False

            except MailboxLoginError:
                self.logger.warning('Login fail')
                return False
        except:
            self.logger.exception('store_email_data')
            return False
Beispiel #13
0
 def get(self, box="INBOX", criteria="ALL", limit=None, mark=None):
     emails = []
     mark_seen = False
     mail_filter = "ALL"
     if mark and mark == "seen":
         mark_seen = True
     if criteria and criteria == "seen":
         mail_filter = AND(seen=True)
     elif criteria and criteria == "unseen":
         mail_filter = AND(seen=False)
     with MailBox(self.smtp_server).login(
         self.username, self.password, initial_folder=box
     ) as mailbox:
         emails = []
         for msg in mailbox.fetch(mail_filter, limit=limit, mark_seen=mark_seen):
             parsed = {
                 "uid": msg.uid,
                 "subject": msg.subject,
                 "from": msg.from_values,
                 "to": list(msg.to_values),
                 "cc": list(msg.cc_values),
                 "bcc": list(msg.bcc_values),
                 "reply_to": list(msg.reply_to_values),
                 "date": msg.date,
                 "text": msg.text,
                 "html": msg.html,
                 "flags": msg.flags,
                 "headers": msg.headers,
                 "size_rfc822": msg.size_rfc822,
                 "size": msg.size,
                 "obj": msg.obj,
                 "attachments": len(msg.attachments),
             }
             emails.append(parsed)
             if mark and mark == "archive":
                 mailbox.delete([msg.uid])
         return pd.DataFrame.from_records(emails)
def get_from_email(start_date, end_date, mail_server, account, sender,
                   password):
    """
    Get raw data from email account.

    Args:
        start_date: datetime.datetime
            pull data from email received from the start date
        end_date: datetime.datetime
            pull data from email received on/before the end date
        mail_server: str
        account: str
            email account to receive new data
        sender: str
            email account of the sender
        password: str
            password of the datadrop email
    output:
        df: pd.DataFrame
    """
    time_flag = None
    df = pd.DataFrame(columns=[
        'SofiaSerNum', 'TestDate', 'Facility', 'City', 'State', 'Zip',
        'PatientAge', 'Result1', 'Result2', 'OverallResult', 'County',
        'FacilityType', 'Assay', 'SCO1', 'SCO2', 'CLN', 'CSN', 'InstrType',
        'StorageDate', 'ResultId', 'SarsTestNumber'
    ])
    with MailBox(mail_server).login(account, password, 'INBOX') as mailbox:
        for search_date in [
                start_date + timedelta(days=x)
                for x in range((end_date - start_date).days + 1)
        ]:
            for message in mailbox.fetch(
                    A(AND(date=search_date.date(), from_=sender))):
                for att in message.attachments:
                    name = att.filename
                    # Only consider covid tests
                    if "Sars" not in name:
                        continue
                    print("Pulling data received on %s" % search_date.date())
                    toread = io.BytesIO()
                    toread.write(att.payload)
                    toread.seek(0)  # reset the pointer
                    newdf = pd.read_excel(toread)  # now read to dataframe
                    df = df.append(newdf)
                    time_flag = search_date
    return df, time_flag
Beispiel #15
0
def fetch_mails():
    mailbox = MailBox(settings.inbox_url)
    mailbox.login(settings.inbox, settings.inbox_pass)
    msgs = mailbox.fetch(AND(seen=False))
    feeds = []
    for msg in msgs:
        feed = {
            'title': msg.subject,
            "description": msg.html,
            'author': msg.from_,
            'pub_date': msg.date,
            'guid': msg.uid,
            'to': msg.headers['envelope-to'][0]
        }
        feeds.append(feed)
        logger.info(f"New message retrieved for {msg.headers['envelope-to']}")
    if len(feeds) == 0:
        logger.info("No new messages.")
    mailbox.logout()
    return feeds
Beispiel #16
0
    def getbypagenum(self,page_number,searchterm):
        d = self.authuser()
        if d:

            print(page_number,self.n_per_page,'ufifidh')
            mb = IMAPClient(self.host)
            mb.login(self.user,self.pwd)
            mb.select_folder(d[self.folder])
            if searchterm:
                ids= mb.search(['OR',['OR',[u'TEXT',f'{searchterm}'],['FROM',f'{searchterm}']],['OR',[u'SUBJECT',f'{searchterm}'],[u'BODY',f'{searchterm}']]])
            else:
                ids = mb.search()
            print(len(ids),'hmmm')
            last = math.ceil(len(ids)/self.n_per_page)
            print(last,'last page')
            page_number = last-page_number+1
            start = max(0,((page_number-1)*self.n_per_page))
            end = min(len(ids),(page_number*self.n_per_page))
            print(start,end)
            print(ids[start:end])
            return (next(self.Mb_main.fetch(AND(uid=f'{m}'),headers_only=True,reverse=True) )for m in reversed(ids[start:end])),last
Beispiel #17
0
    def handle_mail_account(self, account):

        self.renew_logging_group()

        self.log('debug', f"Processing mail account {account}")

        total_processed_files = 0

        with get_mailbox(account.imap_server,
                         account.imap_port,
                         account.imap_security) as M:

            try:
                M.login(account.username, account.password)
            except Exception:
                raise MailError(
                    f"Error while authenticating account {account.name}")

            self.log('debug', f"Account {account}: Processing "
                              f"{account.rules.count()} rule(s)")

            for rule in account.rules.order_by('order'):
                self.log(
                    'debug',
                    f"Account {account}: Processing rule {rule.name}")

                self.log(
                    'debug',
                    f"Rule {account}.{rule}: Selecting folder {rule.folder}")

                try:
                    M.folder.set(rule.folder)
                except MailboxFolderSelectError:
                    raise MailError(
                        f"Rule {rule.name}: Folder {rule.folder} "
                        f"does not exist in account {account.name}")

                criterias = make_criterias(rule)

                self.log(
                    'debug',
                    f"Rule {account}.{rule}: Searching folder with criteria "
                    f"{str(AND(**criterias))}")

                try:
                    messages = M.fetch(criteria=AND(**criterias),
                                       mark_seen=False)
                except Exception:
                    raise MailError(
                        f"Rule {rule.name}: Error while fetching folder "
                        f"{rule.folder} of account {account.name}")

                post_consume_messages = []

                mails_processed = 0

                for message in messages:
                    try:
                        processed_files = self.handle_message(message, rule)
                    except Exception:
                        raise MailError(
                            f"Rule {rule.name}: Error while processing mail "
                            f"{message.uid} of account {account.name}")
                    if processed_files > 0:
                        post_consume_messages.append(message.uid)

                    total_processed_files += processed_files
                    mails_processed += 1

                self.log(
                    'debug',
                    f"Rule {account}.{rule}: Processed {mails_processed} "
                    f"matching mail(s)")

                self.log(
                    'debug',
                    f"Rule {account}.{rule}: Running mail actions on "
                    f"{len(post_consume_messages)} mails")

                try:
                    get_rule_action(rule).post_consume(
                        M,
                        post_consume_messages,
                        rule.action_parameter)

                except Exception:
                    raise MailError(
                        f"Rule {rule.name}: Error while processing "
                        f"post-consume actions for account {account.name}")

        return total_processed_files
Beispiel #18
0
from imap_tools import MailBox, AND

usuario = '*****@*****.**'
senha = '   123'

meu_email = MailBox('imap.gmail.com').login(usuario, senha)

#Pegar email que foram enviados por um remetente especifico

listaEmails = meu_email.fetch(AND(from_='*****@*****.**'))

print(f'Existe quantos e-mails com esse remetente ? {len(list(listaEmails))}')

#Pegar e-mail sobre o assunto ...
listaEmails2 = meu_email.fetch(AND(subject='Alerta'))

for email in listaEmails2:
    print(email.subject)
    print(email.text)

#Pegando anexo
listaEmails3 = meu_email.fetch(AND(from_='*****@*****.**'))
for email in listaEmails3:
    if len(email.attachments) > 0:
        for anexo in email.attachments:
            if 'Relatorio.pdf' in anexo.filename:
                informacoes_anexo = anexo.payload
                with open('CriandoArquivo', 'wb') as arquivo:
                    arquivo.write(informacoes_anexo)

meu_email.logout()
Beispiel #19
0
print("imap email:", settings["user"])
mailbox = None
connected = False
while True:
    if not connected:
        mailbox = MailBox(settings["host"])
        mailbox.login(settings["user"], settings["password"])
        connected = True
    now = datetime.datetime.now()
    print("Checking for new mail notifications:",
          now.strftime("%Y-%m-%d %H:%M:%S"))
    try:
        mailbox.folder.set("INBOX")
        # messages = mailbox.fetch(AND(all=True), headers_only=True)
        # messages = mailbox.fetch(AND(seen=False), headers_only=True)
        messages = mailbox.fetch(AND(seen=False))
    except:
        print("imap connection dropped, or fetch failed...")
        connected = False
    if connected:
        form_notification = False
        for msg in messages:
            print(msg.from_)
            print(msg.subject)
            if "Virtual Choir" in msg.subject:
                form_notification = True
        if form_notification:
            print("new google form work ...")
            responses.fetch(settings["responses"])
            responses.process(settings)
Beispiel #20
0
from imap_tools import MailBox #, Q
from imap_tools import A, AND, OR, NOT
import datetime
import os


# Получение всех вложений с электронной почты с папки Входящие
with MailBox('imap').login('*****@*****.**', 'PASSWORD', 'INBOX') as mailbox:
    for msg in mailbox.fetch((AND(all=True))): # Берет все письма из папки Входящие (INBOX)
            for att in msg.attachments:
                dateSend = str(msg.date)
                dateSend = dateSend[8:10] + '.' + dateSend[5:7] + '.' + dateSend[:4] # Составление даты письма
                path_email = 'C:/Users/gilr.SOFT-SERVIS.000/Desktop/Python/MailPython/' + msg.from_ # Путь с логином почты
                path_full = 'C:/Users/gilr.SOFT-SERVIS.000/Desktop/Python/MailPython/' + msg.from_  + '/' + dateSend  # Путь с логином почты и датой
                if os.path.isdir(path_email) == False: # Проверяем существует ли путь к папке с названием почты
                    os.mkdir(path_email)
                if os.path.isdir(path_full) == False: # Проверяем существует ли путь к папке с названием в виде Даты письма
                    os.mkdir(path_full)
                with open(path_full + '/{}'.format(att.filename), 'wb') as f:
                    f.write(att.payload)
Beispiel #21
0
def change_rulz():
    rundt = datetime.datetime.now()
    runlog.append(str(rundt) + " - checking for rule changes...")
    extractrulesflag = False

    msgs2move = [
    ]  # build a list of messages from myself to move.  Can't move them while in the loop of
    # messages b/c it will invalidate the recordset and next loop will fail

    # Get any mail sent from myself
    try:
        mailbox.folder.set('INBOX')
        mymsgs = mailbox.fetch(AND(from_=[myemailaddress]))
    except Exception as e:
        status = "!!! ERROR fetching messages from myself.  Error = " + str(e)
        runlog.append(status)
        return

    for msg in mymsgs:

        # Get the unique id
        uid = msg.uid

        if msg.subject.lower() == "rulz":  ### DUMP RULES TO EMAIL  ####

            extractrulesflag = True

            # Move the processed msg to the autofile folder to mark as processed
            msgs2move.append(uid)
            # mailbox.move(msg.uid, autofilefolder)

            continue  # onto next message

        # REPLACE all rules from email
        if 'rulz extract' in msg.subject:
            # replace all the rules being sent back

            # status
            runlog.append("Replacing rules...")

            rulzpos = msg.text.find('rulz:')
            if rulzpos < 0:
                status = "!!! ERROR - Could not find the 'rulz:' keyword.   Ignoring file."
                runlog.append(status)

                mailbox.flag(msg.uid, imap_tools.MailMessageFlags.FLAGGED,
                             True)
                msgs2move.append(uid)
                # mailbox.move(msg.uid, autofilefolder)  # Move message as processed
                continue  # onto the next msg

            # The rulz_new table should NOT exist, but attempt to rename just in case
            sql = "ALTER TABLE rulz_new RENAME TO rulz_new_" + datetime.datetime.now(
            ).strftime("%b%d%Y%H%M%S") + ";"
            try:
                cursor.execute(sql)  # drop the temp table
                dbcon.commit()
            except:
                # don't care if this fails
                status = "Error archiving old rulz_new table.   This is normal."
                # runlog.append(status)

            # Create a temp table named rulz_new
            sql = "SELECT sql FROM sqlite_master WHERE name = 'rulz';"
            try:
                cursor.execute(
                    sql)  # Get the CREATE statement for the rulz table
                sql = cursor.fetchall()[0][0].replace(
                    'rulz', 'rulz_new')  # make a copy
                cursor.execute(sql)  # create new table
                dbcon.commit()  # do it
            except Exception as e:
                status = "!!! Error - could not find schema for 'rulz' table."
                runlog.append(status)

                mailbox.flag(msg.uid, imap_tools.MailMessageFlags.FLAGGED,
                             True)
                msgs2move.append(uid)
                # mailbox.move(msg.uid, autofilefolder)  # Move message as processed
                continue  # onto the next msg

            # Build a list of tuples
            temprulz = msg.text[rulzpos + 7:].strip(
            )  # Substring everything past the rulz: tag
            temprulz = temprulz.split(
                '\r\n')  # Create a list from all the lines
            newrulz = []  # start with empty list
            for row in temprulz:  # each line now needs to put into a tuple
                # newrulz.append(tuple(str(row).strip().split(' ')))    # works, version #1

                # print(row)

                # https://stackoverflow.com/questions/2785755/how-to-split-but-ignore-separators-in-quoted-strings-in-python
                row_aslist = re.split(''' (?=(?:[^'"]|'[^']*'|"[^"]*")*$)''',
                                      row)  # I don't get it, but it works

                # parse it out into variables and evaluate them
                actionfield = str(row_aslist[0]).lower()
                if row_aslist[0] not in ActionFields:
                    status = "!!! ERROR parsing rule.  First word not recognized - " + actionfield
                    runlog.append(status)
                    runlog.append(row)
                    continue
                row_aslist[0] = actionfield  # force it to lowercase

                actioncriteria = str(
                    row_aslist[1])  # add any validation rules here

                tofolder = str(row_aslist[2]).lower()
                if tofolder not in SubFolders:
                    status = "!!! ERROR parsing rule.  Target folder not recognized - " + tofolder
                    runlog.append(status)
                    runlog.append(row)
                    continue
                row_aslist[2] = tofolder  # force it to lower case

                # put the values in a tuple and then add it to the list
                newrulz.append(tuple(row_aslist))

            # newrulz=[('aaa','bbb','ccc'),('ddd','eee','fff')]    # this is the expected format
            sql = "INSERT INTO rulz_new (Field,Criteria,ToFolder) VALUES (?,?,?)"
            try:
                cursor.executemany(sql, newrulz)
                dbcon.commit()
            except Exception as e:
                status = "!!! ERROR inserting new data to rulz_new.  Error=" + str(
                    e)
                runlog.append(status)
                runlog.append(sql)
                # status = 'New rules=' + str(newrulz)
                # runlog.append(status)
                for row in newrulz:
                    runlog.append(row)

                mailbox.flag(msg.uid, imap_tools.MailMessageFlags.FLAGGED,
                             True)
                msgs2move.append(uid)
                # mailbox.move(msg.uid, autofilefolder)  # Move message as processed
                continue

            # Make a copy of the current Rulz_new table
            try:
                sql = "ALTER TABLE rulz RENAME TO rulz" + datetime.datetime.now(
                ).strftime("%b%d%Y%H%M%S") + ";"
                cursor.execute(sql)  # drop the temp table

                sql = "ALTER TABLE rulz_new RENAME TO rulz;"
                cursor.execute(sql)
                dbcon.commit()

            except Exception as e:
                status = "!!! ERROR attempting to archive/swap table 'rulz'. Error: " + str(
                    e)
                runlog.append(status)

                mailbox.flag(msg.uid, imap_tools.MailMessageFlags.FLAGGED,
                             True)
                msgs2move.append(uid)
                # mailbox.move(msg.uid, autofilefolder)  # Move message as processed
                continue

            # Move the processed msg to the autofile folder to mark as processed  - everything was good!
            msgs2move.append(uid)
            # mailbox.move(msg.uid, autofilefolder)

            # Extract the rules once more
            extractrulesflag = True

            continue  # onto next message
        # End REPLACE rulz from email

        #####################################################
        # CREATE ONE RULE FROM FORWARDED EMAIL
        #####################################################
        if (msg.subject.find('FW:') > -1) or (msg.subject.find('Fwd:') > -1):

            body = msg.text[:msg.text.find(
                '\r')]  # get the first line of the body
            #print("Body=", body)

            # https://stackoverflow.com/questions/2785755/how-to-split-but-ignore-separators-in-quoted-strings-in-python
            body = re.split(''' (?=(?:[^'"]|'[^']*'|"[^"]*")*$)''',
                            body)  #I don't get it, but it works

            # parse it out into variables
            actionfield = str(body[0]).lower().strip()
            actioncriteria = str(body[1])
            tofolder = str(body[2]).lower().strip()
            # print(actionfield)
            # print(actioncriteria)
            # print(tofolder)

            # If the actioncriteria was a hyperlink, then fix that
            if tofolder.find("mailto:") > -1:
                runlog.append(
                    "Criteria found to be a hyperlink.  Skipping over 'mailto:' tag."
                )
                # tofolder = msg.text.split()[3].lower()
                tofolder = tofolder.replace("mailto:",
                                            "")  #remove the mailto: tag

            status = "FW email found. ActionField='" + actionfield + "'. ActionCriteria='" + actioncriteria \
                     + "'. ToFolder='" + tofolder + "'."
            runlog.append(status)

            # make sure the first word is a valid action field (from, subject,...)
            if actionfield not in ActionFields:
                status = "WARNING - Did not find the first word '" + actionfield + "' to be a valid action field. " \
                        "Email was ignored. List of possible action fields are: " + str(
                    ActionFields)
                runlog.append(status)

                # mailbox.flag(uid, imap_tools.MailMessageFlags.FLAGGED, True)
                # mailbox.move(uid, autofilefolder)  # Move message as processed
                continue  # onto next message

            # make sure the tofolder is in the list of subfolders
            if tofolder not in SubFolders:
                # print(msg.text)
                status = "!!! ERROR - Did not find autofile folder '" + tofolder + ". Email was ignored. " \
                        "List of possible folders are: " + str(
                    SubFolders)
                runlog.append(status)

                mailbox.flag(uid, imap_tools.MailMessageFlags.FLAGGED, True)
                msgs2move.append(uid)
                # mailbox.move(uid, autofilefolder)  # Move message as processed
                continue  # onto next message

            # Create the rule in the database
            sql = "INSERT INTO Rulz (Field,Criteria,ToFolder) VALUES ('" + actionfield + "','" + actioncriteria + "'," \
                "'" + tofolder + "');"

            try:
                cursor.execute(sql)
                dbcon.commit()
            except Exception as e:
                status = "!!! ERROR - Could not insert new rule.  SQL='" + sql + \
                         "Error: " + str(e)
                runlog.append(status)

                mailbox.flag(uid, imap_tools.MailMessageFlags.FLAGGED, True)
                msgs2move.append(uid)
                # mailbox.move(uid, autofilefolder)  # Move message as processed

            # Move the msg to the autofile folder to mark as processed
            msgs2move.append(uid)
            # mailbox.move(uid, autofilefolder)

            # Give good status news
            runlog.append("Rule added! ID=" + str(cursor.lastrowid) + ". Action Field ='" + actionfield \
                          + "'. Criteria='" + actioncriteria + "'.  ToFolder='" + tofolder + "'.")

            # Extract the rules once more
            extractrulesflag = True

            continue  # to the next message
    # for each message sent from myself

    # Move all the processed messages from myself
    mailbox.move(msgs2move, autofilefolder)

    # If something changed, extract the rules again
    if extractrulesflag == True:
        extract_rulz()

    return  # end of change_rulz()
Beispiel #22
0
import common
import responses

settings = common.get_config()

# watch the inbox for form submissions (or edits)
# imap host, username & password are stored externally as a json file.
print("imap host:", settings["host"])
print("imap email:", settings["user"])
mailbox = MailBox(settings["host"])
mailbox.login(settings["user"], settings["password"])
while True:
    now = datetime.datetime.now()
    notification = False
    print("Checking for new mail notifications:",
          now.strftime("%Y-%m-%d %H:%M:%S"))
    mailbox.folder.set("INBOX")
    messages = mailbox.fetch(AND(all=True), headers_only=True)
    # messages = mailbox.fetch(AND(seen=False), headers_only=True)
    for msg in messages:
        print(msg.subject)
        if "Virtual Choir" in msg.subject:
            notification = True
    if notification:
        print("new work ...")
        responses.fetch(settings["responses"])
        responses.process()
    # subjects = [msg.subject for msg in mailbox.fetch(AND(all=True))]
    print("  sleeping", settings["interval"], "seconds ...")
    time.sleep(settings["interval"])
def save_mail(imap_host, imap_user, select_mailbox, imap_pass,
              subject_to_check, text, sender_email, receiver_email,
              flagged_email, check_email, exact_date, after_date, before_date,
              wait):
    # time.sleep(5)
    with MailBox(imap_host).login(imap_user,
                                  imap_pass,
                                  initial_folder=select_mailbox) as mailboxi:

        clauses = []

        def gt(dt):
            dt = datetime.strptime(dt, '%Y-%m-%d')
            return dt

        if subject_to_check:
            clauses.append(AND(subject=subject_to_check))
        if text:
            clauses.append(AND(text=text))
        if sender_email:
            clauses.append(AND(from_=sender_email))
        if check_email:
            if check_email in ("false", "unseen", "unread", "unchecked", "no"):
                clauses.append(AND(seen=False))
            else:
                clauses.append(AND(seen=True))
        if flagged_email:
            if flagged_email in ("true", "ok", "yes", "flag", "flagged"):
                clauses.append(AND(flagged=True))
            else:
                clauses.append(AND(flagged=False))
        if receiver_email:
            clauses.append(AND(to=receiver_email))
        if exact_date:
            f = gt(exact_date)
            clauses.append(AND(date=datetime.date(f)))
        if after_date:
            a = gt(after_date)
            clauses.append(AND(date_gte=datetime.date(a)))
        if before_date:
            b = gt(before_date)
            clauses.append(AND(date_lt=datetime.date(b)))

        end = time.time() + wait
        while True:
            all_mails = list(mailboxi.fetch(AND(*clauses)))
            if len(all_mails) > 0 or time.time() > end:
                break

        value = []
        for msg in all_mails:
            value.append({
                "Sender": msg.from_,
                "Receiver": msg.to,
                "Subject": msg.subject,
                "Date": msg.date,
                "Text": msg.text,
                "htmlBody": msg.html
            })
        return value
def delete_mail(imap_host,
                imap_user,
                select_mailbox,
                imap_pass,
                subject_to_check,
                text,
                sender_email,
                receiver_email,
                flagged_email,
                check_email,
                exact_date,
                after_date,
                before_date,
                wait=10.0):
    sModuleInfo = inspect.currentframe().f_code.co_name + " : " + MODULE_NAME

    # time.sleep(5)

    with MailBox(imap_host).login(imap_user,
                                  imap_pass,
                                  initial_folder=select_mailbox) as mailboxi:

        clauses = []

        def gt(dt):
            dt = datetime.strptime(dt, '%Y-%m-%d')
            return dt

        if subject_to_check:
            clauses.append(AND(subject=subject_to_check))
        if text:
            clauses.append(AND(text=text))
        if sender_email:
            clauses.append(AND(from_=sender_email))
        if check_email:
            if check_email in ("false", "unseen", "unread", "unchecked", "no"):
                clauses.append(AND(seen=False))
            else:
                clauses.append(AND(seen=True))
        if flagged_email:
            if flagged_email in ("true", "ok", "yes", "flag", "flagged"):
                clauses.append(AND(flagged=True))
            else:
                clauses.append(AND(flagged=False))
        if receiver_email:
            clauses.append(AND(to=receiver_email))
        if exact_date:
            f = gt(exact_date)
            clauses.append(AND(date=datetime.date(f)))
        if after_date:
            a = gt(after_date)
            clauses.append(AND(date_gte=datetime.date(a)))
        if before_date:
            b = gt(before_date)
            clauses.append(AND(date_lt=datetime.date(b)))

        end = time.time() + wait
        while True:
            all_mails = list(mailboxi.fetch(AND(*clauses)))
            if len(all_mails) > 0 or time.time() > end:
                break

        mail_list = []
        for mail in all_mails:
            mail_list.append({
                "uid": mail.uid,
                "from": mail.from_,
                "subject": mail.subject,
                "to": mail.to,
                "text": mail.text,
                "html": mail.html,
            })

        try:
            log_msg = json.dumps(mail_list, indent=2)
        except:
            log_msg = str(mail_list)
        CommonUtil.ExecLog(sModuleInfo,
                           "Deleting the following mails:" + log_msg, 1)
        mailboxi.delete([mail["uid"] for mail in mail_list])
Beispiel #25
0
#!/usr/bin/python3

# imports necessary libraries
from imap_tools import MailBox, AND
from time import sleep
import os

# gets list of email subjects from INBOX folder
with MailBox('imap.example.com').login("*****@*****.**",
                                       "PASSWORD",
                                       initial_folder='INBOX') as mailbox:
    body = [msg.text for msg in mailbox.fetch(AND(subject='Domain Blocked'))]
    print(body)
    # Checkes if the folder PiHoleWhitelist exists
    folder_exists = mailbox.folder.exists('PiHoleWhitelist')
    # if it does not exist, create it
    if folder_exists == False:
        mailbox.folder.create('PiHoleWhitelist')
    # Moves email to PiHoleWhitelist folder to avoid a cluttered Inbox
    mailbox.move(mailbox.uids(AND(subject='Domain Blocked')),
                 'PiHoleWhitelist')

    # tries to format email correctly
    try:
        body = body[
            0]  # First line of body only, removes email signature such as "Sent using Mail from Windows", etc.
        forbiddenChars = [
            '"', "'", "&", "|", ";"
        ]  # Emails with characters " ' & or | could potentially execute another command causing a security risk
        for char in forbiddenChars:
            if char in body:
Beispiel #26
0
def sendToSlack(msg: str, token: str):
    slackClient = WebClient(token)
    slackClient.chat_postMessage(channel='G01E0FE3KR7', text=msg)


try:
    logging.basicConfig(level=logging.DEBUG)
    logging.debug('logging in...')

    mailbox = MailBox(IMAP_SERVER)
    mailbox.login(MAIL, PASSWORD)

    logging.debug('Mail counting...')

    nCount = len([msg.subject for msg in mailbox.fetch(AND(all=True))])
    print(nCount)
    while True:
        # get list of email subjects from INBOX folder - equivalent verbose version
        mailbox = MailBox(IMAP_SERVER)
        mailbox.login(MAIL, PASSWORD)

        temp = mailbox.fetch(AND(all=True))
        mails = []
        for msg in temp:
            mails.append((msg.subject, msg.from_, msg.text[:120] + '...'))

        #subjects = [msg.subject for msg in mailbox.fetch(AND(all=True))]

        if len(mails) == nCount:
            logging.debug('No new messages')
Beispiel #27
0
def check_phish(mid):
    phishing_mails = []

    # Retrieves the email address instance
    logger.info("Click-to-check entered..")

    owner_id = get_owner_id_from_email_id(mid)
    if current_user.is_anonymous or not owner_id == current_user.get_id():
        logger.warning("Anonymous or unauthorized user attempting"\
        " phish check of address ID {}!".format(mid))
        return redirect(url_for('index'))

    mailaddr = get_email_address_by_email_id(mid)

    # Redirects back to page if selected email is inactive
    if mailaddr.get_active_status() == False:
        logger.warning("Redirecting.. User selected inactive email address %s"\
        , mailaddr.get_email_address())
        flash("Email is inactive!", 'error')
        return redirect(url_for('dash_email'))

    logger.info("Mailbox selected is %s", mailaddr.get_email_address())

    try:
        # Logs in to mailbox by retrieving the corresponding IMAP server
        imap_svr = get_imap_svr(mailaddr.get_email_address())
        logger.info("Retrieving IMAP server: %s", imap_svr)
        mailbox = MailBox(imap_svr)
        logger.info("Attempting connection..")
        mailbox.login(mailaddr.get_email_address()\
        , mailaddr.get_decrypted_email_password())
        logger.info("Connected to mailbox %s", mailaddr.get_email_address())
    except ConnectionRefusedError:
        logger.error("Unable to connect to mailbox for %s",
                     mailaddr.get_email_address())
        flash("Unable to connect to mailbox, please update your password!",
              'error')
        return redirect(url_for('dash_email'))

    # Retrieves date last updated
    # if new email address is added column is empty
    # sets last_updated to today - 1 day so that mails in the last 24 hours
    # are checked
    last_updated = mailaddr.get_last_updated() \
    if mailaddr.get_last_updated() else datetime.today() - timedelta(days=1)

    # Selects mailbox to Inbox only
    mailbox.folder.set("INBOX")
    logger.info("Fetching mails..")

    # Sets a check criteria so that
    # only mails newer than last_updated and unread mails are checked
    check_criteria = AND(date_gte=last_updated.date(), seen=False)
    """
    FOR DEMO USE
    """
    # Test code to intentionally pull retrieve backdated emails for demo purposes
    # last_updated = datetime(2020, 12,17, 0, 0, 0)
    # check_criteria = AND(date_gte=[date(2020, 12, 17)], seen=False)

    # Fetch mails from mailbox based on criteria, does not "read" the mail
    # and retrieves in bulk for faster performance at higher computing cost
    all_mails = mailbox.fetch(check_criteria,
                              reverse=True,
                              mark_seen=False,
                              bulk=True)

    logger.info("Mails fetched..")

    # Iterates through the mails that are not sent from the sender's address
    # Creates a EmailData instance for each mail to generate features based on
    # preprocessing logic, passes it into the model - if predict returns 1 it is a detected phish
    # appends the detected mail into a list of Mail (phishing_mails)
    # The purpose of Mail class is for easier display - the values are pulled from the
    # imap_tool's Mail item instead of our EmailData.
    # Inserts all phishing mails to the database
    data = {
        'total_count': 0,
        'detection_count': 0,
        'check_time': datetime.now().strftime('%d-%m-%Y, %H:%M')
    }

    mail_check_count = 0

    for msg in all_mails:
        try:
            sender = msg.from_
        except HeaderParseError:
            # Exception happens when a msg.from_ is malformed resulting in
            # unparseable values. Automatically assume phishing email and add to record.
            # Denote Sender as 'INVALID_SENDER'
            logger.error("HeaderParseError, unparseable msg.from_. \
            Setting sender as INVALID_SENDER")
            sender = 'INVALID_SENDER'
        if (check_valid_time(last_updated, msg.date)) \
        and check_valid_sender(sender, mailaddr.get_email_address()):
            data['total_count'] += 1
            mail_check_count += 1
            mail_item = EmailData(msg.subject, sender, msg.attachments\
            , (msg.text + msg.html), msg.headers)
            mail_item.generate_features()
            result = model.predict(mail_item.repr_in_arr())
            logger.info("Checking mail: %s -- Result: %s"\
            , mail_item.get_subject(), result)
            if result == 1:
                logger.info("Phishing mail detected, subject: %s", msg.subject)

                mail_exist = check_p_mail_exist(mailaddr.get_email_id()\
                , msg.subject, mail_item.get_content())

                if not mail_exist:
                    phishing_mails.append(Mail(sender, \
                    msg.date.astimezone(timezone('Asia/Singapore')), msg.subject))
                    data['detection_count'] += 1
                    detected_mail = PhishingEmail( \
                    sender_address = sender, \
                    subject = msg.subject, \
                    content = mail_item.get_content(), \
                    created_at = datetime.now(), \
                    receiver_id = mailaddr.get_email_id()
                    )
                    db.session.add(detected_mail)

    # Updates last updated to current time
    mailaddr.set_last_updated(datetime.now())
    logger.info("Updating mailbox last updated from %s to %s",\
    last_updated.strftime("%d-%m-%Y, %H:%M:%S"), datetime.now())

    mailaddr.set_phishing_mail_detected(data['detection_count'])
    mailaddr.set_total_mails_checked(mail_check_count)
    db.session.commit()
    logger.info("Finished checking mails.. logging out")
    mailbox.logout()
    send_phish_check_notice(mailaddr.get_email_address(), phishing_mails)

    mailaddr = get_email_address_by_email_id(mid)
    mail_address = mailaddr.get_email_address()

    # return redirect(url_for('dashboard'))
    return render_template('dashboard/detection_results.html', \
    phishing_mails = phishing_mails, data=data, mail_address = mail_address)
Beispiel #28
0
r = Redis(host='localhost', port=6379, db=0)

config = dotenv_values("{}/.env".format(os.path.dirname(os.path.realpath(__file__))))
EMAIL_SEARCH_CUTOFF = {'days': 10}


def email_to_userid(email):
    return email.split('@')[0].split('+')[1]


def get_track_id(user_id, track_code):
        track_code_hash = sha256(track_code.encode('utf-8')).hexdigest()
        return f"{user_id}:{track_code_hash}"


with MailBox('imap.gmail.com').login(config['EMAIL_ACCOUNT'], config['EMAIL_PASSWORD']) as mailbox:
    since_datetime = datetime.today() - timedelta(**EMAIL_SEARCH_CUTOFF)
    for msg in mailbox.fetch(AND(from_=config['EMAIL_SERVICE_FROM'], date_gte=since_datetime.date()), bulk=True):
        user_id = email_to_userid(msg.to_values[0]['email'])
        data = re.findall(r"""<(https://.+livetracking.+\?(.+)?)>""", msg.text, re.M, )
        if data:
            url, track_code = data[0][0], data[0][1]
            r.hset(get_track_id(user_id, track_code),
                    mapping={
                        'track_code': track_code,
                        'url': url,
                        'updated_at': datetime.now().timestamp(),
                    })
        else:
            logger.debug(f"No link detected. user_id: {user_id}, msg: `{msg.text}`")
Beispiel #29
0
#!/usr/bin/python
# -*- coding: UTF-8 -*-

from imap_tools import MailBox, AND
from bs4 import BeautifulSoup
import re

# get list of email subjects from INBOX folder
with MailBox('outlook.office365.com').login('*****@*****.**', 'Xhsd@2013', initial_folder='INBOX/招聘') as mailbox:
    # LIST
    # for f in mailbox.folder.list('INBOX'):
    #     print(f)  # {'name': 'INBOX|cats', 'delim': '|', 'flags': ('\\Unmarked', '\\HasChildren')}
    print(mailbox.fetch())
    for msg in mailbox.fetch(AND(subject='51job.com')):  # 前程无忧
        try:
            soup = BeautifulSoup(msg.html, features="html.parser")
            re_phone = soup.find('td', text=re.compile(
                '.*?手机.*?')).find_next_siblings('td')
            re_job = soup.find('td', text=re.compile(
                '.*?应聘职位.*?')).find_next_siblings('td')
            re_email = soup.find(href=re.compile("mailto"))
            print(
                f"{msg.subject.split('-')[1]} {re_phone[0].string} {re_email.string} {re_job[0].string.split(' ')[0]}")
        except Exception:
            print(Exception.__str__)
            continue
    for msg in mailbox.fetch(AND(subject='Zhaopin.com')):  # 智联招聘
        try:
            soup = BeautifulSoup(msg.html, features="html.parser")
            re_phone = soup.find('td', text=re.compile(
                '.*?手机.*?')).find_next_siblings('td')
Beispiel #30
0
        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)"

# from contains one of the address parts
q4 = OR(from_=["@spam.ru", "@tricky-spam.ru"])
# "(OR FROM "@spam.ru" FROM "@tricky-spam.ru")"

# marked as seen and not flagged
q5 = AND(seen=True, flagged=False)
# "(SEEN UNFLAGGED)"

# (text contains tag15 AND subject contains tag15) OR (text contains tag10 AND subject contains tag10)
q6 = OR(AND(text='tag15', subject='tag15'), AND(text='tag10', subject='tag10'))
# "(OR (TEXT "tag15" SUBJECT "tag15") (TEXT "tag10" SUBJECT "tag10"))"

# (text contains tag15 OR subject contains tag15) OR (text contains tag10 OR subject contains tag10)
q7 = OR(OR(text='tag15', subject='tag15'), OR(text='tag10', subject='tag10'))
# "(OR (OR TEXT "tag15" SUBJECT "tag15") (OR TEXT "tag10" SUBJECT "tag10"))"

# header IsSpam contains '++' AND header CheckAntivirus contains '-'
q8 = A(header=[H('IsSpam', '++'), H('CheckAntivirus', '-')])
# "(HEADER "IsSpam" "++" HEADER "CheckAntivirus" "-")"

# complex from README