1
0
mirror of https://github.com/spl0k/supysonic.git synced 2024-12-23 01:16:18 +00:00
supysonic/supysonic/covers.py

85 lines
2.0 KiB
Python

# coding: utf-8
#
# This file is part of Supysonic.
# Supysonic is a Python implementation of the Subsonic server API.
#
# Copyright (C) 2018 Alban 'spl0k' Féron
#
# Distributed under terms of the GNU AGPLv3 license.
import os, os.path
import re
from PIL import Image
EXTENSIONS = ('.jpg', '.jpeg', '.png', '.bmp')
NAMING_SCORE_RULES = (
('cover', 5),
('albumart', 5),
('folder', 5),
('front', 10),
('back', -10),
('large', 2),
('small', -2)
)
class CoverFile(object):
__clean_regex = re.compile(r'[^a-z]')
@staticmethod
def __clean_name(name):
return CoverFile.__clean_regex.sub('', name.lower())
def __init__(self, name, album_name = None):
self.name = name
self.score = 0
for part, score in NAMING_SCORE_RULES:
if part in name.lower():
self.score += score
if album_name:
basename, _ = os.path.splitext(name)
clean = CoverFile.__clean_name(basename)
album_name = CoverFile.__clean_name(album_name)
if clean in album_name or album_name in clean:
self.score += 20
def is_valid_cover(path):
if not os.path.isfile(path):
return False
_, ext = os.path.splitext(path)
if ext.lower() not in EXTENSIONS:
return False
try: # Ensure the image can be read
with Image.open(path):
return True
except IOError:
return False
def find_cover_in_folder(path, album_name = None):
if not os.path.isdir(path):
raise ValueError('Invalid path')
candidates = []
for f in os.listdir(path):
try:
file_path = os.path.join(path, f)
except UnicodeError:
continue
if not is_valid_cover(file_path):
continue
cover = CoverFile(f, album_name)
candidates.append(cover)
if not candidates:
return None
if len(candidates) == 1:
return candidates[0]
return sorted(candidates, key = lambda c: c.score, reverse = True)[0]