commit 503e36e0d38fd7ad57f48fc0f46dba9b6959c84a Author: Maxence G. de Montauzan Date: Sat Jul 4 00:33:32 2020 +0200 First verison with disgusting code and pretty readme https://media.giphy.com/media/7E2taKYzqOux4lwgJY/giphy.gif diff --git a/README.md b/README.md new file mode 100644 index 0000000..b6f23b5 --- /dev/null +++ b/README.md @@ -0,0 +1,48 @@ +What for? +========= + +This project is a simple Python script to send a email when tracked Github projects (specified in conf) have a new release. +The purpose is to use this script in a cron table. + +Unbelievable, but I haven't found an existing equivalent! + +![An example of mail sent by the script](example-mail.png) + +Why using configuration?... +------------------------ +...instead use stared project of your Github account? +Cause I've got about 80 "stared" projects and I don't wan't to be alerted for new releases of each of these project. +But, perhaps I'll add such a feature later on... + +And, Github API limits is at 60 requests by seconds, and I want to write this script really quickly in a first time. + +How to use? +----------- +Really simple! + +* Edit conf.ini file to set `[config]` section + * your SMTP server configuration (host and port) + * sender mail + * receiver mail (:warning: not tested with more than 1 receiver) +* Add the projects you want to follow in the section `[project]` + * Be careful to follow a JSON valid syntax as in the provided file, i.e. coma after each `autor/project` except the last one. + +After first execution, the `conf.ini` file will be filled with last release tag found by the script, as you can see in the provided file. + +Hope you like, and have fun to read your mail! + +Problems I have to solve really quickly +--------------------------------------- +I wrote this script really quickly, certainly faster than this README. So I already have two big proglems: +* The script sends mail even if no new projets or release has been detected +* The biggest, you have to edit script to specify absolute path... +* A lot of other little problems, like the code that's disgusting and so on. +But overall, the script works and sends mail! + +Hey boy, what is the `pit.db` file? +----------------------------------- +Oh, just for fun, and because I love this project, I use [pit by michaeldv](https://github.com/michaeldv/pit) to follow my task etc. + +It makes me think I should push my python version of this project on occasion when I will take the time to do... + + diff --git a/conf.ini b/conf.ini new file mode 100644 index 0000000..15bbe66 --- /dev/null +++ b/conf.ini @@ -0,0 +1,12 @@ +[config] +github_api_url = https://api.github.com/repos/ +smtp_port = 25 +smtp_server = localhost +sender_email = sender@host.eu +receiver_email = receiver@anotherhost.eu + +[projects] +projects = [ + "borgbackup/borg", + "microsoft/vscode" + ] diff --git a/example-mail.png b/example-mail.png new file mode 100644 index 0000000..53a23d8 Binary files /dev/null and b/example-mail.png differ diff --git a/notifier.py b/notifier.py new file mode 100644 index 0000000..d14f158 --- /dev/null +++ b/notifier.py @@ -0,0 +1,115 @@ +from configparser import ConfigParser +import json +import smtplib +from email.mime.text import MIMEText +from email.mime.multipart import MIMEMultipart + +import datetime + +import requests + +SMTP_PORT = 0 +SMTP_SERVER = 'null' +SENDER_EMAIL = 'a@b.c' +RECEIVER_EMAIL = 'd@e.f' + +def main(): + global SMTP_PORT, SMTP_SERVER, SENDER_EMAIL, RECEIVER_EMAIL + parser = ConfigParser() + parser.read('conf.ini') + + SMTP_PORT = parser.get('config', 'smtp_port') + SMTP_SERVER = parser.get('config', 'smtp_server') + SENDER_EMAIL = parser.get('config', 'sender_email') + RECEIVER_EMAIL = parser.get('config', 'receiver_email') + + projects = json.loads(parser.get('projects', 'projects')) + new_releases = [] + new_projects = [] + + if not parser.has_section('release'): + parser.add_section('release') + + for project in projects: + last_release = get_last_release(project) + + if not parser.has_option('release', project): + new_projects.append(last_release) + else: + last_config_tag = parser.get('release', project) + if last_config_tag != last_release['release_tag']: + last_release['preview_tag'] = last_config_tag + new_releases.append(last_release) + parser.set('release', project, last_release['release_tag']) + + content = "" + + for new_r in new_releases: + content += """ +
  • {}: new release {} available (old: {}). + (published {})
  • + """.format( + new_r['release_url'], + new_r['project_name'], + new_r['release_url'], + new_r['release_tag'], + new_r['preview_tag'], + convert_date(new_r['published_date'])) + for new_p in new_projects: + content += """ +
  • {} was added to your configuration. Last release: {} + (published {})
  • """.format( + new_p['release_url'], + new_p['project_name'], + new_p['release_url'], + new_p['release_tag'], + convert_date(new_p['published_date'])) + + # print(content) + + with open('template.html', 'r') as f_template: + template = f_template.read() + + send_mail(template.replace('{{content}}', content)) + + with open('conf.ini', 'w') as configfile: + parser.write(configfile) + +def get_last_release(project): + url = 'https://api.github.com/repos/{}/releases/latest'.format(project) + result = requests.get(url) + + print(project) + print(url) + release = result.json() + release_tag = release['tag_name'] + published_date = release['published_at'] + # body = release['body'] + release_url = release['html_url'] + + return {'release_tag': release_tag, + 'published_date': published_date, + # 'body': body, + 'project_name': project, + 'release_url': release_url} + +def send_mail(content): + message = MIMEMultipart("alternative") + message["Subject"] = "New Github releases" + message["From"] = SENDER_EMAIL + message["To"] = RECEIVER_EMAIL + + # part1 = MIMEText(text, "plain") + part2 = MIMEText(content, "html") + + # message.attach(part1) + message.attach(part2) + + with smtplib.SMTP(SMTP_SERVER, SMTP_PORT) as server: + server.sendmail(SENDER_EMAIL, RECEIVER_EMAIL, message.as_string()) + +def convert_date(date: str, format='%d %b %Y at %H:%M') -> str: + return datetime.datetime.strptime(date, "%Y-%m-%dT%H:%M:%SZ").strftime(format) + +if __name__ == "__main__": + main() diff --git a/pit.db b/pit.db new file mode 100644 index 0000000..63cb69a Binary files /dev/null and b/pit.db differ diff --git a/template.html b/template.html new file mode 100644 index 0000000..5e73f99 --- /dev/null +++ b/template.html @@ -0,0 +1,53 @@ + + + + + + + + + +

    + + Some new release on Github project available!

    +

    +
    + +