kongalib 1.12.0__cp311-cp311-win_amd64.whl → 2.0.0.post1__cp311-cp311-win_amd64.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.

@@ -15,7 +15,6 @@
15
15
 
16
16
  from kongalib import Error, ErrorList
17
17
  from .constants import *
18
- from .compat import *
19
18
 
20
19
 
21
20
  TYPE_TINYINT = 1 #: Tipo di campo SQL TINYINT; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``int``.
@@ -24,16 +23,7 @@ TYPE_INT = 3 #: Tipo di campo SQL INT; i valori ottenuti dalla :meth:`~ko
24
23
  TYPE_BIGINT = 4 #: Tipo di campo SQL BIGINT; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``int``.
25
24
  TYPE_FLOAT = 5 #: Tipo di campo SQL FLOAT; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``float``.
26
25
  TYPE_DOUBLE = 6 #: Tipo di campo SQL DOUBLE; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``float``.
27
- TYPE_DECIMAL = 7
28
- """Tipo di campo SQL DECIMAL; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo :class:`kongalib.Decimal`.
29
-
30
- .. warning:: Konga Server traduce automaticamente questo tipo di dato in BIGINT sul database SQL, e salva i valori decimali come se
31
- fossero interi moltiplicati per 1000000. Questo consente una precisione fino a 6 cifre decimali, e permette a Konga Server di operare anche
32
- con driver SQL che non supportano nativamente il tipo dato DECIMAL (come SQLite). La traduzione è completamente trasparente per kongalib, in
33
- quanto i metodi della classe :class:`kongalib.Client` ricevono e restituiscono oggetti di clase :class:`kongalib.Decimal` per gestire
34
- i decimali.
35
- """
36
-
26
+ TYPE_DECIMAL = 7 #: Tipo di campo SQL DECIMAL; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo :class:`kongalib.Decimal`.
37
27
  TYPE_DATE = 8 #: Tipo di campo SQL DATE; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``datetime.date``.
38
28
  TYPE_TIME = 9 #: Tipo di campo SQL TIME; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``datetime.time``.
39
29
  TYPE_TIMESTAMP = 10 #: Tipo di campo SQL TIMESTAMP; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``datetime.datetime``.
@@ -46,6 +36,7 @@ TYPE_LONGTEXT = 16 #: Tipo di campo SQL LONGTEXT; i valori ottenuti dalla :
46
36
  TYPE_TINYBLOB = 17 #: Tipo di campo SQL TINYBLOB; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``bytes``.
47
37
  TYPE_BLOB = 18 #: Tipo di campo SQL BLOB; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``bytes``.
48
38
  TYPE_LONGBLOB = 19 #: Tipo di campo SQL LONGBLOB; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``bytes``.
39
+ TYPE_JSON = 20 #: Tipo di campo SQL JSON; i valori ottenuti dalla :meth:`~kongalib.Client.select_data` saranno di tipo ``unicode``.
49
40
 
50
41
 
51
42
  TABLE_HAS_IMAGES = 0x1 #: Flag informativo di tabella del data dictionary. Se specificato, i record della tabella possono avere immagini collegate.
@@ -89,7 +80,7 @@ class DataDictionary(object):
89
80
 
90
81
  def get_label(self, key):
91
82
  """Ottiene la descrizione della chiave *key* sotto forma di ``dict`` con le traduzioni corrispondenti a ciascuna lingua."""
92
- if isinstance(key, text_base_types):
83
+ if isinstance(key, str):
93
84
  return self.__data[key][1]
94
85
  for value, label in self.__data.values():
95
86
  if value == key:
kongalib/db.py CHANGED
@@ -18,7 +18,6 @@ import datetime
18
18
 
19
19
  from kongalib import Client, Decimal, Error as _Error, ErrorList
20
20
  from .constants import *
21
- from .compat import *
22
21
 
23
22
 
24
23
  apilevel = "2.0" #: Versione delle API, come da specifica
@@ -142,11 +141,11 @@ class Cursor(object):
142
141
  self.__description = []
143
142
  row = self.__result[0]
144
143
  for field, data in zip(fields, row):
145
- if isinstance(data, int_types) or isinstance(data, (float, Decimal)):
144
+ if isinstance(data, (int, float, Decimal)):
146
145
  t = NUMBER
147
146
  elif isinstance(data, (datetime.date, datetime.datetime)):
148
147
  t = DATETIME
149
- elif isinstance(data, text_type):
148
+ elif isinstance(data, str):
150
149
  t = STRING
151
150
  else:
152
151
  t = BINARY
@@ -251,14 +250,14 @@ def TimeFromTicks(ticks):
251
250
  def TimestampFromTicks(ticks):
252
251
  return Timestamp(*time.localtime(ticks)[:6])
253
252
 
254
- def connect(host, port=0, driver=None, database=None, user=None, password=None):
255
- """Esegue una connessione al server Konga identificato da *host* e *port*, apre *database* usando il *driver* specificato,
256
- ed infine si autentica usando *user* e *password*. Restituisce un oggetto :class:`Connection`; da questo è possibile ottenere un oggetto
257
- :class:`Cursor` che permette di eseguire query SQL sul database aperto sulla connessione.
253
+ def connect(host, port=0, driver=None, database=None, user=None, password=None, tenant_key=None):
254
+ """Esegue una connessione al server Konga identificato da *host* e *port*, usando l'eventuale chiave tenant *tenant_key*, apre *database*
255
+ usando il *driver* specificato, ed infine si autentica usando *user* e *password*. Restituisce un oggetto :class:`Connection`; da questo
256
+ è possibile ottenere un oggetto :class:`Cursor` che permette di eseguire query SQL sul database aperto sulla connessione.
258
257
  """
259
258
  conn = Connection()
260
259
  try:
261
- conn.connect({ 'host': host, 'port': port })
260
+ conn.connect({ 'host': host, 'port': port }, options={ 'tenant_key': tenant_key })
262
261
  conn.open_database(driver, database)
263
262
  conn.authenticate(user, password)
264
263
  except _Error as e:
kongalib/expression.py CHANGED
@@ -20,8 +20,9 @@ import re
20
20
  import io
21
21
  import tempfile
22
22
  import collections
23
+ from xml.etree import ElementTree as ET
23
24
 
24
- from .compat import *
25
+ from kongalib import ensure_text
25
26
 
26
27
 
27
28
 
@@ -202,6 +203,10 @@ def parse(sql):
202
203
  def p_expression_binop(p):
203
204
  'expression : ID OPERAND VALUE'
204
205
  p[0] = Operand(p[1], p[2], p[3])
206
+
207
+ def p_expression_valueop(p):
208
+ 'expression : VALUE OPERAND VALUE'
209
+ p[0] = Operand(p[1], p[2], p[3], _HasLogic.LOGIC_NONE, _HasLogic.FLAG_NO_ESCAPE)
205
210
 
206
211
  def p_expression_func_fieldop(p):
207
212
  'expression : function OPERAND ID'
@@ -366,7 +371,7 @@ class Operand(_HasLogic):
366
371
  def __hash__(self):
367
372
  return hash(str(self))
368
373
 
369
- def __unicode__(self):
374
+ def __str__(self):
370
375
  if self.value is None:
371
376
  value = 'NULL'
372
377
  elif re.match(r'^(\-)?[0-9]+$', self.value):
@@ -381,12 +386,6 @@ class Operand(_HasLogic):
381
386
  value = "'%s'" % self.value.replace("'", "''")
382
387
  return (u'%s %s %s' % (ensure_text(self.column), ensure_text(self.operator), ensure_text(value)))
383
388
 
384
- def __str__(self):
385
- if PY3:
386
- return self.__unicode__()
387
- else:
388
- return self.__unicode__().encode('utf-8')
389
-
390
389
  def __repr__(self):
391
390
  return str(self)
392
391
 
@@ -519,7 +518,7 @@ class OperandIsNotNull(Operand):
519
518
 
520
519
  class OperandIN(OperandNE):
521
520
  def __init__(self, column, value):
522
- if not isinstance(value, text_base_types):
521
+ if not isinstance(value, str):
523
522
  value = u"('%s')" % (u"', '".join([ ensure_text(x).replace("'", "''") for x in value]))
524
523
  Operand.__init__(self, column, 'IN', value, _HasLogic.LOGIC_NONE, _HasLogic.FLAG_NO_ESCAPE)
525
524
 
@@ -527,7 +526,7 @@ class OperandIN(OperandNE):
527
526
 
528
527
  class OperandNotIN(OperandNE):
529
528
  def __init__(self, column, value):
530
- if not isinstance(value, text_base_types):
529
+ if not isinstance(value, str):
531
530
  value = u"('%s')" % (u"', '".join([ ensure_text(x).replace("'", "''") for x in value]))
532
531
  Operand.__init__(self, column, 'NOT IN', value, _HasLogic.LOGIC_NONE, _HasLogic.FLAG_NO_ESCAPE)
533
532
 
@@ -594,6 +593,7 @@ class Expression(_HasLogic):
594
593
  e.logic_op = self.logic_op
595
594
  for child in self.children:
596
595
  e.children.append(child.copy())
596
+ child.parent = e
597
597
  return e
598
598
 
599
599
  def append(self, operand, logic_op):
@@ -623,8 +623,8 @@ class Expression(_HasLogic):
623
623
  if self.children[index + 1].logic_op & _HasLogic.LOGIC_NOT:
624
624
  op += ' NOT'
625
625
  else:
626
- if (len(self.children) == 1) and (self.children[-1].logic_op & _HasLogic.LOGIC_NOT):
627
- l[-1].append(True)
626
+ # if (len(self.children) == 1) and (self.children[-1].logic_op & _HasLogic.LOGIC_NOT):
627
+ # l[-1].append(True)
628
628
  op = None
629
629
  l.append(op)
630
630
  return l
@@ -645,7 +645,7 @@ class Expression(_HasLogic):
645
645
  def __hash__(self):
646
646
  return hash(str(self))
647
647
 
648
- def __unicode__(self):
648
+ def __str__(self):
649
649
  s = u''
650
650
  for child in self.children:
651
651
  if child.logic_op & _HasLogic.LOGIC_NOT:
@@ -657,12 +657,6 @@ class Expression(_HasLogic):
657
657
  elif child.logic_op & _HasLogic.LOGIC_OR:
658
658
  s += ' OR '
659
659
  return ensure_text(s)
660
-
661
- def __str__(self):
662
- if PY3:
663
- return self.__unicode__()
664
- else:
665
- return self.__unicode__().encode('utf-8')
666
660
 
667
661
  def __repr__(self):
668
662
  return str(self)
@@ -789,7 +783,7 @@ def NOT(arg):
789
783
  def where(expr):
790
784
  if expr is None:
791
785
  return []
792
- elif isinstance(expr, text_base_types):
786
+ elif isinstance(expr, str):
793
787
  return where(parse(expr))
794
788
  elif isinstance(expr, Operand):
795
789
  return [ expr.as_list(), None ]
@@ -804,10 +798,10 @@ def loads(xml):
804
798
  if not xml:
805
799
  return None
806
800
  document = ET.ElementTree()
807
- if isinstance(xml, text_base_types):
801
+ if isinstance(xml, str):
808
802
  xml = ensure_text(xml).encode('utf-8')
809
- if isinstance(xml, data_base_types):
810
- xml = io.BytesIO(bytes(xml))
803
+ if isinstance(xml, bytes):
804
+ xml = io.BytesIO(xml)
811
805
  if not ET.iselement(xml):
812
806
  xml = document.parse(xml, ET.XMLTreeBuilder(parse_comments=False))
813
807
  if xml.tag == 'operand':
kongalib/json.py CHANGED
@@ -16,7 +16,6 @@
16
16
  from __future__ import print_function
17
17
 
18
18
  from kongalib import JSONEncoder, JSONDecoder, Decimal
19
- from .compat import *
20
19
 
21
20
 
22
21
 
@@ -64,7 +63,7 @@ class Decoder(JSONDecoder):
64
63
  self.stack = [ [None, None] ]
65
64
  self.top = None
66
65
 
67
- if isinstance(text, text_base_types) or isinstance(text, data_base_types):
66
+ if isinstance(text, (str, bytes)):
68
67
  self.parse(text)
69
68
  else:
70
69
  while True:
kongalib/scripting.py CHANGED
@@ -16,8 +16,8 @@
16
16
  from __future__ import print_function
17
17
  from __future__ import absolute_import
18
18
 
19
- from kongalib import Error, PY3
20
- from ._kongalib import get_application_log_path, set_interpreter_timeout, get_interpreter_timeout, get_interpreter_time_left, _set_process_foreground
19
+ from kongalib import Error
20
+ from _kongalib import get_application_log_path, set_interpreter_timeout, get_interpreter_timeout, get_interpreter_time_left, _set_process_foreground
21
21
 
22
22
  import sys
23
23
  import os
@@ -148,7 +148,7 @@ def timeout_handler():
148
148
 
149
149
 
150
150
 
151
- def init_interpreter(init_logging=True):
151
+ def init_interpreter():
152
152
  _State.io.append((sys.stdout, sys.stderr, sys.stdin))
153
153
  try:
154
154
  proxy._initialize()
@@ -176,10 +176,7 @@ def init_interpreter(init_logging=True):
176
176
  return True
177
177
  tb = list(filter(do_filter, tb))
178
178
  try:
179
- if PY3:
180
- proxy.builtin.print_exception(type, value, tb)
181
- else:
182
- proxy.builtin.print_exception(type.__name__, str(value), tb)
179
+ proxy.builtin.print_exception(type, value, tb)
183
180
  except:
184
181
  debug_log('proxy.builtin.print_exception exception:\n%s' % traceback.format_exc())
185
182
  sys.excepthook = excepthook
@@ -226,7 +223,8 @@ class _Controller(threading.Thread):
226
223
  name = None
227
224
  while name != 'exit':
228
225
  try:
229
- if not self.conn.poll(0.5):
226
+ ready = multiprocessing.connection.wait([ self.conn ], 0.5)
227
+ if not ready:
230
228
  if self.request == _Controller.QUIT_REQUEST:
231
229
  break
232
230
  continue
@@ -281,16 +279,15 @@ class _Controller(threading.Thread):
281
279
 
282
280
 
283
281
 
284
- def _trampoline(conn, sem, foreground, dll_paths, queue):
282
+ def _trampoline(conn, sem, foreground, env, dll_paths, queue, level):
283
+ logging.getLogger().setLevel(level)
285
284
  logger = logging.getLogger('script._trampoline')
286
285
  handler = logging.handlers.QueueHandler(queue)
287
- handler.setLevel(logging.DEBUG)
286
+ handler.setLevel(level)
288
287
  logger.addHandler(handler)
289
- logger.setLevel(logging.DEBUG)
290
288
  logger.debug('entering interpreter process')
291
289
  try:
292
- if foreground:
293
- _set_process_foreground()
290
+ _set_process_foreground(foreground)
294
291
  for path in dll_paths:
295
292
  try:
296
293
  os.add_dll_directory(path)
@@ -298,6 +295,11 @@ def _trampoline(conn, sem, foreground, dll_paths, queue):
298
295
  except:
299
296
  if sys.platform == 'win32':
300
297
  logger.error('error adding DLL directory: %s' % path)
298
+ for key, value in (env or {}).items():
299
+ key = str(key)
300
+ value = str(value)
301
+ os.environ[key] = value
302
+ logger.debug('added env variable %s=%s' % (key, value))
301
303
 
302
304
  _State.controller = _Controller(conn, sem)
303
305
  _State.controller.start()
@@ -309,8 +311,6 @@ def _trampoline(conn, sem, foreground, dll_paths, queue):
309
311
  args, path, timeout, script, cwd = request
310
312
  sys.argv = args
311
313
  sys.path = path
312
- if (not PY3) and isinstance(script, unicode):
313
- script = script.encode('utf-8', 'replace')
314
314
  filename = args[0]
315
315
  if cwd:
316
316
  os.chdir(cwd)
@@ -337,6 +337,8 @@ def _trampoline(conn, sem, foreground, dll_paths, queue):
337
337
  except:
338
338
  pass
339
339
  _State.controller.join()
340
+ except KeyboardInterrupt:
341
+ logger.debug('user issued a keyboard interrupt')
340
342
  except Exception as e:
341
343
  import traceback
342
344
  logger.critical('unhandled error in interpreter process: %s' % traceback.format_exc())
@@ -361,7 +363,7 @@ class _ControllerProxy(Proxy):
361
363
 
362
364
 
363
365
  class Interpreter(object):
364
- def __init__(self, foreground=True):
366
+ def __init__(self, foreground=True, env=None):
365
367
  self.proc = None
366
368
  self.exc_info = None
367
369
  self.conn = None
@@ -370,7 +372,8 @@ class Interpreter(object):
370
372
  self.queue = multiprocessing.Queue()
371
373
  self.proxy = None
372
374
  self.foreground = foreground
373
- self.logger_listener = logging.handlers.QueueListener(self.queue, *logging.getLogger().handlers)
375
+ self.env = env
376
+ self.logger_listener = logging.handlers.QueueListener(self.queue, *logging.getLogger().handlers, respect_handler_level=True)
374
377
 
375
378
  def __del__(self):
376
379
  with self.lock:
@@ -391,7 +394,7 @@ class Interpreter(object):
391
394
  self.conn, self.client_conn = multiprocessing.Pipe()
392
395
  self.proxy = _ControllerProxy(self.conn).controller
393
396
  self.logger_listener.start()
394
- self.proc = multiprocessing.Process(target=_trampoline, args=(self.client_conn, self.sem, self.foreground, _DLL_PATHS, self.queue), daemon=True)
397
+ self.proc = multiprocessing.Process(target=_trampoline, args=(self.client_conn, self.sem, self.foreground, self.env, _DLL_PATHS, self.queue, logging.getLogger().level), daemon=True)
395
398
  self.proc.start()
396
399
  exitcode = self.proc.exitcode
397
400
  if exitcode is not None:
@@ -431,7 +434,10 @@ class Interpreter(object):
431
434
  self.proc = None
432
435
  self.lock.release()
433
436
  try:
434
- proc.terminate()
437
+ try:
438
+ proc.terminate()
439
+ except:
440
+ pass
435
441
  proc.join(3)
436
442
  if proc.is_alive():
437
443
  try:
@@ -442,13 +448,18 @@ class Interpreter(object):
442
448
  self.lock.acquire()
443
449
 
444
450
  def is_running(self):
445
- with self.lock:
446
- return (self.conn is None) or ((self.proc is not None) and self.proc.is_alive())
451
+ conn = self.conn
452
+ proc = self.proc
453
+ return (conn is None) or ((proc is not None) and proc.is_alive())
447
454
 
448
455
  def set_timeout(self, timeout=None, restore=False):
449
456
  with self.lock:
450
457
  if self.proxy is not None:
451
- return self.proxy.set_timeout(timeout, restore)
458
+ func = self.proxy.set_timeout
459
+ else:
460
+ func = None
461
+ if func is not None:
462
+ return func(timeout, restore)
452
463
 
453
464
  def get_time_left(self):
454
465
  with self.lock:
@@ -518,6 +529,7 @@ class _Method(object):
518
529
  if DEBUG:
519
530
  debug_log('[Proxy] call sent in %f secs. Waiting reply: %s' % (time.time() - s, str((self.handler._name, self.name))))
520
531
 
532
+ multiprocessing.connection.wait([ self.handler._conn ])
521
533
  e, result = self.handler._conn.recv()
522
534
  if DEBUG:
523
535
  s = time.time()
@@ -565,7 +577,8 @@ class _ServerProxy(threading.Thread):
565
577
  self.conn = self.listener.accept()
566
578
  debug_log("[ServerProxy] got proxy")
567
579
  while True:
568
- if self.conn.poll(0.1):
580
+ ready = multiprocessing.connection.wait([ self.conn ], 0.5)
581
+ if ready:
569
582
  data = self.conn.recv()
570
583
  handler, name, args, kwargs = data
571
584
  if handler in self.handlers:
@@ -726,6 +739,7 @@ def execute(script=None, filename=None, argv=None, path=None, timeout=0, handler
726
739
  else:
727
740
  debug_log("[ServerProxy] unhandled execute exception: %s" % traceback.format_exc())
728
741
  type, value, tb = sys.exc_info()
742
+ tb = traceback.format_tb(tb)
729
743
  def do_filter(entry):
730
744
  filename = entry[0].replace('\\', '/')
731
745
  if filename.endswith('kongalib/scripting.py') or filename.endswith('__script_host__.py'):
@@ -733,10 +747,7 @@ def execute(script=None, filename=None, argv=None, path=None, timeout=0, handler
733
747
  return True
734
748
  tb = list(filter(do_filter, tb))
735
749
  try:
736
- if PY3:
737
- _handlers['builtin'].print_exception(type, value, tb)
738
- else:
739
- _handlers['builtin'].print_exception(type.__name__, str(value), tb)
750
+ _handlers['builtin'].print_exception(type, value, tb)
740
751
  except:
741
752
  debug_log('proxy.builtin.print_exception exception:\n%s' % traceback.format_exc())
742
753
  finally:
@@ -1,36 +1,42 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: kongalib
3
- Version: 1.12.0
3
+ Version: 2.0.0.post1
4
4
  Summary: Konga client library
5
- Home-page: https://github.com/easybyte-software/kongalib
6
- Author: EasyByte Software
7
- Author-email: konga@easybyte.it
5
+ Author-email: EasyByte Software <konga@easybyte.it>
8
6
  License: LGPL
7
+ Project-URL: homepage, https://github.com/easybyte-software/kongalib
8
+ Project-URL: documentation, https://public.easybyte.it/docs/current/technical/kongalib/index.html
9
+ Project-URL: repository, https://github.com/easybyte-software/kongalib.git
9
10
  Keywords: konga,client,erp
10
11
  Classifier: Natural Language :: Italian
11
12
  Classifier: Programming Language :: Python
12
- Classifier: Programming Language :: Python :: 2
13
- Classifier: Programming Language :: Python :: 2.7
14
13
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.6
16
- Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3 :: Only
17
15
  Classifier: Programming Language :: Python :: 3.8
18
16
  Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
19
22
  Classifier: Programming Language :: C++
20
23
  Classifier: Development Status :: 5 - Production/Stable
21
24
  Classifier: Environment :: Console
22
25
  Classifier: Intended Audience :: Developers
23
26
  Classifier: Intended Audience :: Information Technology
24
27
  Classifier: Intended Audience :: Financial and Insurance Industry
25
- Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
26
28
  Classifier: Operating System :: MacOS :: MacOS X
27
29
  Classifier: Operating System :: Microsoft :: Windows
28
30
  Classifier: Operating System :: POSIX :: Linux
29
31
  Classifier: Topic :: Office/Business
30
32
  Classifier: Topic :: Office/Business :: Financial
31
33
  Classifier: Topic :: Software Development :: Libraries
34
+ Requires-Python: >=3.8
35
+ Description-Content-Type: text/x-rst
32
36
  License-File: LICENSE
33
37
  Requires-Dist: colorama
38
+ Requires-Dist: nest_asyncio
39
+ Dynamic: license-file
34
40
 
35
41
  Kongalib
36
42
  ========
@@ -44,9 +50,9 @@ Kongalib
44
50
  .. image:: https://img.shields.io/badge/License-LGPLv3-blue.svg
45
51
  :alt: LGPL v3 License
46
52
  :target: https://www.gnu.org/licenses/lgpl-3.0.en.html
47
- .. image:: https://dev.azure.com/easybyte-software/kongalib/_apis/build/status/easybyte-software.kongalib?branchName=master
53
+ .. image:: https://github.com/easybyte-software/kongalib/actions/workflows/build_wheels.yml/badge.svg?event=workflow_dispatch
48
54
  :alt: Build Status
49
- :target: https://dev.azure.com/easybyte-software/kongalib
55
+ :target: https://github.com/easybyte-software/kongalib/actions/workflows/build_wheels.yml
50
56
 
51
57
  Libreria Python di comunicazione con i server `EasyByte Konga`_. Tramite
52
58
  *kongalib* è possibile connettersi ad un server Konga (integrato in Konga Pro o
@@ -73,16 +79,16 @@ Se si desidera è possibile compilare i sorgenti. I prerequisiti per compilare
73
79
 
74
80
  **Windows**
75
81
 
76
- Sono supportate le versioni di Windows dalla 7 in su. Come prerequisiti è
82
+ Sono supportate le versioni di Windows dalla 10 in su. Come prerequisiti è
77
83
  necessario installare:
78
84
 
79
- - Microsoft Visual Studio 2017
85
+ - Microsoft Visual Studio 2017 o successiva
80
86
  - `SDK di Konga`_
81
87
 
82
88
 
83
89
  **MacOS X**
84
90
 
85
- Sono supportate le versioni di macOS dalla 10.8 in su. Come prerequisiti è
91
+ Sono supportate le versioni di macOS dalla 10.9 in su. Come prerequisiti è
86
92
  necessario installare:
87
93
 
88
94
  - XCode (assicurarsi di aver installato anche i tool da linea di comando)
@@ -92,9 +98,9 @@ necessario installare:
92
98
  **Linux**
93
99
 
94
100
  Benchè il pacchetto binario wheel per Linux supporti tutte le distribuzioni
95
- Linux moderne (specifica `manylinux`), al momento la compilazione da parte di
101
+ Linux moderne (specifica `manylinux_2_28`_), al momento la compilazione da parte di
96
102
  terzi è supportata ufficialmente solo se si usa una distribuzione Linux basata su
97
- Debian, in particolare Ubuntu Linux dalla versione 16.04 in su. Sono necessari i
103
+ Debian, in particolare Ubuntu Linux dalla versione 20.04 in su. Sono necessari i
98
104
  seguenti pacchetti *deb*:
99
105
 
100
106
  - build-essential
@@ -102,18 +108,15 @@ seguenti pacchetti *deb*:
102
108
  - python-dev
103
109
  - `easybyte-konga-dev`_
104
110
 
105
- La compilazione è possibile tramite la usuale procedura dei pacchetti Python::
111
+ La compilazione come da standard Python è possibile sempre tramite *pip*, eseguendo
112
+ dalla directory dei sorgenti::
106
113
 
107
- python setup.py install
114
+ pip install .
108
115
 
109
116
 
110
117
  .. note:: Sotto piattaforma Windows per la corretta compilazione è necessario
111
- impostare la variabile d'ambiente `KONGASDK` alla directory d'installazione
112
- dell'`SDK di Konga`_. Notare inoltre che l'SDK di Konga è compilato con
113
- Visual Studio 2017 e non è compatibile con Python 2.x (che sotto Windows
114
- richiede Visual Studio 2008); se si desidera usare *kongalib* con Python 2.x
115
- sotto Windows, è necessario usare la *wheel* precompilata installabile
116
- tramite *pip*.
118
+ impostare la variabile d'ambiente `KONGASDK` alla directory d'installazione
119
+ dell'`SDK di Konga`_.
117
120
 
118
121
 
119
122
  Risorse
@@ -143,5 +146,5 @@ Risorse
143
146
  .. _Script di utilità comune per Konga: https://github.com/easybyte-software/konga_scripts
144
147
  .. _SDK di Konga: http://public.easybyte.it/downloads/current
145
148
  .. _easybyte-konga-dev: http://public.easybyte.it/downloads/current
146
- .. _manylinux: https://github.com/pypa/manylinux
149
+ .. _manylinux_2_28: https://github.com/pypa/manylinux
147
150
 
@@ -0,0 +1,21 @@
1
+ _kongalib.cp311-win_amd64.pdb,sha256=jRszejY8QBuoOqG4U2Wfxawq23LhUYS4o7khh-DWsQE,7344128
2
+ _kongalib.cp311-win_amd64.pyd,sha256=BP5_tjH6G1EwmoReYJjnzvxoMYau1gHZkwArtB2x-Qo,2533888
3
+ kongaui.py,sha256=0sSKUsOo5vLNH3wyUUl4icOL4z4CXqoPAR2fqYQZE7o,20598
4
+ kongautil.py,sha256=PSObmHX6kVf54mtIyBXtxzf4CMHUsj_ppDNSWjY3Y2c,24005
5
+ kongalib/__init__.py,sha256=VPFvthIAm7K668_Fxx_4Wf6rwZCAs6dwBz6DfZtwrLU,12979
6
+ kongalib/async_client.py,sha256=XFzkYLr0KbaNvCN3piS-AdWigcFtJqFpcDCN0fUKeMA,48017
7
+ kongalib/client.py,sha256=8fz5L0mvRa5q0G06gK1MEN0_PYapIgkMK_wd1_Yrexo,58834
8
+ kongalib/constants.py,sha256=r59fg2-CCTWRvKOusxXe9FTBrSAmFt5Esn70DsyEn8s,8793
9
+ kongalib/data_dictionary.py,sha256=a-_aTlZeJPGkxkxzG040A2yrfXf_Stup3CTurh_93B0,11298
10
+ kongalib/db.py,sha256=qnSon_7N5Po0-ww-88mL7DZlGX7_ASIM4tMY9bGGBnk,8354
11
+ kongalib/expression.py,sha256=A7-erKQPF4VroB3ERCTvLYyOv5_gm1a-rxToLNhd8VY,21230
12
+ kongalib/json.py,sha256=-8h3e92hLzsElxZhLgpcoQWfakSYyY0i7vsxB7Z7qtk,2341
13
+ kongalib/lex.py,sha256=tV9VGF97XHRFf0eBICVzTILzH878i_slXLsoktFnZTQ,41797
14
+ kongalib/scripting.py,sha256=153S5jtpLie_LztS6FH1QLs1-yrWVCdWM7hzY8FWp6g,20344
15
+ kongalib/yacc.py,sha256=UHnHKzBknH7qzIT7xJFIHYKBTzOIxWILtGPdSI29XcE,131768
16
+ kongalib-2.0.0.post1.dist-info/licenses/LICENSE,sha256=LPNKwDiu5awG-TPd0dqYJuC7k4PBPY4LCI_O0LSpW1s,7814
17
+ kongalib-2.0.0.post1.dist-info/METADATA,sha256=XUhKmSxS4lqMe0PuaQlZFt-qAjZenn0O7Jebn3iBsVE,5408
18
+ kongalib-2.0.0.post1.dist-info/WHEEL,sha256=JLOMsP7F5qtkAkINx5UnzbFguf8CqZeraV8o04b0I8I,101
19
+ kongalib-2.0.0.post1.dist-info/top_level.txt,sha256=htHdvBd1NQjLXNwXgTzCMPtyfCtorpw6jUZzu09vDYY,37
20
+ kongalib-2.0.0.post1.dist-info/zip-safe,sha256=frcCV1k9oG9oKj3dpUqdJg1PxRT2RSN_XKdLCPjaYaY,2
21
+ kongalib-2.0.0.post1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.40.0)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp311-cp311-win_amd64
5
5
 
@@ -1,3 +1,4 @@
1
+ _kongalib
1
2
  kongalib
2
3
  kongaui
3
4
  kongautil
kongaui.py CHANGED
@@ -28,14 +28,6 @@ import kongautil
28
28
  from kongalib.scripting import _TimeoutBlocker
29
29
  from kongalib.scripting import proxy as _proxy
30
30
 
31
- PY3 = (sys.version_info[0] >= 3)
32
-
33
-
34
- if PY3:
35
- basestring = str
36
- else:
37
- input = raw_input
38
-
39
31
 
40
32
 
41
33
  BUTTON_OK = 0x0001 #: Bottone "Ok"
@@ -75,47 +67,8 @@ if not _proxy.is_valid():
75
67
 
76
68
 
77
69
  def _get_term_width():
78
- if PY3:
79
- import shutil
80
- return shutil.get_terminal_size(fallback=(80, 24))[0]
81
- else:
82
- # from https://stackoverflow.com/questions/566746/how-to-get-linux-console-window-width-in-python
83
- if sys.platform == 'win32':
84
- try:
85
- from ctypes import windll, create_string_buffer
86
- h = windll.kernel32.GetStdHandle(-12)
87
- csbi = create_string_buffer(22)
88
- res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
89
- except:
90
- res = None
91
- if res:
92
- import struct
93
- (bufx, bufy, curx, cury, wattr, left, top, right, bottom, maxx, maxy) = struct.unpack("hhhhHhhhhhh", csbi.raw)
94
- return right - left + 1
95
- else:
96
- return 80
97
- else:
98
- def ioctl_GWINSZ(fd):
99
- try:
100
- import fcntl, termios, struct
101
- cr = struct.unpack('hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
102
- except:
103
- return None
104
- return cr
105
- cr = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
106
- if not cr:
107
- try:
108
- fd = os.open(os.ctermid(), os.O_RDONLY)
109
- cr = ioctl_GWINSZ(fd)
110
- os.close(fd)
111
- except:
112
- pass
113
- if not cr:
114
- try:
115
- cr = (env['LINES'], env['COLUMNS'])
116
- except:
117
- return 80
118
- return int(cr[1])
70
+ import shutil
71
+ return shutil.get_terminal_size(fallback=(80, 24))[0]
119
72
 
120
73
 
121
74
 
@@ -338,11 +291,7 @@ def set_progress(progress=None, message=None, state=None):
338
291
  tick = ('\\', '|', '/', '-')[int(time.time() * 5) % 4]
339
292
  bar = '%s %s' % (elide(', '.join(text), term_width - 3), tick)
340
293
  else:
341
- if PY3:
342
- block = u'\u2588'
343
- else:
344
- block = '#'
345
- progress = (block * int((progress * 30) // 100))
294
+ progress = ('\u2588' * int((progress * 30) // 100))
346
295
  bar = '|%-30s| %s' % (progress, elide(', '.join(text), term_width - 34))
347
296
  print('\033[2K\r' + bar, end='')
348
297
  sys.stdout.flush()
@@ -494,7 +443,7 @@ def execute_form(form_data, title=None, message=None, condition=None):
494
443
  raise InvalidInput('Expected iso date (YYYY-MM-DD)')
495
444
  elif wtype in ('choice', 'listbox', 'combobox'):
496
445
  items = entry.get('items', [])
497
- if (not isinstance(items, (tuple, list))) or (not all([ isinstance(item, basestring) for item in items ])):
446
+ if (not isinstance(items, (tuple, list))) or (not all([ isinstance(item, str) for item in items ])):
498
447
  raise RuntimeError("Expected list of strings as 'items' value")
499
448
  print(label)
500
449
  for index, item in enumerate(items):