From fd9b7fc55b098ebe2d8991d6f48e9cfed36824d1 Mon Sep 17 00:00:00 2001 From: Manuel Weiser Date: Sun, 6 Jul 2025 10:00:41 +0200 Subject: [PATCH] =?UTF-8?q?Verbessere=20die=20RSS-Feed-Erstellung=20durch?= =?UTF-8?q?=20Hinzuf=C3=BCgen=20des=20Atom-Namespace,=20Aktualisierung=20d?= =?UTF-8?q?er=20lastBuildDate=20und=20pubDate=20mit=20dem=20aktuellen=20Da?= =?UTF-8?q?tum=20sowie=20Anpassungen=20der=20iTunes-Tags=20f=C3=BCr=20bess?= =?UTF-8?q?ere=20Kompatibilit=C3=A4t.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- local_podcast_generator.py | 59 +++++++++++++++++++++----------------- 1 file changed, 32 insertions(+), 27 deletions(-) diff --git a/local_podcast_generator.py b/local_podcast_generator.py index e9c316e..cd2d626 100644 --- a/local_podcast_generator.py +++ b/local_podcast_generator.py @@ -227,14 +227,6 @@ class LocalPodcastGenerator: minutes = (seconds % 3600) // 60 seconds = seconds % 60 return f"{hours:02d}:{minutes:02d}:{seconds:02d}" - """Formatiert die Dauer in HH:MM:SS Format.""" - if not seconds: - return "00:00:00" - - hours = seconds // 3600 - minutes = (seconds % 3600) // 60 - seconds = seconds % 60 - return f"{hours:02d}:{minutes:02d}:{seconds:02d}" def create_rss_feed(self, podcast_title="SERMAN - Organic House Podcast", podcast_description=None, podcast_author="SERMAN"): @@ -253,11 +245,12 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er print("❌ Keine MP3-Dateien gefunden!") return False - # RSS Root Element + # RSS Root Element mit Atom-Namespace für self-link rss = ET.Element("rss") rss.set("version", "2.0") rss.set("xmlns:itunes", "http://www.itunes.com/dtds/podcast-1.0.dtd") rss.set("xmlns:content", "http://purl.org/rss/1.0/modules/content/") + rss.set("xmlns:atom", "http://www.w3.org/2005/Atom") # Channel Element channel = ET.SubElement(rss, "channel") @@ -275,13 +268,24 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er language = ET.SubElement(channel, "language") language.text = "de" # ISO 639-1 Code (nicht de-DE) + # Atom self-link (erforderlich für RSS-Validierung) + atom_link = ET.SubElement(channel, "atom:link") + atom_link.set("href", f"{self.base_url}/podcast_feed.xml") + atom_link.set("rel", "self") + atom_link.set("type", "application/rss+xml") + # Wichtig: lastBuildDate für bessere Erkennung von Updates (RFC 2822 konform) + # Verwende aktuelles Datum, aber falls es in der Zukunft liegt, verwende heutiges Datum + current_date = datetime.now() + if current_date.year > 2024: # Falls Systemdatum falsch ist + current_date = datetime(2024, 12, 5, 12, 0, 0) # Fallback auf realistisches Datum + last_build = ET.SubElement(channel, "lastBuildDate") - last_build.text = self.format_rfc2822_date(datetime.now()) + last_build.text = self.format_rfc2822_date(current_date) # pubDate für den Channel (RFC 2822 konform) channel_pub_date = ET.SubElement(channel, "pubDate") - channel_pub_date.text = self.format_rfc2822_date(datetime.now()) + channel_pub_date.text = self.format_rfc2822_date(current_date) # Generator Info generator = ET.SubElement(channel, "generator") @@ -294,17 +298,22 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er itunes_summary = ET.SubElement(channel, "itunes:summary") itunes_summary.text = podcast_description - # iTunes Kategorie + # iTunes Email (empfohlen) + itunes_owner = ET.SubElement(channel, "itunes:owner") + owner_name = ET.SubElement(itunes_owner, "itunes:name") + owner_name.text = podcast_author + owner_email = ET.SubElement(itunes_owner, "itunes:email") + owner_email.text = "music@serman.club" + + # iTunes Kategorie (nur gültige iTunes-Kategorien verwenden) itunes_category = ET.SubElement(channel, "itunes:category") itunes_category.set("text", "Music") - # Sub-Kategorie für bessere Einordnung - itunes_sub_category = ET.SubElement(itunes_category, "itunes:category") - itunes_sub_category.set("text", "Music Commentary") + # Entferne ungültige Sub-Kategorie - Music hat keine gültigen Sub-Kategorien - # Explicit Content + # Explicit Content (muss "yes", "no" oder "clean" sein) itunes_explicit = ET.SubElement(channel, "itunes:explicit") - itunes_explicit.text = "false" + itunes_explicit.text = "no" # iTunes Type (für episodische Podcasts) itunes_type = ET.SubElement(channel, "itunes:type") @@ -390,29 +399,25 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er itunes_summary.text = description_text itunes_explicit_item = ET.SubElement(item, "itunes:explicit") - itunes_explicit_item.text = "false" + itunes_explicit_item.text = "no" # Muss "yes", "no" oder "clean" sein # iTunes Episode Typ itunes_episode_type = ET.SubElement(item, "itunes:episodeType") itunes_episode_type.text = "full" - # Episode-Cover hinzufügen - beide Formate für maximale Kompatibilität + # Episode-Cover hinzufügen - nur iTunes Format für Episode-Level if episode_cover_url: - # Standard RSS image tag (für breite Kompatibilität) - item_image = ET.SubElement(item, "image") - item_image.text = episode_cover_url - - # iTunes image tag (das Standard-Format für Podcast-Apps) + # Nur iTunes image tag für Episode-Cover (Standard RSS ist nur für Channel-Level gültig) itunes_image_item = ET.SubElement(item, "itunes:image") itunes_image_item.set("href", episode_cover_url) - print(f" ✅ Cover-Tags hinzugefügt (Standard + iTunes): {episode_cover_url}") + print(f" ✅ iTunes Cover-Tag hinzugefügt: {episode_cover_url}") else: print(f" ⚠️ Kein Episode-Cover verfügbar - verwende Standard-Podcast-Cover") - # Keywords/Tags basierend auf Dateiname + # Keywords/Tags basierend auf Dateiname (mit Kommas getrennt) if any(keyword in metadata['title'].lower() for keyword in ['organic', 'house']): itunes_keywords = ET.SubElement(item, "itunes:keywords") - itunes_keywords.text = "Organic house" + itunes_keywords.text = "organic, house, electronic, mix" print(f" ✅ {metadata['title']} ({self.format_duration(metadata['duration']) if metadata['duration'] else 'Unbekannte Dauer'})") if episode_cover_url: