algorithm for identifying filesystem album art

This commit is contained in:
Adrian Sampson 2011-06-24 21:24:15 -07:00
parent 6ca995f4e7
commit 846b85556d
4 changed files with 66 additions and 7 deletions

View file

@ -1,5 +1,5 @@
# This file is part of beets.
# Copyright 2010, Adrian Sampson.
# Copyright 2011, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@ -17,9 +17,13 @@
import urllib
import sys
import logging
import os
from beets.autotag.mb import album_for_id
IMAGE_EXTENSIONS = ['png', 'jpg', 'jpeg']
COVER_NAMES = ['cover', 'front', 'art', 'album', 'folder']
# The common logger.
log = logging.getLogger('beets')
@ -47,6 +51,34 @@ def art_for_asin(asin):
return fn
# Art from the filesystem.
def art_in_path(path):
"""Look for album art files in a specified directory."""
if not os.path.isdir(path):
return
# Find all files that look like images in the directory.
images = []
print path, os.listdir(path)
for fn in os.listdir(path):
for ext in IMAGE_EXTENSIONS:
if fn.lower().endswith('.' + ext):
images.append(fn)
# Look for "preferred" filenames.
for fn in images:
for name in COVER_NAMES:
if fn.lower().startswith(name):
log.debug('Using well-named art file %s' % fn)
return os.path.join(path, fn)
# Fall back to any image in the folder.
if images:
log.debug('Using fallback art file %s' % images[0])
return os.path.join(path, images[0])
# Main interface.
def art_for_album(album):

View file

@ -187,3 +187,8 @@ class ExtraAsserts(object):
def assertNotExists(self, path):
self.assertFalse(os.path.exists(path),
'file exists: %s' % path)
# Utility.
def touch(path):
open(path, 'a').close()

View file

@ -1,5 +1,5 @@
# This file is part of beets.
# Copyright 2010, Adrian Sampson.
# Copyright 2011, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@ -18,6 +18,8 @@ import unittest
import _common
from beets.autotag import art
import os
import shutil
class MockHeaders(object):
def __init__(self, typeval):
@ -53,6 +55,29 @@ class AmazonArtTest(unittest.TestCase):
artpath = art.art_for_album(album)
self.assertEqual(artpath, None)
class FSArtTest(unittest.TestCase):
def setUp(self):
self.dpath = os.path.join(_common.RSRC, 'arttest')
os.mkdir(self.dpath)
def tearDown(self):
shutil.rmtree(self.dpath)
def test_finds_jpg_in_directory(self):
_common.touch(os.path.join(self.dpath, 'a.jpg'))
fn = art.art_in_path(self.dpath)
self.assertEqual(fn, os.path.join(self.dpath, 'a.jpg'))
def test_appropriately_named_file_takes_precedence(self):
_common.touch(os.path.join(self.dpath, 'a.jpg'))
_common.touch(os.path.join(self.dpath, 'cover.jpg'))
fn = art.art_in_path(self.dpath)
self.assertEqual(fn, os.path.join(self.dpath, 'cover.jpg'))
def test_non_image_file_not_identified(self):
_common.touch(os.path.join(self.dpath, 'a.txt'))
fn = art.art_in_path(self.dpath)
self.assertEqual(fn, None)
def suite():
return unittest.TestLoader().loadTestsFromName(__name__)

View file

@ -1,5 +1,5 @@
# This file is part of beets.
# Copyright 2010, Adrian Sampson.
# Copyright 2011, Adrian Sampson.
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
@ -22,13 +22,10 @@ import stat
from os.path import join
import _common
from _common import item
from _common import item, touch
import beets.library
from beets import util
def touch(path):
open(path, 'a').close()
class MoveTest(unittest.TestCase):
def setUp(self):
# make a temporary file