diff --git a/packages/flamenco/flamenco/job_compilers/commands.py b/packages/flamenco/flamenco/job_compilers/commands.py index 45498c15c15b1d16af2cdc23c70be67d8a3365d5..40254d19f46a37a21deeedc5e9baee0959af693c 100644 --- a/packages/flamenco/flamenco/job_compilers/commands.py +++ b/packages/flamenco/flamenco/job_compilers/commands.py @@ -11,7 +11,9 @@ class AbstractCommand(object): @classmethod def cmdname(cls): """Returns the command name.""" - return cls.__name__.lower() + from flamenco.utils import camel_case_to_lower_case_underscore + + return camel_case_to_lower_case_underscore(cls.__name__) def to_dict(self): """Returns a dictionary representation of this command, for JSON serialisation.""" @@ -34,10 +36,6 @@ class Echo(AbstractCommand): @attr.s class BlenderRender(AbstractCommand): - @classmethod - def cmdname(cls): - return 'blender_render' - # Blender executable to run. blender_cmd = attr.ib(validator=attr.validators.instance_of(unicode)) # blend file path. diff --git a/packages/flamenco/flamenco/utils.py b/packages/flamenco/flamenco/utils.py index 3b663802942552f0e91b76991eb6ea2cf1e5efc9..94cdbf0447826283f97bca2b57104b7d37578b8f 100644 --- a/packages/flamenco/flamenco/utils.py +++ b/packages/flamenco/flamenco/utils.py @@ -103,3 +103,29 @@ def report_duration(logger, description): finally: end_time = time.time() logger.debug('report_duration: %s took %f seconds', description, end_time - start_time) + + +def camel_case_to_lower_case_underscore(string): + """ + Converts a string from CamelCase to lower_case_underscore. + + None-safe. + + :type string: unicode or str or None + :rtype: unicode or str or None + """ + + if string is None: + return None + + words = [] + from_char_position = 0 + for current_char_position, char in enumerate(string): + if char.isupper() and from_char_position < current_char_position: + words.append(string[from_char_position:current_char_position].lower()) + from_char_position = current_char_position + words.append(string[from_char_position:].lower()) + + if isinstance(string, str): + return '_'.join(words) + return u'_'.join(words) diff --git a/packages/flamenco/tests/test_commands.py b/packages/flamenco/tests/test_commands.py new file mode 100644 index 0000000000000000000000000000000000000000..20887eef076e52a45ba6fb44f7fdc9b6989bf590 --- /dev/null +++ b/packages/flamenco/tests/test_commands.py @@ -0,0 +1,8 @@ +from unittest import TestCase + + +class SomeCommandsTest(TestCase): + def test_blender_render_name(self): + from flamenco.job_compilers.commands import BlenderRender + + self.assertEqual('blender_render', BlenderRender.cmdname()) diff --git a/packages/flamenco/tests/test_utils.py b/packages/flamenco/tests/test_utils.py index 390e52fee503531994da8e08ad6fcab4c7f13818..34da6e36dbcf573f524fc70000f3beb5c38ff7fe 100644 --- a/packages/flamenco/tests/test_utils.py +++ b/packages/flamenco/tests/test_utils.py @@ -59,3 +59,17 @@ class FrameRangeTest(unittest.TestCase): [14, 15, 16], ], list(iter_frame_range('4-10, 13-16', 4))) + + def test_camel_case_to_lower_case_underscore(self): + from flamenco.utils import camel_case_to_lower_case_underscore as cctlcu + + self.assertIsInstance(cctlcu(u'word'), unicode) + self.assertIsInstance(cctlcu('word'), str) + + self.assertEqual('word', cctlcu('word')) + self.assertEqual(u'word', cctlcu(u'word')) + self.assertEqual('camel_case', cctlcu('CamelCase')) + self.assertEqual('camel_case', cctlcu('camelCase')) + self.assertEqual('camel_case_with_many_words', cctlcu('CamelCaseWithManyWords')) + self.assertEqual('', cctlcu('')) + self.assertIs(None, cctlcu(None))