mirror of
https://github.com/BreizhHardware/ntfy_alerts.git
synced 2026-01-19 00:47:33 +01:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7b89930f1 | ||
|
|
246b727d0a | ||
|
|
83cfd9a2f1 | ||
|
|
8795add7f0 | ||
|
|
3d33cb8282 | ||
|
|
aa2f654d4b | ||
| e1b16ac645 | |||
|
|
7a221a9ab9 | ||
| a3e892c8f0 | |||
| e8eb8d18d2 | |||
|
|
66759932f0 | ||
|
|
dc831c958f | ||
|
|
edff2e3806 | ||
|
|
91cc7bc9bf | ||
| fc577ea17f | |||
| ae95654ec3 | |||
|
|
7c0e34c08c | ||
|
|
921f40e98e | ||
|
|
dcf9edba97 | ||
|
|
5f2e86d86a | ||
|
|
66e22f6788 | ||
|
|
71cf7baa32 | ||
|
|
8d26c2821c | ||
|
|
3e59106fa6 | ||
|
|
d6c0e4e08e | ||
|
|
4bfc6e254a | ||
| e863be9dc0 | |||
| e4f2ca9e49 | |||
| 996aad9c5e | |||
| b958689318 | |||
| 8800902bf1 | |||
| 8f50debb0a |
104
.github/workflows/create_release.yml
vendored
104
.github/workflows/create_release.yml
vendored
@@ -1,74 +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.4.0"
|
||||
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: 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 }}
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
- name: Upload changelog
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
||||
asset_path: ./CHANGELOG.md
|
||||
asset_name: CHANGELOG.md
|
||||
asset_content_type: text/markdown
|
||||
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
|
||||
73
.github/workflows/create_release.yml.old
vendored
Normal file
73
.github/workflows/create_release.yml.old
vendored
Normal file
@@ -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
|
||||
38
.github/workflows/create_release_arm64.yml
vendored
Normal file
38
.github/workflows/create_release_arm64.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Docker Build and Release for arm64
|
||||
|
||||
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 QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- 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
|
||||
platforms: linux/arm64
|
||||
tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:arm64
|
||||
38
.github/workflows/create_release_armv7.yml
vendored
Normal file
38
.github/workflows/create_release_armv7.yml
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
name: Docker Build and Release for armv7
|
||||
|
||||
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 QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm/v7
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
with:
|
||||
install: true
|
||||
|
||||
- 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
|
||||
platforms: linux/arm/v7
|
||||
tags: ${{ secrets.DOCKER_USERNAME }}/github-ntfy:armv7
|
||||
@@ -1,9 +0,0 @@
|
||||
**New features**:
|
||||
- Change database struct to be able to handle docker hub repos
|
||||
- Now you can add docker hub repo to your watch list
|
||||
- You can connect your docker account to bypass the rate limit of the docker hub API
|
||||
|
||||
**Breaking changes**:
|
||||
- Change in the docker-compose file, you need to add the DOCKER_USERNAME and DOCKER_PASSWORD environment variables
|
||||
|
||||
**Full Changelog**: https://github.com/BreizhHardware/ntfy_alerts/compare/v1.3...v1.4
|
||||
6
CHANGELOG.md
Normal file
6
CHANGELOG.md
Normal file
@@ -0,0 +1,6 @@
|
||||
**New features**:
|
||||
- Add gotify compatibility please Read the README.md
|
||||
- Add arm64 support
|
||||
- Add armv7 support
|
||||
|
||||
**Full Changelog**: https://github.com/BreizhHardware/ntfy_alerts/compare/v1.4.3...v1.5
|
||||
54
CONTRIBUTION.md
Normal file
54
CONTRIBUTION.md
Normal file
@@ -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!
|
||||
@@ -7,9 +7,12 @@ ADD ntfy.py /
|
||||
ADD ntfy_api.py /
|
||||
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
|
||||
RUN apk add --no-cache sqlite-dev sqlite-libs musl-dev nginx gcc
|
||||
RUN pip install -r requirements.txt
|
||||
RUN chmod 700 /entrypoint.sh
|
||||
|
||||
@@ -21,6 +24,10 @@ ENV USERNAME="" \
|
||||
GHNTFY_TOKEN="" \
|
||||
DOCKER_USERNAME="" \
|
||||
DOCKER_PASSWORD="" \
|
||||
GOTIFY_URL="" \
|
||||
GOTIFY_TOKEN="" \
|
||||
DISCORD_WEBHOOK_URL="" \
|
||||
SLACK_WEBHOOK_URL="" \
|
||||
FLASK_ENV=production
|
||||
|
||||
# Exposer le port 5000 pour l'API et le port 80 pour le serveur web
|
||||
|
||||
139
README.md
139
README.md
@@ -1,25 +1,26 @@
|
||||
# ntfy_alerts
|
||||
Personal ntfy alerts system
|
||||
<h1 align="center">Welcome to ntfy_alerts 👋</h1>
|
||||
<p>
|
||||
<img alt="Version" src="https://img.shields.io/badge/version-1.5-blue.svg?cacheSeconds=2592000" />
|
||||
<a href="#" target="_blank">
|
||||
<img alt="License: GPL--3" src="https://img.shields.io/badge/License-GPL--3-yellow.svg" />
|
||||
</a>
|
||||
<a href="https://twitter.com/BreizhHardware" target="_blank">
|
||||
<img alt="Twitter: BreizhHardware" src="https://img.shields.io/twitter/follow/BreizhHardware.svg?style=social" />
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Feel free to contribute and to fork !
|
||||
> This project allows you to receive notifications about new GitHub or Docker Hub releases on ntfy, gotify, and Discord.
|
||||
|
||||
# Python ntfy.py
|
||||
## Description:
|
||||
This script is used to watch the github repos and send a notification to the ntfy server when a new release is published.
|
||||
## Installation
|
||||
|
||||
It can aloso watch Docker Hub repos and do the same as github.
|
||||
## Utilisation:
|
||||
auth and ntfy_url are required to be set as environment variables.
|
||||
To install the dependencies, run:
|
||||
```sh
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
auth: can be generataed by the folowing command: echo -n 'username:password' | base64
|
||||
## Usage
|
||||
|
||||
ntfy_url: the url of the ntfy server including the topic
|
||||
|
||||
````python
|
||||
python ntfy.py
|
||||
````
|
||||
## Docker:
|
||||
If you want to use the docker image you can use the following docker-compose file:
|
||||
If you want to use the Docker image, you can use the following docker-compose file for x86_64:
|
||||
````yaml
|
||||
services:
|
||||
github-ntfy:
|
||||
@@ -28,20 +29,84 @@ services:
|
||||
environment:
|
||||
- USERNAME=username # Required
|
||||
- PASSWORD=password # Required
|
||||
- NTFY_URL=ntfy_url # Required
|
||||
- NTFY_URL=ntfy_url # Required if ntfy is used
|
||||
- GHNTFY_TIMEOUT=timeout # Default is 3600 (1 hour)
|
||||
- GHNTFY_TOKEN= # Default is empty (Github token)
|
||||
- DOCKER_USERNAME= # Default is empty (Docker Hub username)
|
||||
- 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
|
||||
- SLACK_WEBHOOK_URL= # Required if Slack is used
|
||||
volumes:
|
||||
- /path/to/github-ntfy:/github-ntfy/
|
||||
ports:
|
||||
- 80:80
|
||||
restart: unless-stopped
|
||||
````
|
||||
GHNTFY_TOKEN, need to have repo, read:org and read:user
|
||||
For arm64 this docker compose file is ok:
|
||||
````yaml
|
||||
services:
|
||||
github-ntfy:
|
||||
image: breizhhardware/github-ntfy:arm64
|
||||
container_name: github-ntfy
|
||||
environment:
|
||||
- USERNAME=username # Required
|
||||
- PASSWORD=password # Required
|
||||
- NTFY_URL=ntfy_url # Required if ntfy is used
|
||||
- GHNTFY_TIMEOUT=timeout # Default is 3600 (1 hour)
|
||||
- GHNTFY_TOKEN= # Default is empty (Github token)
|
||||
- DOCKER_USERNAME= # Default is empty (Docker Hub username)
|
||||
- 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
|
||||
- SLACK_WEBHOOK_URL= # Required if Slack is used
|
||||
volumes:
|
||||
- /path/to/github-ntfy:/github-ntfy/
|
||||
ports:
|
||||
- 80:80
|
||||
restart: unless-stopped
|
||||
````
|
||||
For armV7 this docker compose is ok:
|
||||
````yaml
|
||||
services:
|
||||
github-ntfy:
|
||||
image: breizhhardware/github-ntfy:armv7
|
||||
container_name: github-ntfy
|
||||
environment:
|
||||
- USERNAME=username # Required
|
||||
- PASSWORD=password # Required
|
||||
- NTFY_URL=ntfy_url # Required if ntfy is used
|
||||
- GHNTFY_TIMEOUT=timeout # Default is 3600 (1 hour)
|
||||
- GHNTFY_TOKEN= # Default is empty (Github token)
|
||||
- DOCKER_USERNAME= # Default is empty (Docker Hub username)
|
||||
- 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
|
||||
- SLACK_WEBHOOK_URL= # Required if Slack is used
|
||||
volumes:
|
||||
- /path/to/github-ntfy:/github-ntfy/
|
||||
ports:
|
||||
- 80:80
|
||||
restart: unless-stopped
|
||||
````
|
||||
GHNTFY_TOKEN is a github token, it need to have repo, read:org and read:user
|
||||
|
||||
## Author
|
||||
|
||||
👤 **BreizhHardware**
|
||||
|
||||
* Website: https://mrqt.fr?ref=github
|
||||
* Twitter: [@BreizhHardware](https://twitter.com/BreizhHardware)
|
||||
* Github: [@BreizhHardware](https://github.com/BreizhHardware)
|
||||
* LinkedIn: [@félix-marquet-5071bb167](https://linkedin.com/in/félix-marquet-5071bb167)
|
||||
|
||||
## Contribution
|
||||
|
||||
If you want to contribut, feel free to open a pull request, but first read the [contribution guide](CONTRIBUTION.md)!
|
||||
|
||||
Docker Hub repo: https://hub.docker.com/r/breizhhardware/github-ntfy
|
||||
## TODO:
|
||||
- [x] Dockerize the ntfy.py
|
||||
- [x] Add the watched repos list as a parameter
|
||||
@@ -49,34 +114,10 @@ Docker Hub repo: https://hub.docker.com/r/breizhhardware/github-ntfy
|
||||
- [x] Add the watched repos list as a web interface
|
||||
- [x] Add Docker Hub compatibility
|
||||
- [ ] Rework of the web interface
|
||||
# Bash setup-notify.sh
|
||||
## Description:
|
||||
This script is used to setup the ntfy notification system on ssh login for a new server.
|
||||
## Utilisation:
|
||||
````bash
|
||||
bash setup-notify.sh <ntfy_url> <username> <password> <topic>
|
||||
````
|
||||
ntfy_url: the url of the ntfy server
|
||||
- [x] Compatibility with Gotify
|
||||
- [x] Compatibility with Discord Webhook
|
||||
- [x] Compatibility and distribution for arm64 and armv7
|
||||
|
||||
username: the username of the user
|
||||
|
||||
password: the password of the user
|
||||
|
||||
topic: the topic of the notification
|
||||
|
||||
This script will create a send-notify.sh in the root of your disk and add the login-notify.sh to the /etc/profile.d/ folder.
|
||||
# Bash send-notify.sh
|
||||
## Description:
|
||||
This script is used to send a notification to the ntfy server.
|
||||
## Utilisation:
|
||||
````bash
|
||||
bash send-notify.sh <ntfy_url> <basic_auth> <topic> <message>
|
||||
````
|
||||
ntfy_url: the url of the ntfy server
|
||||
|
||||
basic_auth: the basic auth of the user
|
||||
|
||||
topic: the topic of the notification
|
||||
|
||||
message: the message of the notification
|
||||
## Show your support
|
||||
|
||||
Give a ⭐️ if this project helped you!
|
||||
119
index.html
119
index.html
@@ -3,74 +3,67 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Github-Ntfy Add a repo</title>
|
||||
<title>Github-Ntfy Add a Repo</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
<script src="./script.js" defer></script>
|
||||
</head>
|
||||
<body class="bg-gradient-to-b from-stone-500 to-green-700">
|
||||
<h1 class="text-4xl font-semibold leading-10 text-gray-900 text-center">Github-Ntfy</h1>
|
||||
<div class="flex flex-row gap-2 justify-center items-center my-2 h-screen">
|
||||
<div class="flex flex-col gap-2 justify-center items-center my-2 h-screen border-double border-2 border-white p-2" id="github">
|
||||
<h1>Add a github repo</h1>
|
||||
<form id="addRepoForm">
|
||||
<div class="space-y-12">
|
||||
<div class="border-b border-gray-900/10 pb-12">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Name of the github repo</h2>
|
||||
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||
<div class="sm:col-span-4">
|
||||
<div class="mt-2">
|
||||
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
|
||||
<span class="flex select-none items-center pl-3 sm:text-sm">github.com/</span>
|
||||
<input type="text" name="repo" id="repo" autocomplete="repo" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 placeholder:text-gray-600 focus:ring-0 sm:text-sm sm:leading-6" placeholder="BreizhHardware/ntfy_alerts">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<body class="bg-[#1b2124] text-gray-200">
|
||||
<header class="text-center py-8 bg-[#23453d] shadow-lg">
|
||||
<h1 class="text-5xl font-bold tracking-wide text-white">Github-Ntfy</h1>
|
||||
</header>
|
||||
|
||||
<main class="flex flex-wrap justify-center gap-8 py-12">
|
||||
<!-- Github Repo Section -->
|
||||
<section class="bg-[#23453d] rounded-lg shadow-lg p-6 w-full max-w-lg">
|
||||
<h2 class="text-2xl font-semibold mb-4">Add a Github Repo</h2>
|
||||
<form id="addRepoForm" class="space-y-6">
|
||||
<div>
|
||||
<label for="repo" class="block text-sm font-medium">Name of the Github Repo</label>
|
||||
<div class="mt-2 flex items-center border rounded-md bg-gray-700">
|
||||
<span class="px-3 text-gray-400">github.com/</span>
|
||||
<input type="text" name="repo" id="repo" autocomplete="repo" class="flex-1 py-2 px-3 bg-transparent focus:outline-none" placeholder="BreizhHardware/ntfy_alerts">
|
||||
</div>
|
||||
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-8">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Watched Github Repositories</h2>
|
||||
<ul id="watchedReposList" class="mt-4">
|
||||
<!-- Dynamically populated with JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col gap-2 justify-center items-center my-2 h-screen border-double border-2 border-white p-2" id="docker">
|
||||
<h1>Add a docker repo</h1>
|
||||
<form id="addDockerRepoForm">
|
||||
<div class="space-y-12">
|
||||
<div class="border-b border-gray-900/10 pb-12">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Name of the docker repo</h2>
|
||||
<div class="mt-10 grid grid-cols-1 gap-x-6 gap-y-8 sm:grid-cols-6">
|
||||
<div class="sm:col-span-4">
|
||||
<div class="mt-2">
|
||||
<div class="flex rounded-md shadow-sm ring-1 ring-inset ring-gray-300 focus-within:ring-2 focus-within:ring-inset focus-within:ring-indigo-600 sm:max-w-md">
|
||||
<span class="flex select-none items-center pl-3 sm:text-sm">hub.docker.com/r/</span>
|
||||
<input type="text" name="dockerRepo" id="dockerRepo" autocomplete="dockerRepo" class="block flex-1 border-0 bg-transparent py-1.5 pl-1 placeholder:text-gray-600 focus:ring-0 sm:text-sm sm:leading-6" placeholder="breizhhardware/github-ntfy">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-6 flex items-center justify-end gap-x-6">
|
||||
<button type="button" class="text-sm font-semibold leading-6 text-gray-900">Cancel</button>
|
||||
<button type="submit" class="rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-8">
|
||||
<h2 class="text-base font-semibold leading-7 text-gray-900">Watched Docker Repositories</h2>
|
||||
<ul id="watchedDockerReposList" class="mt-4">
|
||||
<!-- Dynamically populated with JavaScript -->
|
||||
</ul>
|
||||
<div class="flex justify-end gap-4">
|
||||
<button type="button" class="px-4 py-2 text-gray-400 hover:text-white">Cancel</button>
|
||||
<button type="submit" class="px-4 py-2 bg-green-700 hover:bg-green-600 text-white font-semibold rounded-md">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-8">
|
||||
<h3 class="text-lg font-semibold mb-2">Watched Github Repositories</h3>
|
||||
<ul id="watchedReposList" class="space-y-2">
|
||||
<!-- Dynamically populated with JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<p class="font-semibold leading-10 text-gray-900 text-center">I know this web interface is awfull but I'm not a web designer ^^.</p>
|
||||
</section>
|
||||
|
||||
<!-- Docker Repo Section -->
|
||||
<section class="bg-[#23453d] rounded-lg shadow-lg p-6 w-full max-w-lg">
|
||||
<h2 class="text-2xl font-semibold mb-4">Add a Docker Repo</h2>
|
||||
<form id="addDockerRepoForm" class="space-y-6">
|
||||
<div>
|
||||
<label for="dockerRepo" class="block text-sm font-medium">Name of the Docker Repo</label>
|
||||
<div class="mt-2 flex items-center border rounded-md bg-gray-700">
|
||||
<span class="px-3 text-gray-400">hub.docker.com/r/</span>
|
||||
<input type="text" name="dockerRepo" id="dockerRepo" autocomplete="dockerRepo" class="flex-1 py-2 px-3 bg-transparent focus:outline-none" placeholder="breizhhardware/github-ntfy">
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end gap-4">
|
||||
<button type="button" class="px-4 py-2 text-gray-400 hover:text-white">Cancel</button>
|
||||
<button type="submit" class="px-4 py-2 bg-green-700 hover:bg-green-600 text-white font-semibold rounded-md">Save</button>
|
||||
</div>
|
||||
</form>
|
||||
<div class="mt-8">
|
||||
<h3 class="text-lg font-semibold mb-2">Watched Docker Repositories</h3>
|
||||
<ul id="watchedDockerReposList" class="space-y-2">
|
||||
<!-- Dynamically populated with JavaScript -->
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer class="text-center py-6 bg-[#23453d]">
|
||||
<p class="text-sm">I know this web interface is simple, but I'm improving!</p>
|
||||
</footer>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
237
ntfy.py
237
ntfy.py
@@ -5,22 +5,46 @@ import logging
|
||||
import sqlite3
|
||||
import subprocess
|
||||
import json
|
||||
import threading
|
||||
|
||||
from send_ntfy import (
|
||||
github_send_to_ntfy,
|
||||
docker_send_to_ntfy,
|
||||
)
|
||||
from send_gotify import (
|
||||
github_send_to_gotify,
|
||||
docker_send_to_gotify,
|
||||
)
|
||||
from send_discord import (
|
||||
github_send_to_discord,
|
||||
docker_send_to_discord,
|
||||
)
|
||||
|
||||
from send_slack import (
|
||||
github_send_to_slack,
|
||||
docker_send_to_slack,
|
||||
)
|
||||
|
||||
# Configuring the logger
|
||||
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
logging.basicConfig(
|
||||
level=logging.INFO,
|
||||
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||
)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
github_token = os.environ.get('GHNTFY_TOKEN')
|
||||
github_token = os.environ.get("GHNTFY_TOKEN")
|
||||
github_headers = {}
|
||||
if github_token:
|
||||
github_headers['Authorization'] = f"token {github_token}"
|
||||
github_headers["Authorization"] = f"token {github_token}"
|
||||
|
||||
docker_username = os.environ.get('DOCKER_USERNAME')
|
||||
docker_password = os.environ.get('DOCKER_PASSWORD')
|
||||
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"
|
||||
url = "https://hub.docker.com/v2/users/login"
|
||||
headers = {"Content-Type": "application/json"}
|
||||
data = json.dumps({"username": username, "password": password})
|
||||
|
||||
@@ -40,31 +64,42 @@ def create_dockerhub_token(username, password):
|
||||
docker_token = create_dockerhub_token(docker_username, docker_password)
|
||||
docker_header = {}
|
||||
if docker_token:
|
||||
docker_header['Authorization'] = f"Bearer {docker_token}"
|
||||
docker_header["Authorization"] = f"Bearer {docker_token}"
|
||||
# Connecting to the database to store previous versions
|
||||
conn = sqlite3.connect('/github-ntfy/ghntfy_versions.db', check_same_thread=False)
|
||||
conn = sqlite3.connect(
|
||||
"/github-ntfy/ghntfy_versions.db",
|
||||
check_same_thread=False,
|
||||
)
|
||||
cursor = conn.cursor()
|
||||
|
||||
# Creating the table if it does not exist
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS versions
|
||||
(repo TEXT PRIMARY KEY, version TEXT, changelog TEXT)''')
|
||||
cursor.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS versions
|
||||
(repo TEXT PRIMARY KEY, version TEXT, changelog TEXT)"""
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
cursor.execute('''CREATE TABLE IF NOT EXISTS docker_versions
|
||||
(repo TEXT PRIMARY KEY, digest TEXT, changelog TEXT)''')
|
||||
cursor.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS docker_versions
|
||||
(repo TEXT PRIMARY KEY, digest TEXT)"""
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
logger.info("Starting version monitoring...")
|
||||
|
||||
conn2 = sqlite3.connect('/github-ntfy/watched_repos.db', check_same_thread=False)
|
||||
conn2 = sqlite3.connect("/github-ntfy/watched_repos.db", check_same_thread=False)
|
||||
cursor2 = conn2.cursor()
|
||||
|
||||
cursor2.execute('''CREATE TABLE IF NOT EXISTS watched_repos
|
||||
(id INTEGER PRIMARY KEY, repo TEXT)''')
|
||||
cursor2.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS watched_repos
|
||||
(id INTEGER PRIMARY KEY, repo TEXT)"""
|
||||
)
|
||||
conn2.commit()
|
||||
|
||||
cursor2.execute('''CREATE TABLE IF NOT EXISTS docker_watched_repos
|
||||
(id INTEGER PRIMARY KEY, repo TEXT)''')
|
||||
cursor2.execute(
|
||||
"""CREATE TABLE IF NOT EXISTS docker_watched_repos
|
||||
(id INTEGER PRIMARY KEY, repo TEXT)"""
|
||||
)
|
||||
conn2.commit()
|
||||
|
||||
|
||||
@@ -98,36 +133,41 @@ def get_latest_releases(watched_repos):
|
||||
if response.status_code == 200:
|
||||
release_info = response.json()
|
||||
changelog = get_changelog(repo)
|
||||
release_date = release_info.get('published_at', 'Release date not available')
|
||||
releases.append({
|
||||
"repo": repo,
|
||||
"name": release_info["name"],
|
||||
"tag_name": release_info["tag_name"],
|
||||
"html_url": release_info["html_url"],
|
||||
"changelog": changelog,
|
||||
"published_at": release_date
|
||||
})
|
||||
release_date = release_info.get("published_at", "Release date not available")
|
||||
releases.append(
|
||||
{
|
||||
"repo": repo,
|
||||
"name": release_info["name"],
|
||||
"tag_name": release_info["tag_name"],
|
||||
"html_url": release_info["html_url"],
|
||||
"changelog": changelog,
|
||||
"published_at": release_date,
|
||||
}
|
||||
)
|
||||
else:
|
||||
logger.error(f"Failed to fetch release info for {repo}")
|
||||
return releases
|
||||
|
||||
|
||||
def get_latest_docker_releases(watched_repos):
|
||||
releases = []
|
||||
for repo in watched_repos:
|
||||
url = f"https://hub.docker.com/v2/repositories/{repo_name}/tags/latest"
|
||||
url = f"https://hub.docker.com/v2/repositories/{repo}/tags/latest"
|
||||
response = requests.get(url, headers=docker_header)
|
||||
if response.status_code == 200:
|
||||
release_info = response.json()
|
||||
release_date=release_info["last_upated"]
|
||||
release_date = release_info["last_upated"]
|
||||
digest = release_date["digest"]
|
||||
releases.append({
|
||||
"repo": repo,
|
||||
"digest": digest,
|
||||
"html_url": "https://hub.docker.com/r/" + repo,
|
||||
"published_at": release_date
|
||||
})
|
||||
releases.append(
|
||||
{
|
||||
"repo": repo,
|
||||
"digest": digest,
|
||||
"html_url": "https://hub.docker.com/r/" + repo,
|
||||
"published_at": release_date,
|
||||
}
|
||||
)
|
||||
else:
|
||||
logger.error(f"Failed to fetch Docker Hub info for {repo_name}")
|
||||
logger.error(f"Failed to fetch Docker Hub info for {repo}")
|
||||
return releases
|
||||
|
||||
|
||||
@@ -138,103 +178,78 @@ def get_changelog(repo):
|
||||
releases = response.json()
|
||||
if releases:
|
||||
latest_release_list = releases[0]
|
||||
if 'body' in latest_release_list:
|
||||
return latest_release_list['body']
|
||||
if "body" in latest_release_list:
|
||||
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, slack_webhook_url):
|
||||
threads = []
|
||||
|
||||
def github_send_to_ntfy(releases, auth, 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
|
||||
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)))
|
||||
|
||||
# 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
|
||||
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)))
|
||||
|
||||
message = f"New version: {version_number}\nFor: {app_name}\nPublished on: {release_date}\nChangelog:\n{changelog}\n{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()
|
||||
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)))
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Basic {auth}",
|
||||
"Title": f"New version for {app_name}",
|
||||
"Priority": "urgent",
|
||||
"Markdown": "yes",
|
||||
"Actions": f"view, Update {app_name}, {app_url}, clear=true"}
|
||||
response = requests.post(f"{url}", headers=headers, data=message)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Ntfy for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Ntfy. Status code: {response.status_code}")
|
||||
if slack_webhook_url:
|
||||
if github_latest_release:
|
||||
threads.append(threading.Thread(target=github_send_to_slack, args=(github_latest_release, slack_webhook_url)))
|
||||
if docker_latest_release:
|
||||
threads.append(threading.Thread(target=docker_send_to_slack, args=(docker_latest_release, slack_webhook_url)))
|
||||
|
||||
for thread in threads:
|
||||
thread.start()
|
||||
|
||||
def docker_send_to_ntfy(releases, auth, 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
|
||||
for thread in threads:
|
||||
thread.join()
|
||||
|
||||
# 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
|
||||
|
||||
message = f"New version: {digest_number}\nFor: {app_name}\nPublished on: {release_date}\nChangelog:\n{changelog}\n{app_url}"
|
||||
# Updating the previous digest for this application
|
||||
cursor.execute("INSERT OR REPLACE INTO docker_versions (repo, digest, changelog) VALUES (?, ?, ?)",
|
||||
(app_name, digest_number, changelog))
|
||||
conn.commit()
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Basic {auth}",
|
||||
"Title": f"New version for {app_name}",
|
||||
"Priority": "urgent",
|
||||
"Markdown": "yes",
|
||||
"Actions": f"view, Update {app_name}, {app_url}, clear=true"}
|
||||
response = requests.post(f"{url}", headers=headers, data=message)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Ntfy for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Ntfy. Status code: {response.status_code}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
start_api()
|
||||
with open('/auth.txt', 'r') as f:
|
||||
with open("/auth.txt", "r") as f:
|
||||
auth = f.read().strip()
|
||||
ntfy_url = os.environ.get('NTFY_URL')
|
||||
timeout = float(os.environ.get('GHNTFY_TIMEOUT'))
|
||||
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"))
|
||||
slack_webhook_url = os.environ.get("SLACK_WEBHOOK_URL")
|
||||
|
||||
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)
|
||||
if github_latest_release:
|
||||
github_send_to_ntfy(github_latest_release, auth, ntfy_url)
|
||||
docker_watched_repos_list = get_docker_watched_repos()
|
||||
docker_latest_release = get_latest_docker_releases(docker_watched_repos_list)
|
||||
if docker_latest_release:
|
||||
docker_send_to_ntfy(docker_latest_release, auth, ntfy_url)
|
||||
time.sleep(timeout) # Wait an hour before checking again
|
||||
|
||||
notify_all_services(github_latest_release, docker_latest_release, auth, ntfy_url, gotify_url, gotify_token, discord_webhook_url, slack_webhook_url)
|
||||
|
||||
time.sleep(timeout)
|
||||
else:
|
||||
logger.error("Usage: python ntfy.py")
|
||||
logger.error(
|
||||
"auth: can be generataed by the folowing command: echo -n 'username:password' | base64 and need to be "
|
||||
"stored in a file named auth.txt")
|
||||
"stored in a file named auth.txt"
|
||||
)
|
||||
logger.error("NTFY_URL: the url of the ntfy server need to be stored in an environment variable named NTFY_URL")
|
||||
|
||||
logger.error(
|
||||
"GOTIFY_URL: the url of the gotify server need to be stored in an environment variable named GOTIFY_URL"
|
||||
)
|
||||
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")
|
||||
|
||||
103
ntfy_api.py
103
ntfy_api.py
@@ -6,8 +6,9 @@ app = Flask(__name__)
|
||||
CORS(app)
|
||||
app.logger.setLevel("WARNING")
|
||||
|
||||
|
||||
def get_db_connection():
|
||||
conn = sqlite3.connect('/github-ntfy/watched_repos.db')
|
||||
conn = sqlite3.connect("/github-ntfy/watched_repos.db")
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
@@ -16,14 +17,17 @@ def close_db_connection(conn):
|
||||
conn.close()
|
||||
|
||||
|
||||
@app.route('/app_repo', methods=['POST'])
|
||||
@app.route("/app_repo", methods=["POST"])
|
||||
def app_repo():
|
||||
data = request.json
|
||||
repo = data.get('repo')
|
||||
repo = data.get("repo")
|
||||
|
||||
# Vérifier si le champ 'repo' est présent dans les données JSON
|
||||
if not repo:
|
||||
return jsonify({"error": "The repo field is required."}), 400
|
||||
return (
|
||||
jsonify({"error": "The repo field is required."}),
|
||||
400,
|
||||
)
|
||||
|
||||
# Établir une connexion à la base de données
|
||||
conn = get_db_connection()
|
||||
@@ -31,13 +35,22 @@ def app_repo():
|
||||
|
||||
try:
|
||||
# Vérifier si le dépôt existe déjà dans la base de données
|
||||
cursor.execute("SELECT * FROM watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"SELECT * FROM watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
existing_repo = cursor.fetchone()
|
||||
if existing_repo:
|
||||
return jsonify({"error": f"The GitHub repo {repo} is already in the database."}), 409
|
||||
return (
|
||||
jsonify({"error": f"The GitHub repo {repo} is already in the database."}),
|
||||
409,
|
||||
)
|
||||
|
||||
# Ajouter le dépôt à la base de données
|
||||
cursor.execute("INSERT INTO watched_repos (repo) VALUES (?)", (repo,))
|
||||
cursor.execute(
|
||||
"INSERT INTO watched_repos (repo) VALUES (?)",
|
||||
(repo,),
|
||||
)
|
||||
conn.commit()
|
||||
return jsonify({"message": f"The GitHub repo {repo} as been added to the watched repos."})
|
||||
finally:
|
||||
@@ -45,14 +58,17 @@ def app_repo():
|
||||
close_db_connection(conn)
|
||||
|
||||
|
||||
@app.route('/app_docker_repo', methods=['POST'])
|
||||
@app.route("/app_docker_repo", methods=["POST"])
|
||||
def app_docker_repo():
|
||||
data = request.json
|
||||
repo = data.get('repo')
|
||||
repo = data.get("repo")
|
||||
|
||||
# Vérifier si le champ 'repo' est présent dans les données JSON
|
||||
if not repo:
|
||||
return jsonify({"error": "The repo field is required."}), 400
|
||||
return (
|
||||
jsonify({"error": "The repo field is required."}),
|
||||
400,
|
||||
)
|
||||
|
||||
# Établir une connexion à la base de données
|
||||
conn = get_db_connection()
|
||||
@@ -60,13 +76,22 @@ def app_docker_repo():
|
||||
|
||||
try:
|
||||
# Vérifier si le dépôt existe déjà dans la base de données
|
||||
cursor.execute("SELECT * FROM docker_watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"SELECT * FROM docker_watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
existing_repo = cursor.fetchone()
|
||||
if existing_repo:
|
||||
return jsonify({"error": f"The Docker repo {repo} is already in the database."}), 409
|
||||
return (
|
||||
jsonify({"error": f"The Docker repo {repo} is already in the database."}),
|
||||
409,
|
||||
)
|
||||
|
||||
# Ajouter le dépôt à la base de données
|
||||
cursor.execute("INSERT INTO docker_watched_repos (repo) VALUES (?)", (repo,))
|
||||
cursor.execute(
|
||||
"INSERT INTO docker_watched_repos (repo) VALUES (?)",
|
||||
(repo,),
|
||||
)
|
||||
conn.commit()
|
||||
return jsonify({"message": f"The Docker repo {repo} as been added to the watched repos."})
|
||||
finally:
|
||||
@@ -74,7 +99,7 @@ def app_docker_repo():
|
||||
close_db_connection(conn)
|
||||
|
||||
|
||||
@app.route('/watched_repos', methods=['GET'])
|
||||
@app.route("/watched_repos", methods=["GET"])
|
||||
def get_watched_repos():
|
||||
db = get_db_connection()
|
||||
cursor = db.cursor()
|
||||
@@ -85,7 +110,7 @@ def get_watched_repos():
|
||||
return jsonify(watched_repos)
|
||||
|
||||
|
||||
@app.route('/watched_docker_repos', methods=['GET'])
|
||||
@app.route("/watched_docker_repos", methods=["GET"])
|
||||
def get_watched_docker_repos():
|
||||
db = get_db_connection()
|
||||
cursor = db.cursor()
|
||||
@@ -96,14 +121,17 @@ def get_watched_docker_repos():
|
||||
return jsonify(watched_repos)
|
||||
|
||||
|
||||
@app.route('/delete_repo', methods=['POST'])
|
||||
@app.route("/delete_repo", methods=["POST"])
|
||||
def delete_repo():
|
||||
data = request.json
|
||||
repo = data.get('repo')
|
||||
repo = data.get("repo")
|
||||
|
||||
# Vérifier si le champ 'repo' est présent dans les données JSON
|
||||
if not repo:
|
||||
return jsonify({"error": "The repo field is required."}), 400
|
||||
return (
|
||||
jsonify({"error": "The repo field is required."}),
|
||||
400,
|
||||
)
|
||||
|
||||
# Établir une connexion à la base de données
|
||||
conn = get_db_connection()
|
||||
@@ -111,13 +139,22 @@ def delete_repo():
|
||||
|
||||
try:
|
||||
# Vérifier si le dépôt existe dans la base de données
|
||||
cursor.execute("SELECT * FROM watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"SELECT * FROM watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
existing_repo = cursor.fetchone()
|
||||
if not existing_repo:
|
||||
return jsonify({"error": f"The GitHub repo {repo} is not in the database."}), 404
|
||||
return (
|
||||
jsonify({"error": f"The GitHub repo {repo} is not in the database."}),
|
||||
404,
|
||||
)
|
||||
|
||||
# Supprimer le dépôt de la base de données
|
||||
cursor.execute("DELETE FROM watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"DELETE FROM watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
conn.commit()
|
||||
return jsonify({"message": f"The GitHub repo {repo} as been deleted from the watched repos."})
|
||||
finally:
|
||||
@@ -125,14 +162,17 @@ def delete_repo():
|
||||
close_db_connection(conn)
|
||||
|
||||
|
||||
@app.route('/delete_docker_repo', methods=['POST'])
|
||||
@app.route("/delete_docker_repo", methods=["POST"])
|
||||
def delete_docker_repo():
|
||||
data = request.json
|
||||
repo = data.get('repo')
|
||||
repo = data.get("repo")
|
||||
|
||||
# Vérifier si le champ 'repo' est présent dans les données JSON
|
||||
if not repo:
|
||||
return jsonify({"error": "The repo field is required."}), 400
|
||||
return (
|
||||
jsonify({"error": "The repo field is required."}),
|
||||
400,
|
||||
)
|
||||
|
||||
# Établir une connexion à la base de données
|
||||
conn = get_db_connection()
|
||||
@@ -140,13 +180,22 @@ def delete_docker_repo():
|
||||
|
||||
try:
|
||||
# Vérifier si le dépôt existe dans la base de données
|
||||
cursor.execute("SELECT * FROM docker_watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"SELECT * FROM docker_watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
existing_repo = cursor.fetchone()
|
||||
if not existing_repo:
|
||||
return jsonify({"error": f"The Docker repo {repo} is not in the database."}), 404
|
||||
return (
|
||||
jsonify({"error": f"The Docker repo {repo} is not in the database."}),
|
||||
404,
|
||||
)
|
||||
|
||||
# Supprimer le dépôt de la base de données
|
||||
cursor.execute("DELETE FROM docker_watched_repos WHERE repo=?", (repo,))
|
||||
cursor.execute(
|
||||
"DELETE FROM docker_watched_repos WHERE repo=?",
|
||||
(repo,),
|
||||
)
|
||||
conn.commit()
|
||||
return jsonify({"message": f"The Docker repo {repo} as been deleted from the watched repos."})
|
||||
finally:
|
||||
|
||||
2
pyproject.toml
Normal file
2
pyproject.toml
Normal file
@@ -0,0 +1,2 @@
|
||||
[tool.black]
|
||||
line-length = 120
|
||||
94
send_discord.py
Normal file
94
send_discord.py
Normal file
@@ -0,0 +1,94 @@
|
||||
import requests
|
||||
import sqlite3
|
||||
import logging
|
||||
|
||||
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]
|
||||
version_number = release["tag_name"]
|
||||
app_url = release["html_url"]
|
||||
changelog = release["changelog"]
|
||||
release_date = release["published_at"].replace("T", " ").replace("Z", "")
|
||||
|
||||
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
|
||||
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```"
|
||||
if len(message) > 2000:
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n🔗 *Release Link*: {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": message,
|
||||
"username": "GitHub Ntfy"
|
||||
}
|
||||
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}")
|
||||
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]
|
||||
digest_number = release["digest"]
|
||||
app_url = release["html_url"]
|
||||
release_date = release["published_at"].replace("T", " ").replace("Z", "")
|
||||
|
||||
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
|
||||
|
||||
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}\n\n🔗 *Link*: {app_url}"
|
||||
|
||||
cursor.execute(
|
||||
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?)",
|
||||
(app_name, digest_number),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
data = {
|
||||
"content": message,
|
||||
"username": "GitHub Ntfy"
|
||||
}
|
||||
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}")
|
||||
logger.error(f"Response: {response.text}")
|
||||
conn.close()
|
||||
98
send_gotify.py
Normal file
98
send_gotify.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import requests
|
||||
import sqlite3
|
||||
import logging
|
||||
|
||||
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:
|
||||
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
|
||||
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```\n\n🔗 *Release Url*:{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()
|
||||
|
||||
content = {
|
||||
"title": f"New version for {app_name}",
|
||||
"message": message,
|
||||
"priority": "2",
|
||||
}
|
||||
response = requests.post(url, json=content)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Gotify for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Gotify. Status code: {response.status_code}")
|
||||
|
||||
|
||||
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:
|
||||
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
|
||||
|
||||
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢 *Published*: {release_date}\n\n🔗 *Release Url*:{app_url}"
|
||||
# Updating the previous digest for this application
|
||||
cursor.execute(
|
||||
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?, ?)",
|
||||
(app_name, digest_number),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
content = {
|
||||
"title": f"New version for {app_name}",
|
||||
"message": message,
|
||||
"priority": "2",
|
||||
}
|
||||
response = requests.post(url, json=content)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Gotify for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Gotify. Status code: {response.status_code}")
|
||||
98
send_ntfy.py
Normal file
98
send_ntfy.py
Normal file
@@ -0,0 +1,98 @@
|
||||
import requests
|
||||
import sqlite3
|
||||
import logging
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```\n\n 🔗 *Release Url*: {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()
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Basic {auth}",
|
||||
"Title": f"New version for {app_name}",
|
||||
"Priority": "urgent",
|
||||
"Markdown": "yes",
|
||||
"Actions": f"view, Update {app_name}, {app_url}, clear=true",
|
||||
}
|
||||
response = requests.post(f"{url}", headers=headers, data=message)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Ntfy for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Ntfy. Status code: {response.status_code}")
|
||||
|
||||
|
||||
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"]
|
||||
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
|
||||
|
||||
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}\n\n 🔗 *Release Url*: {app_url}"
|
||||
# Updating the previous digest for this application
|
||||
cursor.execute(
|
||||
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?, ?)",
|
||||
(app_name, digest_number),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
headers = {
|
||||
"Authorization": f"Basic {auth}",
|
||||
"Title": f"🆕 New version for {app_name}",
|
||||
"Priority": "urgent",
|
||||
"Markdown": "yes",
|
||||
"Actions": f"View, Update {app_name}, {app_url}, clear=true",
|
||||
}
|
||||
response = requests.post(f"{url}", headers=headers, data=message)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Ntfy for {app_name}")
|
||||
continue
|
||||
else:
|
||||
logger.error(f"Failed to send message to Ntfy. Status code: {response.status_code}")
|
||||
131
send_slack.py
Normal file
131
send_slack.py
Normal file
@@ -0,0 +1,131 @@
|
||||
import requests
|
||||
import sqlite3
|
||||
import logging
|
||||
|
||||
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_slack(releases, webhook_url):
|
||||
conn = get_db_connection()
|
||||
cursor = conn.cursor()
|
||||
for release in releases:
|
||||
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", "")
|
||||
|
||||
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
|
||||
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n```{changelog}```"
|
||||
if len(message) > 2000:
|
||||
message = f"📌 *New version*: {version_number}\n\n📦*For*: {app_name}\n\n📅 *Published on*: {release_date}\n\n📝 *Changelog*:\n\n `truncated..` use 🔗 instead "
|
||||
|
||||
cursor.execute(
|
||||
"INSERT OR REPLACE INTO versions (repo, version, changelog) VALUES (?, ?, ?)",
|
||||
(app_name, version_number, changelog),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
|
||||
message = {
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": f"{message}"
|
||||
},
|
||||
"accessory": {
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "🔗 Release Url"
|
||||
},
|
||||
"url": f"{app_url}",
|
||||
"action_id": "button-action"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
}
|
||||
]
|
||||
}
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(webhook_url, json=message, headers=headers)
|
||||
if response.status_code == 200:
|
||||
logger.info(f"Message sent to Slack for {app_name}")
|
||||
else:
|
||||
logger.error(f"Failed to send message to Slack. Status code: {response.status_code}")
|
||||
logger.error(f"Response: {response.text}")
|
||||
conn.close()
|
||||
|
||||
def docker_send_to_slack(releases, webhook_url):
|
||||
conn = get_db_connection()
|
||||
cursor = conn.cursor()
|
||||
for release in releases:
|
||||
app_name = release["repo"].split("/")[-1]
|
||||
digest_number = release["digest"]
|
||||
app_url = release["html_url"]
|
||||
release_date = release["published_at"].replace("T", " ").replace("Z", "")
|
||||
|
||||
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
|
||||
|
||||
message = f"🐳 *Docker Image Updated!*\n\n🔐 *New Digest*: `{digest_number}`\n\n📦 *App*: {app_name}\n\n📢*Published*: {release_date}"
|
||||
|
||||
cursor.execute(
|
||||
"INSERT OR REPLACE INTO docker_versions (repo, digest) VALUES (?, ?)",
|
||||
(app_name, digest_number),
|
||||
)
|
||||
conn.commit()
|
||||
|
||||
message = {
|
||||
"blocks": [
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": f"{message}"
|
||||
},
|
||||
"accessory": {
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "🔗 Release Url"
|
||||
},
|
||||
"url": f"{app_url}",
|
||||
"action_id": "button-action"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "divider"
|
||||
}
|
||||
]
|
||||
}
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(webhook_url, json=message, headers=headers)
|
||||
if 200 <= response.status_code < 300:
|
||||
logger.info(f"Message sent to Slack for {app_name}")
|
||||
else:
|
||||
logger.error(f"Failed to send message to Slack. Status code: {response.status_code}")
|
||||
logger.error(f"Response: {response.text}")
|
||||
conn.close()
|
||||
|
||||
Reference in New Issue
Block a user