Esempio n. 1
0
def close_progress():
    """Nasconde la finestra di progresso precedentemente mostrata con :func:`kongaui.open_progress`."""
    if _proxy.is_valid():
        _proxy.ui.close_progress()
    else:
        print('\033[2K\r', end='')
        sys.stdout.flush()
Esempio n. 2
0
def select_record(tablename,
                  multi=False,
                  size=None,
                  where_expr=None,
                  code_azienda=None,
                  num_esercizio=None):
    """Mostra una finestra di selezione record di Konga; la finestra mostrerà i record della tabella *tablename* e avrà dimensione *size* (tupla di due elementi nella forma
	``(width, height)``). *where_expr* può essere un'espressione SQL *WHERE* per filtrare i record selezionabili; *code_azienda* e *code_esercizio* filtrano ulteriormente
	i record visualizzati usando l'azienda e l'esercizio specificati.
	Se *multi* è ``True``, la funzione restituisce una lista di record selezionati sotto forma di ``dict``, altrimenti restituisce il ``dict`` del singolo record selezionato.
	In tutti i casi se l'utente annulla l'operazione, la funzione restituirà ``None``.
	
	.. warning::
	   Questa funzione è disponibile solo all'interno di Konga; eseguendola da fuori verrà lanciata l'eccezione :class:`kongautil.KongaRequiredError`.
	"""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.select_record(tablename,
                                           multi,
                                           size,
                                           where_expr,
                                           code_azienda=code_azienda,
                                           num_esercizio=num_esercizio)
    else:
        raise kongautil.KongaRequiredError
Esempio n. 3
0
def choose_directory(message=None, path=''):
    """Mostra una finestra di selezione directory con titolo *message* e percorso iniziale *path*. La funzione restituisce il percorso della directory selezionata oppure ``None``
	se l'utente ha annullato l'operazione.
	Se eseguita al di fuori di Konga, questa funzione ignora il parametro *path*, e l'utente dovrà inserire il percorso completo della directory; se verrà inserito un percorso
	vuoto, la funzione restituirà ``None``."""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.choose_directory(message, path)
    else:
        if message:
            print(colorama.Style.BRIGHT +
                  textwrap.fill(message, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
        while True:
            try:
                dirname = input(
                    'Enter an existing directory to open or none to cancel: ')
            except KeyboardInterrupt:
                print(colorama.Fore.YELLOW + "aborted" + colorama.Fore.RESET)
                return None
            if not dirname:
                return None
            if os.path.exists(dirname) and os.path.isdir(dirname):
                break
        return dirname
Esempio n. 4
0
def open_file(message=None, specs=None, path='', multi=False):
    """Mostra una finestra di caricamento file con titolo *message. *specs* può essere una lista di tuple ``(extension, description)`` per permettere di caricare solo
	file di tipi specifici; *path* è il percorso predefinito, e *multi* permette di selezionare più di un file da caricare.
	Se *multi* è ``False``, la funzione restituisce il percorso del file selezionato o ``None`` se l'utente ha annullato il caricamento, altrimenti restituisce la lista di file
	selezionati. Se eseguita al di fuori di Konga, questa funzione ignora i parametri *specs*, *path* e *multi*, e l'utente dovrà inserire il percorso completo del file da caricare;
	se verrà inserito un percorso vuoto, la funzione restituirà ``None``."""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.open_file(message, specs, path, multi)
    else:
        if message:
            print(colorama.Style.BRIGHT +
                  textwrap.fill(message, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
        while True:
            try:
                filename = input(
                    'Enter an existing filename to open or none to cancel: ')
            except KeyboardInterrupt:
                print(colorama.Fore.YELLOW + "aborted" + colorama.Fore.RESET)
                return None
            if not filename:
                return None
            if os.path.exists(filename) and os.path.isfile(filename):
                break
        return filename
Esempio n. 5
0
def get_site_packages():
    """Restituisce una lista di percorsi di installazione dei pacchetti Python."""
    if _proxy.is_valid():
        return [_proxy.util.get_site_packages()]
    else:
        import site
        return site.getsitepackages()
Esempio n. 6
0
def get_window_vars():
    """Restituisce un ``dict`` contenente una serie di costanti definite per la finestra di navigazione correntemente aperta su Konga, incluse informazioni
	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``
	restituito sarà vuoto."""
    if _proxy.is_valid():
        return _proxy.util.get_window_vars()
    else:
        return {}
Esempio n. 7
0
def get_context():
    """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.

	.. warning::
	   Questa funzione è disponibile solo all'interno di Konga; eseguendola da fuori verrà lanciata l'eccezione :class:`kongautil.KongaRequiredError`.
	"""
    if _proxy.is_valid():
        return _proxy.util.get_context()
    else:
        raise KongaRequiredError
Esempio n. 8
0
def open_progress(title=None, cancellable=True):
    """Mostra una finestra di progresso con titolo *title*, potenzialmente annullabile dall'utente se *cancellable* è ``True``; la funzione ritorna immediatamente.
	Se eseguita fuori da Konga, questa funzione ignora il parametro *cancellable*."""
    if _proxy.is_valid():
        _proxy.ui.open_progress(title or u'Operazione in corso…', cancellable)
    else:
        if title:
            print(colorama.Style.BRIGHT +
                  textwrap.fill(title, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
        set_progress()
Esempio n. 9
0
def open_window(command,
                key_id=None,
                key_code=None,
                code_azienda=None,
                num_esercizio=None):
    """Apre una finestra di Konga mostrando il comando *command*, ed eventualmente aprendo il record identificato univocamente o da *key_id* (ID del record), o
	dalla tupla (*key_code*, *code_azienda*, *code_esercizio*) (Codice del record, codice dell'azienda e codice dell'esercizio).
	
	.. warning::
	   Questa funzione è disponibile solo all'interno di Konga; eseguendola da fuori verrà lanciata l'eccezione :class:`kongautil.KongaRequiredError`.
	"""
    if _proxy.is_valid():
        _proxy.ui.open_window(command, key_id, key_code, code_azienda,
                              num_esercizio)
    else:
        raise kongautil.KongaRequiredError
Esempio n. 10
0
def set_progress(progress=None, message=None, state=None):
    """Imposta l'avanzamento corrente nella finestra di progresso precedentemente mostrata con :func:`kongaui.open_progress`. *progress* può essere ``None``
	per specificare un avanzamento indefinito, oppure un valore compreso tra 0 e 100 per specificare la percentuale di avanzamento completata. *message* e
	*state* sono messaggi aggiuntivi da mostrare nella finestra di avanzamento."""
    if _proxy.is_valid():
        _proxy.ui.set_progress(progress, message, state)
    else:
        term_width = _get_term_width()

        def elide(s, width):
            if len(s) > width:
                parts = s.split(' ')
                mid = len(parts) // 2
                before = parts[:mid]
                after = parts[mid:]
                while before or after:
                    if len(before) > len(after):
                        del before[-1]
                    elif after:
                        del after[-1]
                    s = ' '.join(before) + ' [...] ' + ' '.join(after)
                    if len(s) <= width:
                        break
            if len(s) > width:
                s = s[:width - 6] + ' [...]'
            return s

        text = []
        if message:
            text.append(message)
        if state:
            text.append(state)
        if not text:
            text.append('Operazione in corso...')
        if (progress is None) or (progress < 0):
            tick = ('\\', '|', '/', '-')[int(time.time() * 5) % 4]
            bar = '%s %s' % (elide(', '.join(text), term_width - 3), tick)
        else:
            if PY3:
                block = u'\u2588'
            else:
                block = '#'
            progress = (block * int((progress * 30) // 100))
            bar = '|%-30s| %s' % (progress,
                                  elide(', '.join(text), term_width - 34))
        print('\033[2K\r' + bar, end='')
        sys.stdout.flush()
Esempio n. 11
0
def save_file(message=None, spec=None, path=''):
    """Mostra una finestra di salvataggio file con titolo *message. *spec* può essere una tupla nella forma ``(extension, description)`` per permettere di salvare file di un
	tipo specifico; *path* è il percorso predefinito. La funzione restituisce il percorso del file da salvare oppure ``None`` se l'utente ha annullato il salvataggio.
	Se eseguita al di fuori di Konga, questa funzione ignora i parametri *specs* e *path*, e l'utente dovrà inserire il percorso completo del file da salvare;
	se verrà inserito un percorso vuoto, la funzione restituirà ``None``."""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.save_file(message, spec, path)
    else:
        if message:
            print(colorama.Style.BRIGHT +
                  textwrap.fill(message, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
        try:
            filename = input('Enter filename to be saved or none to cancel: ')
        except KeyboardInterrupt:
            print(colorama.Fore.YELLOW + "aborted" + colorama.Fore.RESET)
            return None
        return filename or None
Esempio n. 12
0
def suspend_timeout():
    """Sospende il timeout di esecuzione dello script. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
    if _proxy.is_valid():
        return _proxy.builtin.set_timeout(restore=False)
Esempio n. 13
0
def print_log(log, title, target=PRINT_TARGET_PREVIEW, filename=None):
    """Stampa il contenuto dell'oggetto *log* di classe :class:`kongalib.Log`; se si esegue questa funzione dall'interno di Konga, verrà usata la funzione
	:func:`print_layout`, passando i parametri *target* e *filename*; viceversa se si esegue fuori da Konga, il log verrà stampato su terminale."""
    if _proxy.is_valid():
        template = """<?xml version='1.0' encoding='utf-8'?>
			<layout version="2" name="%(title)s" title="%(title)s" orientation="vertical" margin_top="75" margin_right="75" margin_bottom="75" margin_left="75">
				<init>
					<![CDATA[set_datasource(Datasource(['id', 'type', 'message'], DATA, 'Master'))
]]></init>
				<header width="100%%" height="175" only_first="true">
					<label width="100%%" height="100" align="center" font_size="14" bgcolor="#EEE" border_edges="left|right|top|bottom">%(title)s</label>
				</header>
				
				<module width="100%%" alt_bgcolor="#EEE" condition="iterate('id')">
					<field top="0" width="10%%" align="top" type="data">type</field>
					<field left="10%%" top="0" width="90%%" align="top" wrapping="wrap" type="data">message</field>
				</module>
				<module width="100%%">
					<init>
						<![CDATA[this.visible = (len(DATA) == 0)
]]></init>
					<label width="100%%" align="center">
						<text>
							<it>Operazione completata con successo</it>
						</text>
					</label>
				</module>
				
				<footer width="100%%" font_size="7" height="175">
					<rect top="75" width="100%%" height="100" />
					<field padding_left="50" top="75" left="0" width="30%%" height="50" align="bottom" type="expr">DATABASE_NAME</field>
					<field padding_left="50" top="125" left="0" width="30%%" height="50" align="top" type="expr">COMPANY_NAME</field>
					<field top="75" left="30%%" width="40%%" height="50" align="hcenter|bottom" type="expr">TITLE</field>
					<datetime top="125" left="30%%" width="40%%" height="50" align="hcenter|top" format="PdmyHM">
						<text>
							<it>Stampato da $USER_NAME il %%d alle %%t</it>
							<nl>Afgedrukt door $USER_NAME op %%d om %%t uur</nl>
						</text>
					</datetime>
					<page padding_right="50" top="75" left="80%%" width="20%%" height="100" align="vcenter|right">
						<text>
							<it>Pagina %%p di %%t</it>
							<nl>Pagina %%p van %%t</nl>
						</text>
					</page>
				</footer>
			</layout>
		""" % {
            'title': title,
        }
        data = []
        for index, message in enumerate(log.get_messages()):
            msg = log.strip_html(message[1])
            if isinstance(msg, bytes):
                msg = msg.decode('utf-8', 'replace')
            data.append((index, ('INFO', 'WARNING', 'ERROR')[message[0]], msg))

        print_layout(template, {'DATA': data},
                     target=target,
                     filename=filename)
    else:
        import colorama
        print(colorama.Style.BRIGHT + title + colorama.Style.RESET_ALL)
        status = {
            kongalib.Log.INFO:
            colorama.Style.BRIGHT + "INFO      " + colorama.Style.RESET_ALL,
            kongalib.Log.WARNING:
            colorama.Style.BRIGHT + colorama.Fore.YELLOW + "WARNING   " +
            colorama.Style.RESET_ALL,
            kongalib.Log.ERROR:
            colorama.Style.BRIGHT + colorama.Fore.RED + "ERROR     " +
            colorama.Style.RESET_ALL,
        }
        for message in log.get_messages():
            print('%s%s' % (status[message[0]], message[1]))
Esempio n. 14
0
def print_layout(command_or_layout,
                 builtins=None,
                 code_azienda=None,
                 code_esercizio=None,
                 target=None,
                 filename=None,
                 progress=True,
                 client=None):
    """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
	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
	*code_esercizio* identificano l'azienda e l'esercizio per cui eseguire la stampa, mentre *target* è una delle costanti ``PRINT_TARGET_*`` definite sopra, che
	specificano la destinazione della stampa (se non specificata e la funzione è eseguita all'interno di Konga, verrà assunta ``PRINT_TARGET_PREVIEW``,
	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
	a video una barra di progresso dell'operazione di stampa.
	La funzione restituisce un oggetto di classe :class:`kongalib.Log` con il resoconto dell'operazione di stampa, oppure lancia un'eccezione di classe
	:class:`kongautil.PrintError` in caso di errori.
	
	.. warning::
	   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
	   ``PRINT_TARGET_PREVIEW`` e ``PRINT_TARGET_PAPER``. Konga Client (o Konga) verrà invocato e provvederà a connettersi al client corrente e stampare il
	   documento richiesto; i parametri di connessione saranno ricavati automaticamente dal client ottenuto dall'ultima chiamata alla funzione :func:`kongautil.connect`
	   oppure, se specificato, dal parametro ``client``.
	"""
    if _proxy.is_valid():
        if target is None:
            target = PRINT_TARGET_PREVIEW
        log = _proxy.util.print_layout(command_or_layout, builtins or {},
                                       code_azienda, code_esercizio, target,
                                       filename, progress)
    else:
        log = kongalib.Log()
        if not filename:
            raise ValueError("Output filename must be specified")
        if isinstance(command_or_layout, kongalib.text_base_types) and (
                command_or_layout.strip().startswith('<?xml')
                or command_or_layout.strip().startswith('<layout')):
            import tempfile
            temp = tempfile.NamedTemporaryFile(mode='w', delete=False)
            with temp:
                temp.write(command_or_layout)
            command_or_layout = temp.name
        else:
            temp = None
        target = {
            PRINT_TARGET_PDF: 'pdf',
            PRINT_TARGET_CSV: 'csv',
            PRINT_TARGET_XLS: 'xls',
        }.get(target, 'pdf')
        builtins = builtins or {}
        if code_azienda:
            builtins['COMPANY_CODE'] = code_azienda
        if code_esercizio:
            builtins['ACCOUNTING_YEAR_CODE'] = code_esercizio
        script = [
            '.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)
        ]
        try:
            _run_script(script, log, client)
        finally:
            if temp is not None:
                os.unlink(temp)
    if log.has_errors():
        raise PrintError(log)
    return log
Esempio n. 15
0
def connect(host=None,
            port=None,
            driver=None,
            database=None,
            username=None,
            password=None,
            tenant_key=None,
            config=None):
    """Restituisce un oggetto :class:`kongalib.Client` già connesso. Se eseguito dall'interno di Konga, la connessione sarà stabilita
	con il server, il database e l'utenza correntemente aperti sul programma, e i parametri passati a questa funzione saranno ignorati.
	Se eseguita fuori da Konga, la funzione proverà a collegarsi al primo server disponibile sulla rete locale, aprendo il primo
	database disponibile autenticandosi col l'utenza *admin* con password vuota; ogni parametro di connessione può essere forzato
	tramite i parametri passati a questa funzione, oppure da linea di comando specificando gli argomenti ``--host``, ``--port``,
	``--driver``, ``-d|--database``, ``-u|--username``, ``-p|--password`` e ``-k|--tenant-key``. Inoltre, è possibile definire i
	parametri come variabili all'interno di un file di configurazione, nella sezione ``[kongautil.connect]``; tale file deve avere
	il nome passato a questa funzione con il parametro ``config``, altrimenti verranno ricercati nell'ordine anche il file con lo
	stesso nome dello script lanciato da terminale, ma con estensione ``.cfg``, il file ``kongalib.cfg`` sempre nella stessa directory
	da cui si esegue lo script e infine il file ``~/.kongalib`` (sotto Unix) o ``%userprofile%\kongalib.cfg`` (sotto Windows)."""
    if _proxy.is_valid():
        info = _proxy.util.get_connection_info()
        if info is not None:
            host, port, driver, database, username, password, tenant_key = info
            client = kongalib.Client()
            client.connect(host=host,
                           port=port,
                           options={'tenant_key': tenant_key})
            client.open_database(driver, database)
            client.authenticate(username, password)
            return client
    else:
        global _last_client
        global _konga_exe
        global _konga_args
        client = kongalib.Client()
        if host is None:
            import argparse
            try:
                import configparser
            except:
                import ConfigParser as configparser
            files = [
                os.path.splitext(sys.argv[0])[0] + '.cfg',
                os.path.join(os.path.abspath(os.path.dirname(sys.argv[0])),
                             'kongalib.cfg'),
                os.path.abspath(
                    os.path.expanduser(
                        os.path.join(
                            '~', 'kongalib.cfg'
                            if sys.platform == 'win32' else '.kongalib'))),
            ]
            if config:
                files.insert(0, config)
            config = configparser.RawConfigParser({
                'host': host or '',
                'port': str(port or ''),
                'driver': driver or '',
                'database': database or '',
                'username': username or '',
                'password': password or '',
                'tenant_key': tenant_key or '',
                'konga_exe': '',
                'konga_args': '',
            })
            config.add_section('kongautil.connect')
            config.add_section('kongautil.print_layout')
            config.read(files)
            host = config.get('kongautil.connect', 'host') or None
            try:
                port = int(config.get('kongautil.connect', 'port'))
            except:
                pass
            driver = config.get('kongautil.connect', 'driver') or None
            database = config.get('kongautil.connect', 'database') or None
            username = config.get('kongautil.connect', 'username') or None
            password = config.get('kongautil.connect', 'password') or None
            tenant_key = config.get('kongautil.connect', 'tenant_key') or None

            _konga_exe = config.get('kongautil.print_layout',
                                    'konga_exe') or None
            _konga_args = config.get('kongautil.print_layout',
                                     'konga_args') or None

            class ArgumentParser(argparse.ArgumentParser):
                def _print_message(self, message, file=None):
                    pass

                def exit(self, status=0, message=None):
                    if status:
                        raise RuntimeError

            parser = ArgumentParser()
            parser.add_argument('--host', default=host)
            parser.add_argument('--port', type=int, default=port)
            parser.add_argument('--driver', default=driver)
            parser.add_argument('-d', '--database', default=database)
            parser.add_argument('-u', '--username', default=username)
            parser.add_argument('-p', '--password', default=password)
            parser.add_argument('-k', '--tenant-key', default=tenant_key)
            try:
                args = parser.parse_args()
                host = args.host
                port = args.port
                driver = args.driver
                database = args.database
                username = args.username
                password = args.password
                tenant_key = args.tenant_key
            except:
                pass
        if host is None:
            servers_list = client.list_servers(timeout=500)
            if servers_list:
                host = servers_list[0]['host']
                port = servers_list[0]['port']
        if host is not None:
            client.connect(host=host,
                           port=port or 0,
                           options={'tenant_key': tenant_key})
            db_list = None
            if driver is None:
                if database is not None:
                    db_list = client.list_databases(timeout=500)
                    for driver, dbs in db_list.items():
                        if database in [db['name'] for db in dbs]:
                            break
                    else:
                        driver = None
                if driver is None:
                    drivers_list = client.list_drivers(timeout=500)
                    if drivers_list:
                        driver = drivers_list[0]['name']
            if (driver is not None) and (database is None):
                if db_list is None:
                    db_list = client.list_databases(driver, timeout=500)
                if db_list and (len(db_list[driver]) > 0):
                    database = db_list[driver][0]['name']
            if (driver is not None) and (database is not None):
                client.open_database(driver, database)
                client.authenticate(username or 'admin', password or '')
                _last_client = client
                return client
    raise kongalib.Error(kongalib.DATABASE_NOT_CONNECTED,
                         "No database connected")
Esempio n. 16
0
def message_box(text, title='', buttons=BUTTON_OK, icon=ICON_INFORMATION):
    """Mostra una finestra di dialogo modale con titolo *title*, messaggio *text* e icona *icon* (una delle costanti ``ICON_*``). La finestra mostrerà i bottoni identificati
	da *buttons*, che può contenere uno o più costanti ``BUTTON_*`` in *or* tra loro, e ritornerà la costante relativa al bottone selezionato dall'utente per chiudere la
	finestra."""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.message_box(text, title, buttons, icon)
    else:
        print()
        if icon == ICON_WARNING:
            title = colorama.Fore.YELLOW + "WARNING" + (
                ': ' if title else '') + colorama.Fore.RESET + (title or '')
        elif icon == ICON_ERROR:
            title = colorama.Fore.RED + "ERROR" + (
                ': ' if title else '') + colorama.Fore.RESET + (title or '')
        if title:
            print('  ' + colorama.Style.BRIGHT +
                  textwrap.fill(title, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
            print()
        print(textwrap.fill(text, width=_get_term_width() - 1))
        print()
        buttons_info = [
            (BUTTON_OK, 'ok'),
            (BUTTON_YES, 'yes'),
            (BUTTON_YES_ALL, 'yes all'),
            (BUTTON_NO, 'no'),
            (BUTTON_NO_ALL, 'no all'),
            (BUTTON_CANCEL, 'cancel'),
            (BUTTON_OPEN, 'open'),
            (BUTTON_SAVE, 'save'),
            (BUTTON_SAVE_ALL, 'save_all'),
            (BUTTON_CLOSE, 'close'),
            (BUTTON_DISCARD, 'discard'),
            (BUTTON_APPLY, 'apply'),
            (BUTTON_RESET, 'reset'),
            (BUTTON_ABORT, 'abort'),
            (BUTTON_RETRY, 'retry'),
            (BUTTON_IGNORE, 'ignore'),
        ]
        buttons_map = {}
        labels = []
        for bit, label in buttons_info:
            if buttons & bit:
                for i, c in enumerate(label):
                    if c not in buttons_map:
                        buttons_map[c] = bit
                        labels.append('%s(%s)%s' %
                                      (label[:i], c, label[i + 1:]))
                        break
                else:
                    for c in string.ascii_letters:
                        if c not in buttons_map:
                            buttons_map[c] = bit
                            labels.append('%s (%s)' % (label, c))
                            break
        answer = None
        while answer not in buttons_map:
            try:
                answer = input(', '.join(labels) + ': ')
            except KeyboardInterrupt:
                print(colorama.Fore.YELLOW + "aborted" + colorama.Fore.RESET)
                if buttons & BUTTON_CANCEL:
                    return BUTTON_CANCEL
                elif buttons & BUTTON_NO:
                    return BUTTON_NO
                elif buttons & BUTTON_CLOSE:
                    return BUTTON_CLOSE
                elif buttons & BUTTON_DISCARD:
                    return BUTTON_DISCARD
                elif buttons & BUTTON_ABORT:
                    return BUTTON_ABORT
                return buttons & ~(buttons - 1)
        return buttons_map[answer]
Esempio n. 17
0
def resume_timeout(timeout):
    """Ripristina il timeout di esecuzione dello script. La funzione non comporta eccezioni ma non ha alcun effetto se eseguita al di fuori di Konga."""
    if _proxy.is_valid():
        _proxy.builtin.set_timeout(timeout, restore=False)
Esempio n. 18
0
def set_timeout(timeout):
    """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."""
    if _proxy.is_valid():
        _proxy.builtin.set_timeout(timeout * 1000, restore=False)
Esempio n. 19
0
def is_progress_aborted():
    """Restituisce ``True`` se l'utente ha annullato la finestra di progresso precedentemente mostrata con :func:`kongaui.open_progress`."""
    if _proxy.is_valid():
        return _proxy.ui.is_progress_aborted()
    else:
        return False
Esempio n. 20
0
def notify_data_changes(table_name, row_id=None):
    """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
	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."""
    if _proxy.is_valid():
        _proxy.util.notify_data_changes(table_name, row_id)
Esempio n. 21
0
def execute_form(form_data, title=None, message=None, condition=None):
    """Apre un form di immissione dati con titolo *title*; se *message* è specificato, il testo corrispondente sarà visualizzato in alto nella finestra del form.
	*form_data* deve essere una lista di ``dict`` con le specifiche dei campi da mostrare; nel ``dict``	di un singolo campo, l'unica chiave richiesta è ``name``,
	che deve identificare univocamente il nome del campo. E' possibile specificare l'etichetta da mostrare accando al campo stesso tramite la chiave ``label``;
	la tipologia di dato consentità è specificata tramite la chiave ``type``, che può assumere i valori:

	* ``str``: testo semplice, con possibile lunghezza massima ``length`` se la chiave è specificata;
	* ``password``: parola chiave;
	* ``int``: valore intero;
	* ``decimal``: valore decimale (:class:`kongalib.Decimal`);
	* ``range``: valore intero compreso tra un valore minimo (specificato dalla chiave ``min`` con valore predefinito ``0``) e un valore massimo (specificato dalla chiave ``max`` con valore predefinito ``100``);
	* ``slider``: simile a ``range`` ma viene visualizzato come cursore di selezione valore scorrevole;
	* ``bool``: valore booleano;
	* ``date``: data (``datetime.date``);
	* ``choice``: valore interno che identifica l'indice di una scelta tra quelle specificate nella chiave ``items`` (lista di stringhe);
	* ``listbox``: simile a ``choice`` ma viene visualizzato come lista di elementi da cui fare una scelta;
	* ``load``: nome di file esistente da caricare;
	* ``save``: nome di file da salvare;
	* ``dir``: nome di directory esistente;
	* ``code``: stringa di testo che identifica il codice di un record, la cui tabella è indicata dalla chiave ``table``;
	* ``company_code``: simile a ``code``, specifica l'azienda su cui gli altri campi ``code`` possono essere ricercati;
	* ``accounting_year_code``: simile a ``code``, specifica l'esercizio su cui gli altri campi ``code`` possono essere ricercati;

	Se presente, la chiave ``default`` permette di specificare il valore predefinito per un dato campo; inoltre se è presente la chiave ``focus`` (con qualsiasi
	valore), il campo corrispondente prenderà il focus all'avvio della finestra. Se l'utente annulla il form la funzione restituisce ``None``, altrimenti un
	``dict`` le cui chiavi sono i nome dei campi e i valori i dati immessi dall'utente.
	Il parametro *condition*, se presente, permette di specificare una condizione di validazione per il form sotto forma di espressione Python; i nomi dei campi
	specificati in *form_data* saranno disponibili come variabili nell'esecuzione di questa condizione, il cui esito determinerà se consentire o meno l'uscita
	dal form con successo."""
    if _proxy.is_valid():
        with _TimeoutBlocker():
            return _proxy.ui.execute_form(form_data, title, message, condition)
    else:
        import kongalib, decimal, datetime, getpass

        class InvalidInput(RuntimeError):
            pass

        if title:
            print(colorama.Style.BRIGHT +
                  textwrap.fill(title, width=_get_term_width() - 1) +
                  colorama.Style.RESET_ALL)
        if message:
            print(textwrap.fill(message, width=_get_term_width() - 1))
        result = {}
        for entry in form_data:
            if not isinstance(entry, dict):
                raise RuntimeError("Expected dict as form data entry")
            if 'name' not in entry:
                raise RuntimeError(
                    "Expected 'name' key in form data entry dict")
            name = str(entry['name'])
            label = str(entry.get('label', name))
            prompt = input
            wtype = entry.get('type', str)
            if wtype in ('integer', 'int'):
                try:
                    default = str(int(entry.get('default', 0)))
                except:
                    default = '0'

                def validate(text):
                    try:
                        return int(text)
                    except:
                        raise InvalidInput('Expected integer number')
            elif wtype in ('decimal', kongalib.Decimal, decimal.Decimal):
                try:
                    default = str(kongalib.Decimal(entry.get('default', 0)))
                except:
                    default = str(kongalib.Decimal(0))

                def validate(text):
                    try:
                        return kongalib.Decimal(text)
                    except:
                        raise InvalidInput('Expected decimal number')
            elif wtype in ('range', 'slider'):
                try:
                    default = str(int(entry.get('default', 0)))
                except:
                    default = '0'
                try:
                    min_value = int(entry.get('min', 0))
                except:
                    min_value = 0
                try:
                    max_value = int(entry.get('max', 100))
                except:
                    max_value = 100
                label += ' (%d-%d)' % (min_value, max_value)

                def validate(text):
                    try:
                        value = int(text)
                        if (value < min_value) or (value > max_value):
                            raise RuntimeError
                        return value
                    except:
                        raise InvalidInput(
                            'Expected integer number between %d and %d' %
                            (min_value, max_value))
            elif wtype in ('bool', 'boolean', bool, 'check'):
                try:
                    default = 'Y' if bool(entry.get('default', False)) else 'N'
                except:
                    default = 'N'

                def validate(text):
                    if text.lower() in ('t', 'true', 'y', 'yes', '1'):
                        return True
                    if text.lower() in ('f', 'false', 'n', 'no', '0'):
                        return False
                    raise InvalidInput('Expected boolean value')
            elif wtype in ('date', datetime.date):
                try:
                    default = datetime.datetime.strptime(
                        entry.get('default', datetime.date.today()),
                        '%Y-%m-%d').date().isoformat()
                except:
                    default = datetime.date.today().isoformat()

                def validate(text):
                    try:
                        return datetime.datetime.strptime(text,
                                                          '%Y-%m-%d').date()
                    except:
                        raise InvalidInput('Expected iso date (YYYY-MM-DD)')
            elif wtype in ('choice', 'listbox', 'combobox'):
                items = entry.get('items', [])
                if (not isinstance(items, (tuple, list))) or (not all(
                    [isinstance(item, basestring) for item in items])):
                    raise RuntimeError(
                        "Expected list of strings as 'items' value")
                print(label)
                for index, item in enumerate(items):
                    print("%d) %s" % (index + 1, item))
                label = 'Enter selection'
                try:
                    default = str(int(entry.get('default', 0)) + 1)
                except:
                    default = '1'

                def validate(text):
                    try:
                        value = int(text)
                        if (value < 1) or (value > len(items)):
                            raise RuntimeError
                        return value - 1
                    except:
                        raise InvalidInput(
                            'Expected integer number between %d and %d' %
                            (1, len(items)))
            else:
                if wtype == 'password':
                    prompt = getpass.getpass
                    default = None
                else:
                    try:
                        default = str(entry.get('default', ''))
                    except:
                        default = ''
                try:
                    length = int(entry.get('length', 0))
                except:
                    length = 0

                def validate(text):
                    if length and (len(text) > length):
                        raise InvalidInput(
                            'String lengths exceeds maximum size of %d characters'
                            % length)
                    return text

            if default is not None:
                label += ' [%s]' % default
            while True:
                try:
                    value = prompt(label + ': ')
                except KeyboardInterrupt:
                    print(colorama.Fore.YELLOW + "aborted" +
                          colorama.Fore.RESET)
                    return None
                if (not value) and (default is not None):
                    value = default
                try:
                    value = validate(value)
                    break
                except InvalidInput as e:
                    print(colorama.Fore.RED + str(e) + colorama.Fore.RESET)
            result[name] = value
        if condition is not None:
            if not eval(condition, result.copy()):
                print(colorama.Style.BRIGHT + colorama.Fore.RED +
                      "Form input data validation failed; aborted" +
                      colorama.Style.RESET_ALL)
                result = None
        return result
Esempio n. 22
0
def is_batch():
    """Restituisce ``True`` se lo script è eseguito con Python da linea di comando, ``False`` se è eseguito dall'interno di Konga."""
    return not _proxy.is_valid()
Esempio n. 23
0
ICON_ERROR = 24  #: Icona di errore
ICON_QUESTION = 25  #: Icona di domanda
ICON_WARNING = 26  #: Icona di avviso
ICON_INFORMATION = 27  #: Icona informativa


def _shutdown():
    try:
        _proxy.ui.shutdown()
    except:
        pass


atexit.register(_shutdown)

if not _proxy.is_valid():
    colorama.init()


def _get_term_width():
    if PY3:
        import shutil
        return shutil.get_terminal_size(fallback=(80, 24))[0]
    else:
        # from https://stackoverflow.com/questions/566746/how-to-get-linux-console-window-width-in-python
        if sys.platform == 'win32':
            try:
                from ctypes import windll, create_string_buffer
                h = windll.kernel32.GetStdHandle(-12)
                csbi = create_string_buffer(22)
                res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)