Skip to content

Commit

Permalink
feat(example): added email_report example (+ improvements to working_…
Browse files Browse the repository at this point in the history
…hours example)
  • Loading branch information
ErikBjare committed Jan 5, 2022
1 parent b9024b1 commit 2cb09e7
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -6,3 +6,4 @@ dist
*.swp
.*cache
*.json
secret.env
97 changes: 97 additions & 0 deletions examples/email_report.py
@@ -0,0 +1,97 @@
"""
Sends an email with a summary report (WIP)
For now, it just sends stdin.
In the future, it will generate a pretty email and send that.
Requires that an SMTP server is configured through environment variables.
Example usage:
$ env OUTPUT_HTML=true python3 examples/working_hours.py | python3 examples/email_report.py
"""

import smtplib
import os
import sys
from dataclasses import dataclass
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart


@dataclass
class Recipient:
name: str
email: str


def create_msg(
sender: Recipient,
receiver: Recipient,
subject: str,
text: str,
html=None,
) -> MIMEMultipart:
"""Based on https://stackoverflow.com/a/882770/965332"""
msg = MIMEMultipart("alternative")
msg["Subject"] = subject
msg["From"] = sender.email
msg["To"] = receiver.email

# Record the MIME types of both parts - text/plain and text/html.
# Also attach parts into message container.
# According to RFC 2046, the last part of a multipart message, in this case
# the HTML message, is best and preferred.
msg.attach(MIMEText(text, "plain"))
if html:
msg.attach(MIMEText(html, "html"))

return msg


def main(read_stdin=True) -> None:
smtp_server = os.environ["SMTP_SERVER"].strip()
smtp_username = os.environ["SMTP_USERNAME"].strip()
smtp_password = os.environ["SMTP_PASSWORD"].strip()

assert smtp_server, "Enviroment variable SMTP_SERVER not set"
assert smtp_username, "Enviroment variable SMTP_USERNAME not set"
assert smtp_password, "Enviroment variable SMTP_PASSWORD not set"

sender = Recipient("ActivityWatch (automated script)", "noreply@activitywatch.net")
receiver = Recipient("Erik Bjäreholt", "erik.bjareholt@gmail.com")

if read_stdin:
# Accepts input from stdin
text = sys.stdin.read()
else:
text = "Just a test. ActivityWatch stats will go here."

text = text.replace("\n\n", "<hr>")
# text = text.replace("\n\n", "<br>")
# Create the body of the message (a plain-text and an HTML version).
html = f"""\
<html>
<head></head>
<body>
<p>{text}</p>
</body>
</html>
"""

subject = "Example report from aw-client"
msg = create_msg(sender, receiver, subject, text, html)

try:
with smtplib.SMTP_SSL(smtp_server, 465) as smtp:
smtp.login(smtp_username, smtp_password)
smtp.send_message(msg)
smtp.quit()
print("Successfully sent email")
except smtplib.SMTPException as e:
print("Error: unable to send email")
print(e)


if __name__ == "__main__":
main()
19 changes: 15 additions & 4 deletions examples/working_hours.py
@@ -1,6 +1,13 @@
"""
Script that computes how many hours was spent in a regex-specified "work" category for each day in a given month.
Also saves the matching work-events to a JSON file (for auditing purposes).
"""

import json
import re
from datetime import datetime, timedelta, timezone, time
import os
from datetime import datetime, timedelta, time
from typing import List, Tuple, Dict

from tabulate import tabulate
Expand All @@ -10,6 +17,10 @@
from aw_transform import flood


EXAMPLE_REGEX = r"activitywatch|algobit|defiarb|github.com"
OUTPUT_HTML = os.environ.get("OUTPUT_HTML", "").lower() == "true"


def _pretty_timedelta(td: timedelta) -> str:
s = str(td)
s = re.sub(r"^(0+[:]?)+", "", s)
Expand All @@ -35,7 +46,7 @@ def generous_approx(events: List[dict], max_break: float) -> timedelta:
)


def query():
def query(regex: str = EXAMPLE_REGEX, save=True):
print("Querying events...")
td1d = timedelta(days=1)
day_offset = timedelta(hours=4)
Expand All @@ -53,7 +64,7 @@ def query():
["Work"],
{
"type": "regex",
"regex": r"activitywatch|algobit|defiarb|github.com",
"regex": regex,
"ignore_case": True,
},
)
Expand All @@ -80,7 +91,6 @@ def query():
timeperiods, res, break_time, {"category_rule": categories[0][1]["regex"]}
)

save = True
if save:
fn = "working_hours_events.json"
with open(fn, "w") as f:
Expand Down Expand Up @@ -110,6 +120,7 @@ def _print(timeperiods, res, break_time, params: dict):
"left",
"right",
),
tablefmt="html" if OUTPUT_HTML else "simple",
)
)

Expand Down

0 comments on commit 2cb09e7

Please sign in to comment.