sane-tag-music: support "artist.png" artist images

This commit is contained in:
2024-07-11 03:30:42 +00:00
parent 672de68e56
commit 00d644ef07

View File

@@ -94,6 +94,12 @@ logger = logging.getLogger(__name__)
kks = pykakasi.kakasi()
IMAGE_EXTENSIONS = [
"jpg",
"jpeg",
"png",
]
class MediaType(Enum):
Audio = "audio"
Image = "image"
@@ -333,9 +339,24 @@ class Tags:
if loose_compare_str(self.album[0], "Singles"):
self.tracknumber = []
def is_artist_item(self, ext: str) -> bool:
"""
some items are associated with the artist instead of with an album.
for example, `artist.png`.
it's tough to distinguish such an item from an incomplete tag,
so we special-case them.
"""
title = self.title[0].lower() if len(self.title) == 1 else ""
return ext.lower() in IMAGE_EXTENSIONS \
and not self.producer \
and (self.albumartist or self.artist) \
and not self.album \
and title == "artist"
def to_path(self, ext: str) -> str | None:
is_artist_item = self.is_artist_item(ext)
artist = self.albumartist or self.artist
if not (artist and self.album and self.title and ext):
if not (artist and self.album and self.title and ext or is_artist_item):
return None
artist = clean_fields_for_fs(artist, single_fields=False)
@@ -345,6 +366,9 @@ class Tags:
title = clean_fields_for_fs(self.title)
filename = clean_fields_for_fs(trackno + [ f"{title}.{ext}" ])
if is_artist_item:
return os.path.join(artist, filename)
if not (artist and album and title):
return None
@@ -459,13 +483,17 @@ class MediaFile:
def __repr__(self) -> str:
return self.path_
@property
def ext(self):
return os.path.splitext(self.path_)[1][1:]
@staticmethod
def new(f: 'str | MediaFile | None') -> 'MediaFile | None':
if f is None:
return None
if isinstance(f, str):
lower = f.lower()
if lower.endswith(".png") or lower.endswith(".jpg") or lower.endswith("jpeg"):
if any(lower.endswith(f".{e}") for e in IMAGE_EXTENSIONS):
f = ImageFile(f)
else:
f = AudioFile(f)
@@ -630,7 +658,12 @@ class Tagger:
def is_sufficiently_tagged(self, file_: MediaFile) -> bool:
tags = file_.tags_on_disk()
# N.B.: track number isn't wholly necessary; just a nice-to-have.
return (tags.artist or tags.albumartist) and tags.album and tags.title
if (tags.artist or tags.albumartist) and tags.album and tags.title:
return True
if tags.is_artist_item(file_.ext):
# artist image, not part of any album
return True
return False
def tag_file(self, file_: MediaFile) -> None:
old_tags = file_.tags_on_disk()