File: gmDataPackWidgets.py

package info (click to toggle)
gnumed-client 1.4.12%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 164,192 kB
  • ctags: 168,531
  • sloc: python: 88,281; sh: 765; makefile: 37
file content (360 lines) | stat: -rw-r--r-- 10,065 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
"""GNUmed data pack related widgets."""
#================================================================
__author__ = 'karsten.hilbert@gmx.net'
__license__ = 'GPL v2 or later (details at http://www.gnu.org)'

# stdlib
import logging
import sys
import urllib2 as wget

# 3rd party
import wx


# GNUmed
if __name__ == '__main__':
	sys.path.insert(0, '../../')

from Gnumed.pycommon import gmCfg2
from Gnumed.pycommon import gmCfg
from Gnumed.pycommon import gmTools
from Gnumed.pycommon import gmNetworkTools
from Gnumed.pycommon import gmPG2
from Gnumed.business import gmPraxis
from Gnumed.wxpython import gmListWidgets
from Gnumed.wxpython import gmGuiHelpers
from Gnumed.wxpython import gmAuthWidgets
from Gnumed.wxpython import gmCfgWidgets


_log = logging.getLogger('gm.ui')
_cfg = gmCfg2.gmCfgData()


default_dpl_url = u'http://www.gnumed.de/downloads/data/data-packs.conf'
dpl_url_option = u'horstspace.data_packs.url'
#================================================================
def install_data_pack(data_pack=None):

	if data_pack is None:
		return False

	_log.info('attempting installation of data pack: %s', data_pack['name'])

	msg = _(
		'Note that GNUmed data packs are provided\n'
		'\n'
		'WITHOUT ANY GUARANTEE WHATSOEVER\n'
		'\n'
		'regarding their content.\n'
		'\n'
		'Despite data packs having been prepared with the\n'
		'utmost care you must still vigilantly apply caution,\n'
		'common sense, and due diligence to make sure you\n'
		'render appropriate care to your patients.\n'
		'\n'
		'Press [Yes] to declare agreement with this precaution.\n'
		'\n'
		'Press [No] to abort installation of the data pack.\n'
	)
	go_ahead = gmGuiHelpers.gm_show_question(msg, _('Terms of Data Pack Use'))
	if not go_ahead:
		_log.info('user did not agree to terms of data pack use')
		return True

	gm_dbo_conn = gmAuthWidgets.get_dbowner_connection(procedure = _('installing data pack'))
	if gm_dbo_conn is None:
		msg = _('Lacking permissions to install data pack.')
		gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
		return False

	wx.BeginBusyCursor()
	verified, data = gmNetworkTools.download_data_pack (
		data_pack['pack_url'],
		md5_url = data_pack['md5_url']
	)
	wx.EndBusyCursor()
	if not verified:
		_log.error('cannot download and verify data pack: %s', data_pack['name'])
		md5_expected, md5_calculated = data
		msg = _(
			'Cannot validate data pack.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'\n'
			'  MD5\n'
			'   calculated: %s\n'
			'   expected: %s\n'
			'   source: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			md5_calculated,
			md5_expected,
			data_pack['md5_url']
		)
		gmGuiHelpers.gm_show_error(msg, _('Verifying data pack'))
		return False

	data_pack['local_archive'] = data

	wx.BeginBusyCursor()
	unzip_dir = gmNetworkTools.unzip_data_pack(filename = data)
	wx.EndBusyCursor()
	if unzip_dir is None:
		msg = _(
			'Cannot unpack data pack.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'  local: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			data_pack['local_archive']
		)
		gmGuiHelpers.gm_show_error(msg, _('Unpacking data pack'))
		return False

	data_pack['unzip_dir'] = unzip_dir

	wx.BeginBusyCursor()
	try:
		installed = gmNetworkTools.install_data_pack(data_pack, gm_dbo_conn)
	finally:
		wx.EndBusyCursor()

	# check schema hash
	db_version = gmPG2.map_client_branch2required_db_version[_cfg.get(option = 'client_branch')]
	if not gmPG2.database_schema_compatible(version = db_version):
		if db_version != 0:
			msg = _(
				'Installation of data pack failed because\n'
				'it attempted to modify the database layout.\n'
				'\n'
				'  name: %s\n'
				'  URL: %s\n'
				'  local: %s\n'
				'\n'
				'You will need to contact your administrator.'
			) % (
				data_pack['name'],
				data_pack['pack_url'],
				data_pack['local_archive']
			)
			gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
			return False

	if not installed:
		msg = _(
			'Installation of data pack failed.\n'
			'\n'
			'  name: %s\n'
			'  URL: %s\n'
			'  local: %s\n'
			'\n'
			'You may want to try downloading again or you\n'
			'may need to contact your administrator.'
		) % (
			data_pack['name'],
			data_pack['pack_url'],
			data_pack['local_archive']
		)
		gmGuiHelpers.gm_show_error(msg, _('Installing data pack'))
		return False

	msg = _(
		'Successfully installed data pack.\n'
		'\n'
		'  name: %s\n'
		'  URL: %s\n'
	) % (
		data_pack['name'],
		data_pack['pack_url']
	)
	gmGuiHelpers.gm_show_info(msg, _('Installing data pack'))

	return True
#----------------------------------------------------------------
def load_data_packs_list():

	dbcfg = gmCfg.cCfgSQL()
	dpl_url = dbcfg.get2 (
		option = dpl_url_option,
		workplace = gmPraxis.gmCurrentPraxisBranch().active_workplace,
		bias = 'workplace',
		default = default_dpl_url
	)

	items = []
	data = []

	dpl_fname = gmNetworkTools.download_data_packs_list(dpl_url)
	if dpl_fname is None:
		return (items, data)
	try:
		_cfg.add_file_source(source = 'data-packs', file = dpl_fname)
	except (UnicodeDecodeError):
		_log.exception("cannot read data pack list from [%s]", dpl_fname)
		return (items, data)

	packs = _cfg.get('data packs', 'data packs', source_order = [('data-packs', 'return')])
	if packs is None:
		_log.info('no data packs listed in data packs list file')
		_cfg.remove_source('data-packs')
		return (items, data)

	for pack in packs:
		_log.debug('reading pack [%s] metadata', pack)
		pack_group = u'pack %s' % pack
		name = _cfg.get(pack_group, u'name', source_order = [('data-packs', 'return')])
		pack_url = _cfg.get(pack_group, u'URL', source_order = [('data-packs', 'return')])
		md5_url = pack_url + u'.md5'
		db_min = _cfg.get(pack_group, u'minimum database version', source_order = [('data-packs', 'return')])
		converted, db_min = gmTools.input2int (
			db_min,
			# here we introduced data packs:
			#16,
			0,
			# no use looking at data packs requiring a database > the current database:
			_cfg.get(option = 'database_version')
		)
		if not converted:
			_log.error('cannot convert minimum database version [%s]', db_min)
			continue

		db_max = _cfg.get(pack_group, u'maximum database version', source_order = [('data-packs', 'return')])
		if db_max is None:
			db_max = sys.maxint
		converted, db_max = gmTools.input2int (
			db_max,
			db_min		# max version must be at least db_min
		)
		if not converted:
			_log.error('cannot convert maximum database version [%s]', db_max)
			continue

		if _cfg.get(option = 'database_version') < db_min:
			_log.error('ignoring data pack: current database version (%s) < minimum required database version (%s)', _cfg.get(option = 'database_version'), db_min)
			continue

		if _cfg.get(option = 'database_version') > db_max:
			_log.error('ignoring data pack: current database version (%s) > maximum allowable database version (%s)', _cfg.get(option = 'database_version'), db_max)
			continue

		items.append([name, u'v%s' % db_min, u'v%s' % db_max, pack_url])
		data.append ({
			'name': name,
			'pack_url': pack_url,
			'md5_url': md5_url,
			'db_min': db_min,
			'db_max': db_max
		})

	_cfg.remove_source('data-packs')
	return (items, data)
#----------------------------------------------------------------
def manage_data_packs(parent=None):

	if parent is None:
		parent = wx.GetApp().GetTopWindow()

	#--------------------------------------------
	def validate_url(url):
		return True, url
	#--------------------------------------------
	def configure_dpl_url(item):
		gmCfgWidgets.configure_string_option (
			parent = parent,
			message = _(
				'Please enter the URL under which to load\n'
				'the list of available data packs.\n'
				'\n'
				'The default URL is:\n'
				'\n'
				' [%s]\n'
			) % default_dpl_url,
			option = dpl_url_option,
			bias = u'workplace',
			default_value = default_dpl_url,
			validator = validate_url
		)
		return True
	#--------------------------------------------
	def refresh(lctrl):
		items, data = load_data_packs_list()
		lctrl.set_string_items(items)
		lctrl.set_data(data)
	#--------------------------------------------
	lb_tt = _(
		'Install the selected data pack.\n'
		'\n'
		'This can take quite a while depending on\n'
		'the amount of data to be installed.\n'
		'\n'
		'GNUmed will block until installation is\n'
		'complete and eventually inform you of\n'
		'success or failure.'
	)
	gmListWidgets.get_choices_from_list (
		parent = parent,
		msg = _(
			'Data packs available for installation into this v%s database.\n'
		) % (
			_cfg.get(option = 'database_version')
		),
		caption = _('Showing data packs.'),
		columns = [ _('Data pack'), _('min DB'), _('max DB'), _('Source') ],
		single_selection = True,
		can_return_empty = False,
		ignore_OK_button = True,
		refresh_callback = refresh,
		left_extra_button = (
			_('&Install'),
			lb_tt,
			install_data_pack
		),
#		middle_extra_button=None,
		right_extra_button = (
			_('&Configure'),
			_('Configure the data packs list source'),
			configure_dpl_url
		)
	)

#================================================================
# main
#----------------------------------------------------------------
if __name__ == '__main__':

	if len(sys.argv) < 2:
		sys.exit()

	if sys.argv[1] != 'test':
		sys.exit()

	from Gnumed.pycommon import gmI18N
	gmI18N.activate_locale()
	gmI18N.install_domain()
#	from Gnumed.pycommon import gmPG2

	#--------------------------------------------------------
#	def test_generic_codes_prw():
#		gmPG2.get_connection()
#		app = wx.PyWidgetTester(size = (500, 40))
#		pw = cGenericCodesPhraseWheel(app.frame, -1)
#		#pw.set_context(context = u'zip', val = u'04318')
#		app.frame.Show(True)
#		app.MainLoop()
#	#--------------------------------------------------------
#	test_generic_codes_prw()

#================================================================