def insert_communication(self, raw,account_name): """Create new doc of mailbox and append info retrived from email and the attachments against mailbox""" email = Email(raw) date = datetime.datetime.strptime(email.date,'%Y-%m-%d %H:%M:%S') final_recipients=self.make_listof_recipients(email.mail.get("To")) if email.mail.get("Cc"): final_cc=self.make_listof_recipients(email.mail.get("Cc")) else: final_cc='' mailbox = frappe.get_doc({ "doctype": "Mailbox", "subject": email.subject, "content": email.content, "sender_full_name": email.from_real_name, "sender": email.from_email, "email_account": self.name, "user":self.user, "recipient": final_recipients, "recipients_name":account_name, "cc":final_cc, "date_time":date }) #self.set_thread(communication, email) mailbox.insert(ignore_permissions = 1) # save attachments email.save_attachments_in_doc(mailbox) mailbox.check_contact_exists() mailbox.save()
def insert_communication(self, raw): email = Email(raw) communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.insert(ignore_permissions=1) # save attachments email.save_attachments_in_doc(communication) if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) # notify all participants of this thread # convert content to HTML - by default text parts of replies are used. communication.content = markdown2.markdown(communication.content) communication.notify(attachments=email.attachments, except_recipient=True)
def insert_communication(self, raw): email = Email(raw) if email.from_email == self.email_id: # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again raise SentEmailInInbox communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.insert(ignore_permissions = 1) # save attachments communication._attachments = email.save_attachments_in_doc(communication) if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) # notify all participants of this thread # convert content to HTML - by default text parts of replies are used. communication.content = markdown2.markdown(communication.content) return communication
def insert_communication(self, raw): email = Email(raw) communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.insert(ignore_permissions = 1) # save attachments email.save_attachments_in_doc(communication) if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) # notify all participants of this thread # convert content to HTML - by default text parts of replies are used. communication.content = markdown2.markdown(communication.content) communication.notify(attachments=email.attachments, except_recipient = True)
def insert_communication(self, raw): email = Email(raw) if email.from_email == self.email_id: # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again raise SentEmailInInbox communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, 'text_content': email.text_content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.flags.in_receive = True communication.insert(ignore_permissions = 1) # save attachments communication._attachments = email.save_attachments_in_doc(communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace("cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication
def insert_communication(self, raw): email = Email(raw) if email.from_email == self.email_id: # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again raise SentEmailInInbox communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.flags.in_receive = True communication.insert(ignore_permissions=1) # save attachments communication._attachments = email.save_attachments_in_doc( communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace( "cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication
def receive(self, test_mails=None): """Called by scheduler to receive emails from this EMail account using POP3.""" if self.enable_incoming: if frappe.local.flags.in_test: incoming_mails = test_mails else: pop3 = self.get_pop3() incoming_mails = pop3.get_messages() for raw in incoming_mails: email = Email(raw) communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.insert(ignore_permissions=1) # save attachments email.save_attachments_in_doc(communication) if self.enable_auto_reply: self.send_auto_reply(communication) # notify all participants of this thread # convert content to HTML - by default text parts of replies are used. communication.content = markdown2.markdown( communication.content) communication.notify(communication.get_email(), except_sender=True)
def test_handle_bad_emails(self): mail_content = self.get_test_mail(fname="incoming-1.raw") message_id = Email(mail_content).mail.get('Message-ID') email_account = frappe.get_doc("Email Account", "_Test Email Account 1") email_account.handle_bad_emails(uid=-1, raw=mail_content, reason="Testing") self.assertTrue( frappe.db.get_value("Unhandled Email", {'message_id': message_id}))
def insert_communication(self, raw): email = Email(raw) date = datetime.datetime.strptime(email.date,'%Y-%m-%d %H:%M:%S').strftime('%d-%m-%Y %H:%M:%S') communication = frappe.get_doc({ "doctype": "Inbox", "subject": email.subject, "content": email.content, "sender_full_name": email.from_real_name, "from": email.from_email, "email_account": self.name, "user":self.user, "date_time":date }) #self.set_thread(communication, email) communication.insert(ignore_permissions = 1) #communication.submit() # save attachments email.save_attachments_in_doc(communication)
def insert_communication(self, raw): email = Email(raw) if email.from_email == self.email_id: # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again raise SentEmailInInbox communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email" }) self.set_thread(communication, email) communication.insert(ignore_permissions=1) # save attachments communication._attachments = email.save_attachments_in_doc( communication) if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) # notify all participants of this thread # convert content to HTML - by default text parts of replies are used. communication.content = markdown2.markdown(communication.content) return communication
def test_8bit_utf_8_decoding(self): text_content_bytes = b"\xed\x95\x9c\xea\xb8\x80\xe1\xa5\xa1\xe2\x95\xa5\xe0\xba\xaa\xe0\xa4\x8f" text_content = text_content_bytes.decode('utf-8') content_bytes = b"""MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit From: [email protected] Reply-To: [email protected] """ + text_content_bytes mail = Email(content_bytes) self.assertEqual(mail.text_content, text_content)
def insert_communication(self, raw): email = Email(raw) date = datetime.datetime.strptime(email.date,'%Y-%m-%d %H:%M:%S') communication = frappe.get_doc({ "doctype": "Inbox", "subject": email.subject, "content": email.content, "sender_full_name": email.from_real_name, "sender": email.from_email, "email_account": self.name, "user":self.user, "recipients": email.mail.get("To"), "date_time":date }) #self.set_thread(communication, email) communication.insert(ignore_permissions = 1) # save attachments email.save_attachments_in_doc(communication) communication.check_contact_exists() communication.save()
def test_mail_exist_validation(self): """Do not create communication record if the mail is already downloaded into the system. """ mail_content = self.get_test_mail(fname="incoming-1.raw") message_id = Email(mail_content).message_id # Create new communication record in DB communication = self.new_communication(message_id=message_id) email_account = frappe.get_doc("Email Account", "_Test Email Account 1") inbound_mail = InboundMail(mail_content, email_account, 12345, 1) new_communiction = inbound_mail.process() # Make sure that uid is changed to new uid self.assertEqual(new_communiction.uid, 12345) self.assertEqual(communication.name, new_communiction.name)
def insert_communication(self, msg, args={}): if isinstance(msg, list): raw, uid, seen = msg else: raw = msg uid = -1 seen = 0 if args.get("uid", -1): uid = args.get("uid", -1) if args.get("seen", 0): seen = args.get("seen", 0) email = Email(raw) if email.from_email == self.email_id and not email.mail.get( "Reply-To"): # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again # dont count emails sent by the system get those raise SentEmailInInbox if email.message_id: names = frappe.db.sql( """select distinct name from tabCommunication where message_id='{message_id}' order by creation desc limit 1""".format(message_id=email.message_id), as_dict=True) if names: name = names[0].get("name") # email is already available update communication uid instead communication = frappe.get_doc("Communication", name) communication.uid = uid communication.save(ignore_permissions=True) communication._attachments = [] return communication communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, 'text_content': email.text_content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email", "uid": int(uid or -1), "message_id": email.message_id, "communication_date": email.date, "has_attachment": 1 if email.attachments else 0, "seen": seen or 0 }) self.set_thread(communication, email) if communication.seen: # get email account user and set communication as seen users = frappe.get_all("User Email", filters={"email_account": self.name}, fields=["parent"]) users = list(set([user.get("parent") for user in users])) communication._seen = json.dumps(users) communication.flags.in_receive = True communication.insert(ignore_permissions=1) # save attachments communication._attachments = email.save_attachments_in_doc( communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace( "cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication
def insert_communication(self, msg, args={}): if isinstance(msg, list): raw, uid, seen = msg else: raw = msg uid = -1 seen = 0 if args.get("uid", -1): uid = args.get("uid", -1) if args.get("seen", 0): seen = args.get("seen", 0) email = Email(raw) if email.from_email == self.email_id and not email.mail.get("Reply-To"): # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again # dont count emails sent by the system get those if frappe.flags.in_test: print('WARN: Cannot pull email. Sender sames as recipient inbox') raise SentEmailInInbox if email.message_id: names = frappe.db.sql("""select distinct name from tabCommunication where message_id='{message_id}' order by creation desc limit 1""".format( message_id=email.message_id ), as_dict=True) if names: name = names[0].get("name") # email is already available update communication uid instead frappe.db.set_value("Communication", name, "uid", uid, update_modified=False) return communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, 'text_content': email.text_content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email", "uid": int(uid or -1), "message_id": email.message_id, "communication_date": email.date, "has_attachment": 1 if email.attachments else 0, "seen": seen or 0 }) self.set_thread(communication, email) if communication.seen: # get email account user and set communication as seen users = frappe.get_all("User Email", filters={ "email_account": self.name }, fields=["parent"]) users = list(set([ user.get("parent") for user in users ])) communication._seen = json.dumps(users) communication.flags.in_receive = True communication.insert(ignore_permissions = 1) # save attachments communication._attachments = email.save_attachments_in_doc(communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace("cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication
def insert_communication(self, msg, args=None): if isinstance(msg, list): raw, uid, seen = msg else: raw = msg uid = -1 seen = 0 if isinstance(args, dict): if args.get("uid", -1): uid = args.get("uid", -1) if args.get("seen", 0): seen = args.get("seen", 0) email = Email(raw) if email.from_email == self.email_id and not email.mail.get( "Reply-To"): # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again # dont count emails sent by the system get those if frappe.flags.in_test: print( 'WARN: Cannot pull email. Sender sames as recipient inbox') raise SentEmailInInbox if email.message_id: # https://stackoverflow.com/a/18367248 names = frappe.db.sql( """SELECT DISTINCT `name`, `creation` FROM `tabCommunication` WHERE `message_id`='{message_id}' ORDER BY `creation` DESC LIMIT 1""".format(message_id=email.message_id), as_dict=True) if names: name = names[0].get("name") # email is already available update communication uid instead frappe.db.set_value("Communication", name, "uid", uid, update_modified=False) return frappe.get_doc("Communication", name) if email.content_type == 'text/html': email.content = clean_email_html(email.content) communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, 'text_content': email.text_content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.mail.get("To"), "cc": email.mail.get("CC"), "email_account": self.name, "communication_medium": "Email", "uid": int(uid or -1), "message_id": email.message_id, "communication_date": email.date, "has_attachment": 1 if email.attachments else 0, "seen": seen or 0 }) self.set_thread(communication, email) if communication.seen: # get email account user and set communication as seen users = frappe.get_all("User Email", filters={"email_account": self.name}, fields=["parent"]) users = list(set([user.get("parent") for user in users])) communication._seen = json.dumps(users) communication.flags.in_receive = True communication.insert(ignore_permissions=True) # save attachments communication._attachments = email.save_attachments_in_doc( communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace( "cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication
def insert_communication(self, msg): if isinstance(msg,list): raw, uid, seen = msg else: raw = msg seen = uid = None email = Email(raw) if email.from_email == self.email_id and not email.mail.get("Reply-To"): # gmail shows sent emails in inbox # and we don't want emails sent by us to be pulled back into the system again # dont count emails sent by the system get those raise SentEmailInInbox communication = frappe.get_doc({ "doctype": "Communication", "subject": email.subject, "content": email.content, "sent_or_received": "Received", "sender_full_name": email.from_real_name, "sender": email.from_email, "recipients": email.To, "cc": email.CC, "email_account": self.name, "communication_medium": "Email", "uid":uid, "message_id":email.message_id, "communication_date":email.date, "has_attachment": 1 if email.attachments else 0, "seen":seen, "unique_id":email.unique_id }) self.set_thread(communication, email) if not self.no_remaining == '0': communication.unread_notification_sent = 1 communication.flags.in_receive = True communication.insert(ignore_permissions = 1) # save attachments communication._attachments = email.save_attachments_in_doc(communication) # replace inline images dirty = False for file in communication._attachments: if file.name in email.cid_map and email.cid_map[file.name]: dirty = True email.content = email.content.replace("cid:{0}".format(email.cid_map[file.name]), file.file_url) if dirty: # not sure if using save() will trigger anything communication.db_set("content", sanitize_html(email.content)) # notify all participants of this thread if self.enable_auto_reply and getattr(communication, "is_first", False): self.send_auto_reply(communication, email) return communication