"""NFO-Generator für Jellyfin (Kodi/NFO-Schema).""" from pathlib import Path from typing import List from xml.dom.minidom import getDOMImplementation class NFOGenerator: def __init__(self): self.dom_impl = getDOMImplementation() def _create_element(self, doc, name: str, text: str = None) -> None: """Hilfsfunktion für Element-Erstellung.""" element = doc.createElement(name) if text: element.appendChild(doc.createTextNode(str(text))) return element def generate_movie_nfo(self, title: str, year: int, overview: str = "", rating: float = 0.0, runtime: int = 0, genres: List[str] = None, director: str = "", writer: str = "", actors: List[str] = None, studio: str = "", premiered: str = "", mpaa: str = "") -> str: """Generiere movie.nfo für Filme.""" doc = self.dom_impl.createDocument(None, "movie", None) root = doc.documentElement root.appendChild(self._create_element(doc, "title", title)) root.appendChild(self._create_element(doc, "year", year)) root.appendChild(self._create_element(doc, "plot", overview)) root.appendChild(self._create_element(doc, "rating", rating)) root.appendChild(self._create_element(doc, "runtime", runtime)) if genres: for genre in genres: root.appendChild(self._create_element(doc, "genre", genre)) if director: root.appendChild(self._create_element(doc, "director", director)) if writer: root.appendChild(self._create_element(doc, "writer", writer)) if actors: for actor in actors: actor_node = doc.createElement("actor") actor_node.appendChild(self._create_element(doc, "name", actor)) root.appendChild(actor_node) if studio: root.appendChild(self._create_element(doc, "studio", studio)) if premiered: root.appendChild(self._create_element(doc, "premiered", premiered)) if mpaa: root.appendChild(self._create_element(doc, "mpaa", mpaa)) # Attribution root.appendChild(self._create_element(doc, "details", "Source: TMDB")) return doc.toprettyxml(indent=" ") def generate_series_nfo(self, title: str, year: int, overview: str = "", rating: float = 0.0, genres: List[str] = None, studio: str = "", premiered: str = "") -> str: """Generiere series.nfo für Serien.""" doc = self.dom_impl.createDocument(None, "tvshow", None) root = doc.documentElement root.appendChild(self._create_element(doc, "title", title)) root.appendChild(self._create_element(doc, "year", year)) root.appendChild(self._create_element(doc, "plot", overview)) root.appendChild(self._create_element(doc, "rating", rating)) if genres: for genre in genres: root.appendChild(self._create_element(doc, "genre", genre)) if studio: root.appendChild(self._create_element(doc, "studio", studio)) if premiered: root.appendChild(self._create_element(doc, "premiered", premiered)) # Attribution root.appendChild(self._create_element(doc, "details", "Source: TMDB")) return doc.toprettyxml(indent=" ") def generate_episode_nfo(self, title: str, season: int, episode: int, overview: str = "", rating: float = 0.0, director: str = "", premiered: str = "", writers: List[str] = None) -> str: """Generiere episode.nfo für Episoden.""" doc = self.dom_impl.createDocument(None, "episodedetails", None) root = doc.documentElement root.appendChild(self._create_element(doc, "title", title)) root.appendChild(self._create_element(doc, "season", season)) root.appendChild(self._create_element(doc, "episode", episode)) root.appendChild(self._create_element(doc, "plot", overview)) root.appendChild(self._create_element(doc, "rating", rating)) if director: root.appendChild(self._create_element(doc, "director", director)) if premiered: root.appendChild(self._create_element(doc, "premiered", premiered)) if writers: for writer in writers: root.appendChild(self._create_element(doc, "credits", writer)) return doc.toprettyxml(indent=" ") def generate_album_nfo(self, title: str, artist: str, year: int, genres: List[str] = None, rating: float = 0.0, review: str = "") -> str: """Generiere album.nfo für Musikalben.""" doc = self.dom_impl.createDocument(None, "musicalbum", None) root = doc.documentElement root.appendChild(self._create_element(doc, "title", title)) root.appendChild(self._create_element(doc, "artist", artist)) root.appendChild(self._create_element(doc, "year", year)) root.appendChild(self._create_element(doc, "rating", rating)) root.appendChild(self._create_element(doc, "review", review)) if genres: for genre in genres: root.appendChild(self._create_element(doc, "genre", genre)) # Attribution root.appendChild(self._create_element(doc, "details", "Source: MusicBrainz")) return doc.toprettyxml(indent=" ") def save_nfo(self, content: str, output_path: Path) -> bool: """Speichere NFO-Datei.""" try: output_path.parent.mkdir(parents=True, exist_ok=True) with open(output_path, 'w', encoding='utf-8') as f: f.write(content) return True except Exception as e: print(f"NFO save error: {e}") return False # Beispieldaten if __name__ == "__main__": nfo_gen = NFOGenerator() # movie.nfo movie_nfo = nfo_gen.generate_movie_nfo( title="Inception", year=2010, overview="A thief who steals corporate secrets through the use of dream-sharing technology is given the inverse task of planting an idea into the mind of a C.E.O.", rating=8.8, runtime=148, genres=["Action", "Sci-Fi", "Thriller"], director="Christopher Nolan", actors=["Leonardo DiCaprio", "Joseph Gordon-Levitt", "Ellen Page"] ) print(movie_nfo)