Commit 5fea189d authored by Eelco van der Wel's avatar Eelco van der Wel :speech_balloon:
Browse files

update test

parent aa04d786
Pipeline #4630 passed with stage
in 1 minute and 39 seconds
Showing with 12 additions and 9 deletions
+12 -9
%% Cell type:code id:6b1cf025 tags:
``` python
%load_ext autoreload
%autoreload 2
# default_exp smtp_client
```
%% Cell type:code id:18736d78 tags:
``` python
# export
import threading
import smtplib
from gmail_importer.schema import EmailMessage
import email
import time
from typing import List
from datetime import datetime
from gmail_importer.settings import *
from gmail_importer.utils import get_username_password
```
%% Cell type:code id:2e3461c9 tags:
``` python
# export
class GmailSMTPClient:
def __init__(
self,
username: str,
password: str,
host: str = GMAIL_SMTP_HOST,
port: str = GMAIL_SMTP_PORT,
from_addr: str = None,
):
self.from_addr = from_addr if from_addr else username
self.host = host
self.port = port
self.username = username
self.password = password
self.setup()
def setup(self):
self.smtp_client = smtplib.SMTP_SSL(host=self.host, port=self.port)
self.smtp_client.login(self.username, self.password)
def send_mail(
self,
body: str,
subject: str = None,
to: List[str] = None,
cc: List[str] = None,
bcc: List[str] = None,
prev_message: EmailMessage = None,
reply_to: List[str] = None,
) -> bool:
"""
Formats and sends an email over SMTP.
"""
recipients = []
if to:
recipients.extend(to)
if cc:
recipients.extend(cc)
if bcc:
recipients.extend(bcc)
if not len(recipients):
return False
email_str = self.format_mail(
body=body,
subject=subject,
to=to,
cc=cc,
bcc=bcc,
prev_message=prev_message,
reply_to=reply_to,
)
self._send_mail(email_str, recipients)
return True
def _send_mail(self, msg: email.message.EmailMessage, recipients: List[str]):
self.smtp_client.sendmail(
from_addr=self.from_addr, to_addrs=recipients, msg=msg
)
def format_mail(
self,
body: str,
subject: str = None,
to: List[str] = None,
cc: List[str] = None,
bcc: List[str] = None,
prev_message: EmailMessage = None,
reply_to: List[str] = None,
):
"""
Format an email for SMTP.
Note: In order to reply to a gmail thread, subject should be None (inferred from prev_message).
"""
msg = email.message.EmailMessage()
if subject:
msg["Subject"] = subject
elif prev_message is not None and prev_message.subject:
prev_subject = prev_message.subject
if not prev_subject.startswith("Re:"):
prev_subject = "Re: " + prev_subject
msg["Subject"] = prev_subject
else:
raise ValueError("Could not format message, no subject defined")
msg["From"] = self.from_addr
if to:
to_str = ", ".join(to)
msg.add_header("To", to_str)
if cc:
cc_str = ", ".join(cc)
msg.add_header("CC", cc_str)
if bcc:
bcc_str = ", ".join(bcc)
msg.add_header("BCC", bcc_str)
if reply_to:
reply_to_str = ", ".join(reply_to)
msg.add_header("Reply-To", reply_to_str)
if prev_message is not None:
msg.add_header("In-Reply-To", prev_message.externalId)
msg.add_header("References", prev_message.externalId)
msg.set_content(body)
return msg.as_string()
```
%% Cell type:code id:0dd4d347 tags:
``` python
# export
def send_mails_from_pod(client, send_message_method, verbose=True):
# all messages that arent older than 5 seconds, with service gmail and toSend status
query_time = int(datetime.now().timestamp() * 1000) - 5000
msgs_to_send = client.search({
"type": "EmailMessage",
"dateServerModified>=": query_time,
"sendStatus": "toSend",
"service": SERVICE_NAME
})
for msg in msgs_to_send:
if verbose:
print("Sending message...")
try:
to = [a.externalId for a in msg.receiver if a.externalId is not None]
cc = [a.externalId for a in msg.cc if a.externalId is not None]
bcc = [a.externalId for a in msg.bcc if a.externalId is not None]
reply_to = [a.externalId for a in msg.replyTo if a.externalId is not None]
if not (len(to) or len(cc) or len(bcc)):
raise ValueError(f"Could not send email, no receivers defined.")
prev_message = None
if len(msg.previous_message):
prev_message = msg.previous_message[0]
success = send_message_method(
body=msg.content,
subject=msg.subject,
to=to,
cc=cc,
bcc=bcc,
prev_message=prev_message,
reply_to=reply_to,
)
if success:
msg.sendStatus = "sent"
msg.update(client)
if verbose:
print("message sent")
else:
raise RuntimeError
except Exception as e:
print(f"failed to send message:\n{e}")
msg.sendStatus = "sendFailed"
msg.update(client)
def send_mail_listener(client, send_mail_method, verbose=True, interval=5):
if verbose:
print("Send Message listener started")
while threading.main_thread().is_alive():
time.sleep(interval)
send_mails_from_pod(client, send_mail_method, verbose=verbose)
```
%% Cell type:code id:8ea7758c tags:
``` python
# hide
# skip
from pymemri.pod.client import PodClient
from pymemri.data.schema import Account
from pymemri.data.itembase import Edge
```
%% Cell type:code id:daa05cee tags:
``` python
# hide
# skip
username, password = get_username_password()
```
%% Cell type:code id:5acf3f00 tags:
``` python
# hide
# skip
client = PodClient()
client = PodClient.from_local_keys()
client.add_to_schema(Account, EmailMessage)
body = """
Sed consequat scelerisque ex. Nulla facilisi. Duis pellentesque felis at aliquet bibendum. Interdum et malesuada fames ac ante ipsum primis in faucibus. Suspendisse potenti. Pellentesque finibus tellus at purus tincidunt vestibulum sit amet ut ex. Mauris hendrerit nunc semper dapibus facilisis. Aenean tincidunt viverra dui in volutpat. Integer interdum in ex sit amet pharetra. Nam purus dolor, dictum eget varius sed, maximus sed justo. Pellentesque nisl felis, congue sit amet condimentum vitae, malesuada in velit. Donec quis tincidunt quam.
This is a test
Sent with Memri Gmail plugin!
"""
receiver_email = "fake@email.com"
receiver = Account(externalId=receiver_email)
bcc = Account(externalId=username)
prev_message = EmailMessage(
externalId="<6182886b.1c69fb81.4d229.4b46@mx.google.com>",
subject="new thread"
)
mail_to_send = EmailMessage(
content=body,
subject=None,
sendStatus="toSend",
service=SERVICE_NAME
)
edges = [
Edge(mail_to_send, prev_message, "previous_message"),
Edge(mail_to_send, receiver, "receiver"),
Edge(mail_to_send, bcc, "bcc")
]
client.bulk_action(
create_items = [mail_to_send, prev_message, receiver, bcc],
create_edges = edges
)
```
%% Output
reading database_key from /home/eelco/.pymemri/pod_keys/keys.json
reading owner_key from /home/eelco/.pymemri/pod_keys/keys.json
BULK: Writing 7/7 items/edges
Completed Bulk action, written 7 items/edges
True
%% Cell type:code id:1177c90e tags:
``` python
# hide
# skip
query_time = int(datetime.now().timestamp() * 1000) - 5000
msgs_to_send = client.search(
{"type": "EmailMessage",
"dateServerModified>=": query_time,
"sendStatus": "toSend",
"service": SERVICE_NAME})
msgs_to_send
```
%% Output
[EmailMessage (#d3d91ef1a69645ccaa9e46c8cfb80693)]
%% Cell type:code id:e427b672 tags:
``` python
# hide
# skip
smtp_client = GmailSMTPClient(username, password)
send_message_test(client, smtp_client.send_mail)
```
%% Cell type:code id:d138963f tags:
``` python
# hide
from nbdev.export import *
notebook2script()
```
%% Output
Converted authenticator.ipynb.
Converted gmailimporter.ipynb.
Converted imap_client.ipynb.
Converted index.ipynb.
Converted pod big query.ipynb.
Converted schema.ipynb.
Converted settings.ipynb.
Converted smtp_client.ipynb.
Converted utils.ipynb.
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment