Verbessere die RSS-Feed-Erstellung durch Hinzufügen des Atom-Namespace, Aktualisierung der lastBuildDate und pubDate mit dem aktuellen Datum sowie Anpassungen der iTunes-Tags für bessere Kompatibilität.
This commit is contained in:
		@@ -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 <image> 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:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user