Start of the gotify implementation

This commit is contained in:
Félix MARQUET
2024-10-24 13:10:10 +00:00
committed by GitHub
parent d6c0e4e08e
commit 3e59106fa6
9 changed files with 365 additions and 152 deletions

View File

@@ -45,7 +45,7 @@ jobs:
run: |
latest_tag=${{ env.latest_tag }}
if [ -z "$latest_tag" ]; then
new_version="v1.4.3"
new_version="v1.5"
else
IFS='.' read -r -a version_parts <<< "${latest_tag#v}"
new_version="v${version_parts[0]}.$((version_parts[1] + 1)).0"

View File

@@ -1,9 +1,4 @@
**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
- Add gotify compatibility please Read the README.md
**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.3
**Full Changelog**: https://github.com/BreizhHardware/ntfy_alerts/compare/v1.4.3...v1.5

View File

@@ -21,6 +21,8 @@ ENV USERNAME="" \
GHNTFY_TOKEN="" \
DOCKER_USERNAME="" \
DOCKER_PASSWORD="" \
GOTIFY_URL="" \
GOTIFY_TOKEN="" \
FLASK_ENV=production
# Exposer le port 5000 pour l'API et le port 80 pour le serveur web

View File

@@ -28,11 +28,13 @@ 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
volumes:
- /path/to/github-ntfy:/github-ntfy/
ports:
@@ -49,7 +51,7 @@ 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
- [ ] Compatibility with Gotify
- [x] Compatibility with Gotify
- [ ] Compatibility with Discord Webhook
- [ ] Compatibility and distribution for arm64 and armv7
# Bash setup-notify.sh

197
ntfy.py
View File

@@ -5,18 +5,29 @@ import logging
import sqlite3
import subprocess
import json
from send_ntfy import (
github_send_to_ntfy,
docker_send_to_ntfy,
)
from send_gotify import (
github_send_to_gotify,
docker_send_to_gotify,
)
# 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")
def create_dockerhub_token(username, password):
@@ -40,31 +51,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 +120,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 +165,43 @@ 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 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
# 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}\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()
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):
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"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")
timeout = float(os.environ.get("GHNTFY_TIMEOUT"))
if auth and ntfy_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)
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 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)
time.sleep(timeout) # Wait an hour before checking again
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")

View File

@@ -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
View File

@@ -0,0 +1,2 @@
[tool.black]
line-length = 120

98
send_gotify.py Normal file
View File

@@ -0,0 +1,98 @@
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_gotify(releases, token, url):
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}\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()
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_ntfy(releases, token, url):
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"New version: {digest_number}\nFor: {app_name}\nPublished on: {release_date}\n{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
View File

@@ -0,0 +1,98 @@
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_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
# 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}\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()
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):
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"New version: {digest_number}\nFor: {app_name}\nPublished on: {release_date}\n{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}")