[core/theme] Add iconset support
Allow themes to specify iconsets. To do so, add a new util library "util.algorithm", which currently contains support for deep merging of dicts.
This commit is contained in:
parent
ef75e593f7
commit
3bb857f250
3 changed files with 71 additions and 2 deletions
|
@ -3,6 +3,7 @@ import io
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import core.event
|
import core.event
|
||||||
|
import util.algorithm
|
||||||
|
|
||||||
THEME_BASE_DIR=os.path.dirname(os.path.realpath(__file__))
|
THEME_BASE_DIR=os.path.dirname(os.path.realpath(__file__))
|
||||||
PATHS=[
|
PATHS=[
|
||||||
|
@ -19,6 +20,11 @@ class Theme(object):
|
||||||
self.__data = raw_data
|
self.__data = raw_data
|
||||||
else:
|
else:
|
||||||
self.__data = self.load(name)
|
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('update', self.__start)
|
||||||
core.event.register('next-widget', self.__next_widget)
|
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))
|
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:
|
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):
|
if os.path.isfile(theme_file):
|
||||||
with io.open(theme_file, encoding='utf-8') as data:
|
with io.open(theme_file, encoding='utf-8') as data:
|
||||||
return json.load(data)
|
return json.load(data)
|
||||||
|
|
40
tests/util/test_algorithm.py
Normal file
40
tests/util/test_algorithm.py
Normal file
|
@ -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
|
23
util/algorithm.py
Normal file
23
util/algorithm.py
Normal file
|
@ -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
|
Loading…
Reference in a new issue