Initial commit

This commit is contained in:
florian 2025-07-16 13:32:21 +02:00
parent 22957fa34e
commit 0d04a0f790
8 changed files with 184 additions and 0 deletions

2
.gitignore vendored
View File

@ -168,3 +168,5 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
state.json

View File

@ -1,2 +1,13 @@
# docker-repository-query
## Necessary environment variables saved in .env
GITHUB_TOKEN=
DOCKER_TOKEN=
DOCKER_USERNAME=
MAIL_ADDRESS=
FROM_ADDRESS=

29
dockerhub_api.py Normal file
View File

@ -0,0 +1,29 @@
import requests
from dotenv import load_dotenv
import os
load_dotenv()
DOCKER_TOKEN = os.getenv("DOCKER_TOKEN")
DOCKER_USERNAME = os.getenv("DOCKER_USERNAME")
def login_and_get_token():
login_url = "https://hub.docker.com/v2/users/login/"
response = requests.post(login_url,
json={"username": DOCKER_USERNAME, "password": DOCKER_TOKEN})
if response.status_code == 200:
token = response.json()["token"]
return token
else:
print(f"Login failed: {response.status_code} - {response.text}")
def find_package_version_with_tag(repo, tag):
token = login_and_get_token()
headers = {"Authorization": f"JWT {token}"}
tags_url = f"https://hub.docker.com/v2/repositories/{repo}/tags/{tag}?page_size=1"
tags_response = requests.get(tags_url, headers=headers)
id = tags_response.json()["id"]
return id
if __name__ == "__main__":
print(find_package_version_with_tag("pihole/pihole", "latest"))

42
github_api.py Normal file
View File

@ -0,0 +1,42 @@
import requests
from dotenv import load_dotenv
import os
load_dotenv()
GITHUB_TOKEN = os.getenv("GITHUB_TOKEN")
def find_package_version_with_tag(org , package, target_tag):
headers = {
"Authorization": f"Bearer {GITHUB_TOKEN}",
"Accept": "application/vnd.github+json"
}
page = 1
per_page = 100
while True:
url = f"https://api.github.com/orgs/{org}/packages/container/{package}/versions"
params = {"per_page": per_page, "page": page}
response = requests.get(url, headers=headers, params=params)
if response.status_code != 200:
print(f"Error {response.status_code}: {response.text}")
return None
versions = response.json()
if not versions:
print(f"Reached end of pages — tag '{target_tag}' not found.")
return None
for version in versions:
tags = version.get("metadata", {}).get("container", {}).get("tags", [])
if target_tag in tags:
print(f"Found tag '{target_tag}' on page {page}:\n")
return version["id"]
page += 1
if __name__ == "__main__":
find_package_version_with_tag("Suwayomi", "tachidesk", "stable")

45
query_and_compare.py Normal file
View File

@ -0,0 +1,45 @@
from github_api import find_package_version_with_tag as find_package_version_with_tag_github
from dockerhub_api import find_package_version_with_tag as find_package_version_with_tag_dockerhub
import os
import json
def retrieve_state ():
default_state = {
"suwayomi_id": "",
"pihole_id":""
}
if os.path.exists("state.json"):
with open("state.json", "r") as f:
return json.load(f)
else:
state = default_state.copy()
return state
def save_state(state):
with open("state.json", "w") as f:
json.dump(state, f, indent=2)
def check_for_new_suwayomi_version():
latest_online_version = find_package_version_with_tag_github("Suwayomi", "tachidesk", "stable")
local_state = retrieve_state()
if latest_online_version != local_state["suwayomi_id"]:
local_state["suwayomi_id"] = latest_online_version
save_state(local_state)
print("New Suwayomi version has been found")
return True
print("No new Suwayomi version found")
return False
def check_for_new_pihole_version():
latest_online_version = find_package_version_with_tag_dockerhub("pihole/pihole", "latest")
local_state = retrieve_state()
if latest_online_version != local_state["pihole_id"]:
local_state["pihole_id"] = latest_online_version
save_state(local_state)
print("New Pi-hole version has been found")
return True
print("No new Pi-hole version found")
return False
if __name__ == '__main__':
check_for_new_pihole_version()

14
requirements.txt Normal file
View File

@ -0,0 +1,14 @@
blinker==1.9.0
certifi==2025.7.14
charset-normalizer==3.4.2
click==8.2.1
dotenv==0.9.9
Flask==3.1.1
idna==3.10
itsdangerous==2.2.0
Jinja2==3.1.6
MarkupSafe==3.0.2
python-dotenv==1.1.1
requests==2.32.4
urllib3==2.5.0
Werkzeug==3.1.3

19
send_mail.py Normal file
View File

@ -0,0 +1,19 @@
import smtplib
from email.message import EmailMessage
from dotenv import load_dotenv
import os
load_dotenv()
MAIL_ADDRESS = os.getenv("MAIL_ADDRESS")
FROM_ADDRESS = os.getenv("FROM_ADDRESS", "noreply@localhost")
def send_mail(subject):
msg = EmailMessage()
msg["From"] = FROM_ADDRESS
msg["To"] = MAIL_ADDRESS
msg["Subject"] = subject
msg.set_content("New Docker image is available")
with smtplib.SMTP("localhost", 25) as server:
server.send_message(msg)

22
webserver.py Normal file
View File

@ -0,0 +1,22 @@
from query_and_compare import check_for_new_suwayomi_version,check_for_new_pihole_version
from flask import Flask
from send_mail import send_mail
app = Flask(__name__)
@app.route('/suwayomi', methods=['GET'])
def handle_suwayomi():
print("Suwayomi handler invoked")
if check_for_new_suwayomi_version():
send_mail("New Suwayomi version available")
return '', 200
@app.route('/pihole', methods=['GET'])
def handle_pihole():
print("Pi-hole handler invoked")
if check_for_new_pihole_version():
send_mail("New Pi-hole version available")
return '', 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)