Skip to content

Commit

Permalink
add: sending email logic and config
Browse files Browse the repository at this point in the history
  • Loading branch information
adnene-guessoum committed Dec 22, 2024
1 parent 2a2e211 commit 8c01e4b
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 9 deletions.
10 changes: 9 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
# example of .env file / env variable needed
# example of .env file / env variables needed

PERSONAL_GITHUB_USERNAME = "your_github_username"
PERSONAL_GITHUB_TOKEN = "your_github_token" # you can create a token from "https://github.com/settings/apps"

# the person you want to follow
TARGET_GITHUB_USERNAME = "target_username"

# email configuration. see here for some help if you use gmail: https://support.google.com/a/answer/176600?hl=fr
SMTP_SERVER = "smtp.gmail.com" # for using gmail server
SMTP_PORT = 465 # for SSL, gmail uses 465

EMAIL_SENDER = "" # your email
EMAIL_RECIPIENT = "" # the email of the person you want to send the email to
EMAIL_PASSWORD = "" # your email password, eventually an app password if you use gmail and have 2FA enabled
41 changes: 39 additions & 2 deletions script/panopticron.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
import datetime
import logging
import os
import smtplib
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from urllib.parse import urljoin

import requests
Expand All @@ -13,6 +16,12 @@
PERSONAL_GITHUB_TOKEN = os.getenv("PERSONAL_GITHUB_TOKEN")
TARGET_GITHUB_USERNAME = os.getenv("TARGET_GITHUB_USERNAME")

SMTP_SERVER = os.getenv("SMTP_SERVER")
SMTP_PORT = os.getenv("SMTP_PORT")
EMAIL_SENDER = os.getenv("EMAIL_SENDER")
EMAIL_PASSWORD = os.getenv("EMAIL_PASSWORD")
EMAIL_RECIPIENT = os.getenv("EMAIL_RECIPIENT")


def get_user_activity(username):
"""request target user's activity from GitHub API based on username."""
Expand Down Expand Up @@ -45,7 +54,8 @@ def check_sanity_github_api_response(response, username):

if not bool(response.json()): # empty response
logger.error("No data found for %s", username)
logger.info(
logger.warning(
"No email will be sent. Exiting script..."
"Check if the username is correct. %s"
"Otherwise, check the GitHub API documentation for more information : "
"https://docs.github.com/rest",
Expand All @@ -59,6 +69,9 @@ def check_sanity_github_api_response(response, username):
def filter_last_24_hours_activity(user_activity):
"""extract relevant info from response"""

if not user_activity:
return None

today = datetime.datetime.now(datetime.timezone.utc)
user_activity_last_24_hours = []
for event in user_activity:
Expand All @@ -83,9 +96,33 @@ def filter_last_24_hours_activity(user_activity):
return user_activity_last_24_hours


def send_email(user_activity_last_24_hours):
"""send email with the extracted info"""

if not user_activity_last_24_hours:
return

content = "".join(user_activity_last_24_hours)

email = MIMEMultipart()
email["From"] = EMAIL_SENDER
email["To"] = EMAIL_RECIPIENT
email["Subject"] = f"Last 24H GitHub Activity from {TARGET_GITHUB_USERNAME}"
email.attach(MIMEText(content, "plain"))

with smtplib.SMTP_SSL(host=SMTP_SERVER, port=SMTP_PORT) as server:
server.login(EMAIL_SENDER, EMAIL_PASSWORD)
server.send_message(email)
logger.info("Email sent successfully: %s", email["Subject"])

return


def main(username):
"""main function when running the script"""
return username
user_activity = get_user_activity(username)
user_activity_last_24_hours = filter_last_24_hours_activity(user_activity)
send_email(user_activity_last_24_hours)


if __name__ == "__main__":
Expand Down
20 changes: 14 additions & 6 deletions tests/test_panopticron.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,19 +50,27 @@ def get_user_activity():


class TestPanopticron:
def test_main(self):
result = panopticron.main(TARGET_GITHUB_USERNAME)
assert result == TARGET_GITHUB_USERNAME
def test_main_wrong_target_username(self, caplog):
panopticron.main(TARGET_GITHUB_USERNAME)
capture_log = caplog.text
assert f"No data found for {TARGET_GITHUB_USERNAME}" in capture_log
assert "No email will be sent. Exiting script..." in capture_log
assert "Check if the username is correct. testuser" in capture_log

def test_check_sanity_github_api_response_wrong_username(self, capsys, caplog):
username = "nonexistentuser"
response = MockEmptyResponse() # github api response for nonexistent user
sanity_check = panopticron.check_sanity_github_api_response(response, username)
sanity_check = panopticron.check_sanity_github_api_response(
response, TARGET_GITHUB_USERNAME
)
capture_out_err = capsys.readouterr()
capture_log = caplog.text
assert capture_out_err.out == ""
assert capture_out_err.err == ""
assert f"No data found for {username}" in capture_log
assert f"No data found for {TARGET_GITHUB_USERNAME}" in capture_log
assert "No email will be sent. Exiting script..." in capture_log
assert (
f"Check if the username is correct. {TARGET_GITHUB_USERNAME}" in capture_log
)
assert sanity_check is None

def test_filter_last_24_hours_activity_valid(self):
Expand Down

0 comments on commit 8c01e4b

Please sign in to comment.