Compare commits

...

4 Commits
v1.2.1 ... v1.3

6 changed files with 106 additions and 27 deletions

View File

@@ -16,7 +16,8 @@ ENV USERNAME="" \
PASSWORD="" \
NTFY_URL="" \
GHNTFY_TIMEOUT="3600" \
GHNTFY_TOKEN=""
GHNTFY_TOKEN="" \
FLASK_ENV=production
# Exposer le port 5000 pour l'API et le port 80 pour le serveur web
EXPOSE 5000 80

View File

@@ -7,7 +7,7 @@
<script src="https://cdn.tailwindcss.com"></script>
<script src="./script.js" defer></script>
</head>
<body class="bg-gradient-to-b from-cyan-500 to-fuchsia-500">
<body class="bg-gradient-to-b from-stone-500 to-green-700">
<div class="flex flex-col gap-2 justify-center items-center my-2 h-screen">
<h1 class="text-4xl font-semibold leading-10 text-gray-900">Github-Ntfy</h1>
<h1>Add a repo</h1>

View File

@@ -28,5 +28,12 @@ http {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /delete_repo {
proxy_pass http://127.0.0.1:5000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
}

44
ntfy.py
View File

@@ -5,7 +5,7 @@ import logging
import sqlite3
import subprocess
# Configurer le logger
# Configuring the logger
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
@@ -14,16 +14,16 @@ github_headers = {}
if github_token:
github_headers['Authorization'] = f"token {github_token}"
# Connexion à la base de données pour stocker les versions précédentes
# Connecting to the database to store previous versions
conn = sqlite3.connect('/github-ntfy/ghntfy_versions.db', check_same_thread=False)
cursor = conn.cursor()
# Création de la table si elle n'existe pas
# Creating the table if it does not exist
cursor.execute('''CREATE TABLE IF NOT EXISTS versions
(repo TEXT PRIMARY KEY, version TEXT, changelog TEXT)''')
conn.commit()
logger.info("Démarrage de la surveillance des versions...")
logger.info("Starting version monitoring...")
conn2 = sqlite3.connect('/github-ntfy/watched_repos.db', check_same_thread=False)
cursor2 = conn2.cursor()
@@ -54,12 +54,14 @@ 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
"changelog": changelog,
"published_at": release_date
})
else:
logger.error(f"Failed to fetch release info for {repo}")
@@ -75,25 +77,27 @@ def get_changelog(repo):
latest_release_list = releases[0]
if 'body' in latest_release_list:
return latest_release_list['body']
return "Changelog non disponible"
return "Changelog not available"
def send_to_ntfy(releases, auth, url):
for release in releases:
app_name = release['repo'].split('/')[-1] # Obtenir le nom de l'application à partir du repo
version_number = release['tag_name'] # Obtenir le numéro de version
app_url = release['html_url'] # Obtenir l'URL de l'application
changelog = release['changelog'] # Obtenir le changelog
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
# Vérifier si la version a changé depuis la dernière fois
# 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"La version de {app_name} n'a pas changé. Pas de notification envoyée.")
continue # Passer à l'application suivante
logger.info(f"The version of {app_name} has not changed. No notification sent.")
continue # Move on to the next application
message = f"Nouvelle version: {version_number}\nPour: {app_name}\nChangelog:\n{changelog}\n{app_url}"
# Mettre à jour la version précédente pour cette 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()
@@ -106,10 +110,10 @@ def send_to_ntfy(releases, auth, url):
"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 envoyé à Ntfy pour {app_name}")
logger.info(f"Message sent to Ntfy for {app_name}")
continue
else:
logger.error(f"Échec de l'envoi du message à Ntfy. Code d'état : {response.status_code}")
logger.error(f"Failed to send message to Ntfy. Status code: {response.status_code}")
if __name__ == "__main__":
@@ -125,9 +129,11 @@ if __name__ == "__main__":
latest_release = get_latest_releases(watched_repos_list)
if latest_release:
send_to_ntfy(latest_release, auth, ntfy_url)
time.sleep(timeout) # Attendre une heure avant de vérifier à nouveau
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")
"auth: can be generataed by the folowing command: echo -n 'username:password' | base64 and need to be "
"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

@@ -4,7 +4,7 @@ import sqlite3
app = Flask(__name__)
CORS(app)
app.logger.setLevel("WARNING")
def get_db_connection():
conn = sqlite3.connect('/github-ntfy/watched_repos.db')
@@ -23,7 +23,7 @@ def app_repo():
# Vérifier si le champ 'repo' est présent dans les données JSON
if not repo:
return jsonify({"error": "Le champ 'repo' est requis."}), 400
return jsonify({"error": "The repo field is required."}), 400
# Établir une connexion à la base de données
conn = get_db_connection()
@@ -34,12 +34,12 @@ def app_repo():
cursor.execute("SELECT * FROM watched_repos WHERE repo=?", (repo,))
existing_repo = cursor.fetchone()
if existing_repo:
return jsonify({"error": f"Le dépôt {repo} existe déjà."}), 409
return jsonify({"error": f"The 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,))
conn.commit()
return jsonify({"message": f"Le dépôt {repo} a été ajouté à la liste des dépôts surveillés."})
return jsonify({"message": f"The repo {repo} as been added to the watched repos."})
finally:
# Fermer la connexion à la base de données
close_db_connection(conn)
@@ -56,5 +56,34 @@ def get_watched_repos():
return jsonify(watched_repos)
@app.route('/delete_repo', methods=['POST'])
def delete_repo():
data = request.json
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
# Établir une connexion à la base de données
conn = get_db_connection()
cursor = conn.cursor()
try:
# Vérifier si le dépôt existe dans la base de données
cursor.execute("SELECT * FROM watched_repos WHERE repo=?", (repo,))
existing_repo = cursor.fetchone()
if not existing_repo:
return jsonify({"error": f"The 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,))
conn.commit()
return jsonify({"message": f"The repo {repo} as been deleted from the watched repos."})
finally:
# Fermer la connexion à la base de données
close_db_connection(conn)
if __name__ == "__main__":
app.run(debug=True)
app.run(debug=False)

View File

@@ -32,7 +32,24 @@ function refreshWatchedRepos() {
// Ajouter chaque dépôt surveillé à la liste
data.forEach(repo => {
const listItem = document.createElement('li');
listItem.textContent = repo;
const repoName = document.createElement('span');
repoName.textContent = repo;
repoName.className = 'repo-name';
listItem.appendChild(repoName);
const deleteButton = document.createElement('button');
deleteButton.textContent = ' X';
deleteButton.className = 'delete-btn text-red-500 ml-2';
deleteButton.addEventListener('click', () => {
// Remove the repo from the watched repos
// This is a placeholder. Replace it with your actual code to remove the repo from the watched repos.
removeRepoFromWatchedRepos(repo);
// Remove the repo from the DOM
listItem.remove();
});
listItem.appendChild(deleteButton);
watchedReposList.appendChild(listItem);
});
})
@@ -41,5 +58,24 @@ function refreshWatchedRepos() {
});
}
function removeRepoFromWatchedRepos(repo) {
fetch('/delete_repo', {
method: 'POST',
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json'
},
body: JSON.stringify({repo: repo})
})
.then(response => {
if (!response.ok) {
throw new Error('Erreur lors de la suppression du dépôt');
}
})
.catch(error => {
console.error('Error:', error);
});
}
// Appeler la fonction pour charger les dépôts surveillés au chargement de la page
refreshWatchedRepos();