10
10
FILE_HASSIO_ADDONS , ATTR_NAME , ATTR_VERSION , ATTR_SLUG , ATTR_DESCRIPTON ,
11
11
ATTR_STARTUP , ATTR_BOOT , ATTR_MAP_SSL , ATTR_MAP_CONFIG , ATTR_OPTIONS ,
12
12
ATTR_PORTS , BOOT_AUTO , DOCKER_REPO , ATTR_INSTALLED , ATTR_SCHEMA ,
13
- ATTR_IMAGE )
13
+ ATTR_IMAGE , ATTR_DEDICATED )
14
14
from ..config import Config
15
15
from ..tools import read_json_file , write_json_file
16
16
17
17
_LOGGER = logging .getLogger (__name__ )
18
18
19
19
ADDONS_REPO_PATTERN = "{}/*/config.json"
20
+ SYSTEM = "system"
21
+ USER = "user"
20
22
21
23
22
24
class AddonsData (Config ):
@@ -26,12 +28,22 @@ def __init__(self, config):
26
28
"""Initialize data holder."""
27
29
super ().__init__ (FILE_HASSIO_ADDONS )
28
30
self .config = config
29
- self ._addons_data = {}
31
+ self ._addons_data = self ._data .get (SYSTEM , {})
32
+ self ._user_data = self ._data .get (USER , {})
33
+ self ._current_data = {}
30
34
self .arch = None
31
35
36
+ def save (self ):
37
+ """Store data to config file."""
38
+ self ._data = {
39
+ USER : self ._user_data ,
40
+ SYSTEM : self ._addons_data ,
41
+ }
42
+ super ().save ()
43
+
32
44
def read_addons_repo (self ):
33
45
"""Read data from addons repository."""
34
- self ._addons_data = {}
46
+ self ._current_data = {}
35
47
36
48
self ._read_addons_folder (self .config .path_addons_repo )
37
49
self ._read_addons_folder (self .config .path_addons_custom )
@@ -45,7 +57,7 @@ def _read_addons_folder(self, folder):
45
57
addon_config = read_json_file (addon )
46
58
47
59
addon_config = SCHEMA_ADDON_CONFIG (addon_config )
48
- self ._addons_data [addon_config [ATTR_SLUG ]] = addon_config
60
+ self ._current_data [addon_config [ATTR_SLUG ]] = addon_config
49
61
50
62
except (OSError , KeyError ):
51
63
_LOGGER .warning ("Can't read %s" , addon )
@@ -57,32 +69,33 @@ def _read_addons_folder(self, folder):
57
69
@property
58
70
def list_installed (self ):
59
71
"""Return a list of installed addons."""
60
- return set (self ._data .keys ())
61
-
62
- @property
63
- def list_all (self ):
64
- """Return a list of available addons."""
65
72
return set (self ._addons_data .keys ())
66
73
67
74
@property
68
75
def list (self ):
69
76
"""Return a list of available addons."""
70
77
data = []
71
- for addon , values in self ._addons_data .items ():
78
+ all_addons = {** self ._addons_data , ** self ._current_data }
79
+ dedicated = self .list_removed
80
+
81
+ for addon , values in all_addons .items ():
82
+ i_version = self ._addons_data .get (addon , {}).get (ATTR_VERSION )
83
+
72
84
data .append ({
73
85
ATTR_NAME : values [ATTR_NAME ],
74
86
ATTR_SLUG : values [ATTR_SLUG ],
75
87
ATTR_DESCRIPTON : values [ATTR_DESCRIPTON ],
76
88
ATTR_VERSION : values [ATTR_VERSION ],
77
- ATTR_INSTALLED : self ._data .get (addon , {}).get (ATTR_VERSION ),
89
+ ATTR_INSTALLED : i_version ,
90
+ ATTR_DEDICATED : addon in dedicated ,
78
91
})
79
92
80
93
return data
81
94
82
95
def list_startup (self , start_type ):
83
96
"""Get list of installed addon with need start by type."""
84
97
addon_list = set ()
85
- for addon in self ._data .keys ():
98
+ for addon in self ._addons_data .keys ():
86
99
if self .get_boot (addon ) != BOOT_AUTO :
87
100
continue
88
101
@@ -99,58 +112,64 @@ def list_startup(self, start_type):
99
112
def list_removed (self ):
100
113
"""Return local addons they not support from repo."""
101
114
addon_list = set ()
102
- for addon in self ._data .keys ():
103
- if addon not in self ._addons_data :
115
+ for addon in self ._addons_data .keys ():
116
+ if addon not in self ._current_data :
104
117
addon_list .add (addon )
105
118
106
119
return addon_list
107
120
108
121
def exists_addon (self , addon ):
109
122
"""Return True if a addon exists."""
110
- return addon in self ._addons_data
123
+ return addon in self ._current_data or addon in self . _addons_data
111
124
112
125
def is_installed (self , addon ):
113
126
"""Return True if a addon is installed."""
114
- return addon in self ._data
127
+ return addon in self ._addons_data
115
128
116
129
def version_installed (self , addon ):
117
130
"""Return installed version."""
118
- return self ._data [addon ][ATTR_VERSION ]
131
+ return self ._addons_data [addon ][ATTR_VERSION ]
119
132
120
- def set_install_addon (self , addon , version ):
133
+ def set_addon_install (self , addon , version ):
121
134
"""Set addon as installed."""
122
- self ._data [addon ] = {
123
- ATTR_VERSION : version ,
124
- ATTR_OPTIONS : {}
135
+ self ._addons_data [addon ] = self . _current_data [ addon ]
136
+ self . _user_data [ addon ] = {
137
+ ATTR_OPTIONS : {},
125
138
}
126
139
self .save ()
127
140
128
- def set_uninstall_addon (self , addon ):
141
+ def set_addon_uninstall (self , addon ):
129
142
"""Set addon as uninstalled."""
130
- self ._data .pop (addon , None )
143
+ self ._addons_data .pop (addon , None )
144
+ self ._user_data .pop (addon , None )
145
+ self .save ()
146
+
147
+ def set_addon_update (self , addon , version ):
148
+ """Update version of addon."""
149
+ self ._addons_data [addon ] = self ._current_data [addon ]
131
150
self .save ()
132
151
133
152
def set_options (self , addon , options ):
134
153
"""Store user addon options."""
135
- self ._data [addon ][ATTR_OPTIONS ] = options
154
+ self ._user_data [addon ][ATTR_OPTIONS ] = options
136
155
self .save ()
137
156
138
- def set_version (self , addon , version ):
139
- """Update version of addon ."""
140
- self ._data [addon ][ATTR_VERSION ] = version
157
+ def set_boot (self , addon , boot ):
158
+ """Store user boot options ."""
159
+ self ._user_data [addon ][ATTR_BOOT ] = boot
141
160
self .save ()
142
161
143
162
def get_options (self , addon ):
144
163
"""Return options with local changes."""
145
- opt = self . _addons_data [ addon ][ ATTR_OPTIONS ]
146
- if addon in self ._data :
147
- opt . update ( self ._data [addon ][ATTR_OPTIONS ])
148
- return opt
164
+ return {
165
+ ** self ._addons_data [ addon ][ ATTR_OPTIONS ],
166
+ ** self ._user_data [addon ][ATTR_OPTIONS ],
167
+ }
149
168
150
169
def get_boot (self , addon ):
151
170
"""Return boot config with prio local settings."""
152
- if ATTR_BOOT in self ._data [addon ]:
153
- return self ._data [addon ][ATTR_BOOT ]
171
+ if ATTR_BOOT in self ._user_data [addon ]:
172
+ return self ._user_data [addon ][ATTR_BOOT ]
154
173
155
174
return self ._addons_data [addon ][ATTR_BOOT ]
156
175
@@ -164,23 +183,22 @@ def get_description(self, addon):
164
183
165
184
def get_version (self , addon ):
166
185
"""Return version of addon."""
167
- return self ._addons_data [addon ][ATTR_VERSION ]
168
-
169
- def get_slug (self , addon ):
170
- """Return slug of addon."""
171
- return self ._addons_data [addon ][ATTR_SLUG ]
186
+ if addon not in self ._current_data :
187
+ return self .version_installed (addon )
188
+ return self ._current_data [addon ][ATTR_VERSION ]
172
189
173
190
def get_ports (self , addon ):
174
191
"""Return ports of addon."""
175
192
return self ._addons_data [addon ].get (ATTR_PORTS )
176
193
177
194
def get_image (self , addon ):
178
195
"""Return image name of addon."""
179
- if ATTR_IMAGE not in self ._addons_data [addon ]:
180
- return "{}/{}-addon-{}" .format (
181
- DOCKER_REPO , self .arch , self .get_slug (addon ))
196
+ addon_data = self ._addons_data .get (addon , self ._current_data [addon ])
197
+
198
+ if ATTR_IMAGE not in addon_data :
199
+ return "{}/{}-addon-{}" .format (DOCKER_REPO , self .arch , addon )
182
200
183
- return self . _addons_data [ addon ] [ATTR_IMAGE ]
201
+ return addon_data [ATTR_IMAGE ]
184
202
185
203
def need_config (self , addon ):
186
204
"""Return True if config map is needed."""
@@ -192,13 +210,11 @@ def need_ssl(self, addon):
192
210
193
211
def path_data (self , addon ):
194
212
"""Return addon data path inside supervisor."""
195
- return "{}/{}" .format (
196
- self .config .path_addons_data , self ._addons_data [addon ][ATTR_SLUG ])
213
+ return "{}/{}" .format (self .config .path_addons_data , addon )
197
214
198
215
def path_data_docker (self , addon ):
199
216
"""Return addon data path external for docker."""
200
- return "{}/{}" .format (self .config .path_addons_data_docker ,
201
- self ._addons_data [addon ][ATTR_SLUG ])
217
+ return "{}/{}" .format (self .config .path_addons_data_docker , addon )
202
218
203
219
def path_addon_options (self , addon ):
204
220
"""Return path to addons options."""
0 commit comments