diff --git a/etiquette/helpers.py b/etiquette/helpers.py index 285258a..bcd80e4 100644 --- a/etiquette/helpers.py +++ b/etiquette/helpers.py @@ -267,6 +267,44 @@ def read_filebytes(filepath, range_min, range_max, chunk_size=2 ** 20): yield chunk sent_amount += len(chunk) +def recursive_dict_update(d1, d2): + ''' + Update d1 using d2, but when the value is a dictionary update the insides + instead of replacing the dictionary itself. + ''' + for (key, value) in d2.items(): + if isinstance(value, dict): + existing = d1.get(key, None) + if existing is None: + d1[key] = value + else: + recursive_dict_update(existing, value) + else: + d1[key] = value + +def recursive_dict_keys(d): + ''' + Given a dictionary, return a set containing all of its keys and the keys of + all other dictionaries that appear as values within. The subkeys will use \\ + to indicate their lineage. + + { + 'hi': { + 'ho': 'neighbor' + } + } + + returns + + {'hi', 'hi\\ho'} + ''' + keys = set(d.keys()) + for (key, value) in d.items(): + if isinstance(value, dict): + subkeys = {'%s\\%s' % (key, subkey) for subkey in recursive_dict_keys(value)} + keys.update(subkeys) + return keys + def remove_characters(text, characters): translator = {ord(c): None for c in characters} text = text.translate(translator) diff --git a/etiquette/photodb.py b/etiquette/photodb.py index d03e5e2..0008992 100644 --- a/etiquette/photodb.py +++ b/etiquette/photodb.py @@ -1124,8 +1124,10 @@ class PhotoDB(PDBAlbumMixin, PDBBookmarkMixin, PDBPhotoMixin, PDBTagMixin, PDBUs if user_config_exists: with open(self.config_filepath.absolute_path, 'r') as handle: user_config = json.load(handle) - needs_dump = len(user_config) < len(self.config) - self.config.update(user_config) + my_keys = helpers.recursive_dict_keys(self.config) + stored_keys = helpers.recursive_dict_keys(user_config) + needs_dump = not my_keys.issubset(stored_keys) + helpers.recursive_dict_update(self.config, user_config) else: needs_dump = True