From e1db3e9f0b22e09e92b0b329bf4551df8390a748 Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Mon, 17 Nov 2014 13:42:53 +0100 Subject: [PATCH 1/7] Added fix_permissions plugin --- beetsplug/fix_permissions.py | 37 ++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 beetsplug/fix_permissions.py diff --git a/beetsplug/fix_permissions.py b/beetsplug/fix_permissions.py new file mode 100644 index 000000000..41c706ba8 --- /dev/null +++ b/beetsplug/fix_permissions.py @@ -0,0 +1,37 @@ +''' +Fixes file permissions after the file gets written on import. + +Put something like the following in your config.yaml to configure: + + fix_permissions: + file: 0644 + +IMPORTANT: Write it exactly in this format. Else you could run into problems. +''' + +import os +from beets import config +from beets.plugins import BeetsPlugin + + +def check_permissions(path, permission): + ''' checks the permissions on the written path ''' + return oct(os.stat(path).st_mode & 0777) == oct(permission) + + +class FixPermissions(BeetsPlugin): + ''' our plugin class ''' + pass + + +@FixPermissions.listen('after_write') +def fix_permissions(path): + file_perm = config['fix_permissions'].get()['file'] + + # doing the permission magic + os.chmod(path, file_perm) + + # check permissions + if not check_permissions(path, file_perm): + message = 'There was a problem fixing permission on {}'.format(path) + print(message) From df1136756acc934624bc4ee269f4f469b13fb3a0 Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Mon, 17 Nov 2014 16:29:54 +0100 Subject: [PATCH 2/7] a little refactoring --- beetsplug/fix_permissions.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/beetsplug/fix_permissions.py b/beetsplug/fix_permissions.py index 41c706ba8..6a4d773b0 100644 --- a/beetsplug/fix_permissions.py +++ b/beetsplug/fix_permissions.py @@ -4,9 +4,9 @@ Fixes file permissions after the file gets written on import. Put something like the following in your config.yaml to configure: fix_permissions: - file: 0644 + file: '644' -IMPORTANT: Write it exactly in this format. Else you could run into problems. +IMPORTANT: Needs to be a string. ''' import os @@ -16,7 +16,7 @@ from beets.plugins import BeetsPlugin def check_permissions(path, permission): ''' checks the permissions on the written path ''' - return oct(os.stat(path).st_mode & 0777) == oct(permission) + return oct(os.stat(path).st_mode & 0o777) == oct(permission) class FixPermissions(BeetsPlugin): @@ -26,7 +26,10 @@ class FixPermissions(BeetsPlugin): @FixPermissions.listen('after_write') def fix_permissions(path): - file_perm = config['fix_permissions'].get()['file'] + ''' running the permission fixer ''' + + # getting the config + file_perm = int(config['fix_permissions'].get()['file'], 8) # doing the permission magic os.chmod(path, file_perm) From 5f03185bdd53252674a0437f97e2d0f34bbefeac Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Tue, 18 Nov 2014 13:45:55 +0100 Subject: [PATCH 3/7] did even more refactoring with the suggestions of sampsyo. added documentation page --- beetsplug/fix_permissions.py | 40 ------------------------------ beetsplug/permissions.py | 48 ++++++++++++++++++++++++++++++++++++ docs/plugins/permissions.rst | 18 ++++++++++++++ 3 files changed, 66 insertions(+), 40 deletions(-) delete mode 100644 beetsplug/fix_permissions.py create mode 100644 beetsplug/permissions.py create mode 100644 docs/plugins/permissions.rst diff --git a/beetsplug/fix_permissions.py b/beetsplug/fix_permissions.py deleted file mode 100644 index 6a4d773b0..000000000 --- a/beetsplug/fix_permissions.py +++ /dev/null @@ -1,40 +0,0 @@ -''' -Fixes file permissions after the file gets written on import. - -Put something like the following in your config.yaml to configure: - - fix_permissions: - file: '644' - -IMPORTANT: Needs to be a string. -''' - -import os -from beets import config -from beets.plugins import BeetsPlugin - - -def check_permissions(path, permission): - ''' checks the permissions on the written path ''' - return oct(os.stat(path).st_mode & 0o777) == oct(permission) - - -class FixPermissions(BeetsPlugin): - ''' our plugin class ''' - pass - - -@FixPermissions.listen('after_write') -def fix_permissions(path): - ''' running the permission fixer ''' - - # getting the config - file_perm = int(config['fix_permissions'].get()['file'], 8) - - # doing the permission magic - os.chmod(path, file_perm) - - # check permissions - if not check_permissions(path, file_perm): - message = 'There was a problem fixing permission on {}'.format(path) - print(message) diff --git a/beetsplug/permissions.py b/beetsplug/permissions.py new file mode 100644 index 000000000..227390826 --- /dev/null +++ b/beetsplug/permissions.py @@ -0,0 +1,48 @@ +"""Fixes file permissions after the file gets written on import. Put something +like the following in your config.yaml to configure: + + permissions: + file: 644 +""" +import os +from beets import config, util +from beets.plugins import BeetsPlugin + + +def check_permissions(path, permission): + """Checks the permissions of a path. + """ + return oct(os.stat(path).st_mode & 0o777) == oct(permission) + + +class Permissions(BeetsPlugin): + def __init__(self): + super(Permissions, self).__init__() + + # Adding defaults. + self.config.add({ + u'file': 644 + }) + + +@Permissions.listen('after_write') +def permissions(path): + """Running the permission fixer. + """ + # Getting the config + file_perm = config['permissions']['file'].get() + + # If the config is a int it will first convert it to a string and back + # to an oct int. Else it just converts it to oct. + if isinstance(file_perm, int): + file_perm = int(str(file_perm), 8) + else: + file_perm = int(file_perm, 8) + + # Changing permissions on the path. + os.chmod(util.bytestring_path(path), file_perm) + + # Checks if the path has the permissions configured. + if not check_permissions(util.bytestring_path(path), file_perm): + message = 'There was a problem setting permission on {}'.format(path) + print(message) diff --git a/docs/plugins/permissions.rst b/docs/plugins/permissions.rst new file mode 100644 index 000000000..250597c3b --- /dev/null +++ b/docs/plugins/permissions.rst @@ -0,0 +1,18 @@ +Permissions Plugin +================== + +The ``permissions`` plugin allows you to set file permissions after they got written. + +To use the ``permissions`` plugin, enable it in your configuration (see +:ref:`using-plugins`). + +Configuration +------------- + +To configure the plugin, make an ``permissions:`` section in your configuration +file. You need to use **octal modes** to configure permissions. + +Here's an example:: + + permissions: + file: 644 From 38c509b092531f9f5a84bb81b5ba43d58d022df1 Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Wed, 19 Nov 2014 17:26:39 +0100 Subject: [PATCH 4/7] created a function to convert permissions to oct --- beetsplug/permissions.py | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/beetsplug/permissions.py b/beetsplug/permissions.py index 227390826..2bab18abc 100644 --- a/beetsplug/permissions.py +++ b/beetsplug/permissions.py @@ -9,6 +9,16 @@ from beets import config, util from beets.plugins import BeetsPlugin +def convert_perm(perm): + """If the perm is a int it will first convert it to a string and back + to an oct int. Else it just converts it to oct. + """ + if isinstance(perm, int): + return int(str(perm), 8) + else: + return int(perm, 8) + + def check_permissions(path, permission): """Checks the permissions of a path. """ @@ -29,15 +39,11 @@ class Permissions(BeetsPlugin): def permissions(path): """Running the permission fixer. """ - # Getting the config + # Getting the config. file_perm = config['permissions']['file'].get() - # If the config is a int it will first convert it to a string and back - # to an oct int. Else it just converts it to oct. - if isinstance(file_perm, int): - file_perm = int(str(file_perm), 8) - else: - file_perm = int(file_perm, 8) + # Converts file permissions to oct. + file_perm = convert_perm(file_perm) # Changing permissions on the path. os.chmod(util.bytestring_path(path), file_perm) From 3ffd41d72a1b82d6147333157ed35f59b2d829e8 Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Wed, 19 Nov 2014 17:32:10 +0100 Subject: [PATCH 5/7] fixed plugin toc in docs --- docs/plugins/index.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/plugins/index.rst b/docs/plugins/index.rst index c669034b9..30bddd115 100644 --- a/docs/plugins/index.rst +++ b/docs/plugins/index.rst @@ -60,6 +60,7 @@ Each plugin has its own set of options that can be defined in a section bearing missing mpdstats mpdupdate + permissions play random replaygain From a01e73d81387ee4b49332f774bca3f69b20a75ee Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Wed, 19 Nov 2014 19:43:31 +0100 Subject: [PATCH 6/7] added not working test for debugging --- test/test_permissions.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 test/test_permissions.py diff --git a/test/test_permissions.py b/test/test_permissions.py new file mode 100644 index 000000000..1b181b901 --- /dev/null +++ b/test/test_permissions.py @@ -0,0 +1,33 @@ +from _common import unittest +from helper import TestHelper +from beetsplug.permissions import check_permissions, convert_perm + + +class PermissionsPluginTest(unittest.TestCase, TestHelper): + def setUp(self): + self.setup_beets() + self.load_plugins('permissions') + + self.config['permissions'] = { + 'file': 777} + + def tearDown(self): + self.teardown_beets() + self.unload_plugins() + + def test_perm(self): + self.importer = self.create_importer() + self.importer.run() + item = self.lib.items().get() + config_perm = self.config['permissions']['file'].get() + config_perm = convert_perm(config_perm) + + assert check_permissions(item.path, config_perm) + + +def suite(): + return unittest.TestLoader().loadTestsFromName(__name__) + + +if __name__ == '__main__': + unittest.main(defaultTest='suite') From 8784e8d8ca90b0ca058078e4fe5651d801b7bc2e Mon Sep 17 00:00:00 2001 From: Marvin Steadfast Date: Thu, 20 Nov 2014 11:40:02 +0100 Subject: [PATCH 7/7] plugin now listens for item_copied instead of after_write. now the test works --- beetsplug/permissions.py | 15 ++++++++------- test/test_permissions.py | 4 +++- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/beetsplug/permissions.py b/beetsplug/permissions.py index 2bab18abc..458debc09 100644 --- a/beetsplug/permissions.py +++ b/beetsplug/permissions.py @@ -35,8 +35,8 @@ class Permissions(BeetsPlugin): }) -@Permissions.listen('after_write') -def permissions(path): +@Permissions.listen('item_copied') +def permissions(item, source, destination): """Running the permission fixer. """ # Getting the config. @@ -45,10 +45,11 @@ def permissions(path): # Converts file permissions to oct. file_perm = convert_perm(file_perm) - # Changing permissions on the path. - os.chmod(util.bytestring_path(path), file_perm) + # Changing permissions on the destination path. + os.chmod(util.bytestring_path(destination), file_perm) - # Checks if the path has the permissions configured. - if not check_permissions(util.bytestring_path(path), file_perm): - message = 'There was a problem setting permission on {}'.format(path) + # Checks if the destination path has the permissions configured. + if not check_permissions(util.bytestring_path(destination), file_perm): + message = 'There was a problem setting permission on {}'.format( + destination) print(message) diff --git a/test/test_permissions.py b/test/test_permissions.py index 1b181b901..cad7a47da 100644 --- a/test/test_permissions.py +++ b/test/test_permissions.py @@ -1,3 +1,5 @@ +"""Tests for the 'permissions' plugin. +""" from _common import unittest from helper import TestHelper from beetsplug.permissions import check_permissions, convert_perm @@ -22,7 +24,7 @@ class PermissionsPluginTest(unittest.TestCase, TestHelper): config_perm = self.config['permissions']['file'].get() config_perm = convert_perm(config_perm) - assert check_permissions(item.path, config_perm) + self.assertTrue(check_permissions(item.path, config_perm)) def suite():