45 lines
1.1 KiB
Python
45 lines
1.1 KiB
Python
from dataclasses import dataclass
|
|
from abc import ABC, abstractmethod
|
|
from typing import Optional, Self
|
|
from pathlib import Path
|
|
import mutagen
|
|
|
|
|
|
@dataclass
|
|
class Song:
|
|
title: str
|
|
artist: str
|
|
album: Optional[str] = None
|
|
duration: Optional[int] = None
|
|
|
|
@classmethod
|
|
def from_file(cls, path: Path) -> Self:
|
|
metadata = mutagen.File(path, easy=True)
|
|
|
|
if (
|
|
("title" not in metadata) or
|
|
("artist" not in metadata and "albumartist" not in metadata)
|
|
):
|
|
raise RuntimeError("Song is missing title or artist name")
|
|
|
|
title = ", ".join(metadata.get("title"))
|
|
|
|
if "albumartist" in metadata:
|
|
artist = ", ".join(metadata.get("albumartist"))
|
|
else:
|
|
artist = ", ".join(metadata.get("artist"))
|
|
|
|
album = metadata.get("album")
|
|
if album:
|
|
album = ", ".join(album)
|
|
|
|
duration = metadata.info.length
|
|
|
|
return cls(title=title, artist=artist, album=album, duration=duration)
|
|
|
|
|
|
class AbstractProvider(ABC):
|
|
name: str = ""
|
|
@abstractmethod
|
|
def fetch_lyrics(self, song: Song) -> Optional[str]:
|
|
pass
|