diff --git a/local_podcast_generator.py b/local_podcast_generator.py index 1f6d848..072a795 100644 --- a/local_podcast_generator.py +++ b/local_podcast_generator.py @@ -121,7 +121,7 @@ class LocalPodcastGenerator: # Prüfe ob Cover bereits existiert if cover_path.exists(): # Cover existiert bereits - verwende es einfach (URL-encoded) - cover_url = f"{self.base_url}/_audio/{urllib.parse.quote(cover_filename)}" + cover_url = f"{self.base_url}/_audio/{self.safe_url_encode(cover_filename)}" print(f" 🖼️ Cover bereits vorhanden: {cover_filename}") return cover_url @@ -193,13 +193,18 @@ class LocalPodcastGenerator: return None # Rückgabe der URL zum Cover (URL-encoded für korrekte Links) - cover_url = f"{self.base_url}/_audio/{urllib.parse.quote(cover_filename)}" + cover_url = f"{self.base_url}/_audio/{self.safe_url_encode(cover_filename)}" return cover_url except Exception as e: print(f" ⚠️ Fehler beim Extrahieren des Covers: {e}") return None + def safe_url_encode(self, filename): + """Erstellt URL-sichere Dateinamen durch korrektes Encoding.""" + # Verwende quote_plus für bessere URL-Sicherheit (ersetzt Leerzeichen mit +) + return urllib.parse.quote(filename, safe='') + def format_duration(self, seconds): """Formatiert die Dauer in HH:MM:SS Format.""" if not seconds: @@ -209,6 +214,14 @@ 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"): @@ -247,13 +260,13 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er link.text = self.base_url language = ET.SubElement(channel, "language") - language.text = "de-DE" + language.text = "de" # ISO 639-1 Code (nicht de-DE) - # Wichtig: lastBuildDate für bessere Erkennung von Updates + # Wichtig: lastBuildDate für bessere Erkennung von Updates (RFC 2822 konform) last_build = ET.SubElement(channel, "lastBuildDate") last_build.text = datetime.now().strftime('%a, %d %b %Y %H:%M:%S +0000') - # pubDate für den Channel + # pubDate für den Channel (RFC 2822 konform) channel_pub_date = ET.SubElement(channel, "pubDate") channel_pub_date.text = datetime.now().strftime('%a, %d %b %Y %H:%M:%S +0000') @@ -334,14 +347,14 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er # GUID (eindeutige ID - verwende Audio-URL) item_guid = ET.SubElement(item, "guid") - # Die Audio-URL als eindeutige GUID - audio_url = f"{self.base_url}/_audio/{urllib.parse.quote(metadata['filename'])}" + # Die Audio-URL als eindeutige GUID (URL-safe encoded) + audio_url = f"{self.base_url}/_audio/{self.safe_url_encode(metadata['filename'])}" item_guid.text = audio_url item_guid.set("isPermaLink", "false") - # Veröffentlichungsdatum (korrekt formatiert für RSS) + # Veröffentlichungsdatum (RFC 2822 konform) item_pubdate = ET.SubElement(item, "pubDate") - # RFC 2822 Format für RSS (mit Timezone) + # RFC 2822 Format mit korrekter Timezone pub_date_formatted = metadata['pub_date'].strftime('%a, %d %b %Y %H:%M:%S +0000') item_pubdate.text = pub_date_formatted @@ -351,10 +364,10 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er enclosure.set("type", "audio/mpeg") enclosure.set("length", str(metadata['file_size'])) - # Dauer + # Dauer (Apple empfiehlt Sekunden als Integer) if metadata['duration']: item_duration = ET.SubElement(item, "itunes:duration") - item_duration.text = self.format_duration(metadata['duration']) + item_duration.text = str(int(metadata['duration'])) # Integer Sekunden für Apple # iTunes-spezifische Tags für bessere Episode-Erkennung itunes_title = ET.SubElement(item, "itunes:title") @@ -399,7 +412,8 @@ Ich spezialisiere mich auf House Music, die mehr als nur Beats bietet – sie er ET.indent(tree, space=" ", level=0) try: - tree.write(self.output_file, encoding='utf-8', xml_declaration=True) + # Explizite XML-Deklaration mit UTF-8 encoding + tree.write(self.output_file, encoding='UTF-8', xml_declaration=True) print(f"✅ RSS-Feed erfolgreich erstellt: {self.output_file}") print(f"📊 Anzahl der Episoden: {len(mp3_files)}") print(f"🌐 Audio-URLs verwenden Basis-URL: {self.base_url}")