def postprocess(self, input): " Heavily borrowed from https://www.mkyong.com/python/how-do-send-email-in-python-via-smtplib/ " smtpserver = smtplib.SMTP(self.smtp_addr, self.smtp_port) smtpserver.ehlo() smtpserver.starttls() if self.smtp_user and self.smtp_pass: smtpserver.login(self.smtp_user, self.smtp_pass) with open(input) as f: email = Parser().parse(f) if not self.recipient: # Set recipients from .mail file # Multiple recipients can be comma seperated self.recipient = ','.join( filter(None, [email.get('To'), email.get('Cc')])) else: # Set To header from config email['To'] = self.recipient smtpserver.sendmail(self.smtp_user, self.recipient.split(','), email.as_string()) smtpserver.close()
def cb_action_ACCEPT(module, filepath): log.info(_("Accepting message in %s (by module %s)") % (filepath, module)) log.debug(_("Accepting message in: %r") % (filepath), level=8) # parse message headers message = Parser().parse(open(filepath, 'r'), True) sender = [ formataddr(x) for x in getaddresses(message.get_all('X-Kolab-From', [])) ] recipients = [ formataddr(x) for x in getaddresses(message.get_all('X-Kolab-To', [])) ] log.debug(_("recipients: %r") % (recipients)) # delete X-Kolab-* headers del message['X-Kolab-From'] del message['X-Kolab-To'] result = _sendmail( sender, recipients, # - Make sure we do not send this as binary. # - Second, strip NUL characters - I don't know where they # come from (TODO) # - Third, a character return is inserted somewhere. It # divides the body from the headers - and we don't like (TODO) # @TODO: check if we need Parser().parse() to load the whole message message.as_string()) if result: os.unlink(filepath)
def main(): message = """From: Example <*****@*****.**> This is a message body. Fun! """ selector = "_dkim" signing_domain = "example.com" secret_key = "-----BEGIN RSA PRIVATE KEY-----\n" \ "MIICXQIBAAKBgQC4GUGr+d/6SFNzVLYpphnRd0QPGKz2uWnV65RAxa1Pw352Bqiz\n" \ "qiKOBjgYGzj8pJQSs8tOvv/2k6jpI809RnESqOFgF0gu3UJbNnu3+cd8k/kiQj+q\n" \ "4cKKRpAT92ccxc7svhCNgN1sBGmROYZuysG3Vu3Dyc079gSLtnSrgXb+gQIDAQAB\n" \ "AoGAemlI0opm1Kvs2T4VliH8/tvX5FXbBH8LEZQAUwVeFTB/UQlieXyCV39pIxZO\n" \ "0Sa50qm8YNL9rb5HTSZiHQFOwyAKNqS4m/7JCsbuH4gQkPgPF561BHNL9oKfYgJq\n" \ "9P4kEFfDTBoXKBMxwWtT7AKV8dYvCa3vYzPQ/1BnqQdw2zECQQDyscdgR9Ih59PQ\n" \ "b72ddibdsxS65uXS2vzYLe7SKl+4R5JgJzw0M6DTAnoYFf6JAsKGZM15PCC0E16t\n" \ "RRo47U9VAkEAwjEVrlQ0/8yPACbDggDJg/Zz/uRu1wK0zjqj4vKjleubaX4SEvj7\n" \ "r6xxZm9hC1pMJAC9y3bbkbgCRBjXfyY6fQJBANe5aq2MaZ41wTOPf45NjbKXEiAo\n" \ "SbUpboKCIbyyaa8V/2h0t7D3C0dE9l4efsguqdZoF7Rh2/f1F70QpYRgfJkCQQCH\n" \ "oRrAeGXP50JVW72fNgeJGH/pnghgOa6of0JpxwhENJuGMZxUDfxTtUA6yD3iXP3j\n" \ "A3WL/wbaHsfOYf9Y+g1NAkAGLhx67Ah+uBNK4Xvfz0YPGINX20m+CMsxAw7FOaNv\n" \ "IW2oWFfZCB4APkIis79Ql45AHpavwx5XodBMzZwJUvlL\n" \ "-----END RSA PRIVATE KEY-----\n" message = Parser().parsestr(text=message) dkim.Signer(message, selector, signing_domain, secret_key.encode()).add_signature_to_message() print(message.as_string())
def prepare_message(email, recipient, recipients_list): message = email.message if not message: return "" if email.add_unsubscribe_link and email.reference_doctype: # is missing the check for unsubscribe message but will not add as there will be no unsubscribe url unsubscribe_url = get_unsubcribed_url(email.reference_doctype, email.reference_name, recipient, email.unsubscribe_method, email.unsubscribe_params) message = message.replace("<!--unsubscribe url-->", quopri.encodestring(unsubscribe_url.encode()).decode()) if email.expose_recipients == "header": pass else: if email.expose_recipients == "footer": if isinstance(email.show_as_cc, string_types): email.show_as_cc = email.show_as_cc.split(",") email_sent_to = [r.recipient for r in recipients_list] email_sent_cc = ", ".join([e for e in email_sent_to if e in email.show_as_cc]) email_sent_to = ", ".join([e for e in email_sent_to if e not in email.show_as_cc]) if email_sent_cc: email_sent_message = _("This email was sent to {0} and copied to {1}").format(email_sent_to,email_sent_cc) else: email_sent_message = _("This email was sent to {0}").format(email_sent_to) message = message.replace("<!--cc message-->", quopri.encodestring(email_sent_message.encode()).decode()) message = message.replace("<!--recipient-->", recipient) message = (message and message.encode('utf8')) or '' if not email.attachments: return message # On-demand attachments from email.parser import Parser msg_obj = Parser().parsestr(message) attachments = json.loads(email.attachments) for attachment in attachments: if attachment.get('fcontent'): continue fid = attachment.get("fid") if fid: fname, fcontent = get_file(fid) attachment.update({ 'fname': fname, 'fcontent': fcontent, 'parent': msg_obj }) attachment.pop("fid", None) add_attachment(**attachment) elif attachment.get("print_format_attachment") == 1: attachment.pop("print_format_attachment", None) print_format_file = frappe.attach_print(**attachment) print_format_file.update({"parent": msg_obj}) add_attachment(**print_format_file) return msg_obj.as_string()
def send_email(to, subject, body): msg = Parser().parsestr( 'From: <*****@*****.**>\n' + 'To: <' + to + '>\n' + 'Subject: ' + subject + '\n' + '\n' + '' + body + '\n') if not DEBUG: s = smtplib.SMTP('localhost') s.sendmail('*****@*****.**', [to], msg.as_string()) s.quit() else: print msg
def do_email(msg_content, ip): # 稍后解析出邮件: msg = Parser().parsestr(msg_content) email_str = msg.as_string() p = ParseEmail(email_str) m = p.parseMailTemplate() text = m.get('html_text', '').strip() if not text: text = m.get('plain_text', '') ip_info = "IP Address {} from the Spamhaus PBL database".format(ip) if text.find(ip_info) > 0: m = re.search(r"Verification/Confirmation Code:\s+(\d+)", text) if m: return m.group(1) return None
def send_email(to, subject, body): msg = Parser().parsestr('From: <*****@*****.**>\n' + 'To: <'+ to + '>\n' + 'Subject: '+ subject + '\n' + '\n' + '' + body + '\n') if not DEBUG: s = smtplib.SMTP('localhost') s.sendmail('*****@*****.**', [to], msg.as_string()) s.quit() else: print msg
def do_email(msg_content, mail_to): # 稍后解析出邮件: msg = Parser().parsestr(msg_content) email_str = msg.as_string() p = parse_email.ParseEmail(email_str) m = p.parseMailTemplate() try: text = html2text.beautifulsoup_html2text( m.get('html_text', '').decode(m.get('html_charset', 'utf-8'), errors='ignore').encode('utf-8')) return do_email_text(text, mail_to) except: return None, None
def send_msg(args): # The Database needs to be open to build Chains and for Mix to encode # messages. with sqlite3.connect(dbkeys()) as conn: conn.text_factory = str # Create a message object, either from file or stdin. if args.filename: with open(args.filename, 'r') as f: msg = Parser().parse(f) else: sys.stdout.write("Type message here. Finish with Ctrl-D.\n") msg = Parser().parsestr(sys.stdin.read()) # Create or override important headers if args.recipient: msg['To'] = args.recipient if args.sender: msg['From'] = args.sender if args.subject: msg['Subject'] = args.subject if 'To' not in msg: sys.stderr.write("Message has no recipient specified.\nUse " "\"--recipient RECIPIENT_ADDRESS\" " "to add one.\n") sys.exit(1) if 'From' not in msg: msg['From'] = config.get('general', 'sender') m = mix.send(conn, msg.as_string(), args.chainstr) if args.stdout: sys.stdout.write(m.text) else: payload = {'base64': m.text} url = '%s/collector.py/msg' % m.send_to_address try: # Send the message to the first hop. r = requests.post(url, data=payload) if r.status_code == requests.codes.ok: sys.stdout.write("Message delivered to %s\n" % m.send_to_address) else: sys.stderr.write("Delivery to %s failed with status " "code: %s.\n" % (url, r.status_code)) except requests.exceptions.ConnectionError: #TODO Mark down remailer statistics. sys.stderr.write("Unable to connect to %s.\n" % m.send_to_address)
def write_reply(self, template, buildlog, args): with open(template, 'r') as fd: substdict = dict(args) substdict['buildlog'] = buildlog substdict['fromaddr'] = self.fromaddr substdict['lintlog'] = 'No log' if self.lintlog: self.dependencies = ['Lintian'] lintfile = os.path.join(self.resultdir, '%s.lintian' % args['package']) if os.path.isfile(lintfile): with open(lintfile, 'r') as lintfd: substdict['lintlog'] = lintfd.read() reply = fd.read() % substdict msg = Parser().parsestr(reply) return msg.as_string()
def write_reply(self, template, buildlog, package): lintianoutput = 'No log' with open(template, 'r') as fd: if self.lintian: lintfile = os.path.join(self.resultdir, '%s.lintian' % package) if os.path.isfile(lintfile): with open(lintfile, 'r') as lintfd: lintianoutput = lintfd.read() params = {'sender': self.sender, 'uploader': self.uploader, 'package': package, 'buildlog': buildlog, 'lintian': lintianoutput} reply = fd.read() % params msg = Parser().parsestr(reply) return msg.as_string().encode('utf-8')
def send_email(cfg, email_body): """Send email.""" try: server = smtplib.SMTP(cfg["smtp-server"], port=cfg["smtp-port"]) server.set_debuglevel(1) to_addresses = EMAIL_SPLIT_RE.split(cfg["destination-emails"].strip()) message = Parser().parsestr(email_body) message["Date"] = formatdate(localtime=True) server.sendmail(cfg["source-email"], to_addresses, message.as_string()) server.quit() return True except (smtplib.SMTPException, socket.error, EnvironmentError) as e: logging.getLogger("%s.Notifications" % __name__).exception(e) return False
def write_reply(self, template, buildlog, package): lintianoutput = 'No log' with open(template, 'r') as fd: if self.lintian: lintfile = os.path.join(self.resultdir, '%s.lintian' % package) if os.path.isfile(lintfile): with open(lintfile, 'r') as lintfd: lintianoutput = lintfd.read() params = { 'sender': self.sender, 'uploader': self.uploader, 'package': package, 'buildlog': buildlog, 'lintian': lintianoutput } reply = fd.read() % params msg = Parser().parsestr(reply) return msg.as_string().encode('utf-8')
def lambda_handler(event, context): for record in event['Records']: bucket = record["s3"]["bucket"]["name"] key = record["s3"]["object"]["key"] obj = s3.Object(bucket, key) raw_contents = obj.get()['Body'].read() msg = Parser(policy=policy.default).parsestr( raw_contents.decode('utf-8')) orig_to = msg['to'] orig_subject = msg['subject'] print('To: ', msg['to']) print('From: ', msg['from']) print('Subject: ', msg['subject']) account = get_account_info(msg['to']) del msg['DKIM-Signature'] del msg['Sender'] del msg['subject'] del msg['Source'] del msg['From'] del msg['Return-Path'] msg['subject'] = "[{}]: {}".format(account.account_id, orig_subject) try: response = ses_client.send_raw_email( RawMessage=dict(Data=msg.as_string()), Destinations=[account.internal_email_address], Source=orig_to) except ClientError as e: print(e.response['Error']['Message']) raise e else: print("Email sent. Message ID: ", response['MessageId']) return { "statusCode": 200, "body": json.dumps(response), }
def send_email(cfg, email_body): """Send email.""" try: server = smtplib.SMTP(cfg["smtp-server"], port=cfg["smtp-port"], timeout=float(cfg["smtp-timeout"])) server.set_debuglevel(1) to_addresses = EMAIL_SPLIT_RE.split(cfg["destination-emails"].strip()) message = Parser().parsestr(email_body) message["Date"] = formatdate(localtime=True) server.sendmail(cfg["source-email"], to_addresses, message.as_string()) server.quit() return True except (smtplib.SMTPException, socket.error, EnvironmentError, socket.timeout, ValueError) as e: logging.getLogger("{0}.Notifications".format(__name__)).exception(e) return False
def testStripLeapHeaders(self): ENC_HEADER = "fake encryption header" SIG_HEADER = "fake signature header" message = Parser().parsestr(self.EMAIL) message.add_header("X-Leap-Encryption", ENC_HEADER) message.add_header("X-Leap-Signature", SIG_HEADER) self.fetcher._add_message_locally = Mock() def check_headers(_): self.assertTrue(self.fetcher._add_message_locally.called, "The message was not added to soledad") _, data = self.fetcher._add_message_locally.call_args[0][0] msg = Parser().parsestr(data) self.assertNotEqual(msg.get('X-Leap-Encryption', ''), ENC_HEADER) self.assertNotEqual(msg.get('X-Leap-Signature', ''), SIG_HEADER) d = self._do_fetch(message.as_string()) d.addCallback(check_headers) return d
def process_message(self, peer, mailfrom, rcpttos, data): # Print the request information sys.stdout.write(u"Receiving message from: %s\n" % str(peer)) sys.stdout.write(u"Message addressed from: %s\n" % str(mailfrom)) sys.stdout.write(u"Message addressed to: %s\n" % str(rcpttos)) sys.stdout.write(u"Message length: %s\n" % str(len(data))) sys.stdout.flush() # Parse the message and remove headers that are offensive to SES msg = Parser().parsestr(data) if 'Errors-To' in msg: del msg['Errors-To'] # Send out via SES try: connection = SESConnection(aws_access_key_id=self.aws_key, aws_secret_access_key=self.aws_secret) connection.send_raw_email(msg.as_string(), source=mailfrom) except BotoServerError, err: sys.stderr.write(str(err)) sys.stdout.flush()
def testExtractOpenPGPHeaderInvalidUrl(self): """ Test the OpenPGP header key extraction """ KEYURL = "https://someotherdomain.com/key.txt" OpenPGP = "id=12345678; url=\"%s\"; preference=signencrypt" % (KEYURL,) message = Parser().parsestr(self.EMAIL) message.add_header("OpenPGP", OpenPGP) self.fetcher._keymanager.fetch_key = Mock() def fetch_key_called(ret): self.assertFalse(self.fetcher._keymanager.fetch_key.called) d = self._create_incoming_email(message.as_string()) d.addCallback( lambda email: self._mock_soledad_get_from_index(fields.JUST_MAIL_IDX, [email])) d.addCallback(lambda _: self.fetcher.fetch()) d.addCallback(fetch_key_called) return d
def cb_action_ACCEPT(module, filepath): log.info(_("Accepting message in %s (by module %s)") % (filepath, module)) log.debug(_("Accepting message in: %r") %(filepath), level=8) # parse message headers message = Parser().parse(open(filepath, 'r'), True) sender = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-From', []))] recipients = [formataddr(x) for x in getaddresses(message.get_all('X-Kolab-To', []))] log.debug(_("recipients: %r") % (recipients)) # delete X-Kolab-* headers del message['X-Kolab-From'] del message['X-Kolab-To'] smtp = smtplib.SMTP("localhost", 10027) if conf.debuglevel > 8: smtp.set_debuglevel(True) try: smtp.sendmail( sender, recipients, # - Make sure we do not send this as binary. # - Second, strip NUL characters - I don't know where they # come from (TODO) # - Third, a character return is inserted somewhere. It # divides the body from the headers - and we don't like (TODO) # @TODO: check if we need Parser().parse() to load the whole message message.as_string() ) except smtplib.SMTPDataError, errmsg: log.error("SMTP Data Error, %r" % (errmsg)) # DEFER pass
def post(self): """ This actually sends out the email when the existing user clicks 'send' """ currentinvitee = self.graph.invitees.index.lookup(\ email=self.get_argument("email")) # check to see if this email has already been invited. # If it has, remove all of its previos occurrences if ( currentinvitee is not None ): for current in currentinvitee: self.graph.invitees.delete(current.eid) #creates an Invitee object with the given email and a generated uuid currentinvitee = self.graph.invitees.create( email=self.get_argument("email"), token=uuid.uuid4().hex) #TODO: Does this need to be more secure? currentuser = self.graph.users.index.lookup(\ userid=self.get_secure_cookie("userid")).next() self.graph.invited.create(currentuser, currentinvitee) ## build the email and send it. SMTP host is localhost for now. s = smtplib.SMTP('localhost') headers = Parser().parsestr('From: <[email protected])\n' 'To: <'+ self.get_argument("email") +'>\n' 'Subject: You have been invited to enclav.es\n' '\n' ## TODO: Write out a better invite email 'Click here to accept the invitation: http://enclav.es/sign-up?token='\ +currentinvitee.token+'\n') s.sendmail(headers['from'],[headers['to']],headers.as_string()) self.redirect("/invite")
def testExtractOpenPGPHeader(self): """ Test the OpenPGP header key extraction """ KEYURL = "https://leap.se/key.txt" OpenPGP = "id=12345678; url=\"%s\"; preference=signencrypt" % (KEYURL,) message = Parser().parsestr(self.EMAIL) message.add_header("OpenPGP", OpenPGP) self.fetcher._keymanager.fetch_key = Mock( return_value=defer.succeed(None)) def fetch_key_called(ret): self.fetcher._keymanager.fetch_key.assert_called_once_with( ADDRESS_2, KEYURL, OpenPGPKey) d = self._create_incoming_email(message.as_string()) d.addCallback( lambda email: self._mock_soledad_get_from_index(fields.JUST_MAIL_IDX, [email])) d.addCallback(lambda _: self.fetcher.fetch()) d.addCallback(fetch_key_called) return d
def walk_domain(domain, path): new_path = os.path.join(path, 'new') email_filenames = os.listdir(new_path) email_count = len(email_filenames) print 'Reading %s, %d emails.' % (domain, email_count) for i, email_filename in enumerate(email_filenames): email_filepath = os.path.join(new_path, email_filename) try: message = Parser().parse(open(email_filepath, 'r')) email = Email() email.domain = domain email.header_from = message['from'] email.header_to = message['to'] email.header_subject = message['subject'] email.header_date = parser.parse(message['date']) email.postgres_filename = email_filename email.original = message.as_string() session.add(email) session.commit() cur_path = os.path.join(path, 'cur') os.rename(email_filepath, os.path.join(cur_path, email_filename)) except Exception, exc: print exc fail_path = os.path.join(path, 'fail') if not os.path.exists(fail_path): os.makedirs(fail_path) os.rename(email_filepath, os.path.join(fail_path, email_filename)) stdout('\r%5d/%5d : %0.2f%%' % (i, email_count, i * 100.0 / email_count))
f = feedparser.parse('http://www.asti.dost.gov.ph/job-opportunities?format=feed&type=rss') #f = feedparser.parse('http://twitrss.me/twitter_user_to_rss/?user=intel') print "Date now in UTC: " print datetime.utcnow() job_items = "" for item in f.entries: publishedDate = parse(item.published) if publishedDate.day == datetime.utcnow().day and publishedDate.month == datetime.utcnow().month: #print item.published #print publishedDate #print item.title #print item.link job_items = job_items + item.title + "\n" + item.link + "\n\n" if job_items != "": print job_items mail_content = Parser().parsestr('From: mail@localhost \n' 'To: [email protected]\n' 'Subject: Test\n' '\n' '%s' % job_items) server = smtplib.SMTP('smtp.sendgrid.net') server.login('scrapy', 'scrapy123') server.sendmail(mail_content['from'], mail_content['to'], mail_content.as_string()) server.quit()
def execute(*args, **kw): if not os.path.isdir(mybasepath): os.makedirs(mybasepath) for stage in ['incoming', 'ACCEPT' ]: if not os.path.isdir(os.path.join(mybasepath, stage)): os.makedirs(os.path.join(mybasepath, stage)) # TODO: Test for correct call. filepath = args[0] if kw.has_key('stage'): log.debug(_("Issuing callback after processing to stage %s") % (kw['stage']), level=8) log.debug(_("Testing cb_action_%s()") % (kw['stage']), level=8) if hasattr(modules, 'cb_action_%s' % (kw['stage'])): log.debug(_("Attempting to execute cb_action_%s()") % (kw['stage']), level=8) exec('modules.cb_action_%s(%r, %r)' % (kw['stage'],'optout',filepath)) return log.debug(_("Executing module footer for %r, %r") % (args, kw), level=8) new_filepath = os.path.join('/var/spool/pykolab/wallace/footer/incoming', os.path.basename(filepath)) os.rename(filepath, new_filepath) filepath = new_filepath # parse message headers # @TODO: make sure we can use True as the 2nd argument here message = Parser().parse(open(filepath, 'r'), True) # Possible footer answers are limited to ACCEPT only answers = [ 'ACCEPT' ] footer = {} footer_html_file = conf.get('wallace', 'footer_html') footer_text_file = conf.get('wallace', 'footer_text') if not os.path.isfile(footer_text_file) and not os.path.isfile(footer_html_file): exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) return if os.path.isfile(footer_text_file): footer['plain'] = open(footer_text_file, 'r').read() if not os.path.isfile(footer_html_file): footer['html'] = '<p>' + self.footer['plain'] + '</p>' else: footer['html'] = open(footer_html_file, 'r').read() if footer['html'] == "": footer['html'] = '<p>' + self.footer['plain'] + '</p>' if footer['plain'] == "" and footer['html'] == "<p></p>": exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) return footer_added = False try: _footer_added = message.get("X-Wallace-Footer") except: pass if _footer_added == "YES": exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', filepath)) return if message.is_multipart(): if message.get_content_type() == "multipart/alternative": log.debug("The message content type is multipart/alternative.") for part in message.walk(): disposition = None try: content_type = part.get_content_type() except: continue try: disposition = part.get("Content-Disposition") except: pass if not disposition == None: continue if content_type == "text/plain": content = part.get_payload() content += "\n\n--\n%s" % (footer['plain']) part.set_payload(content) footer_added = True elif content_type == "text/html": content = part.get_payload() content += "\n<!-- footer appended by Wallace -->\n" content += "\n<html><body><hr />%s</body></html>\n" % (footer['html']) part.set_payload(content) footer_added = True else: # Check the main content-type. if message.get_content_type() == "text/html": content = message.get_payload() content += "\n<!-- footer appended by Wallace -->\n" content += "\n<html><body><hr />%s</body></html>\n" % (footer['html']) message.set_payload(content) footer_added = True else: content = message.get_payload() content += "\n\n--\n%s" % (footer['plain']) message.set_payload(content) footer_added = True if footer_added: log.debug("Footer attached.") message.add_header("X-Wallace-Footer", "YES") (fp, new_filepath) = tempfile.mkstemp(dir="/var/spool/pykolab/wallace/footer/ACCEPT") os.write(fp, message.as_string()) os.close(fp) os.unlink(filepath) exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT','footer', new_filepath))
for msg_id in data[0].split(' '): if msg_id: if get_conf('secrets', 'debug'): print('parsing msg_id=%s' % msg_id) syslog.syslog('parsing msg_id=%s' % msg_id) typ, data = imapclient.fetch(msg_id, '(RFC822)') message = Parser().parsestr(data[0][1]) from_data = message.get('From') to_data = message.get('To') subject = message.get('Subject') if not parseaddr(to_data)[1]: continue dbcursor.execute( 'SELECT support_email FROM vendors WHERE kiosk_email=(%s)', (to_data, )) if dbcursor.rowcount == 0: syslog.syslog("kiosk_email=%s not found" % to_data) continue else: support_email = dbcursor.fetchone().support_email if support_email is None: syslog.syslog("support_email=none") continue else: mailer(message.as_string(), support_email) if __name__ == "__main__": signal.signal(signal.SIGINT, sigint_handler) main()
addr = addr_subj(msg)[0] subj = addr_subj(msg)[1] # Initialize the searchname and searchnumber searchname = "?" searchnumber = "?" if len(subj.split())>0: searchname = subj.split()[0] if len(subj.split())>1: searchnumber = subj.split()[1] # Initialize the searchgrade to check if it will be changed searchgrade = "?" # Search grade, if successful, then change "searchgrade" to the real grade for i in range(student_number): if (searchname == name[i]) and (searchnumber == number[i]) and (addr == corr_addr[i]): searchgrade = grade[i] # If search successfully, then reply if (searchgrade != "?"): send_str = "Your grade is "+searchgrade msg = MIMEText(send_str, 'plain', 'utf-8') msg['subject'] = 'Grade of the middle-term exam' msg['from'] = "Quantum Mechanics B" msg['to'] = addr smtp_server.sendmail(email, [addr], msg.as_string()) # Delete mail directly from the server according to the mail index number: pop3_server.dele(index) pop3_server.quit() #quit pop3 # quit smtp, we don't need it #smtp_server.quit()
def header_check (db, cl, nodeid, new_values) : """ Check header of new messages and determine original customer from that header -- only if sender is the support special account (any account with system status). If send_to_customer flag is set *and* account is not a system account, munge the headers and add X-ROUNDUP-TO and X-ROUNDUP-CC headers. """ send_to_customer = False # Be sure to alway set send_to_customer to False! if 'send_to_customer' in new_values : send_to_customer = new_values ['send_to_customer'] new_values ['send_to_customer'] = False newmsgs = new_values.get ('messages') if not newmsgs : return newmsgs = set (newmsgs) if nodeid : oldmsgs = set (cl.get (nodeid, 'messages')) else : oldmsgs = set () system = db.user_status.lookup ('system') cemail = db.contact_type.lookup ('Email') for msgid in newmsgs.difference (oldmsgs) : msg = db.msg.getnode (msgid) h = None if msg.header : h = Parser ().parsestr (msg.header, headersonly = True) else : h = Message () if db.user.get (msg.author, 'status') == system : frm = fix_emails (h.get_all ('From')) subj = header_utf8 (h.get_all ('Subject') [0]) if ( frm and 'customer' not in new_values and 'emails' not in new_values ) : cc = {} if not nodeid : # use only first 'From' address (there shouldn't be more) rn, mail = getaddresses (frm) [0] # the *to* address in this mail is the support user we # want as a from-address for future mails *to* this user autad = None hto = fix_emails (h.get_all ('To')) if hto : torn, autad = getaddresses (hto) [0] if not autad.startswith ('support') : autad = None c = find_or_create_contact \ (db, mail, rn, frm = autad, subject = subj) cust = new_values ['customer'] = \ db.contact.get (c, 'customer') new_values ['emails'] = [c] else : supi = cl.getnode (nodeid) cust = supi.customer new_values ['emails'] = supi.emails new_values ['cc_emails'] = supi.cc_emails if supi.cc : cc = dict.fromkeys \ (x.strip ().lower () for x in supi.cc.split (',')) # Parse To and CC headers to find more customer email # addresses. Check if these contain the same domain # part as the From. ccs = h.get_all ('CC') or [] tos = h.get_all ('To') or [] if nodeid : tos.extend (frm) cfrm = db.customer.get (cust, 'fromaddress') alltocc = dict.fromkeys (new_values ['emails']) if 'cc_emails' in new_values : alltocc.update (dict.fromkeys (new_values ['cc_emails'])) for addrs, field in ((tos, 'emails'), (ccs, 'cc_emails')) : addrs = fix_emails (addrs) for rn, mail in getaddresses (addrs) : if mail == cfrm : continue c = find_or_create_contact \ (db, mail, rn, customer = cust) if c : if field not in new_values : new_values [field] = [] if c not in alltocc : new_values [field].append (c) alltocc [c] = 1 elif uidFromAddress (db, (rn, mail), create = 0) : # ignore internal addresses pass else : cc [mail.lower ()] = 1 if cc : new_values ['cc'] = ', '.join (cc.keys ()) else : if send_to_customer : mails = [] cc = [] if 'emails' in new_values : mails = new_values ['emails'] elif nodeid : mails = cl.get (nodeid, 'emails') if 'cc_emails' in new_values : mcc = new_values ['cc_emails'] elif nodeid : mcc = cl.get (nodeid, 'cc_emails') mails = mails or [] mcc = mcc or [] mails = (db.contact.get (x, 'contact') for x in mails) mcc = (db.contact.get (x, 'contact') for x in mcc) if 'cc' in new_values : cc = new_values ['cc'] elif nodeid : cc = cl.get (nodeid, 'cc') m = ','.join (mails) mc = ','.join (mcc) if mc : if cc : mc = ','.join ((mc, cc)) else : mc = cc if not m and not mc : raise Reject, \ _ ("Trying to send to customer with empty CC and " "without configured contact-email for customer" ) if m : h.add_header ('X-ROUNDUP-TO', m) if mc : h.add_header ('X-ROUNDUP-CC', mc) if 'bcc' in new_values : bcc = new_values ['bcc'] elif nodeid : bcc = cl.get (nodeid, 'bcc') if bcc : h.add_header ('X-ROUNDUP-BCC', bcc) # Time-Stamp of first reply to customer if not nodeid or not cl.get (nodeid, 'first_reply') : new_values ['first_reply'] = Date ('.') h = h.as_string () if h != '\n' and h != msg.header : db.msg.set (msgid, header = h)
class Message(object): def __init__(self, imap, uid): self.__imap = imap self.__uid = uid self.__cache = {} data = ImapResult(self.__imap.uid('fetch', self.__uid, '(BODY.PEEK[HEADER])')) raw_headers = data[0][1] self.__header_size = len(raw_headers) self.__headers = Parser().parsestr(raw_headers) def print_headers(self): print ' subject: %s' % (self.subject,) print ' from: %s' % (self.froms,) print ' to: %s' % (self.tos,) if self.ccs: print ' cc: %s' % (self.ccs,) print ' date: %s' % (self.date,) # print ' received: %s' % (repr(self.received),) print ' uid: %s' % self.uid def raw_email(self): data = ImapResult(self.__imap.uid('fetch', self.__uid, '(RFC822.PEEK)')) raw_email = data[0][1] return raw_email def raw_body(self, part=None, skip=0, take=0): if part is None: skip = self.__header_size + skip if take == 0: span = '<%d.>' % (skip,) else: span = '<%d.%d>' % (skip, take) if part is None: part = '' else: part = '[%d]' % part expr = '(BODY.PEEK%s%s)' % (part, span) resp = ImapResult(self.__imap.uid('fetch', self.__uid, expr)) response, data = resp[0] reLen = re.compile('.*<(?P<start>\d+)> \{(?P<len>\d+)\}.*') m = reLen.match(response) len = int(m.group('len')) return data #decorator def _cache(func): # pylint: disable=E0213 def _cache_(self, *args, **kwargs): if func.__name__ in self.__cache: return self.__cache[func.__name__] value = func(self, *args, **kwargs) # pylint: disable=E1102 self.__cache[func.__name__] = value return value return _cache_ @property @_cache def subject(self): return self.__headers['subject'].replace('\r\n', ' ').replace('\n\r', ' ').replace('\n', ' ').replace(' ', ' ') @property @_cache def date(self): return dateutil.parser.parse(self.__headers['date']) @property def uid(self): return self.__uid @property @_cache def froms(self): return AddressField(self.__headers, 'from') @property @_cache def tos(self): return AddressField(self.__headers, 'to') @property @_cache def ccs(self): return AddressField(self.__headers, 'cc') @property @_cache def bccs(self): return AddressField(self.__headers, 'bcc') @property @_cache def all_tos(self): return AddressField(self.__headers, ('to', 'cc', 'bcc')) @property @_cache def received(self): t = self.__headers['received'] if t: t = t.split(";", 1)[1] t = t.lstrip() d = dateutil.parser.parse(t) return time.mktime(d.timetuple()) t = self.__headers['date'] if t: d = dateutil.parser.parse(t) return time.mktime(d.timetuple()) print self.__headers.as_string() raise Exception("Can't establish delivery time") def move(self, folder): try: print " --> %s" % folder data = ImapResult(self.__imap.uid('COPY', self.__uid, folder)) data = ImapResult(self.__imap.uid('STORE', self.__uid, '+FLAGS', '(\Deleted)')) self.__imap.expunge() return True except ImapResultError, e: import sys print >> sys.stderr, '! %s' % e
def import_mail_problem_address(self, cr, uid, ids, context=None): ''' Check error message folder and parse name for check error in partner mail address ''' # Utility: def clean(all_mail, mail_sent): ''' Remove not necessary mail ''' res = [] for email in all_mail: if email in mail_sent and email not in res: res.append(email) return res partner_pool = self.pool.get('res.partner') # Read base folder for mailing error_path = self.pool.get('res.company').get_base_local_folder( cr, uid, subfolder='mailing_error', context=context) error_path = os.path.expanduser(error_path) # Read 2 subfolder for mailing: mail_path = os.path.join(error_path, 'mail') csv_path = os.path.join(error_path, 'csv') # Create if not existe 2 subfolder paths os.system('mkdir -p %s' % mail_path) os.system('mkdir -p %s' % csv_path) # --------------------------------------------------------------------- # Read all mail in newsletter # --------------------------------------------------------------------- file_mail = os.path.join(csv_path, 'mail.csv') mail_sent = {} for address in open(file_mail, 'r'): address = address.strip() partner_ids = partner_pool.search(cr, uid, [ ('email', '=', address), ], context=context) # TODO test partner not present mail_sent[address] = partner_ids # --------------------------------------------------------------------- # Read all mail in error mail folder # --------------------------------------------------------------------- for mail_file in [f for f in os.listdir(mail_path)]: mail_fullfile = os.path.join(mail_path, mail_file) message = Parser().parse(open(mail_fullfile, 'r')) # Parse message parameters: subject = message['subject'].replace('\n', '').replace('\r', '') mail_to = message['to'] mail_from = message['from'] # Extract list of mail address in mail text file: all_mail = clean( re.findall(r'[\w\.-]+@[\w\.-]+', message.as_string()), mail_sent, ) for mail_found in all_mail: partner_error_ids = mail_sent.get(mail_found, False) if partner_error_ids: partner_pool.write(cr, uid, partner_error_ids, { 'address_error': True, 'address_error_text': 'Subject: %s\nFrom: %s To: %s' % ( subject, mail_from, mail_to, ) }, context=context) # TODO delete file after update res.partner # Extract mail: #try: # mail_address = mail.split('<')[1].split('>')[0] #except: # mail_address = mail # --------------------------------------------------------------------- # Search customer mail for mark problem # --------------------------------------------------------------------- partner_error_ids = partner_pool.search( cr, uid, [ ('address_error', '=', True), ], context=context) # --------------------------------------------------------------------- # Get list of partner problems and return custom tree list # --------------------------------------------------------------------- model_pool = self.pool.get('ir.model.data') view_id = model_pool.get_object_reference( cr, uid, 'mailing_error', 'view_res_partner_mailing_error')[1] return { 'type': 'ir.actions.act_window', 'name': _('Mailing error'), 'view_type': 'form', 'view_mode': 'tree,form', #'res_id': 1, 'res_model': 'res.partner', 'view_id': view_id, # False 'views': [(view_id, 'tree'), (False, 'form')], 'domain': [('id', 'in', partner_error_ids)], 'context': context, 'target': 'current', # 'new' 'nodestroy': False, }
def prepare_message(email, recipient, recipients_list): message = email.message if not message: return "" # Parse "Email Account" from "Email Sender" email_account = get_outgoing_email_account(raise_exception_not_set=False, sender=email.sender) if frappe.conf.use_ssl and email_account.track_email_status: # Using SSL => Publically available domain => Email Read Reciept Possible message = message.replace("<!--email open check-->", quopri.encodestring('<img src="https://{}/api/method/frappe.core.doctype.communication.email.mark_email_as_seen?name={}"/>'.format(frappe.local.site, email.communication).encode()).decode()) else: # No SSL => No Email Read Reciept message = message.replace("<!--email open check-->", quopri.encodestring("".encode()).decode()) if email.add_unsubscribe_link and email.reference_doctype: # is missing the check for unsubscribe message but will not add as there will be no unsubscribe url unsubscribe_url = get_unsubcribed_url(email.reference_doctype, email.reference_name, recipient, email.unsubscribe_method, email.unsubscribe_params) message = message.replace("<!--unsubscribe url-->", quopri.encodestring(unsubscribe_url.encode()).decode()) if email.expose_recipients == "header": pass else: if email.expose_recipients == "footer": if isinstance(email.show_as_cc, string_types): email.show_as_cc = email.show_as_cc.split(",") email_sent_to = [r.recipient for r in recipients_list] email_sent_cc = ", ".join([e for e in email_sent_to if e in email.show_as_cc]) email_sent_to = ", ".join([e for e in email_sent_to if e not in email.show_as_cc]) if email_sent_cc: email_sent_message = _("This email was sent to {0} and copied to {1}").format(email_sent_to,email_sent_cc) else: email_sent_message = _("This email was sent to {0}").format(email_sent_to) message = message.replace("<!--cc message-->", quopri.encodestring(email_sent_message.encode()).decode()) message = message.replace("<!--recipient-->", recipient) message = (message and message.encode('utf8')) or '' message = safe_decode(message) if not email.attachments: return message # On-demand attachments from email.parser import Parser msg_obj = Parser().parsestr(message) attachments = json.loads(email.attachments) for attachment in attachments: if attachment.get('fcontent'): continue fid = attachment.get("fid") if fid: fname, fcontent = get_file(fid) attachment.update({ 'fname': fname, 'fcontent': fcontent, 'parent': msg_obj }) attachment.pop("fid", None) add_attachment(**attachment) elif attachment.get("print_format_attachment") == 1: attachment.pop("print_format_attachment", None) print_format_file = frappe.attach_print(**attachment) print_format_file.update({"parent": msg_obj}) add_attachment(**print_format_file) return msg_obj.as_string()
msg = Parser().parsestr(msg_content) print_info(msg) file.close() server.close() from_addr = email # to_addr = '*****@*****.**' to_addr = input('To Email address: ') smtp_server = 'smtp.163.com' text = 'Dear' + '\n\n' + u'交大邮件通知,请查收附件。' + '\n\n' + 'best regards' + '\n' + 'Andy Zhang' msg = MIMEMultipart() msg['From'] = _format_addr('Andy Zhang <%s>' % from_addr) msg['To'] = _format_addr('Gmail <%s>' % to_addr) msg['Subject'] = Header(u'交大邮件通知', 'utf-8') msg.attach(MIMEText(text, 'plain', 'utf-8')) with codecs.open('/Users/zhangzhifan/Desktop/mail_log.txt', 'rb', encoding='utf-8') as f: mime = MIMEText(f.read()) mime.add_header('Content-Disposition', 'attachment', filename='mail_log.txt') msg.attach(mime) server = smtplib.SMTP(smtp_server, 25) server.login(from_addr, password) server.sendmail(from_addr, [to_addr], msg.as_string()) server.quit()
import glob import sys from email.parser import Parser import smtplib if __name__ == '__main__': port = int(sys.argv[1]) if len(sys.argv) > 1 else 2025 smtp = smtplib.SMTP("localhost", port) for file in glob.glob('spam/*.txt'): msg = Parser().parse(open(file, 'rb')) smtp.sendmail('*****@*****.**', ['*****@*****.**'], msg.as_string())
def handler(q=False): if q is False: return False results = [] # Decode and parse email request = json.loads(q) # request data is always base 64 byte encoded data = base64.b64decode(request["data"]) message = message_from_bytes(data) # Ensure Content-Transfer-Encoding exists, otherwise headers cannot be parsed if 'Content-Transfer-Encoding' not in message: message['Content-Transfer-Encoding'] = '8-bit' # Double decode to force headers to be re-parsed with proper encoding message = Parser().parsestr(message.as_string()) # FIX: No need to guess encoding, use built in python email class from email.header import make_header for key, val in message.items(): replacement = str(make_header(decode_header(val))) if replacement is not None: message.replace_header(key, replacement) # Extract all header information all_headers = "" for k, v in message.items(): all_headers += "{0}: {1}\n".format(k.strip(), v.strip()) all_headers = all_headers.replace('\\', '') results.append({"values": all_headers, "type": 'email-header'}) # E-Mail MIME Boundry if message.get_boundary(): results.append({"values": message.get_boundary(), "type": 'email-mime-boundary'}) # E-Mail In Reply To if message.get('In-Reply-To'): results.append({"values": message.get('In-Reply-To').strip(), "type": 'email-reply-to'}) # NEW: E-Mail Reply To if message.get('Reply-To'): results.append({"values": message.get('Reply-To').strip(), "type": 'email-reply-to'}) # X-Mailer if message.get('X-Mailer'): results.append({"values": message.get('X-Mailer'), "type": 'email-x-mailer'}) # Thread Index if message.get('Thread-Index'): results.append({"values": message.get('Thread-Index'), "type": 'email-thread-index'}) # Email Message ID if message.get('Message-ID'): results.append({"values": message.get('Message-ID'), "type": 'email-message-id'}) # Subject if message.get('Subject'): subject = re.sub('\r|\n|\t', '', message.get('Subject').strip()) results.append({"values": subject, "type": 'email-subject'}) # Source source = '' if message.get('From'): source = getaddresses(message.get_all('From')) for address in source: results.append({"values": address[1], "type": 'email-src', "comment": "From: {0}".format(address)}) results.append({"values": address[0], "type": 'email-src-display-name', "comment": "From: {0}".format(address)}) # Check other source fields smtp_regex = re.compile(r'smtp\.mailfrom=[^;:]+@[^;:]+(?=[;\s])', re.S) #Old: smtp\.mailfrom=[^;:]+@[^;:]+(?=;)? smtp_match = re.search(smtp_regex, all_headers) if smtp_match: source = smtp_match.group() results.append({"values": source.replace('smtp.mailfrom=',''), "type": 'email-src', "comment": "{0}".format(source)}) envelope_from_regex = re.compile(r'envelope-from.*?>', re.S) envelope_from_match = re.search(envelope_from_regex, all_headers) if envelope_from_match: source = envelope_from_match.group() results.append({"values": parseaddr(source)[1], "type": 'email-src', "comment": "{0}".format(source)}) sender_regex = re.compile(r'sender\s.*?>(?=\))', re.S) sender_match = re.search(sender_regex, all_headers) if sender_match: source = sender_match.group() results.append({"values": parseaddr(source)[1], "type": 'email-src', "comment": "{0}".format(source)}) if message.get('X-Sender'): source = message.get('X-Sender').strip() results.append({"values": source, "type": 'email-src', "comment": "X-Sender"}) if message.get('X-Sender-Id'): source = message.get('X-Sender-Id').strip() results.append({"values": source, "type": 'email-src', "comment": "X-Sender-Id"}) if message.get('X-Auth-ID'): source = message.get('X-Auth-ID').strip() results.append({"values": source, "type": 'email-src', "comment" : "X-Auth-ID"}) # If no source has been identified, try to use Reply To if not source: if message.get('Reply-To'): results.append({"values": parseaddr(message.get('Reply-To').strip())[1], "type": 'email-src', "comment" : "Reply To: {0}".format(message.get('Reply-To'))}) # Return Path return_path = message.get('Return-Path') if return_path: # E-Mail Source results.append({"values": parseaddr(return_path)[1], "type": 'email-src', "comment": "Return Path: {0}".format(return_path)}) # E-Mail Source Name results.append({"values": parseaddr(return_path)[0], "type": 'email-src-display-name', "comment": "Return Path: {0}".format(return_path)}) # Destinations # Split and sort destination header values recipient_headers = ['To', 'Cc', 'Bcc'] for hdr_val in recipient_headers: if message.get(hdr_val): addrs = message.get(hdr_val).split(',') for addr in addrs: # Parse and add destination header values parsed_addr = parseaddr(addr) results.append({"values": parsed_addr[1], "type": "email-dst", "comment": "{0}: {1}".format(hdr_val, addr)}) results.append({"values": parsed_addr[0], "type": "email-dst-display-name", "comment": "{0}: {1}".format(hdr_val, addr)}) # Get E-Mail Targets # Get the addresses that received the email. # As pulled from the Received header received = message.get_all('Received') if received: email_targets = set() for rec in received: try: email_check = re.search("for\s(.*@.*);", rec).group(1) email_check = email_check.strip(' <>') email_targets.add(parseaddr(email_check)[1]) except (AttributeError): continue for tar in email_targets: results.append({"values": tar, "type": "target-email", "comment": "Extracted from email 'Received' header"}) # Check if we were given a configuration config = request.get("config", {}) # Don't be picky about how the user chooses to say yes to these acceptable_config_yes = ['y', 'yes', 'true', 't'] # Do we unzip attachments we find? unzip = config.get("unzip_attachments", None) if (unzip is not None and unzip.lower() in acceptable_config_yes): unzip = True # Do we try to find passwords for protected zip files? zip_pass_crack = config.get("guess_zip_attachment_passwords", None) if (zip_pass_crack is not None and zip_pass_crack.lower() in acceptable_config_yes): zip_pass_crack = True password_list = None # Only want to collect password list once # Do we extract URL's from the email. extract_urls = config.get("extract_urls", None) if (extract_urls is not None and extract_urls.lower() in acceptable_config_yes): extract_urls = True # Get Attachments # Get file names of attachments for part in message.walk(): # FIX: Skip container if part.is_multipart(): continue # FIX: Look for attachment in 'content-disposition' header as 'filename', otherwise check 'name' parameter of 'content-type' header filename = part.get_param('filename', None, 'content-disposition') if not filename: filename=part.get_param('name', None) if filename is not None: # FIX: decode any encoded attachment names -- decode header returns a tuple [(text, encoding), ...] if decode_header(filename)[0][1] is not None: filename = str(decode_header(filename)[0][0].decode(decode_header(filename)[0][1])) filename = re.sub('\r|\n|\t', '', filename.strip()) results.append({"values": filename, "type": 'email-attachment'}) attachment_data = part.get_payload(decode=True) # Base attachment data is default attachment_files = [{"values": filename, "data": base64.b64encode(attachment_data).decode()}] if unzip is True: # Attempt to unzip the attachment and return its files zipped_files = ["doc", "docx", "dot", "dotx", "xls", "xlsx", "xlm", "xla", "xlc", "xlt", "xltx", "xlw", "ppt", "pptx", "pps", "ppsx", "pot", "potx", "potx", "sldx", "odt", "ods", "odp", "odg", "odf", "fodt", "fods", "fodp", "fodg", "ott", "uot"] zipped_filetype = False for ext in zipped_files: if filename.endswith(ext) is True: zipped_filetype = True if zipped_filetype == False: try: attachment_files += get_zipped_contents(filename, attachment_data) except RuntimeError: # File is encrypted with a password if zip_pass_crack is True: if password_list is None: password_list = get_zip_passwords(message) password = test_zip_passwords(attachment_data, password_list) if password is None: # Inform the analyst that we could not crack password attachment_files[0]['comment'] = "Encrypted Zip: Password could not be cracked from message" else: attachment_files[0]['comment'] = """Original Zipped Attachment with Password {0}""".format(password) attachment_files += get_zipped_contents(filename, attachment_data, password=password) except zipfile.BadZipFile: # Attachment is not a zipfile pass for attch_item in attachment_files: attch_item["type"] = 'malware-sample' results.append(attch_item) # FIX: Pull this out of the else statement -- Check email body part for urls if extract_urls is True: charset = get_charset(part, get_charset(message)) urls_unique = [] if part.get_content_type() == 'text/html': url_parser = HTMLURLParser() # FIX: Account for different encoding types in the email body decoded_part = part.get_payload(decode=True).decode(charset, errors='ignore') # Decode Quoted-Printable if part.__getitem__('Content-Transer-Encoding') == 'quoted-printable': import quopri decoded_part = quopri.decodestring(part.get_payload(decode=True).decode(charset, errors='ignore')) # Decode Base64 elif part.__getitem__('Content-Transer-Encoding') == 'base64': decoded_part = base64.b64decode(part.get_payload(decode=True).decode(charset, errors='ignore')) # Parse URLs url_parser.feed(decoded_part) urls = url_parser.urls for url in urls: # FIX: Sometimes url values are 'None' -- skip these if url and url not in urls_unique: urls_unique.append(url) # FIX: Parse urls not contained in text/html elif part.get_content_type() == 'text/plain': decoded_part = part.get_payload(decode=True).decode(charset, errors='ignore') url_regex = re.compile(r"((http|ftp|mailto|telnet|ssh)(s){0,1}\:\/\/[\w|\/|\.|\#|\?|\&|\=|\-|\%]+)+", re.VERBOSE | re.MULTILINE) for match in url_regex.findall(decoded_part): url = match[0] if url not in urls_unique: urls_unique.append(url) # FIX: Append unique urls to results if extract_urls config was set to True if extract_urls is True: url_scheme_pattern = r'^(http|ftp|mailto|telnet|ssh|tel)(s){0,1}\:.*' url_scheme_regex = re.compile(url_scheme_pattern, re.I) # For each URL ensure a path was provided; exclude URLs equal to pound sign for url in urls_unique: if '#' not in url and 'mailto' not in url: url_scheme_match = re.search(url_scheme_regex, url) # Due to a bug with urlparse adding an extra escape for scheme, http:///, scheme must be hardcoded prior to parsing if not url_scheme_match: url = 'http://'+url # Parse pattern in traffic based on path component returned from urlparse; exclude when path is empty or equal to '/' results.append({"values": url, "type": 'url'}) parsed = urlparse(url) if parsed.path and parsed.path != '/': results.append({"values": parsed.path, "type": 'pattern-in-traffic'}) r = {'results': results} return r
# Import the email modules we'll need from email.mime.text import MIMEText textfile = '/tmp/mail.txt' me = '"UPC" <*****@*****.**>' you = '*****@*****.**' # Open a plain text file for reading. For this example, assume that # the text file contains only ASCII characters. message = Parser().parse(open(textfile, 'r')) # fp = open(textfile, 'rb') # # Create a text/plain message # msg = MIMEText(fp.read()) # fp.close() # # me == the sender's email address # # you == the recipient's email address # msg['Subject'] = 'The contents of %s' % textfile # msg['From'] = me # msg['To'] = you # print msg.as_string() # quit() # Send the message via our own SMTP server, but don't include the # envelope header. s = smtplib.SMTP('localhost', 10025) s.sendmail(me, [you], message.as_string()) s.quit()
if tanNrReminder >= tansReminderLength: print '\n\n(i) sent mails for all entries in ' + tanFileReminder break print '(i) processing TAN ' + tans[tanNr].rstrip() + ', looking for ' + tansReminder[tanNrReminder].rstrip() if tans[tanNr] != tansReminder[tanNrReminder]: tanNr += 1 continue # To-Feld in Mailheader einfügen mail.__delitem__('To') mail['To'] = line.rstrip() try: print '(i) preparing and sending mail to: ' + mail['To'] + ' with TAN ' + tans[tanNr].rstrip() mail.set_payload(mail.get_payload().replace(tans[tanNrLastSent], tans[tanNr])) tanNrLastSent = tanNr s.sendmail(mail['From'], line, mail.as_string()) # Fehlerbehandlung except smtplib.SMTPRecipientsRefused: print '\nERROR on sending mail to:' + line.rstrip() +'\n' sys.exit(2) mailCount += 1 print '(i) ... sent! (line ' + str(tanNr+1) + ' in ' + addressFile + ')' # damit wurde eine Mail versendet, also Zähler erhöhen tanNr += 1 tanNrReminder += 1 # Ende
host = config.get("Database","host")) cur = conn.cursor() if config.get("Mailserver","ssl") == "true": print "SSL" mailserver = smtplib.SMTP_SSL(config.get("Mailserver","host"),config.get("Mailserver","port")) else: print "Not-SSL" mailserver = smtplib.SMTP(config.get("Mailserver","host"),config.get("Mailserver","port")) print "Read Standard in now!" email = Parser().parse(sys.stdin) print "End of standard in!" # Main Body! cur.execute('SELECT customer_number, customer_name, correspond_contact_email, correspond_contact_first FROM api.customer WHERE customer_type = %s', (options.cust_type, )) custlist = cur.fetchall() for cust in custlist: (cust_number, cust_name, contact_email, contact_first) = cust print cust email.replace_header('To', contact_email) mytemplate = Template(email.as_string()) print mytemplate.render(cust_name=cust_name, contact_email=contact_email, contact_first=contact_first) # mailserver.sendmail(email['From'],email['To'], email.as_string()) # Clean everything up! mailserver.quit() cur.close() conn.close()
def execute(*args, **kw): if not os.path.isdir(mybasepath): os.makedirs(mybasepath) for stage in ['incoming', 'ACCEPT']: if not os.path.isdir(os.path.join(mybasepath, stage)): os.makedirs(os.path.join(mybasepath, stage)) # TODO: Test for correct call. filepath = args[0] if kw.has_key('stage'): log.debug(_("Issuing callback after processing to stage %s") % (kw['stage']), level=8) log.debug(_("Testing cb_action_%s()") % (kw['stage']), level=8) if hasattr(modules, 'cb_action_%s' % (kw['stage'])): log.debug(_("Attempting to execute cb_action_%s()") % (kw['stage']), level=8) exec('modules.cb_action_%s(%r, %r)' % (kw['stage'], 'gpgencrypt', filepath)) log.debug(_("Executing module gpgencrypt for %r, %r") % (args, kw), level=8) new_filepath = os.path.join( '/var/spool/pykolab/wallace/gpgencrypt/incoming', os.path.basename(filepath)) if not filepath == new_filepath: log.debug("Renaming %r to %r" % (filepath, new_filepath)) os.rename(filepath, new_filepath) filepath = new_filepath # parse message headers # @TODO: make sure we can use True as the 2nd argument here message = Parser().parse(open(filepath, 'r'), True) # Possible gpgencrypt answers are limited to ACCEPT only answers = ['ACCEPT'] # from Mail::GnuPG.is_encrypted # #sub is_encrypted { # my ($self,$entity) = @_; # return 1 # if (($entity->effective_type =~ m!multipart/encrypted!) # || # ($entity->as_string =~ m!^-----BEGIN PGP MESSAGE-----!m)); # return 0; #} message_already_encrypted = False for part in message.walk(): if part.get_content_type() in ["application/pgp-encrypted"]: message_already_encrypted = True log.debug( _("Message is already encrypted (app/pgp-enc content-type)"), level=8) if message.get_content_type() in ["multipart/encrypted"]: message_already_encrypted = True log.debug(_("Message already encrypted by main content-type header"), level=8) if message_already_encrypted: return filepath try: # What are recipient addresses to encrypt to (bitmask)? # 1 - organization key # 2 - envelope to # 4 - to # 8 - cc # 16 - resent-to # 32 - resent-cc encrypt_to_rcpts = conf.get('wallace', 'gpgencrypt_to_rcpts') if encrypt_to_rcpts == None: encrypt_to_rcpts = 14 else: encrypt_to_rcpts = (int)(encrypt_to_rcpts) # Only encrypt to keys that are trusted strict_crypt = conf.get('wallace', 'gpgencrypt_strict') if strict_crypt == None: strict_crypt = False # Organization key ID if encrypt_to_rcpts & 1: encrypt_to_org = conf.get('wallace', 'gpgencrypt_to_org_key') if encrypt_to_org == None and encrypt_to_rcpts & 1: if strict_crypt: log.error( _("Configured to encrypt to a key not configured, and strict policy enabled. Bailing out." )) modules.cb_action_REJECT('gpgencrypt', filepath) else: log.error( _("Configured to encrypt to a key not configured, but continuing anyway (see 'gpgencrypt_strict')." )) else: encrypt_to_org = [] # Bounce the message if encryption fails? force_crypt = conf.get('wallace', 'gpgencrypt_force') if force_crypt == None: force_crypt = False # Retrieve keys from remote server(s) automatically? retrieve_keys = conf.get('wallace', 'gpgencrypt_retrieve_keys') if retrieve_keys == None: retrieve_keys = False if retrieve_keys: gpgserver = conf.get('wallace', 'gpgencrypt_server') if gpgserver == None: gpgserver = 'pgp.mit.edu' encrypt_to = [] if encrypt_to_rcpts & 2: encrypt_to.extend(message.get_all('X-Kolab-To', [])) if encrypt_to_rcpts & 4: encrypt_to.extend(message.get_all('to', [])) if encrypt_to_rcpts & 8: encrypt_to.extend(message.get_all('cc', [])) if encrypt_to_rcpts & 16: encrypt_to.extend(message.get_all('resent-to', [])) if encrypt_to_rcpts & 32: encrypt_to.extend(message.get_all('resent-cc', [])) recipients = [ address for displayname, address in getaddresses(encrypt_to) ] log.debug(_("Recipients: %r") % (recipients)) # Split between recipients we can encrypt for/to, and ones we can not encrypt_rcpts = [] nocrypt_rcpts = [] gpg = gnupg.GPG(gnupghome='/var/lib/kolab/.gnupg', verbose=conf.debuglevel > 8) gpg.encoding = 'utf-8' local_keys = gpg.list_keys() log.debug(_("Current keys: %r") % (local_keys), level=8) for recipient in recipients: key_local = False log.debug(_("Retrieving key for recipient: %r") % (recipient)) for key in local_keys: for address in [ x for x in [ address for displayname, address in getaddresses( key['uids']) ] if x == recipient ]: log.debug(_("Found matching address %r") % (address)) key_local = key['keyid'] if key_local == False: if retrieve_keys: remote_keys = gpg.search_keys(recipient, gpgserver) if len(remote_keys) == 1: for address in [ x for x in [ address for displayname, address in getaddresses(remote_keys[0]['uids']) ] if x == recipient ]: log.debug( _("Found matching address %r in remote keys") % (address)) gpg.recv_keys(gpgserver, remote_keys[0]['keyid']) local_keys = gpg.list_keys() else: nocrypt_rcpts.append(recipient) for key in local_keys: for address in [ x for x in [ address for displayname, address in getaddresses( key['uids']) ] if x == recipient ]: log.debug(_("Found matching address %r") % (address)) key_local = key['keyid'] if not key_local == False: encrypt_rcpts.append(key_local) payload = message.get_payload() #print "payload:", payload if len(encrypt_rcpts) < 1: return filepath if "multipart" in message.get_content_type(): log.debug(_( "Mime Message - we need to build multipart/encrypted structure" ), level=8) msg = message enc_mime_message = pgp_mime(msg, encrypt_rcpts) message = enc_mime_message else: log.debug(_("No Mime Message - encypt plain"), level=8) encrypted_data = gpg.encrypt(payload, encrypt_rcpts, always_trust=True) encrypted_string = str(encrypted_data) message.set_payload(encrypted_string) message.add_header('X-wallace-gpg-encrypted', 'true') (fp, new_filepath) = tempfile.mkstemp( dir="/var/spool/pykolab/wallace/gpgencrypt/ACCEPT") os.write(fp, message.as_string()) os.close(fp) os.unlink(filepath) exec('modules.cb_action_%s(%r, %r)' % ('ACCEPT', 'gpgencrypt', new_filepath)) except Exception, errmsg: log.error(_("An error occurred: %r") % (errmsg)) if conf.debuglevel > 8: import traceback traceback.print_exc()
def processMailFile(fileName): # Open mail mainMsg = Parser().parse(open(fileName)) try: debug(1, "Processing message with Message-ID {}".format(mainMsg['Message-ID'])) except ValueError: debug(1, "Processing message with unknown Message-ID") ######################################################################## # If mail message isn't already multipart, i.e. MIME, message then # we don't do anything with it... ######################################################################## if not mainMsg.is_multipart(): debug(2, "Not a multipart message. Skipping.") return ######################################################################## # Create a lists of senders and recepients! ######################################################################## fromStr = mainMsg['From'] debug(4, "FROM string: {0}".format(fromStr)) fromList = [] if fromStr: fromList = re.findall('<[^ <]+@[^ >,]+>', fromStr) if fromList == []: fromList = re.findall('[^ <]+@[^ >,]+', fromStr) debug(3, "Discovered sender: {0}".format(str(fromList))) toStr = mainMsg['To'] debug(4, "TO string: {0}".format(toStr)) toList = [] if toStr: toList = re.findall('<[^ <]+@[^ >,]+>', toStr) if toList == []: toList = re.findall('[^ <]+@[^ >,]+', toStr) ccStr = mainMsg['Cc'] debug(4, "CC string: {0}".format(ccStr)) ccList = [] if ccStr: ccList = re.findall('<[^ <]+@[^ >,]+>', ccStr) if ccList == []: ccList = re.findall('[^ <]+@[^ >,]+', ccStr) toList.extend(ccList) debug(3, "Discovered recipients: {0}".format(str(toList))) ######################################################################## # Check if this is an internal mail. If so, don't do anything # with a message ######################################################################## try: for mailAddress in toList: mailAddress.index(MY_DOMAIN) debug(1, "Internal mail message. Skipping.") return except ValueError: debug(1, "Found external mail address.") ######################################################################## # Check blacklisted sender. If there is one, just skip further # processing ######################################################################## for mailAddress in toList: for b in SENDER_BLACK_LIST: try: mailAddress.index(b) debug(3, "In From header field found sender {} from the black list".format(b)) debug(2, "Sender in the black list. Stopping.") return except ValueError: pass ######################################################################## # Check white list ######################################################################## if len(SENDER_WHITE_LIST): white_found = False for mailAddress in toList: for w in SENDER_WHITE_LIST: try: mailAddress.index(w) white_found = True debug(3, "In From header field found sender {} from the white list".format(w)) break except ValueError: pass if white_found: break if not white_found: debug(2, "White list specified without sender of the current message in the list. Stopping.") return ######################################################################## # Check blacklisted receiver. If there is one, just skip further # processing ######################################################################## for mailAddress in toList: for b in RECEIVER_BLACK_LIST: try: mailAddress.index(b) debug(3, "In From header field found receiver {} from the black list".format(b)) debug(2, "Receiver in the black list. Stopping.") return except ValueError: pass ######################################################################## # Check if attachment is already there. If so, don't # do anything with it, only replace it with newer version ######################################################################## debug(2, "Checking if attachment already exists") found, changed, newPayload = checkSubparts(mainMsg) if found: if changed: mainMsg.set_payload(newPayload) open(fileName, 'w').write(mainMsg.as_string()) return ######################################################################## # No attachment so recreate a message ######################################################################## debug(3, "No existing attachment version, recreating message to include one") replaced = processMultipartMessage(mainMsg) ######################################################################## # Finally, add the message to the mail, and save new version of the # mail message ######################################################################## if not DRY_RUN: if replaced: debug(2, "Inserting image into mail message.") open(fileName, 'w').write(mainMsg.as_string()) else: debug(3, "Probably old disclaimer without image reference. No image attached!") else: debug(1, "Dry run specified. Message wasn't changed!")
incoming = Parser().parse(sys.stdin, True) frm = incoming['From'] name, addr = parseaddr(frm) if addr.lower() != cfg['main']['notify'].lower(): # Received a message from unrecognized email from modules import smtp mailer = smtp.Mailer(cfg) subject = 'Unauthorized Usage' body = 'An email has been received from unauthorized email address: <%s>\n\n' % addr body += 'Complete original email follows:\n\n' body += incoming.as_string(True) mailer.send_email(subject, body) sys.exit(0) # Extract phone number to send SMS to subject = incoming['Subject'] match = SUBJECT_REGEX.search(subject) if not match: # Try one more time, this time searching "To" header. to = incoming['To'] name, addr = parseaddr(to)
#Import the email modules we'll need from email.parser import Parser import os import sys rootdir = sys.argv[1] print "Date,Name,Phone,Email" with open('fboutput.csv','w') as fo: for rootdir, subFolders, files in os.walk(rootdir): for file in files: filePath = rootdir + '/' + file f = open( filePath, 'r') headers = Parser().parse(f) body = headers.as_string() lines = body.split("\n") for index, line in enumerate(lines): # if "Online:" in line: # print lines[index+1] # fo.write(lines[index+1]+",") # continue if "----------------" in line: print lines[index+2] fo.write(lines[index+2]+",") continue if "Name:" in line: print line fo.write(line+",") continue elif "Email:" in line:
def prepare_message(email, recipient, recipients_list): message = email.message if not message: return "" # Parse "Email Account" from "Email Sender" email_account = get_outgoing_email_account(raise_exception_not_set=False, sender=email.sender) if frappe.conf.use_ssl and email_account.track_email_status: # Using SSL => Publically available domain => Email Read Reciept Possible message = message.replace( "<!--email open check-->", quopri.encodestring( '<img src="https://{}/api/method/frappe.core.doctype.communication.email.mark_email_as_seen?name={}"/>' .format(frappe.local.site, email.communication).encode()).decode()) else: # No SSL => No Email Read Reciept message = message.replace("<!--email open check-->", quopri.encodestring("".encode()).decode()) if email.add_unsubscribe_link and email.reference_doctype: # is missing the check for unsubscribe message but will not add as there will be no unsubscribe url unsubscribe_url = get_unsubcribed_url(email.reference_doctype, email.reference_name, recipient, email.unsubscribe_method, email.unsubscribe_params) message = message.replace( "<!--unsubscribe url-->", quopri.encodestring(unsubscribe_url.encode()).decode()) if email.expose_recipients == "header": pass else: if email.expose_recipients == "footer": if isinstance(email.show_as_cc, string_types): email.show_as_cc = email.show_as_cc.split(",") email_sent_to = [r.recipient for r in recipients_list] email_sent_cc = ", ".join( [e for e in email_sent_to if e in email.show_as_cc]) email_sent_to = ", ".join( [e for e in email_sent_to if e not in email.show_as_cc]) if email_sent_cc: email_sent_message = _( "This email was sent to {0} and copied to {1}").format( email_sent_to, email_sent_cc) else: email_sent_message = _("This email was sent to {0}").format( email_sent_to) message = message.replace( "<!--cc message-->", quopri.encodestring(email_sent_message.encode()).decode()) message = message.replace("<!--recipient-->", recipient) message = (message and message.encode('utf8')) or '' message = safe_decode(message) if PY3: from email.policy import SMTPUTF8 message = Parser(policy=SMTPUTF8).parsestr(message) else: message = Parser().parsestr(message) if email.attachments: # On-demand attachments attachments = json.loads(email.attachments) for attachment in attachments: if attachment.get('fcontent'): continue fid = attachment.get("fid") if fid: _file = frappe.get_doc("File", fid) fcontent = _file.get_content() attachment.update({ 'fname': _file.file_name, 'fcontent': fcontent, 'parent': message }) attachment.pop("fid", None) add_attachment(**attachment) elif attachment.get("print_format_attachment") == 1: attachment.pop("print_format_attachment", None) print_format_file = frappe.attach_print(**attachment) print_format_file.update({"parent": message}) add_attachment(**print_format_file) return safe_encode(message.as_string())
def import_mail_problem_address(self, cr, uid, ids, context=None): ''' Check error message folder and parse name for check error in partner mail address ''' # Utility: def clean(all_mail, mail_sent): ''' Remove not necessary mail ''' res = [] for email in all_mail: if email in mail_sent and email not in res: res.append(email) return res partner_pool = self.pool.get('res.partner') # Read base folder for mailing error_path = self.pool.get('res.company').get_base_local_folder( cr, uid, subfolder='mailing_error', context=context) error_path = os.path.expanduser(error_path) # Read 2 subfolder for mailing: mail_path = os.path.join(error_path, 'mail') csv_path = os.path.join(error_path, 'csv') # Create if not existe 2 subfolder paths os.system('mkdir -p %s' % mail_path) os.system('mkdir -p %s' % csv_path) # --------------------------------------------------------------------- # Read all mail in newsletter # --------------------------------------------------------------------- file_mail = os.path.join(csv_path, 'mail.csv') mail_sent = {} for address in open(file_mail, 'r'): address = address.strip() partner_ids = partner_pool.search(cr, uid, [ ('email', '=', address), ], context=context) # TODO test partner not present mail_sent[address] = partner_ids # --------------------------------------------------------------------- # Read all mail in error mail folder # --------------------------------------------------------------------- for mail_file in [f for f in os.listdir(mail_path)]: mail_fullfile = os.path.join(mail_path, mail_file) message = Parser().parse(open(mail_fullfile, 'r')) # Parse message parameters: subject = message['subject'].replace('\n','').replace('\r','') mail_to = message['to'] mail_from = message['from'] # Extract list of mail address in mail text file: all_mail = clean( re.findall(r'[\w\.-]+@[\w\.-]+', message.as_string()), mail_sent, ) for mail_found in all_mail: partner_error_ids = mail_sent.get(mail_found, False) if partner_error_ids: partner_pool.write(cr, uid, partner_error_ids, { 'address_error': True, 'address_error_text': 'Subject: %s\nFrom: %s To: %s' % ( subject, mail_from, mail_to, ) }, context=context) # TODO delete file after update res.partner # Extract mail: #try: # mail_address = mail.split('<')[1].split('>')[0] #except: # mail_address = mail # --------------------------------------------------------------------- # Search customer mail for mark problem # --------------------------------------------------------------------- partner_error_ids = partner_pool.search(cr, uid, [ ('address_error', '=', True), ], context=context) # --------------------------------------------------------------------- # Get list of partner problems and return custom tree list # --------------------------------------------------------------------- model_pool = self.pool.get('ir.model.data') view_id = model_pool.get_object_reference(cr, uid, 'mailing_error', 'view_res_partner_mailing_error')[1] return { 'type': 'ir.actions.act_window', 'name': _('Mailing error'), 'view_type': 'form', 'view_mode': 'tree,form', #'res_id': 1, 'res_model': 'res.partner', 'view_id': view_id, # False 'views': [(view_id, 'tree'), (False, 'form')], 'domain': [('id', 'in', partner_error_ids)], 'context': context, 'target': 'current', # 'new' 'nodestroy': False, }