119 lines
4.0 KiB
Python
119 lines
4.0 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
DUDA17 - YouTube Video-Liste aktualisieren
|
|
==========================================
|
|
Dieses Skript laeuft auf deinem Server (einmal am Tag per Cron)
|
|
und holt automatisch die aktuellen Video-IDs deines YouTube-Kanals
|
|
ueber die offizielle YouTube Data API v3.
|
|
|
|
Es schreibt die Video-IDs in die Datei "videos.json", die deine
|
|
Webseite dann einfach liest und anzeigt. So bleibt dein API-Key
|
|
auf dem Server versteckt und ist NICHT im Browser/DevTools sichtbar.
|
|
|
|
EINRICHTUNG:
|
|
1. Setze nachfolgend API_KEY und CHANNEL_ID ein.
|
|
2. Teste: python3 fetch_videos.py
|
|
3. Danach einmal taeglich automatisch ausfuehren (Cron):
|
|
crontab -e
|
|
# folgende Zeile einfügen (jeden Tag um 06:00):
|
|
0 6 * * * cd /PFAD/ZU/DEINER/WEBSEITE && /usr/bin/python3 fetch_videos.py
|
|
|
|
Der Pfad in der Cron-Zeile ist der Ordner, in dem auch 'videos.json'
|
|
abgelegt werden soll (= WebRoot-Ordner).
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import os
|
|
import urllib.request
|
|
import urllib.parse
|
|
|
|
# ---------------------------------------------------------------
|
|
# KONFIGURATION - hier eintragen!
|
|
# ---------------------------------------------------------------
|
|
API_KEY = "AIzaSyC-3qzGsalOYpT_gqay1arltMGKjJYPH-8" # dein YouTube API-Key
|
|
CHANNEL_ID = "UCC0zG_TbEEic12DQHnEGmlQ" # deine Kanal-ID
|
|
MAX_RESULTS = 50 # wie viele Videos holen
|
|
|
|
# Ordner, in den videos.json geschrieben werden soll.
|
|
# Standard: aktuelles Verzeichnis dieses Skripts.
|
|
# Auf dem Server: absolute Pfad zu deiner WebRoot angeben, z.B.:
|
|
# OUT_DIR = "/var/www/html/social"
|
|
OUT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
# ---------------------------------------------------------------
|
|
|
|
|
|
def get_uploads_playlist(channel_id):
|
|
# Uploads-Playlist eines Kanals: "UU" + Kanal-ID ohne "UC"
|
|
return "UU" + channel_id[2:] if channel_id.startswith("UC") else "UU" + channel_id
|
|
|
|
|
|
def build_url(playlist_id):
|
|
params = {
|
|
"part": "snippet",
|
|
"playlistId": playlist_id,
|
|
"maxResults": str(MAX_RESULTS),
|
|
"key": API_KEY,
|
|
}
|
|
return "https://www.googleapis.com/youtube/v3/playlistItems?" + urllib.parse.urlencode(params)
|
|
|
|
|
|
def fetch_json(url):
|
|
req = urllib.request.Request(
|
|
url,
|
|
headers={"User-Agent": "Mozilla/5.0 (Duda17-fetch)"},
|
|
)
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
return json.loads(resp.read().decode("utf-8"))
|
|
|
|
|
|
def main():
|
|
if API_KEY == "DEIN_API_KEY_HIER":
|
|
print("FEHLER: Setze zuerst API_KEY in fetch_videos.py", file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
playlist_id = get_uploads_playlist(CHANNEL_ID)
|
|
url = build_url(playlist_id)
|
|
|
|
print("Hole Videos von Kanal:", CHANNEL_ID)
|
|
print("Uploads-Playlist:", playlist_id)
|
|
|
|
data = fetch_json(url)
|
|
|
|
if "error" in data:
|
|
print("API-Fehler:", json.dumps(data["error"], indent=2), file=sys.stderr)
|
|
sys.exit(1)
|
|
|
|
items = []
|
|
for it in data.get("items", []):
|
|
snippet = it.get("snippet", {})
|
|
video_id = snippet.get("resourceId", {}).get("videoId")
|
|
if video_id:
|
|
items.append(
|
|
{
|
|
"id": video_id,
|
|
"title": snippet.get("title", ""),
|
|
"thumb": snippet.get("thumbnails", {}).get("high", {}).get("url", ""),
|
|
"published": snippet.get("publishedAt", ""),
|
|
}
|
|
)
|
|
|
|
# Neueste zuerst (die API liefert bereits chronologisch; schneller
|
|
# hier nach Erscheinungsdatum sortieren, um sicherzugehen)
|
|
items.sort(key=lambda x: x.get("published") or "", reverse=True)
|
|
|
|
# Nur die IDs in die Datei schreiben - schlank fuer die Webseite,
|
|
# die nur die Embed-URLs braucht.
|
|
video_ids = [v["id"] for v in items]
|
|
|
|
os.makedirs(OUT_DIR, exist_ok=True)
|
|
out_path = os.path.join(OUT_DIR, "videos.json")
|
|
with open(out_path, "w", encoding="utf-8") as f:
|
|
json.dump(video_ids, f, ensure_ascii=False, indent=2)
|
|
|
|
print(f"Erfolgreich. {len(video_ids)} Videos geschrieben nach {out_path}")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|