sane-tag-music: support "artist.png" artist images
This commit is contained in:
@@ -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()
|
||||
|
Reference in New Issue
Block a user