diff --git a/.gitignore b/.gitignore index 48f8b5a..b3416b9 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ config.json # VS Code Project Files .vscode +# Local temp files +tmp + ############################################################################ # From https://github.com/github/gitignore/blob/master/Python.gitignore diff --git a/Makefile b/Makefile index 72a4f6a..d4034e7 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ build: instructions run: instructions cd ./src/github_projects_burndown_chart \ - && PYTHONPATH=. python main.py $(type) $(name) + && PYTHONPATH=. python main.py $(type) $(name) $(opts) test: instructions coverage run \ diff --git a/README.md b/README.md index 3ebc65d..f8bdd32 100644 --- a/README.md +++ b/README.md @@ -119,6 +119,16 @@ To see Golang's progress on their current roadmap: make run type=organization name=golang_on_deck ``` +### Discord Webhook +This project also supports posting the burndown chart to a Discord Webhook. Here's how to set that up: +1. [Create a webhook](https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks#:~:text=Facebook-,making%20a%20webhook,-With%20that%20in) in your Discord server. +2. Put the webhook's URL into the `discord_webhook` setting in `secrets.json`. +3. Add the `--discord` option when running the script. + +``` +make run type=repository name=burndown_chart_kickoff opts="--discord" +``` + ## Contributing Contributions are welcome via a [Pull Request](https://docs.github.com/en/github/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request). diff --git a/src/github_projects_burndown_chart/chart/burndown.py b/src/github_projects_burndown_chart/chart/burndown.py index 414c193..cb0a778 100644 --- a/src/github_projects_burndown_chart/chart/burndown.py +++ b/src/github_projects_burndown_chart/chart/burndown.py @@ -1,5 +1,6 @@ -import matplotlib.pyplot as plt from datetime import datetime +import matplotlib.pyplot as plt +import os from config import config from gh.project import Project @@ -19,7 +20,7 @@ def __init__(self, project: Project): self.project: Project = project - def render(self): + def __prepare_chart(self): end_date = self.chart_end_date_utc if self.chart_end_date_utc else self.end_date_utc outstanding_points_by_day = self.project.outstanding_points_by_date( self.start_date_utc, @@ -52,5 +53,12 @@ def render(self): plt.ylabel(f"Outstanding {'Points' if points_label else 'Issues'}") plt.xlabel("Date") - # Generate Plot + def generate_chart(self, path): + self.__prepare_chart() + if not os.path.exists(path): + os.makedirs(os.path.dirname(path)) + plt.savefig(path) + + def render(self): + self.__prepare_chart() plt.show() diff --git a/src/github_projects_burndown_chart/config/secrets.json.dist b/src/github_projects_burndown_chart/config/secrets.json.dist index 35d9240..34fee54 100644 --- a/src/github_projects_burndown_chart/config/secrets.json.dist +++ b/src/github_projects_burndown_chart/config/secrets.json.dist @@ -1,3 +1,4 @@ { - "github_token": "" + "github_token": "", + "discord_webhook": "" } \ No newline at end of file diff --git a/src/github_projects_burndown_chart/discord/__init__.py b/src/github_projects_burndown_chart/discord/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/github_projects_burndown_chart/discord/webhook.py b/src/github_projects_burndown_chart/discord/webhook.py new file mode 100644 index 0000000..85a9008 --- /dev/null +++ b/src/github_projects_burndown_chart/discord/webhook.py @@ -0,0 +1,13 @@ +import requests + +from config import secrets + +def post_burndown_chart(chart_path): + requests.post( + secrets['discord_webhook'], + json={'content': "Today's Burndown Chart"} + ) + requests.post( + secrets['discord_webhook'], + files={'file': open(chart_path, 'rb')}, + ) \ No newline at end of file diff --git a/src/github_projects_burndown_chart/main.py b/src/github_projects_burndown_chart/main.py index d8be4b7..2c27f8d 100644 --- a/src/github_projects_burndown_chart/main.py +++ b/src/github_projects_burndown_chart/main.py @@ -2,6 +2,7 @@ from chart.burndown import BurndownChart from config import config +from discord import webhook from gh.api_wrapper import get_organization_project, get_repository_project from gh.project import Project @@ -13,6 +14,7 @@ choices=['repository', 'organization'], help="The type of project to generate a burndown chart for. Can be either 'organization' or 'repository'.") parser.add_argument("project_name", help="The name of the project as it appears in the config.json") + parser.add_argument("--discord", action='store_true', help="If present, posts the burndown chart to the configured webhook") args = parser.parse_args() # Point the config to the correct project @@ -26,5 +28,10 @@ # Generate the burndown chart burndown_chart = BurndownChart(project) - burndown_chart.render() + if args.discord: + chart_path = "./tmp/chart.png" + burndown_chart.generate_chart(chart_path) + webhook.post_burndown_chart(chart_path) + else: + burndown_chart.render() print('Done')