diff --git a/core/theme.py b/core/theme.py index 8b29f67..79437cc 100644 --- a/core/theme.py +++ b/core/theme.py @@ -3,6 +3,7 @@ import io import json import core.event +import util.algorithm THEME_BASE_DIR=os.path.dirname(os.path.realpath(__file__)) PATHS=[ @@ -19,6 +20,11 @@ class Theme(object): self.__data = raw_data else: self.__data = self.load(name) + for icons in self.__data['icons']: + util.algorithm.merge(self.__data, self.load(icons, 'icons')) + if iconset: + util.algorithm.merge(self.__data, iconset) + core.event.register('update', self.__start) core.event.register('next-widget', self.__next_widget) @@ -34,9 +40,9 @@ class Theme(object): ]: setattr(self, attr.replace('-', '_'), lambda widget=None, default=default, attr=attr: self.__get(widget, attr, default)) - def load(self, name): + def load(self, name, subdir=''): for path in PATHS: - theme_file = os.path.join(path, '{}.json'.format(name)) + theme_file = os.path.join(path, subdir, '{}.json'.format(name)) if os.path.isfile(theme_file): with io.open(theme_file, encoding='utf-8') as data: return json.load(data) diff --git a/tests/util/test_algorithm.py b/tests/util/test_algorithm.py new file mode 100644 index 0000000..5dee8fc --- /dev/null +++ b/tests/util/test_algorithm.py @@ -0,0 +1,40 @@ +import unittest + +from util.algorithm import * + +class algorithm(unittest.TestCase): + def setUp(self): + self.someData = {'a': 100, 'b': 200, 'c': [1,2,3]} + self.differentData = {'x': 20, 'y': 'bla', 'z': ['a','b']} + self.moreData = {'n': 100} + self.overlapData = {'a': 200, 'c': [1,2,4]} + + def test_merge_with_empty(self): + self.assertEqual(self.someData, merge(self.someData, {})) + self.assertEqual(None, merge(self.someData, None)) + + def test_merge_no_overwrite(self): + result = merge(self.someData, self.differentData) + for k in self.someData: + self.assertEqual(result[k], self.someData[k]) + for k in self.differentData: + self.assertEqual(result[k], self.differentData[k]) + + def test_merge_multiple(self): + result = merge(self.someData, self.differentData, self.moreData) + for k in self.someData: + self.assertEqual(result[k], self.someData[k]) + for k in self.differentData: + self.assertEqual(result[k], self.differentData[k]) + for k in self.moreData: + self.assertEqual(result[k], self.moreData[k]) + + def merge_overlap(self): + result = merge(self.someData, self.overlapData) + for k in self.someData: + if not k in self.overlapData: + self.assertEqual(result[k], self.someData[k]) + for k in self.overlapData: + self.assertEqual(result[k], self.overlapData[k]) + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 diff --git a/util/algorithm.py b/util/algorithm.py new file mode 100644 index 0000000..67cf9d9 --- /dev/null +++ b/util/algorithm.py @@ -0,0 +1,23 @@ +import copy + +# algorithm copied from +# http://blog.impressiver.com/post/31434674390/deep-merge-multiple-python-dicts +# nicely done :) +def merge(target, *args): + if len(args) > 1: + for item in args: + merge(target, item) + return target + + item = args[0] + if not isinstance(item, dict): + return item + for key, value in item.items(): + if key in target and isinstance(target[key], dict): + merge(target[key], value) + else: + if not key in target: + target[key] = copy.deepcopy(value) + return target + +# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4