From a78cc65826295daa4034067f5257294dedc774da Mon Sep 17 00:00:00 2001 From: Bruno Cauet Date: Thu, 29 Jan 2015 13:06:26 +0100 Subject: [PATCH] Merge freedesktop plugin into thumbnails Add test for that new code, update docs, update the changelog. --- beets/config_default.yaml | 1 + beetsplug/freedesktop.py | 53 +++++++----------------------------- beetsplug/thumbnails.py | 20 +++++++++++++- docs/changelog.rst | 4 ++- docs/plugins/freedesktop.rst | 25 ++--------------- docs/plugins/thumbnails.rst | 4 +++ test/test_thumbnails.py | 31 +++++++++++++++++++++ 7 files changed, 71 insertions(+), 67 deletions(-) diff --git a/beets/config_default.yaml b/beets/config_default.yaml index 295245edf..479edcc10 100644 --- a/beets/config_default.yaml +++ b/beets/config_default.yaml @@ -112,3 +112,4 @@ match: thumbnails: force: no auto: yes + dolphin: no diff --git a/beetsplug/freedesktop.py b/beetsplug/freedesktop.py index c4ca24d3a..675061925 100644 --- a/beetsplug/freedesktop.py +++ b/beetsplug/freedesktop.py @@ -19,51 +19,18 @@ from __future__ import (division, absolute_import, print_function, unicode_literals) from beets.plugins import BeetsPlugin -from beets.ui import Subcommand -from beets.ui import decargs - -import os - - -def create_file(albumpath, artfile): - file_contents = "[Desktop Entry]\nIcon=./" + artfile - outfilename = os.path.join(albumpath, ".directory") - - if not os.path.exists(outfilename): - file = open(outfilename, 'w') - file.write(file_contents) - file.close() +from beets import ui class FreedesktopPlugin(BeetsPlugin): - def __init__(self): - super(FreedesktopPlugin, self).__init__() - self.config.add({ - 'auto': False - }) - self.register_listener('album_imported', self.imported) - def commands(self): - freedesktop_command = Subcommand("freedesktop", - help="Create .directory files") - freedesktop_command.func = self.process_query - return [freedesktop_command] + deprecated = ui.Subcommand("freedesktop", help="Print a message to " + "redirect to thumbnails --dolphin") + deprecated.func = self.deprecation_message + return [deprecated] - def imported(self, lib, album): - automatic = self.config['auto'].get(bool) - if not automatic: - return - self.process_album(album) - - def process_query(self, lib, opts, args): - for album in lib.albums(decargs(args)): - self.process_album(album) - - def process_album(self, album): - albumpath = album.item_dir() - if album.artpath: - fullartpath = album.artpath - artfile = os.path.split(fullartpath)[1] - create_file(albumpath, artfile) - else: - self._log.debug(u'album has no art') + def deprecation_message(self, lib, opts, args): + ui.print_("This plugin is deprecated. Its functionality is superseded " + "by the 'thumbnails' plugin") + ui.print_("'thumbnails --dolphin' replaces freedesktop. See doc & " + "changelog for more information") diff --git a/beetsplug/thumbnails.py b/beetsplug/thumbnails.py index a92779b3c..e994cefe4 100644 --- a/beetsplug/thumbnails.py +++ b/beetsplug/thumbnails.py @@ -47,6 +47,7 @@ class ThumbnailsPlugin(BeetsPlugin): self.config.add({ 'auto': True, 'force': False, + 'dolphin': False, }) self.write_metadata = None @@ -60,14 +61,18 @@ class ThumbnailsPlugin(BeetsPlugin): '-f', '--force', dest='force', action='store_true', default=False, help='force regeneration of thumbnails deemed fine (existing & ' 'recent enough)') + thumbnails_command.parser.add_option( + '--dolphin', dest='dolphin', action='store_true', default=False, + help="create Dolphin-compatible thumbnail information (for KDE)") thumbnails_command.func = self.process_query + return [thumbnails_command] def imported(self, lib, album): self.process_album(album) def process_query(self, lib, opts, args): - self.config['force'] = opts.force + self.config.set_args(opts) if self._check_local_ok(): for album in lib.albums(decargs(args)): self.process_album(album) @@ -103,6 +108,9 @@ class ThumbnailsPlugin(BeetsPlugin): self._log.info(u'album {0} has no art', album) return + if self.config['dolphin']: + self.make_dolphin_cover_thumbnail(album) + size = ArtResizer.shared.get_size(album.artpath) if not size: self._log.warning('problem getting the picture size for {0}', @@ -159,6 +167,16 @@ class ThumbnailsPlugin(BeetsPlugin): self._log.exception("could not write metadata to {0}", util.displayable_path(image_path)) + def make_dolphin_cover_thumbnail(self, album): + outfilename = os.path.join(album.path, b".directory") + if os.path.exists(outfilename): + return + artfile = os.path.split(album.artpath)[1] + with open(outfilename, 'w') as f: + f.write(b"[Desktop Entry]\nIcon=./{0}".format(artfile)) + f.close() + self._log.debug("Wrote file {0}", util.displayable_path(outfilename)) + def write_metadata_im(file, metadata): """Enrich the file metadata with `metadata` dict thanks to IM.""" diff --git a/docs/changelog.rst b/docs/changelog.rst index 8ad20865a..70fe5085a 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -29,7 +29,9 @@ Features: * :doc:`/plugins/fetchart`: There's a new Wikipedia image source that uses DBpedia to find albums. Thanks to Tom Jaspers. :bug:`1194` * A new :doc:`/plugins/thumbnails` generates thumbnails with cover art for - album folders for all freedesktop.org-compliant file managers. + album folders for all freedesktop.org-compliant file managers. This replaces + the :doc:`/plugins/freedesktop` which only worked with the Dolphin file + manager. Core changes: diff --git a/docs/plugins/freedesktop.rst b/docs/plugins/freedesktop.rst index 3c91d2520..61943718e 100644 --- a/docs/plugins/freedesktop.rst +++ b/docs/plugins/freedesktop.rst @@ -1,25 +1,6 @@ Freedesktop Plugin ================== -The ``freedesktop`` plugin creates .directory files in your album folders. -This lets Freedesktop.org compliant file managers such as Dolphin or Nautilus -to use an album's cover art as the folder's thumbnail. - -To use the ``freedesktop`` plugin, enable it (see :doc:`/plugins/index`). - -Configuration -------------- - -To configure the plugin, make a ``freedesktop:`` section in your configuration -file. The only available option is: - -- **auto**: Create .directory files automatically during import. - Default: ``no``. - -Creating .directory Files Manually ----------------------------------- - -The ``freedesktop`` command provided by this plugin creates .directory files -for albums that match a query (see :doc:`/reference/query`). For example, ``beet -freedesktop man the animal cannon`` will create the .directory file for the -folder containing the album Man the Animal Cannon. +The ``freedesktop`` plugin created .directory files in your album folders. +This plugin is now deprecated and replaced by the :doc:`/plugins/thumbnails` +with the `dolphin` option enabled. diff --git a/docs/plugins/thumbnails.rst b/docs/plugins/thumbnails.rst index e73d0a584..c91c97910 100644 --- a/docs/plugins/thumbnails.rst +++ b/docs/plugins/thumbnails.rst @@ -27,6 +27,10 @@ file. The available options are - **force**: Generate the thumbnail even when there's one that seems fine (more recent than the cover art). Default: ``no``. +- **dolphin**: Generate dolphin-compatible thumbnails. Dolphin (KDE file + explorer) does not respect freedesktop.org's standard on thumbnails. This + functionality replaces the :doc:`/plugins/freedesktop` + Default: ``no`` Usage ----- diff --git a/test/test_thumbnails.py b/test/test_thumbnails.py index 6e2ebb06e..6bee3c081 100644 --- a/test/test_thumbnails.py +++ b/test/test_thumbnails.py @@ -17,6 +17,8 @@ from __future__ import (division, absolute_import, print_function, import os.path from mock import Mock, patch, call +from tempfile import mkdtemp +from shutil import rmtree from test._common import unittest from test.helper import TestHelper @@ -166,6 +168,24 @@ class ThumbnailsTest(unittest.TestCase, TestHelper): resize.assert_called_once_with(12345, b"/path/to/art", b"/thumbnail/dir/md5") + @patch('beetsplug.thumbnails.ThumbnailsPlugin._check_local_ok') + def test_make_dolphin_cover_thumbnail(self, _): + plugin = ThumbnailsPlugin() + tmp = mkdtemp() + album = Mock(path=tmp, + artpath=os.path.join(tmp, b"cover.jpg")) + plugin.make_dolphin_cover_thumbnail(album) + with open(os.path.join(tmp, b".directory"), "rb") as f: + self.assertEqual(f.read(), b"[Desktop Entry]\nIcon=./cover.jpg") + + # not rewritten when it already exists (yup that's a big limitation) + album.artpath = b"/my/awesome/art.tiff" + plugin.make_dolphin_cover_thumbnail(album) + with open(os.path.join(tmp, b".directory"), "rb") as f: + self.assertEqual(f.read(), b"[Desktop Entry]\nIcon=./cover.jpg") + + rmtree(tmp) + @patch('beetsplug.thumbnails.ThumbnailsPlugin._check_local_ok') @patch('beetsplug.thumbnails.ArtResizer') def test_process_album(self, mock_artresizer, _): @@ -173,11 +193,13 @@ class ThumbnailsTest(unittest.TestCase, TestHelper): plugin = ThumbnailsPlugin() make_cover = plugin.make_cover_thumbnail = Mock() + make_dolphin = plugin.make_dolphin_cover_thumbnail = Mock() # no art album = Mock(artpath=None) plugin.process_album(album) self.assertEqual(get_size.call_count, 0) + self.assertEqual(make_dolphin.call_count, 0) # cannot get art size album.artpath = b"/path/to/art" @@ -186,6 +208,15 @@ class ThumbnailsTest(unittest.TestCase, TestHelper): get_size.assert_called_once_with(b"/path/to/art") self.assertEqual(make_cover.call_count, 0) + # dolphin tests + plugin.config['dolphin'] = False + plugin.process_album(album) + self.assertEqual(make_dolphin.call_count, 0) + + plugin.config['dolphin'] = True + plugin.process_album(album) + make_dolphin.assert_called_once_with(album) + # small art get_size.return_value = 200, 200 plugin.process_album(album)