1 """GNUmed data pack related widgets."""
2
3 __author__ = 'karsten.hilbert@gmx.net'
4 __license__ = 'GPL v2 or later (details at http://www.gnu.org)'
5
6
7 import logging
8 import sys
9
10
11
12 import wx
13
14
15
16 if __name__ == '__main__':
17 sys.path.insert(0, '../../')
18
19 from Gnumed.pycommon import gmCfg2
20 from Gnumed.pycommon import gmCfg
21 from Gnumed.pycommon import gmTools
22 from Gnumed.pycommon import gmNetworkTools
23 from Gnumed.pycommon import gmPG2
24 from Gnumed.business import gmPraxis
25 from Gnumed.wxpython import gmListWidgets
26 from Gnumed.wxpython import gmGuiHelpers
27 from Gnumed.wxpython import gmAuthWidgets
28 from Gnumed.wxpython import gmCfgWidgets
29
30
31 _log = logging.getLogger('gm.ui')
32 _cfg = gmCfg2.gmCfgData()
33
34
35 default_dpl_url = 'http://www.gnumed.de/downloads/data/data-packs.conf'
36 dpl_url_option = 'horstspace.data_packs.url'
37
39
40 if data_pack is None:
41 return False
42
43 _log.info('attempting installation of data pack: %s', data_pack['name'])
44
45 msg = _(
46 'Note that GNUmed data packs are provided\n'
47 '\n'
48 'WITHOUT ANY GUARANTEE WHATSOEVER\n'
49 '\n'
50 'regarding their content.\n'
51 '\n'
52 'Despite data packs having been prepared with the\n'
53 'utmost care you must still vigilantly apply caution,\n'
54 'common sense, and due diligence to make sure you\n'
55 'render appropriate care to your patients.\n'
56 '\n'
57 'Press [Yes] to declare agreement with this precaution.\n'
58 '\n'
59 'Press [No] to abort installation of the data pack.\n'
60 )
61 go_ahead = gmGuiHelpers.gm_show_question(msg, _('Terms of Data Pack Use'))
62 if not go_ahead:
63 _log.info('user did not agree to terms of data pack use')
64 return True
65
66 gm_dbo_conn = gmAuthWidgets.get_dbowner_connection(procedure = _('installing data pack'))
67 if gm_dbo_conn is None:
68 msg = _('Lacking permissions to install data pack.')
69 gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
70 return False
71
72 wx.BeginBusyCursor()
73 verified, data = gmNetworkTools.download_data_pack (
74 data_pack['pack_url'],
75 md5_url = data_pack['md5_url']
76 )
77 wx.EndBusyCursor()
78 if not verified:
79 _log.error('cannot download and verify data pack: %s', data_pack['name'])
80 md5_expected, md5_calculated = data
81 msg = _(
82 'Cannot validate data pack.\n'
83 '\n'
84 ' name: %s\n'
85 ' URL: %s\n'
86 '\n'
87 ' MD5\n'
88 ' calculated: %s\n'
89 ' expected: %s\n'
90 ' source: %s\n'
91 '\n'
92 'You may want to try downloading again or you\n'
93 'may need to contact your administrator.'
94 ) % (
95 data_pack['name'],
96 data_pack['pack_url'],
97 md5_calculated,
98 md5_expected,
99 data_pack['md5_url']
100 )
101 gmGuiHelpers.gm_show_error(msg, _('Verifying data pack'))
102 return False
103
104 data_pack['local_archive'] = data
105
106 wx.BeginBusyCursor()
107 unzip_dir = gmNetworkTools.unzip_data_pack(filename = data)
108 wx.EndBusyCursor()
109 if unzip_dir is None:
110 msg = _(
111 'Cannot unpack data pack.\n'
112 '\n'
113 ' name: %s\n'
114 ' URL: %s\n'
115 ' local: %s\n'
116 '\n'
117 'You may want to try downloading again or you\n'
118 'may need to contact your administrator.'
119 ) % (
120 data_pack['name'],
121 data_pack['pack_url'],
122 data_pack['local_archive']
123 )
124 gmGuiHelpers.gm_show_error(msg, _('Unpacking data pack'))
125 return False
126
127 data_pack['unzip_dir'] = unzip_dir
128
129 wx.BeginBusyCursor()
130 try:
131 installed = gmNetworkTools.install_data_pack(data_pack, gm_dbo_conn)
132 finally:
133 wx.EndBusyCursor()
134
135
136 db_version = gmPG2.map_client_branch2required_db_version[_cfg.get(option = 'client_branch')]
137 if not gmPG2.database_schema_compatible(version = db_version):
138 if db_version != 0:
139 msg = _(
140 'Installation of data pack failed because\n'
141 'it attempted to modify the database layout.\n'
142 '\n'
143 ' name: %s\n'
144 ' URL: %s\n'
145 ' local: %s\n'
146 '\n'
147 'You will need to contact your administrator.'
148 ) % (
149 data_pack['name'],
150 data_pack['pack_url'],
151 data_pack['local_archive']
152 )
153 gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
154 return False
155
156 if not installed:
157 msg = _(
158 'Installation of data pack failed.\n'
159 '\n'
160 ' name: %s\n'
161 ' URL: %s\n'
162 ' local: %s\n'
163 '\n'
164 'You may want to try downloading again or you\n'
165 'may need to contact your administrator.'
166 ) % (
167 data_pack['name'],
168 data_pack['pack_url'],
169 data_pack['local_archive']
170 )
171 gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
172 return False
173
174 msg = _(
175 'Successfully installed data pack.\n'
176 '\n'
177 ' name: %s\n'
178 ' URL: %s\n'
179 ) % (
180 data_pack['name'],
181 data_pack['pack_url']
182 )
183 gmGuiHelpers.gm_show_info(msg, _('Installing data pack'))
184
185 return True
186
187
189
190 dbcfg = gmCfg.cCfgSQL()
191 dpl_url = dbcfg.get2 (
192 option = dpl_url_option,
193 workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
194 bias = 'workplace',
195 default = default_dpl_url
196 )
197
198 items = []
199 data = []
200
201 dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url)
202 if dpl_fname is None:
203 return (items, data)
204 try:
205 _cfg.add_file_source(source = 'data-packs', file = dpl_fname)
206 except (UnicodeDecodeError):
207 _log.exception("cannot read data pack list from [%s]", dpl_fname)
208 return (items, data)
209
210 packs = _cfg.get('data packs', 'data packs', source_order = [('data-packs', 'return')])
211 if packs is None:
212 _log.info('no data packs listed in data packs list file')
213 _cfg.remove_source('data-packs')
214 return (items, data)
215
216 for pack in packs:
217 _log.debug('reading pack [%s] metadata', pack)
218 pack_group = 'pack %s' % pack
219 name = _cfg.get(pack_group, 'name', source_order = [('data-packs', 'return')])
220 pack_url = _cfg.get(pack_group, 'URL', source_order = [('data-packs', 'return')])
221 md5_url = pack_url + '.md5'
222 db_min = _cfg.get(pack_group, 'minimum database version', source_order = [('data-packs', 'return')])
223 converted, db_min = gmTools.input2int (
224 db_min,
225
226
227 0,
228
229 _cfg.get(option = 'database_version')
230 )
231 if not converted:
232 _log.error('cannot convert minimum database version [%s]', db_min)
233 continue
234
235 db_max = _cfg.get(pack_group, 'maximum database version', source_order = [('data-packs', 'return')])
236 if db_max is None:
237 db_max = sys.maxsize
238 converted, db_max = gmTools.input2int (
239 db_max,
240 db_min
241 )
242 if not converted:
243 _log.error('cannot convert maximum database version [%s]', db_max)
244 continue
245
246 if _cfg.get(option = 'database_version') < db_min:
247 _log.error('ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option = 'database_version'), db_min)
248 continue
249
250 if _cfg.get(option = 'database_version') > db_max:
251 _log.error('ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option = 'database_version'), db_max)
252 continue
253
254 items.append([name, 'v%s' % db_min, 'v%s' % db_max, pack_url])
255 data.append ({
256 'name': name,
257 'pack_url': pack_url,
258 'md5_url': md5_url,
259 'db_min': db_min,
260 'db_max': db_max
261 })
262
263 _cfg.remove_source('data-packs')
264 return (items, data)
265
267
268 if parent is None:
269 parent = wx.GetApp().GetTopWindow()
270
271
272 def validate_url(url):
273 return True, url
274
275 def configure_dpl_url(item):
276 gmCfgWidgets.configure_string_option (
277 parent = parent,
278 message = _(
279 'Please enter the URL under which to load\n'
280 'the list of available data packs.\n'
281 '\n'
282 'The default URL is:\n'
283 '\n'
284 ' [%s]\n'
285 ) % default_dpl_url,
286 option = dpl_url_option,
287 bias = 'workplace',
288 default_value = default_dpl_url,
289 validator = validate_url
290 )
291 return True
292
293 def refresh(lctrl):
294 items, data = load_data_packs_list()
295 lctrl.set_string_items(items)
296 lctrl.set_data(data)
297
298 lb_tt = _(
299 'Install the selected data pack.\n'
300 '\n'
301 'This can take quite a while depending on\n'
302 'the amount of data to be installed.\n'
303 '\n'
304 'GNUmed will block until installation is\n'
305 'complete and eventually inform you of\n'
306 'success or failure.'
307 )
308 gmListWidgets.get_choices_from_list (
309 parent = parent,
310 msg = _(
311 'Data packs available for installation into this v%s database.\n'
312 ) % (
313 _cfg.get(option = 'database_version')
314 ),
315 caption = _('Showing data packs.'),
316 columns = [ _('Data pack'), _('min DB'), _('max DB'), _('Source') ],
317 single_selection = True,
318 can_return_empty = False,
319 ignore_OK_button = True,
320 refresh_callback = refresh,
321 left_extra_button = (
322 _('&Install'),
323 lb_tt,
324 install_data_pack
325 ),
326
327 right_extra_button = (
328 _('&Configure'),
329 _('Configure the data packs list source'),
330 configure_dpl_url
331 )
332 )
333
334
335
336
337 if __name__ == '__main__':
338
339 if len(sys.argv) < 2:
340 sys.exit()
341
342 if sys.argv[1] != 'test':
343 sys.exit()
344
345 from Gnumed.pycommon import gmI18N
346 gmI18N.activate_locale()
347 gmI18N.install_domain()
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362