diff --git a/beetsplug/permissions.py b/beetsplug/permissions.py new file mode 100644 index 0000000000..458debc09e --- /dev/null +++ b/beetsplug/permissions.py @@ -0,0 +1,55 @@ +"""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 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. + """ + 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('item_copied') +def permissions(item, source, destination): + """Running the permission fixer. + """ + # Getting the config. + file_perm = config['permissions']['file'].get() + + # Converts file permissions to oct. + file_perm = convert_perm(file_perm) + + # Changing permissions on the destination path. + os.chmod(util.bytestring_path(destination), file_perm) + + # 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/docs/plugins/index.rst b/docs/plugins/index.rst index c669034b91..30bddd1159 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 diff --git a/docs/plugins/permissions.rst b/docs/plugins/permissions.rst new file mode 100644 index 0000000000..250597c3b9 --- /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 diff --git a/test/test_permissions.py b/test/test_permissions.py new file mode 100644 index 0000000000..cad7a47dac --- /dev/null +++ b/test/test_permissions.py @@ -0,0 +1,35 @@ +"""Tests for the 'permissions' plugin. +""" +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) + + self.assertTrue(check_permissions(item.path, config_perm)) + + +def suite(): + return unittest.TestLoader().loadTestsFromName(__name__) + + +if __name__ == '__main__': + unittest.main(defaultTest='suite')