From 91cc7bc9bfe588331e93f162563cc57d10a66d5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= <72651575+BreizhHardware@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:20:13 +0000 Subject: [PATCH 1/6] =?UTF-8?q?First=20it=C3=A9ration=20for=20discord?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Dockerfile | 2 + README.md | 5 ++- ntfy.py | 21 +++++++-- send_discord.py | 114 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 138 insertions(+), 4 deletions(-) create mode 100644 send_discord.py diff --git a/Dockerfile b/Dockerfile index a074be4..a76fd45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,6 +9,7 @@ ADD requirements.txt / ADD entrypoint.sh / ADD send_ntfy.py / ADD send_gotify.py / +ADD send_discord.py / ADD index.html /var/www/html/index.html ADD script.js /var/www/html/script.js RUN apk add --no-cache sqlite-dev sqlite-libs gcc musl-dev nginx @@ -25,6 +26,7 @@ ENV USERNAME="" \ DOCKER_PASSWORD="" \ GOTIFY_URL="" \ GOTIFY_TOKEN="" \ + DISCORD_WEBHOOK_URL="" \ FLASK_ENV=production # Exposer le port 5000 pour l'API et le port 80 pour le serveur web diff --git a/README.md b/README.md index f820b79..35e6b7d 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ services: - DOCKER_PASSWORD= # Default is empty (Docker Hub password) - GOTIFY_URL=gotify_url # Required if gotify is used - GOTIFY_TOKEN= # Required if gotify is used + - DISCORD_WEBHOOK_URL= # Required if discord is used volumes: - /path/to/github-ntfy:/github-ntfy/ ports: @@ -51,6 +52,7 @@ services: - DOCKER_PASSWORD= # Default is empty (Docker Hub password) - GOTIFY_URL=gotify_url # Required if gotify is used - GOTIFY_TOKEN= # Required if gotify is used + - DISCORD_WEBHOOK_URL= # Required if discord is used volumes: - /path/to/github-ntfy:/github-ntfy/ ports: @@ -73,6 +75,7 @@ services: - DOCKER_PASSWORD= # Default is empty (Docker Hub password) - GOTIFY_URL=gotify_url # Required if gotify is used - GOTIFY_TOKEN= # Required if gotify is used + - DISCORD_WEBHOOK_URL= # Required if discord is used volumes: - /path/to/github-ntfy:/github-ntfy/ ports: @@ -102,7 +105,7 @@ If you want to contribut, feel free to open a pull request (CONTRIBUTION.md comm - [x] Add Docker Hub compatibility - [ ] Rework of the web interface - [x] Compatibility with Gotify -- [ ] Compatibility with Discord Webhook +- [x] Compatibility with Discord Webhook - [x] Compatibility and distribution for arm64 and armv7 ## Show your support diff --git a/ntfy.py b/ntfy.py index a5e26a3..260ceb6 100644 --- a/ntfy.py +++ b/ntfy.py @@ -13,6 +13,10 @@ from send_gotify import ( github_send_to_gotify, docker_send_to_gotify, ) +from send_discord import ( + github_send_to_discord, + docker_send_to_discord, +) # Configuring the logger logging.basicConfig( @@ -29,6 +33,8 @@ if github_token: docker_username = os.environ.get("DOCKER_USERNAME") docker_password = os.environ.get("DOCKER_PASSWORD") +discord_webhook_url = os.environ.get("DISCORD_WEBHOOK_URL") + def create_dockerhub_token(username, password): url = "https://hub.docker.com//v2/users/login" @@ -177,26 +183,34 @@ if __name__ == "__main__": ntfy_url = os.environ.get("NTFY_URL") gotify_url = os.environ.get("GOTIFY_URL") gotify_token = os.environ.get("GOTIFY_TOKEN") + discord_webhook_url = os.environ.get("DISCORD_WEBHOOK_URL") timeout = float(os.environ.get("GHNTFY_TIMEOUT")) - if auth and ntfy_url: + if auth and (ntfy_url or gotify_url or discord_webhook_url): while True: github_watched_repos_list = get_watched_repos() github_latest_release = get_latest_releases(github_watched_repos_list) docker_watched_repos_list = get_docker_watched_repos() docker_latest_release = get_latest_docker_releases(docker_watched_repos_list) - if ntfy_url != "": + + if ntfy_url: if github_latest_release: github_send_to_ntfy(github_latest_release, auth, ntfy_url) if docker_latest_release: docker_send_to_ntfy(docker_latest_release, auth, ntfy_url) - if gotify_url != "" and gotify_token != "": + if gotify_url and gotify_token: if github_latest_release: github_send_to_gotify(github_latest_release, gotify_token, gotify_url) if docker_latest_release: docker_send_to_gotify(docker_latest_release, gotify_token, gotify_url) + if discord_webhook_url: + if github_latest_release: + github_send_to_discord(github_latest_release, discord_webhook_url) + if docker_latest_release: + docker_send_to_discord(docker_latest_release, discord_webhook_url) + time.sleep(timeout) # Wait an hour before checking again else: logger.error("Usage: python ntfy.py") @@ -211,4 +225,5 @@ if __name__ == "__main__": logger.error( "GOTIFY_TOKEN: the token of the gotify server need to be stored in an environment variable named GOTIFY_TOKEN" ) + logger.error("DISCORD_WEBHOOK_URL: the webhook URL for Discord notifications need to be stored in an environment variable named DISCORD_WEBHOOK_URL") logger.error("GHNTFY_TIMEOUT: the time interval between each check") diff --git a/send_discord.py b/send_discord.py new file mode 100644 index 0000000..a0c3c9a --- /dev/null +++ b/send_discord.py @@ -0,0 +1,114 @@ +import requests +import sqlite3 +import logging + +conn = sqlite3.connect( + "/github-ntfy/ghntfy_versions.db", + check_same_thread=False, +) +cursor = conn.cursor() + +logging.basicConfig( + level=logging.INFO, + format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", +) +logger = logging.getLogger(__name__) + + +def github_send_to_discord(releases, webhook_url): + for release in releases: + app_name = release["repo"].split("/")[-1] # Getting the application name from the repo + version_number = release["tag_name"] # Getting the version number + app_url = release["html_url"] # Getting the application URL + changelog = release["changelog"] # Getting the changelog + release_date = release["published_at"] # Getting the release date + release_date = release_date.replace("T", " ").replace("Z", "") # Formatting the release date + + # Checking if the version has changed since the last time + cursor.execute( + "SELECT version FROM versions WHERE repo=?", + (app_name,), + ) + previous_version = cursor.fetchone() + if previous_version and previous_version[0] == version_number: + logger.info(f"The version of {app_name} has not changed. No notification sent.") + continue # Move on to the next application + + # Creating the embed message + embed = { + "title": f"New version for {app_name}", + "url": app_url, + "color": "#027d21", + "fields": [ + { + "name": "Version", + "value": version_number, + "inline": True + }, + { + "name": "Published on", + "value": release_date, + "inline": True + }, + { + "name": "Changelog", + "value": changelog, + "inline": False + } + ] + } + + data = { + "embeds": [embed] + } + response = requests.post(webhook_url, json=data) + if response.status_code == 204: + logger.info(f"Message sent to Discord for {app_name}") + else: + logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") + +def docker_send_to_discord(releases, webhook_url): + for release in releases: + app_name = release["repo"].split("/")[-1] # Getting the application name from the repo + digest_number = release["digest"] + app_url = release["html_url"] # Getting the application URL + release_date = release["published_at"] # Getting the release date + release_date = release_date.replace("T", " ").replace("Z", "") # Formatting the release date + + # Checking if the version has changed since the last time + cursor.execute( + "SELECT digest FROM docker_versions WHERE repo=?", + (app_name,), + ) + previous_digest = cursor.fetchone() + if previous_digest and previous_digest[0] == digest_number: + logger.info(f"The digest of {app_name} has not changed. No notification sent.") + continue # Move on to the next application + + # Creating the embed message + embed = { + "title": f"New version for {app_name}", + "url": app_url, + "color": "#027d21", + "fields": [ + { + "name": "Digest", + "value": digest_number, + "inline": True + }, + { + "name": "Published on", + "value": release_date, + "inline": True + } + ] + } + + data = { + "embeds": [embed] + } + response = requests.post(webhook_url, json=data) + if response.status_code == 204: + logger.info(f"Message sent to Discord for {app_name}") + else: + logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") \ No newline at end of file From edff2e380663e3573aea5a2ef64efdbd42e0e50c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= <72651575+BreizhHardware@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:29:18 +0000 Subject: [PATCH 2/6] docs: add CONTRIBUTION.md and update README.md with contribution guidelines - Added CONTRIBUTION.md to provide guidelines for contributing to the project. - Updated README.md to include a link to CONTRIBUTION.md for easy access to contribution guidelines. --- CONTRIBUTION.md | 54 +++++++++++++++++++++++++++++++++++++++++++++++++ README.md | 2 +- 2 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTION.md diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md new file mode 100644 index 0000000..f9066d1 --- /dev/null +++ b/CONTRIBUTION.md @@ -0,0 +1,54 @@ +# Contribution Guidelines + +Thank you for considering contributing to this project! Your help is greatly appreciated. Please follow these guidelines to ensure a smooth contribution process. + +## How to Contribute + +1. **Fork the repository**: Click the "Fork" button at the top right of this repository to create a copy of the repository in your GitHub account. + +2. **Clone your fork**: Clone your forked repository to your local machine. + ```sh + git clone https://github.com/BreizhHardware/ntfy_alerts.git + cd ntfy_alerts + ``` + +3. **Create a new branch**: Create a new branch for your feature or bugfix. + ```sh + git checkout -b feat/my-feature-branch + ``` + +4. **Make your changes**: Make your changes to the codebase. Ensure your code follows the project's coding standards and includes appropriate tests. + +5. **Commit your changes**: Commit your changes with a clear and concise commit message using conventional commit. + ```sh + git add . + git commit -m "feat: add feature X" + ``` + +6. **Push to your fork**: Push your changes to your forked repository. + ```sh + git push origin feat/my-feature-branch + ``` + +7. **Create a Pull Request**: Go to the original repository and create a pull request from your forked repository. Provide a clear description of your changes and the problem they solve. + +## Code Style + +- Follow the existing code style and conventions. +- Write clear and concise comments where necessary. +- Ensure your code is well-documented. + +## Testing + +- Write tests for any new features or bug fixes. +- Ensure all tests pass before submitting your pull request. + +## Reporting Issues + +If you find a bug or have a feature request, please create an issue on the GitHub repository. Provide as much detail as possible to help us understand and address the issue. + +## Code of Conduct + +Please note that this project is released with a Contributor Code of Conduct. By participating in this project, you agree to abide by its terms. + +Thank you for contributing! \ No newline at end of file diff --git a/README.md b/README.md index 35e6b7d..286d818 100644 --- a/README.md +++ b/README.md @@ -95,7 +95,7 @@ GHNTFY_TOKEN is a github token, it need to have repo, read:org and read:user ## Contribution -If you want to contribut, feel free to open a pull request (CONTRIBUTION.md comming soon)! +If you want to contribut, feel free to open a pull request, but first read the [contribution guide](CONTRIBUTION.md)! ## TODO: - [x] Dockerize the ntfy.py From dc831c958f72bca49c729fb60737bbe2a5130a71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= <72651575+BreizhHardware@users.noreply.github.com> Date: Mon, 23 Dec 2024 12:41:57 +0000 Subject: [PATCH 3/6] docs: update README.md with dependancies installation - Add instruction for installing the dependencies --- README.md | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 286d818..3875fe0 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,18 @@

-> This project allow you to have notification about new github or docker hub release on ntfy, gotify and (soon) discord. +> This project allows you to receive notifications about new GitHub or Docker Hub releases on ntfy, gotify, and Discord. + +## Installation + +To install the dependencies, run: +```sh +pip install -r requirements.txt +``` ## Usage -If you want to use the docker image you can use the following docker-compose file for x86_64: +If you want to use the Docker image, you can use the following docker-compose file for x86_64: ````yaml services: github-ntfy: From 66759932f0fba8f1f059d087ee24f498cf1f37d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= <72651575+BreizhHardware@users.noreply.github.com> Date: Mon, 23 Dec 2024 15:47:49 +0000 Subject: [PATCH 4/6] chore(ci): remove GitHub release build to use Docker only Edit CI configuration to remove GitHub release build. Now, builds are only for Docker, and I will use the Conventional Release Bot app to manage releases. --- .github/workflows/create_release.yml | 103 +++++++---------------- .github/workflows/create_release.yml.old | 73 ++++++++++++++++ 2 files changed, 103 insertions(+), 73 deletions(-) create mode 100644 .github/workflows/create_release.yml.old diff --git a/.github/workflows/create_release.yml b/.github/workflows/create_release.yml index 8640cca..d8d60e3 100644 --- a/.github/workflows/create_release.yml +++ b/.github/workflows/create_release.yml @@ -1,73 +1,30 @@ -name: Docker Build and Release - -on: - push: - branches: - - main - -jobs: - build-and-push-on-docker-hub: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v3 - - - name: Log in to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKER_USERNAME }} - password: ${{ secrets.DOCKER_PASSWORD }} - - - name: Build and push Docker image - uses: docker/build-push-action@v6 - with: - context: . - push: true - tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest - - release-on-github: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Get the latest tag - id: get_latest_tag - run: echo "latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV - - - name: Increment version - id: increment_version - run: | - latest_tag=${{ env.latest_tag }} - if [ -z "$latest_tag" ]; then - new_version="v1.5.2" - else - IFS='.' read -r -a version_parts <<< "${latest_tag#v}" - new_version="v${version_parts[0]}.$((version_parts[1] + 1)).0" - fi - echo "new_version=$new_version" >> $GITHUB_ENV - - - name: Read changelog - id: read_changelog - run: echo "changelog=$(base64 -w 0 CHANGELOG.md)" >> $GITHUB_ENV - - - name: Decode changelog - id: decode_changelog - run: echo "${{ env.changelog }}" | base64 -d > decoded_changelog.txt - - - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.TOKEN }} - with: - tag_name: ${{ env.new_version }} - release_name: Release ${{ env.new_version }} - body: ${{ steps.decode_changelog.outputs.changelog }} - draft: false - prerelease: false \ No newline at end of file +name: Docker Build and Release + +on: + push: + branches: + - main + +jobs: + build-and-push-on-docker-hub: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest \ No newline at end of file diff --git a/.github/workflows/create_release.yml.old b/.github/workflows/create_release.yml.old new file mode 100644 index 0000000..8640cca --- /dev/null +++ b/.github/workflows/create_release.yml.old @@ -0,0 +1,73 @@ +name: Docker Build and Release + +on: + push: + branches: + - main + +jobs: + build-and-push-on-docker-hub: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Log in to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push Docker image + uses: docker/build-push-action@v6 + with: + context: . + push: true + tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:latest + + release-on-github: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Get the latest tag + id: get_latest_tag + run: echo "latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)" >> $GITHUB_ENV + + - name: Increment version + id: increment_version + run: | + latest_tag=${{ env.latest_tag }} + if [ -z "$latest_tag" ]; then + new_version="v1.5.2" + else + IFS='.' read -r -a version_parts <<< "${latest_tag#v}" + new_version="v${version_parts[0]}.$((version_parts[1] + 1)).0" + fi + echo "new_version=$new_version" >> $GITHUB_ENV + + - name: Read changelog + id: read_changelog + run: echo "changelog=$(base64 -w 0 CHANGELOG.md)" >> $GITHUB_ENV + + - name: Decode changelog + id: decode_changelog + run: echo "${{ env.changelog }}" | base64 -d > decoded_changelog.txt + + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.TOKEN }} + with: + tag_name: ${{ env.new_version }} + release_name: Release ${{ env.new_version }} + body: ${{ steps.decode_changelog.outputs.changelog }} + draft: false + prerelease: false \ No newline at end of file From e8eb8d18d26fea227786c5636bf1ef5c93603cae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= Date: Mon, 23 Dec 2024 19:33:49 +0100 Subject: [PATCH 5/6] fix: use separate database connections for each function - Refactored `send_gotify.py`, `send_ntfy.py`, and `send_discord.py` to use separate database connections for each function. - Added `get_db_connection` function to create a new database connection. - Updated `github_send_to_gotify`, `docker_send_to_gotify`, `github_send_to_ntfy`, `docker_send_to_ntfy`, `github_send_to_discord`, and `docker_send_to_discord` functions to use the new `get_db_connection` function. - Modified `ntfy.py` to use threading for calling notification functions simultaneously. --- ntfy.py | 50 +++++++++++++++++++++++++++++++----------------- send_discord.py | 51 +++++++++++++++++++------------------------------ send_gotify.py | 12 ++++++------ send_ntfy.py | 12 ++++++------ 4 files changed, 64 insertions(+), 61 deletions(-) diff --git a/ntfy.py b/ntfy.py index 260ceb6..3c2bdce 100644 --- a/ntfy.py +++ b/ntfy.py @@ -5,6 +5,8 @@ import logging import sqlite3 import subprocess import json +import threading + from send_ntfy import ( github_send_to_ntfy, docker_send_to_ntfy, @@ -175,6 +177,34 @@ def get_changelog(repo): return latest_release_list["body"] return "Changelog not available" +def notify_all_services(github_latest_release, docker_latest_release, auth, ntfy_url, gotify_url, gotify_token, discord_webhook_url): + threads = [] + + if ntfy_url: + if github_latest_release: + threads.append(threading.Thread(target=github_send_to_ntfy, args=(github_latest_release, auth, ntfy_url))) + if docker_latest_release: + threads.append(threading.Thread(target=docker_send_to_ntfy, args=(docker_latest_release, auth, ntfy_url))) + + if gotify_url and gotify_token: + if github_latest_release: + threads.append(threading.Thread(target=github_send_to_gotify, args=(github_latest_release, gotify_token, gotify_url))) + if docker_latest_release: + threads.append(threading.Thread(target=docker_send_to_gotify, args=(docker_latest_release, gotify_token, gotify_url))) + + if discord_webhook_url: + if github_latest_release: + threads.append(threading.Thread(target=github_send_to_discord, args=(github_latest_release, discord_webhook_url))) + if docker_latest_release: + threads.append(threading.Thread(target=docker_send_to_discord, args=(docker_latest_release, discord_webhook_url))) + + for thread in threads: + thread.start() + + for thread in threads: + thread.join() + + if __name__ == "__main__": start_api() @@ -193,25 +223,9 @@ if __name__ == "__main__": docker_watched_repos_list = get_docker_watched_repos() docker_latest_release = get_latest_docker_releases(docker_watched_repos_list) - if ntfy_url: - if github_latest_release: - github_send_to_ntfy(github_latest_release, auth, ntfy_url) - if docker_latest_release: - docker_send_to_ntfy(docker_latest_release, auth, ntfy_url) + notify_all_services(github_latest_release, docker_latest_release, auth, ntfy_url, gotify_url, gotify_token, discord_webhook_url) - if gotify_url and gotify_token: - if github_latest_release: - github_send_to_gotify(github_latest_release, gotify_token, gotify_url) - if docker_latest_release: - docker_send_to_gotify(docker_latest_release, gotify_token, gotify_url) - - if discord_webhook_url: - if github_latest_release: - github_send_to_discord(github_latest_release, discord_webhook_url) - if docker_latest_release: - docker_send_to_discord(docker_latest_release, discord_webhook_url) - - time.sleep(timeout) # Wait an hour before checking again + time.sleep(timeout) else: logger.error("Usage: python ntfy.py") logger.error( diff --git a/send_discord.py b/send_discord.py index a0c3c9a..c3e927d 100644 --- a/send_discord.py +++ b/send_discord.py @@ -2,20 +2,18 @@ import requests import sqlite3 import logging -conn = sqlite3.connect( - "/github-ntfy/ghntfy_versions.db", - check_same_thread=False, -) -cursor = conn.cursor() - logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) +def get_db_connection(): + return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False) def github_send_to_discord(releases, webhook_url): + conn = get_db_connection() + cursor = conn.cursor() for release in releases: app_name = release["repo"].split("/")[-1] # Getting the application name from the repo version_number = release["tag_name"] # Getting the version number @@ -34,40 +32,31 @@ def github_send_to_discord(releases, webhook_url): logger.info(f"The version of {app_name} has not changed. No notification sent.") continue # Move on to the next application - # Creating the embed message - embed = { - "title": f"New version for {app_name}", - "url": app_url, - "color": "#027d21", - "fields": [ - { - "name": "Version", - "value": version_number, - "inline": True - }, - { - "name": "Published on", - "value": release_date, - "inline": True - }, - { - "name": "Changelog", - "value": changelog, - "inline": False - } - ] + + embeds = { + "title": f"New version for {app_name}", + "url": app_url, + "color": "#027d21", + "description": f"New version: {version_number}\nPublished on: {release_date}\nChangelog:\n{changelog}" } data = { - "embeds": [embed] + "content": "New version available", + "username": "GitHub Ntfy", + "embeds": [embeds] } - response = requests.post(webhook_url, json=data) - if response.status_code == 204: + headers = { + "Content-Type": "application/json" + } + response = requests.post(webhook_url, json = data, headers = headers) + if 200 <= response.status_code < 300: logger.info(f"Message sent to Discord for {app_name}") else: logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") def docker_send_to_discord(releases, webhook_url): + conn = get_db_connection() + cursor = conn.cursor() for release in releases: app_name = release["repo"].split("/")[-1] # Getting the application name from the repo digest_number = release["digest"] diff --git a/send_gotify.py b/send_gotify.py index 9084066..367b56d 100644 --- a/send_gotify.py +++ b/send_gotify.py @@ -2,20 +2,18 @@ import requests import sqlite3 import logging -conn = sqlite3.connect( - "/github-ntfy/ghntfy_versions.db", - check_same_thread=False, -) -cursor = conn.cursor() - logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) +def get_db_connection(): + return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False) def github_send_to_gotify(releases, token, url): + conn = get_db_connection() + cursor = conn.cursor() url = url + "/message" url = url + "?token=" + token for release in releases: @@ -58,6 +56,8 @@ def github_send_to_gotify(releases, token, url): def docker_send_to_gotify(releases, token, url): + conn = get_db_connection() + cursor = conn.cursor() url = url + "/message" url = url + "?token=" + token for release in releases: diff --git a/send_ntfy.py b/send_ntfy.py index cd3be10..210d1d3 100644 --- a/send_ntfy.py +++ b/send_ntfy.py @@ -2,20 +2,18 @@ import requests import sqlite3 import logging -conn = sqlite3.connect( - "/github-ntfy/ghntfy_versions.db", - check_same_thread=False, -) -cursor = conn.cursor() - logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(name)s - %(levelname)s - %(message)s", ) logger = logging.getLogger(__name__) +def get_db_connection(): + return sqlite3.connect("/github-ntfy/ghntfy_versions.db", check_same_thread=False) def github_send_to_ntfy(releases, auth, url): + conn = get_db_connection() + cursor = conn.cursor() for release in releases: app_name = release["repo"].split("/")[-1] # Getting the application name from the repo version_number = release["tag_name"] # Getting the version number @@ -58,6 +56,8 @@ def github_send_to_ntfy(releases, auth, url): def docker_send_to_ntfy(releases, auth, url): + conn = get_db_connection() + cursor = conn.cursor() for release in releases: app_name = release["repo"].split("/")[-1] # Getting the application name from the repo digest_number = release["digest"] From a3e892c8f0cb7eb299655348b53def1ea4e6ed76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix=20MARQUET?= Date: Mon, 23 Dec 2024 19:56:57 +0100 Subject: [PATCH 6/6] fix: use separate database connections for each function - Refactored `send_discord.py` to better work with webhook (but remove the embed) - Updated Dockerfile to adjust package installation order. --- Dockerfile | 2 +- send_discord.py | 103 ++++++++++++++++++++++-------------------------- 2 files changed, 49 insertions(+), 56 deletions(-) diff --git a/Dockerfile b/Dockerfile index a76fd45..2174512 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ ADD send_gotify.py / ADD send_discord.py / ADD index.html /var/www/html/index.html ADD script.js /var/www/html/script.js -RUN apk add --no-cache sqlite-dev sqlite-libs gcc musl-dev nginx +RUN apk add --no-cache sqlite-dev sqlite-libs musl-dev nginx gcc RUN pip install -r requirements.txt RUN chmod 700 /entrypoint.sh diff --git a/send_discord.py b/send_discord.py index c3e927d..16e2465 100644 --- a/send_discord.py +++ b/send_discord.py @@ -15,89 +15,82 @@ def github_send_to_discord(releases, webhook_url): conn = get_db_connection() cursor = conn.cursor() for release in releases: - app_name = release["repo"].split("/")[-1] # Getting the application name from the repo - version_number = release["tag_name"] # Getting the version number - app_url = release["html_url"] # Getting the application URL - changelog = release["changelog"] # Getting the changelog - release_date = release["published_at"] # Getting the release date - release_date = release_date.replace("T", " ").replace("Z", "") # Formatting the release date + app_name = release["repo"].split("/")[-1] + version_number = release["tag_name"] + app_url = release["html_url"] + changelog = release["changelog"] + release_date = release["published_at"].replace("T", " ").replace("Z", "") - # Checking if the version has changed since the last time - cursor.execute( - "SELECT version FROM versions WHERE repo=?", - (app_name,), - ) + cursor.execute("SELECT version FROM versions WHERE repo=?", (app_name,)) previous_version = cursor.fetchone() if previous_version and previous_version[0] == version_number: logger.info(f"The version of {app_name} has not changed. No notification sent.") continue # Move on to the next application - - embeds = { - "title": f"New version for {app_name}", - "url": app_url, - "color": "#027d21", - "description": f"New version: {version_number}\nPublished on: {release_date}\nChangelog:\n{changelog}" - } - + message = f"New version: {version_number}\nFor: {app_name}\nPublished on: {release_date}\nChangelog:\n{changelog}\n{app_url}" + if len(message) > 2000: + message = f"New version: {version_number}\nFor: {app_name}\nPublished on: {release_date}\nFull changelog: {app_url}" + # Updating the previous version for this application + cursor.execute( + "INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)", + (app_name, version_number, changelog), + ) + conn.commit() data = { - "content": "New version available", - "username": "GitHub Ntfy", - "embeds": [embeds] + "content": message, + "username": "GitHub Ntfy" } headers = { "Content-Type": "application/json" } - response = requests.post(webhook_url, json = data, headers = headers) + + response = requests.post(webhook_url, json=data, headers=headers) if 200 <= response.status_code < 300: logger.info(f"Message sent to Discord for {app_name}") else: logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") + logger.error(f"Response: {response.text}") + conn.close() def docker_send_to_discord(releases, webhook_url): conn = get_db_connection() cursor = conn.cursor() for release in releases: - app_name = release["repo"].split("/")[-1] # Getting the application name from the repo + app_name = release["repo"].split("/")[-1] digest_number = release["digest"] - app_url = release["html_url"] # Getting the application URL - release_date = release["published_at"] # Getting the release date - release_date = release_date.replace("T", " ").replace("Z", "") # Formatting the release date + app_url = release["html_url"] + release_date = release["published_at"].replace("T", " ").replace("Z", "") - # Checking if the version has changed since the last time - cursor.execute( - "SELECT digest FROM docker_versions WHERE repo=?", - (app_name,), - ) + cursor.execute("SELECT digest FROM docker_versions WHERE repo=?", (app_name,)) previous_digest = cursor.fetchone() if previous_digest and previous_digest[0] == digest_number: logger.info(f"The digest of {app_name} has not changed. No notification sent.") - continue # Move on to the next application + continue - # Creating the embed message - embed = { - "title": f"New version for {app_name}", - "url": app_url, - "color": "#027d21", - "fields": [ - { - "name": "Digest", - "value": digest_number, - "inline": True - }, - { - "name": "Published on", - "value": release_date, - "inline": True - } - ] - } + message = f"New version for {app_name}\nDigest: {digest_number}\nPublished on: {release_date}\n{app_url}" + if len(message) > 2000: + message = f"New version for {app_name}\nDigest: {digest_number}\nPublished on: {release_date}\nFull details: {app_url}" + + cursor.execute( + "INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?)", + (app_name, digest_number), + ) + conn.commit() data = { - "embeds": [embed] + "content": message, + "username": "GitHub Ntfy" } - response = requests.post(webhook_url, json=data) - if response.status_code == 204: + headers = { + "Content-Type": "application/json" + } + + logger.info(f"Sending payload to Discord: {data}") + + response = requests.post(webhook_url, json=data, headers=headers) + if 200 <= response.status_code < 300: logger.info(f"Message sent to Discord for {app_name}") else: - logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") \ No newline at end of file + logger.error(f"Failed to send message to Discord. Status code: {response.status_code}") + logger.error(f"Response: {response.text}") + conn.close() \ No newline at end of file