kongalib 2.0.4__cp314-cp314-macosx_10_15_universal2.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of kongalib might be problematic. Click here for more details.

kongautil.py ADDED
@@ -0,0 +1,581 @@
1
+ # -*- coding: utf-8 -*-
2
+ # _ _ _ _
3
+ # | | | (_) |
4
+ # | | _____ _ __ __ _ __ _| |_| |__
5
+ # | |/ / _ \| '_ \ / _` |/ _` | | | '_ \
6
+ # | < (_) | | | | (_| | (_| | | | |_) |
7
+ # |_|\_\___/|_| |_|\__, |\__,_|_|_|_.__/
8
+ # __/ |
9
+ # |___/
10
+ #
11
+ # Konga client library, by EasyByte Software
12
+ #
13
+ # https://github.com/easybyte-software/kongalib
14
+
15
+ from __future__ import print_function
16
+
17
+ import sys
18
+ import os, os.path
19
+ import kongalib
20
+
21
+ try:
22
+ from shlex import quote
23
+ except:
24
+ from pipes import quote
25
+
26
+ from kongalib.scripting import proxy as _proxy
27
+
28
+
29
+ PRINT_TARGET_PREVIEW = 0 #: Stampa a video
30
+ PRINT_TARGET_PAPER = 1 #: Stampa su carta
31
+ PRINT_TARGET_PDF = 2 #: Stampa su file PDF
32
+ PRINT_TARGET_CSV = 3 #: Stampa su file CSV
33
+ PRINT_TARGET_XLS = 4 #: Stampa su file Excel
34
+ PRINT_TARGET_LABEL = 5 #: Stampa su etichette
35
+
36
+
37
+ _last_client = None
38
+ _konga_exe = None
39
+ _konga_args = None
40
+ _konga_reuse_client = False
41
+ _konga_proc = None
42
+
43
+
44
+
45
+ class KongaRequiredError(RuntimeError):
46
+ """Eccezione lanciata quando si esegue una funzione disponibile solo dall'interno di Konga."""
47
+ def __str__(self):
48
+ return "Function requires script to be executed from within Konga"
49
+
50
+
51
+
52
+ class PrintError(RuntimeError):
53
+ """Eccezione lanciata se ci sono errori nell'esecuzione di una stampa con la funzione :func:`print_layout`."""
54
+ def __init__(self, log):
55
+ self._log = log
56
+ def __str__(self):
57
+ return 'Log:\n%s' % ('\n'.join([ (' %s' % line) for line in kongalib.ensure_text(self._log.dumps()).split(u'\n') ]))
58
+ def get_log(self):
59
+ """Ottiene un oggetto di classe :class:`kongalib.Log` contenente gli errori di stampa."""
60
+ return self._log
61
+
62
+
63
+
64
+ class ScriptContext(object):
65
+ """ Classe per l'accesso al contesto di esecuzione delle azioni esterne lato client di Konga.
66
+ La classe prevede l'uso di proprietà per accedere alle informazioni in lettura e scrittura."""
67
+ def __init__(self, database, company, tablename, record_id, record_code, record_data, **kwargs):
68
+ self._database = database
69
+ self._company = company
70
+ self._tablename = tablename
71
+ self._record_id = record_id
72
+ self._record_code = record_code
73
+ self._record_data = record_data
74
+ self._params = kwargs
75
+ self._result = None
76
+
77
+ @property
78
+ def database(self):
79
+ """Ritorna un oggetto ``dict`` che contiene informazioni sul database attualmente connesso.
80
+ Contiene le chiavi ``name``, ``driver``, ``desc`` e tutti i nomi dei campi della tabella EB_Master,
81
+ i cui valori sono presi dal database."""
82
+ return self._database
83
+
84
+ @property
85
+ def company(self):
86
+ """Ritorna un oggetto ``dict`` che contiene informazioni sull'azienda attualmente impostata nella
87
+ finestra che sta eseguendo l'azione esterna. Contiene come chiavi tutti i campi delle tabelle EB_Aziende
88
+ e EB_StatoArchivi (al contrario della proprietà ``database`` le cui chiavi sono nella forma ``<nomecampo>``,
89
+ qui i campi sono nella forma ``<nometabella>.<nomecampo>`` per evitare conflitti di nomi tra le tabelle
90
+ EB_Aziende e EB_StatoArchivi) con i relativi valori presi dal database."""
91
+ return self._company
92
+
93
+ @property
94
+ def tablename(self):
95
+ """Ritorna il nome della tabella su cui l'azione esterna sta operando."""
96
+ return self._tablename
97
+
98
+ @property
99
+ def record_id(self):
100
+ """Ritorna l'ID (chiave primaria) del record su cui l'azione esterna sta operando. Vedere anche :meth:`.tablename`."""
101
+ return self._record_id
102
+
103
+ @property
104
+ def record_code(self):
105
+ """Ritorna il codice del record su cui l'azione esterna sta operando. Vedere anche :meth:`.tablename`."""
106
+ return self._record_code
107
+
108
+ @property
109
+ def record_data(self):
110
+ """Ritorna un ``dict`` con i dati del record visibili sulla scheda della finestra che sta eseguendo l'azione esterna."""
111
+ return self._record_data
112
+
113
+ @property
114
+ def params(self):
115
+ """Ritorna un ``dict`` con i parametri che Konga passa allo script per l'esecuzione dell'azione esterna;
116
+ questi parametri variano a seconda del tipo di azione che si sta eseguendo."""
117
+ return self._params
118
+
119
+ @property
120
+ def result(self):
121
+ """Ritorna o imposta il valore di ritorno dell'azione esterna, in modo che Konga possa usarlo al termine dell'esecuzione dell'azione
122
+ stessa. Il tipo ed il valore che andranno impostati dipendono dal tipo di azione esterna che si sta eseguendo."""
123
+ return self._result
124
+
125
+ @result.setter
126
+ def result(self, result):
127
+ self._result = result
128
+ _proxy.util.set_script_result(result)
129
+
130
+
131
+
132
+ def connect(host=None, port=None, driver=None, database=None, username=None, password=None, tenant_key=None, config=None):
133
+ """Restituisce un oggetto :class:`kongalib.Client` già connesso. Se eseguito dall'interno di Konga, la connessione sarà stabilita
134
+ con il server, il database e l'utenza correntemente aperti sul programma, e i parametri passati a questa funzione saranno ignorati.
135
+ Se eseguita fuori da Konga, la funzione proverà a collegarsi al primo server disponibile sulla rete locale, aprendo il primo
136
+ database disponibile autenticandosi col l'utenza *admin* con password vuota; ogni parametro di connessione può essere forzato
137
+ tramite i parametri passati a questa funzione, oppure da linea di comando specificando gli argomenti ``--host``, ``--port``,
138
+ ``--driver``, ``-d|--database``, ``-u|--username``, ``-p|--password`` e ``-k|--tenant-key``. Inoltre, è possibile definire i
139
+ parametri come variabili all'interno di un file di configurazione, nella sezione ``[kongautil.connect]``; tale file deve avere
140
+ il nome passato a questa funzione con il parametro ``config``, altrimenti verranno ricercati nell'ordine anche il file con lo
141
+ stesso nome dello script lanciato da terminale, ma con estensione ``.cfg``, il file ``kongalib.cfg`` sempre nella stessa directory
142
+ da cui si esegue lo script e infine il file ``~/.kongalib`` (sotto Unix) o ``%userprofile%\\kongalib.cfg`` (sotto Windows)."""
143
+ if _proxy.is_valid():
144
+ info = _proxy.util.get_connection_info()
145
+ if info is not None:
146
+ host, port, driver, database, username, password, tenant_key = info
147
+ client = kongalib.Client()
148
+ client.connect(host=host, port=port, options={ 'tenant_key': tenant_key })
149
+ client.open_database(driver, database)
150
+ client.authenticate(username, password)
151
+ return client
152
+ else:
153
+ global _last_client
154
+ global _konga_exe
155
+ global _konga_args
156
+ global _konga_reuse_client
157
+ client = kongalib.Client()
158
+ if host is None:
159
+ import argparse
160
+ import configparser
161
+ files = [
162
+ os.path.abspath(os.path.expanduser(os.path.join('~', 'kongalib.cfg' if sys.platform == 'win32' else '.kongalib'))),
163
+ os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])), 'kongalib.cfg'),
164
+ os.path.splitext(sys.argv[0])[0] + '.cfg',
165
+ ]
166
+ if config:
167
+ files.append(config)
168
+ config = configparser.RawConfigParser({
169
+ 'host': host or '',
170
+ 'port': str(port or ''),
171
+ 'driver': driver or '',
172
+ 'database': database or '',
173
+ 'username': username or '',
174
+ 'password': password or '',
175
+ 'tenant_key': tenant_key or '',
176
+ 'konga_exe': '',
177
+ 'konga_args': '',
178
+ 'reuse_client': '',
179
+ })
180
+ config.add_section('kongautil.connect')
181
+ config.add_section('kongautil.print_layout')
182
+ config.read(files)
183
+ host = config.get('kongautil.connect', 'host') or None
184
+ try: port = int(config.get('kongautil.connect', 'port'))
185
+ except: pass
186
+ driver = config.get('kongautil.connect', 'driver') or None
187
+ database = config.get('kongautil.connect', 'database') or None
188
+ username = config.get('kongautil.connect', 'username') or None
189
+ password = config.get('kongautil.connect', 'password') or None
190
+ tenant_key = config.get('kongautil.connect', 'tenant_key') or None
191
+
192
+ _konga_exe = config.get('kongautil.print_layout', 'konga_exe') or None
193
+ _konga_args = config.get('kongautil.print_layout', 'konga_args') or None
194
+ _konga_reuse_client = config.get('kongautil.print_layout', 'reuse_client') or False
195
+
196
+ class ArgumentParser(argparse.ArgumentParser):
197
+ def _print_message(self, message, file=None):
198
+ pass
199
+ def exit(self, status=0, message=None):
200
+ if status:
201
+ raise RuntimeError
202
+ parser = ArgumentParser()
203
+ parser.add_argument('--host', default=host)
204
+ parser.add_argument('--port', type=int, default=port)
205
+ parser.add_argument('--driver', default=driver)
206
+ parser.add_argument('-d', '--database', default=database)
207
+ parser.add_argument('-u', '--username', default=username)
208
+ parser.add_argument('-p', '--password', default=password)
209
+ parser.add_argument('-k', '--tenant-key', default=tenant_key)
210
+ try:
211
+ args = parser.parse_args()
212
+ host = args.host
213
+ port = args.port
214
+ driver = args.driver
215
+ database = args.database
216
+ username = args.username
217
+ password = args.password
218
+ tenant_key = args.tenant_key
219
+ except:
220
+ pass
221
+ if host is None:
222
+ servers_list = client.list_servers(timeout=500)
223
+ if servers_list:
224
+ host = servers_list[0]['host']
225
+ port = servers_list[0]['port']
226
+ if host is not None:
227
+ client.connect(host=host, port=port or 0, options={ 'tenant_key': tenant_key })
228
+ db_list = None
229
+ if driver is None:
230
+ if database is not None:
231
+ db_list = client.list_databases(timeout=500)
232
+ for driver, dbs in db_list.items():
233
+ if database in [ db['name'] for db in dbs ]:
234
+ break
235
+ else:
236
+ driver = None
237
+ if driver is None:
238
+ drivers_list = client.list_drivers(timeout=500)
239
+ if drivers_list:
240
+ driver = drivers_list[0]['name']
241
+ if (driver is not None) and (database is None):
242
+ if db_list is None:
243
+ db_list = client.list_databases(driver, timeout=500)
244
+ if db_list and (len(db_list[driver]) > 0):
245
+ database = db_list[driver][0]['name']
246
+ if (driver is not None) and (database is not None):
247
+ client.open_database(driver, database)
248
+ client.authenticate(username or 'admin', password or '')
249
+ _last_client = client
250
+ return client
251
+ raise kongalib.Error(kongalib.DATABASE_NOT_CONNECTED, "No database connected")
252
+
253
+
254
+
255
+ def get_window_vars():
256
+ """Restituisce un ``dict`` contenente una serie di costanti definite per la finestra di navigazione correntemente aperta su Konga, incluse informazioni
257
+ sull'azienda corrente, l'eventuale selezione se la finestra mostra una vista a lista, e molto altro. Se la funzione è eseguita fuori da Konga, il ``dict``
258
+ restituito sarà vuoto."""
259
+ if _proxy.is_valid():
260
+ return _proxy.util.get_window_vars()
261
+ else:
262
+ return {}
263
+
264
+
265
+
266
+ def _terminate_script_proc():
267
+ try:
268
+ _konga_proc.stdin.write('.quit\n')
269
+ _konga_proc.stdin.flush()
270
+ try:
271
+ _konga_proc.wait(5)
272
+ except:
273
+ _konga_proc.terminate()
274
+ except:
275
+ pass
276
+
277
+
278
+
279
+ def _run_script(script, log, client):
280
+ import tempfile, subprocess, string, random, atexit
281
+ client_exe = _konga_exe
282
+ if client_exe is None:
283
+ if sys.platform == 'win32':
284
+ files = ( 'kongaclient.com', 'konga.com' )
285
+ else:
286
+ files = ( 'easybyte-konga-client', 'easybyte-konga' )
287
+ path = os.environ.get("PATH", None)
288
+ if path is None:
289
+ try:
290
+ path = os.confstr("CS_PATH")
291
+ except (AttributeError, ValueError):
292
+ path = os.defpath
293
+ if path is not None:
294
+ path = path.split(os.pathsep)
295
+ for exe in files:
296
+ seen = set()
297
+ for dir in path:
298
+ normdir = os.path.normcase(dir)
299
+ if not normdir in seen:
300
+ seen.add(normdir)
301
+ name = os.path.join(dir, exe)
302
+ if os.path.exists(name) and os.access(name, os.F_OK | os.X_OK) and not os.path.isdir(name):
303
+ client_exe = exe
304
+ break
305
+ if client_exe is not None:
306
+ break
307
+ if client_exe is None:
308
+ raise RuntimeError('Cannot find Konga executable')
309
+ client = client or _last_client
310
+ if client is not None:
311
+ info = client.get_connection_info()
312
+ lines = [
313
+ '.connect "%s" -p %d' % (info['host'], info['port']),
314
+ '.user "%s" -p "%s"' % (info['user']['name'], info['user']['password']),
315
+ '.open_database "%s" -d "%s"' % (info['database']['name'], info['database']['driver']),
316
+ ]
317
+ else:
318
+ lines = []
319
+ lines += script
320
+ try:
321
+ if _konga_reuse_client:
322
+ global _konga_proc
323
+ if (_konga_proc is None) or (_konga_proc.poll() is not None):
324
+ try:
325
+ _konga_proc = subprocess.Popen('%s %s --script -' % (client_exe, _konga_args or ''), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True, universal_newlines=True)
326
+ except Exception as e:
327
+ raise subprocess.CalledProcessError(-1, '', e)
328
+ atexit.unregister(_terminate_script_proc)
329
+ atexit.register(_terminate_script_proc)
330
+ marker = ''.join(random.choice(string.ascii_uppercase + string.digits) for i in range(32))
331
+ if client is not None:
332
+ lines += [ '.disconnect' ]
333
+ lines += [ '.echo %s' % marker, '' ]
334
+ _konga_proc.stdin.write('\n'.join(lines))
335
+ _konga_proc.stdin.flush()
336
+ while True:
337
+ line = _konga_proc.stdout.readline()
338
+ if not line:
339
+ break
340
+ line = line[:-1]
341
+ if line == marker:
342
+ break
343
+ log.info(line)
344
+ else:
345
+ temp = tempfile.NamedTemporaryFile(mode='w', delete=False)
346
+ try:
347
+ with temp:
348
+ temp.write('\n'.join(lines))
349
+ output = subprocess.check_output('%s %s --script %s' % (client_exe, _konga_args or '', quote(temp.name)), stderr=subprocess.STDOUT, shell=True, universal_newlines=True).splitlines()
350
+ for line in output:
351
+ log.info(line)
352
+ finally:
353
+ os.unlink(temp.name)
354
+ except subprocess.CalledProcessError as e:
355
+ log.warning("Errors running script:")
356
+ output = kongalib.ensure_text(e.output).splitlines()
357
+ for line in output:
358
+ log.error(line)
359
+ log.info("Original script was:")
360
+ for line in script:
361
+ log.info(" %s" % line)
362
+
363
+
364
+
365
+ def print_layout(command_or_layout, builtins=None, code_azienda=None, code_esercizio=None, target=None, filename=None, progress=True, client=None):
366
+ """Esegue una stampa su Konga. *command_or_layout* può essere un nome di comando di Konga, oppure un sorgente XML contenente la struttura stessa del layout da
367
+ stampare; *builtins* è un ``dict`` i cui valori verranno passati al motore di stampa e saranno disponibili all'interno degli script del layout; *code_azienda* e
368
+ *code_esercizio* identificano l'azienda e l'esercizio per cui eseguire la stampa, mentre *target* è una delle costanti ``PRINT_TARGET_*`` definite sopra, che
369
+ specificano la destinazione della stampa (se non specificata e la funzione è eseguita all'interno di Konga, verrà assunta ``PRINT_TARGET_PREVIEW``,
370
+ altrimenti ``PRINT_TARGET_PDF``); *filename* è il nome del file da salvare ed ha un senso solo quando si stampa su file. Se *progress* è ``True`` verrà mostrata
371
+ a video una barra di progresso dell'operazione di stampa.
372
+ La funzione restituisce un oggetto di classe :class:`kongalib.Log` con il resoconto dell'operazione di stampa, oppure lancia un'eccezione di classe
373
+ :class:`kongautil.PrintError` in caso di errori.
374
+
375
+ .. warning::
376
+ Se eseguita fuori da Konga, questa funzione richiede che sull'host sia stato installato Konga Client (o Konga), e non supporta come *target* i valori
377
+ ``PRINT_TARGET_PREVIEW`` e ``PRINT_TARGET_PAPER``. Konga Client (o Konga) verrà invocato e provvederà a connettersi al client corrente e stampare il
378
+ documento richiesto; i parametri di connessione saranno ricavati automaticamente dal client ottenuto dall'ultima chiamata alla funzione :func:`kongautil.connect`
379
+ oppure, se specificato, dal parametro ``client``.
380
+ """
381
+ if _proxy.is_valid():
382
+ if target is None:
383
+ target = PRINT_TARGET_PREVIEW
384
+ log = _proxy.util.print_layout(command_or_layout, builtins or {}, code_azienda, code_esercizio, target, filename, progress)
385
+ else:
386
+ log = kongalib.Log()
387
+ if not filename:
388
+ raise ValueError("Output filename must be specified")
389
+ if isinstance(command_or_layout, str) and (command_or_layout.strip().startswith('<?xml') or command_or_layout.strip().startswith('<layout')):
390
+ import tempfile
391
+ temp = tempfile.NamedTemporaryFile(mode='w', delete=False)
392
+ with temp:
393
+ temp.write(command_or_layout)
394
+ command_or_layout = temp.name
395
+ else:
396
+ temp = None
397
+ target = {
398
+ PRINT_TARGET_PDF: 'pdf',
399
+ PRINT_TARGET_CSV: 'csv',
400
+ PRINT_TARGET_XLS: 'xls',
401
+ }.get(target, 'pdf')
402
+ builtins = builtins or {}
403
+ if code_azienda:
404
+ builtins['COMPANY_CODE'] = code_azienda
405
+ if code_esercizio:
406
+ builtins['ACCOUNTING_YEAR_CODE'] = code_esercizio
407
+ script = [
408
+ '.print "%s" %s -o %s -f "%s"' % (command_or_layout, ' '.join([ '%s=%s' % (key, quote(str(value))) for key, value in builtins.items() ]), target, filename)
409
+ ]
410
+ try:
411
+ _run_script(script, log, client)
412
+ finally:
413
+ if temp is not None:
414
+ os.unlink(temp)
415
+ if log.has_errors():
416
+ raise PrintError(log)
417
+ return log
418
+
419
+
420
+
421
+ def print_log(log, title, target=PRINT_TARGET_PREVIEW, filename=None):
422
+ """Stampa il contenuto dell'oggetto *log* di classe :class:`kongalib.Log`; se si esegue questa funzione dall'interno di Konga, verrà usata la funzione
423
+ :func:`print_layout`, passando i parametri *target* e *filename*; viceversa se si esegue fuori da Konga, il log verrà stampato su terminale."""
424
+ if _proxy.is_valid():
425
+ template = """<?xml version='1.0' encoding='utf-8'?>
426
+ <layout version="3" name="%(title)s" title="%(title)s" orientation="vertical" margin_top="75" margin_right="75" margin_bottom="75" margin_left="75">
427
+ <init>
428
+ <![CDATA[set_datasource(Datasource(['id', 'type', 'message'], DATA, 'Master'))
429
+ ]]></init>
430
+ <header width="100%%" height="175" only_first="true">
431
+ <label width="100%%" height="100" align="center" font_size="14" bgcolor="#EEE" border_edges="left|right|top|bottom">%(title)s</label>
432
+ </header>
433
+
434
+ <module width="100%%" alt_bgcolor="#EEE" condition="iterate('id')">
435
+ <field top="0" width="10%%" align="top" type="data">type</field>
436
+ <field left="10%%" top="0" width="90%%" align="top" wrapping="wrap" type="data">message</field>
437
+ </module>
438
+ <module width="100%%">
439
+ <init>
440
+ <![CDATA[this.visible = (len(DATA) == 0)
441
+ ]]></init>
442
+ <label width="100%%" align="center">
443
+ <text>
444
+ <it>Operazione completata con successo</it>
445
+ </text>
446
+ </label>
447
+ </module>
448
+
449
+ <footer width="100%%" font_size="7" height="175">
450
+ <rect top="75" width="100%%" height="100" />
451
+ <field padding_left="50" top="75" left="0" width="30%%" height="50" align="bottom" type="expr">DATABASE_NAME</field>
452
+ <field padding_left="50" top="125" left="0" width="30%%" height="50" align="top" type="expr">COMPANY_NAME</field>
453
+ <field top="75" left="30%%" width="40%%" height="50" align="hcenter|bottom" type="expr">TITLE</field>
454
+ <datetime top="125" left="30%%" width="40%%" height="50" align="hcenter|top" format="PdmyHM">
455
+ <text>
456
+ <it>Stampato da $USER_NAME il %%d alle %%t</it>
457
+ <nl>Afgedrukt door $USER_NAME op %%d om %%t uur</nl>
458
+ </text>
459
+ </datetime>
460
+ <page padding_right="50" top="75" left="80%%" width="20%%" height="100" align="vcenter|right">
461
+ <text>
462
+ <it>Pagina %%p di %%t</it>
463
+ <nl>Pagina %%p van %%t</nl>
464
+ </text>
465
+ </page>
466
+ </footer>
467
+ </layout>
468
+ """ % {
469
+ 'title': title,
470
+ }
471
+ data = []
472
+ for index, message in enumerate(log.get_messages()):
473
+ msg = log.strip_html(message[1])
474
+ if isinstance(msg, bytes):
475
+ msg = msg.decode('utf-8', 'replace')
476
+ data.append((index, ('INFO', 'WARNING', 'ERROR')[message[0]], msg))
477
+
478
+ print_layout(template, { 'DATA': data }, target=target, filename=filename)
479
+ else:
480
+ import colorama
481
+ print(colorama.Style.BRIGHT + title + colorama.Style.RESET_ALL)
482
+ status = {
483
+ kongalib.Log.INFO: colorama.Style.BRIGHT + "INFO " + colorama.Style.RESET_ALL,
484
+ kongalib.Log.WARNING: colorama.Style.BRIGHT + colorama.Fore.YELLOW + "WARNING " + colorama.Style.RESET_ALL,
485
+ kongalib.Log.ERROR: colorama.Style.BRIGHT + colorama.Fore.RED + "ERROR " + colorama.Style.RESET_ALL,
486
+ }
487
+ for message in log.get_messages():
488
+ print('%s%s' % (status[message[0]], message[1]))
489
+
490
+
491
+
492
+ def show_log(log, title, size=None, iconsize=32):
493
+ """Visualizza il contenuto dell'oggetto *log* di classe :class:`kongalib.Log`; se si esegue questa funzione dall'interno di Konga, il log verrà
494
+ visualizzato in una finestra dedicata; viceversa se si esegue fuori da Konga, il comportamento di questa funzione equivale a chiamare
495
+ :func:`print_log` con gli stessi argomenti. La finestra del log mostrerà *title* come messaggio informativo e se specificato avrà dimensione *size*;
496
+ è possibile specificare anche la dimensione delle icone dei singoli messaggi tramite il parametro *iconsize*."""
497
+ if _proxy.is_valid():
498
+ log = _proxy.util.show_log(log.get_messages(), title, size, iconsize)
499
+ else:
500
+ print_log(log, title)
501
+
502
+
503
+
504
+ def suspend_timeout():
505
+ """Sospende il timeout di esecuzione dello script. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
506
+ if _proxy.is_valid():
507
+ return _proxy.builtin.set_timeout(restore=False)
508
+
509
+
510
+
511
+ def resume_timeout(timeout):
512
+ """Ripristina il timeout di esecuzione dello script. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
513
+ if _proxy.is_valid():
514
+ _proxy.builtin.set_timeout(timeout, restore=False)
515
+
516
+
517
+
518
+ def set_timeout(timeout):
519
+ """Imposta il timeout di esecuzione dello script in secondi, passati i quali verrà mostrata una finestra di avviso. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
520
+ if _proxy.is_valid():
521
+ _proxy.builtin.set_timeout(timeout * 1000, restore=False)
522
+
523
+
524
+
525
+ def get_external_images_path(table_name, code_azienda):
526
+ raise RuntimeError('Images storage is managed by the server since Konga 1.9; please use kongalib.Client.fetch_binary() and kongalib.Client.store_binary() to load/save images')
527
+
528
+
529
+
530
+ def get_external_attachments_path(table_name, code_azienda):
531
+ raise RuntimeError('Attachments storage is managed by the server since Konga 1.9; please use kongalib.Client.fetch_binary() and kongalib.Client.store_binary() to load/save attachments')
532
+
533
+
534
+
535
+ def get_site_packages():
536
+ """Restituisce una lista di percorsi di installazione dei pacchetti Python."""
537
+ if _proxy.is_valid():
538
+ return [ _proxy.util.get_site_packages() ]
539
+ else:
540
+ import site
541
+ return site.getsitepackages()
542
+
543
+
544
+
545
+ def notify_data_changes(table_name, row_id=None):
546
+ """Notifica Konga che uno o tutti i record di una tabella sono stati modificati, causando un aggiornamento a tutti quei client Konga che stanno operando su tali record. Se *row_id* è ``None``, tutti
547
+ i record della tabella *table_name* verranno marcati come modificati, altrimenti il solo record con *ID* *row_id*. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
548
+ if _proxy.is_valid():
549
+ _proxy.util.notify_data_changes(table_name, row_id)
550
+
551
+
552
+
553
+ def open_uri(uri):
554
+ """Tenta di aprire l'URI specificato con l'applicazione predefinita di sistema (se configurata)."""
555
+ import subprocess
556
+ if sys.platform == 'darwin':
557
+ subprocess.call(('open', uri))
558
+ elif sys.platform == 'win32':
559
+ os.startfile(uri)
560
+ else:
561
+ subprocess.call(('xdg-open', uri))
562
+
563
+
564
+
565
+ def get_context():
566
+ """Restituisce un oggetto di classe :class:`kongautil.ScriptContext` da usare per la gestione dell'I/O da parte degli script usati come azioni esterne di Konga.
567
+
568
+ .. warning::
569
+ Questa funzione è disponibile solo all'interno di Konga; eseguendola da fuori verrà lanciata l'eccezione :class:`kongautil.KongaRequiredError`.
570
+ """
571
+ if _proxy.is_valid():
572
+ return _proxy.util.get_context()
573
+ else:
574
+ raise KongaRequiredError
575
+
576
+
577
+
578
+ def is_batch():
579
+ """Restituisce ``True`` se lo script è eseguito con Python da linea di comando, ``False`` se è eseguito dall'interno di Konga."""
580
+ return not _proxy.is_valid()
581
+