0
|
1 import gi
|
|
2 import importlib
|
|
3 import json
|
|
4 import os
|
|
5 import pathlib
|
|
6 import sys
|
1
|
7 import types
|
0
|
8 import uuid
|
2
|
9 from types import SimpleNamespace
|
0
|
10 gi.require_version("Gtk", "3.0")
|
1
|
11 from gi.repository import Gtk # noqa: E402
|
|
12 from gi.repository import GLib # noqa: E402
|
|
13
|
0
|
14
|
|
15 class ColorProfileBase:
|
|
16
|
1
|
17 type_name = '(no name)'
|
0
|
18
|
1
|
19 def __init__(self):
|
|
20 self.name = ''
|
2
|
21 self.id = str(uuid.uuid4())
|
0
|
22
|
1
|
23 def build_settings_ui(self):
|
|
24 glade_file = sys.modules[self.__module__].__file__.replace('.py', '.glade')
|
|
25 builder = Gtk.Builder()
|
|
26 builder.add_from_file(glade_file)
|
|
27 return builder.get_object('edit_profile_container')
|
|
28
|
2
|
29 def serialize(self):
|
|
30 properties = self.__dict__
|
|
31 properties['module'] = self.__class__.__module__
|
|
32 return properties
|
|
33
|
|
34 @staticmethod
|
|
35 def unserialize(data):
|
|
36 profile_module = importlib.import_module(data['module'])
|
|
37 profile_class = getattr(profile_module, 'ColorProfile')
|
|
38 profile = profile_class()
|
|
39 profile.__dict__.update(data)
|
|
40 return profile
|
|
41
|
0
|
42
|
|
43 class ProfileManager:
|
|
44
|
1
|
45 def __init__(self):
|
2
|
46 profile_list = self.load_profiles()
|
|
47 self.profiles = {p.id: p for p in profile_list}
|
0
|
48
|
1
|
49 def get_types(self):
|
|
50 types = []
|
|
51 profile_directory = os.path.dirname(os.path.realpath(__file__))
|
|
52 (_, dirnames, _) = next(os.walk(profile_directory))
|
|
53 for dirname in dirnames:
|
|
54 module_file = os.path.join(profile_directory, dirname, dirname + '.py')
|
|
55 if os.path.isfile(module_file):
|
|
56 module_name = 'keyboard_colors.' + dirname + '.' + dirname
|
|
57 profile_module = importlib.import_module(module_name)
|
|
58 profile_class = getattr(profile_module, 'ColorProfile')
|
|
59 types.append(profile_class)
|
|
60 return types
|
0
|
61
|
1
|
62 def config_path(self):
|
|
63 dir = GLib.get_user_config_dir()
|
|
64 if not os.path.isdir(dir):
|
|
65 os.mkdir(dir)
|
|
66 return os.path.join(dir, 'keyboard-color-profiles.conf')
|
0
|
67
|
1
|
68 def load_profiles(self):
|
|
69 if os.path.isfile(self.config_path()):
|
|
70 data = pathlib.Path(self.config_path()).read_text('utf-8')
|
|
71 try:
|
2
|
72 return json.loads(data, object_hook=lambda d: ColorProfileBase.unserialize(d))
|
1
|
73 except json.decoder.JSONDecodeError:
|
|
74 return []
|
|
75 else:
|
|
76 return []
|
0
|
77
|
1
|
78 def save_profiles(self):
|
2
|
79 data = json.dumps(self.profiles, default=lambda o: o.serialize())
|
1
|
80 pathlib.Path(self.config_path()).write_text(data, 'utf-8')
|
0
|
81
|
1
|
82 def get_profiles(self):
|
|
83 return self.profiles
|
2
|
84
|
|
85 def get_profile(self, profile_id):
|
|
86 return self.get_profiles()[profile_id]
|