diff --git a/beetsplug/permissions.py b/beetsplug/permissions.py index dd9e098436..8642eeb996 100644 --- a/beetsplug/permissions.py +++ b/beetsplug/permissions.py @@ -70,10 +70,29 @@ def __init__(self): self.register_listener('item_imported', self.fix) self.register_listener('album_imported', self.fix) + self.register_listener('art_set', self.fix_art) def fix(self, lib, item=None, album=None): """Fix the permissions for an imported Item or Album. """ + files = [] + dirs = set() + if item: + files.append(item.path) + dirs.update(dirs_in_library(lib.directory, item.path)) + elif album: + for album_item in album.items(): + files.append(album_item.path) + dirs.update(dirs_in_library(lib.directory, album_item.path)) + self.set_permissions(files=files, dirs=dirs) + + def fix_art(self, album): + """Fix the permission for Album art file. + """ + if album.artpath: + self.set_permissions(files=[album.artpath]) + + def set_permissions(self, files=[], dirs=[]): # Get the configured permissions. The user can specify this either a # string (in YAML quotes) or, for convenience, as an integer so the # quotes can be omitted. In the latter case, we need to reinterpret the @@ -83,18 +102,7 @@ def fix(self, lib, item=None, album=None): file_perm = convert_perm(file_perm) dir_perm = convert_perm(dir_perm) - # Create chmod_queue. - file_chmod_queue = [] - if item: - file_chmod_queue.append(item.path) - elif album: - for album_item in album.items(): - file_chmod_queue.append(album_item.path) - - # A set of directories to change permissions for. - dir_chmod_queue = set() - - for path in file_chmod_queue: + for path in files: # Changing permissions on the destination file. self._log.debug( u'setting file permissions on {}', @@ -105,13 +113,8 @@ def fix(self, lib, item=None, album=None): # Checks if the destination path has the permissions configured. assert_permissions(path, file_perm, self._log) - # Adding directories to the directory chmod queue. - dir_chmod_queue.update( - dirs_in_library(lib.directory, - path)) - # Change permissions for the directories. - for path in dir_chmod_queue: + for path in dirs: # Chaning permissions on the destination directory. self._log.debug( u'setting directory permissions on {}', diff --git a/docs/changelog.rst b/docs/changelog.rst index f32cae2b99..22a3e7120d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -27,6 +27,9 @@ Major new features: * :doc:`/plugins/albumtypes`: An accompanying plugin for formatting ``albumtypes``. Thanks to :user:`edgars-supe`. +Other new things: + +* Permissions plugin now sets cover art permissions to the file permissions. 1.5.0 (August 19, 2021) ----------------------- diff --git a/test/test_permissions.py b/test/test_permissions.py index ed84798f1e..9397fe0936 100644 --- a/test/test_permissions.py +++ b/test/test_permissions.py @@ -10,6 +10,7 @@ from mock import patch, Mock from test.helper import TestHelper +from test._common import touch from beets.util import displayable_path from beetsplug.permissions import (check_permissions, convert_perm, @@ -82,6 +83,25 @@ def test_convert_perm_from_string(self): def test_convert_perm_from_int(self): self.assertEqual(convert_perm(10), 8) + def test_permissions_on_set_art(self): + self.do_set_art(True) + + @patch("os.chmod", Mock()) + def test_failing_permissions_on_set_art(self): + self.do_set_art(False) + + def do_set_art(self, expect_success): + if platform.system() == 'Windows': + self.skipTest('permissions not available on Windows') + self.importer = self.create_importer() + self.importer.run() + album = self.lib.albums().get() + artpath = os.path.join(self.temp_dir, b'cover.jpg') + touch(artpath) + album.set_art(artpath) + self.assertEqual(expect_success, + check_permissions(album.artpath, 0o777)) + def suite(): return unittest.TestLoader().loadTestsFromName(__name__)