worker-automate-hub 0.5.749__py3-none-any.whl → 0.5.912__py3-none-any.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.
- worker_automate_hub/api/client.py +186 -68
- worker_automate_hub/api/rpa_historico_service.py +1 -0
- worker_automate_hub/cli.py +91 -111
- worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +112 -229
- worker_automate_hub/tasks/jobs/descartes.py +91 -77
- worker_automate_hub/tasks/jobs/devolucao_produtos.py +1386 -0
- worker_automate_hub/tasks/jobs/entrada_de_notas_15.py +3 -46
- worker_automate_hub/tasks/jobs/entrada_de_notas_22.py +833 -0
- worker_automate_hub/tasks/jobs/entrada_de_notas_36.py +29 -9
- worker_automate_hub/tasks/jobs/entrada_de_notas_37.py +619 -0
- worker_automate_hub/tasks/jobs/entrada_de_notas_39.py +1 -1
- worker_automate_hub/tasks/jobs/entrada_de_notas_9.py +63 -16
- worker_automate_hub/tasks/jobs/extracao_dados_nielsen.py +504 -0
- worker_automate_hub/tasks/jobs/extracao_saldo_estoque.py +242 -108
- worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py +688 -0
- worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py +2 -2
- worker_automate_hub/tasks/jobs/fidc_remessa_cobranca_cnab240.py +25 -16
- worker_automate_hub/tasks/jobs/geracao_balancetes_filial.py +330 -0
- worker_automate_hub/tasks/jobs/importacao_extratos.py +538 -0
- worker_automate_hub/tasks/jobs/importacao_extratos_748.py +800 -0
- worker_automate_hub/tasks/jobs/inclusao_pedidos_ipiranga.py +222 -0
- worker_automate_hub/tasks/jobs/inclusao_pedidos_raizen.py +174 -0
- worker_automate_hub/tasks/jobs/inclusao_pedidos_vibra.py +327 -0
- worker_automate_hub/tasks/jobs/notas_faturamento_sap.py +438 -157
- worker_automate_hub/tasks/jobs/opex_capex.py +540 -326
- worker_automate_hub/tasks/jobs/sped_fiscal.py +8 -8
- worker_automate_hub/tasks/jobs/transferencias.py +52 -41
- worker_automate_hub/tasks/task_definitions.py +46 -1
- worker_automate_hub/tasks/task_executor.py +11 -0
- worker_automate_hub/utils/util.py +252 -215
- worker_automate_hub/utils/utils_nfe_entrada.py +1 -1
- worker_automate_hub/worker.py +1 -9
- {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/METADATA +4 -2
- {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/RECORD +36 -25
- {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/WHEEL +1 -1
- {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/entry_points.txt +0 -0
|
@@ -2,12 +2,13 @@ from decimal import ROUND_HALF_UP, Decimal
|
|
|
2
2
|
import threading
|
|
3
3
|
from typing import Optional
|
|
4
4
|
import aiohttp
|
|
5
|
-
|
|
5
|
+
import re
|
|
6
|
+
from collections import defaultdict
|
|
6
7
|
import aiohttp
|
|
7
8
|
import requests
|
|
8
9
|
from aiohttp import ClientSession
|
|
9
10
|
from rich.console import Console
|
|
10
|
-
|
|
11
|
+
from typing import List, Dict, Any
|
|
11
12
|
from worker_automate_hub.api.helpers.api_helpers import handle_api_response
|
|
12
13
|
from worker_automate_hub.config.settings import load_env_config
|
|
13
14
|
from worker_automate_hub.models.dao.rpa_configuracao import RpaConfiguracao
|
|
@@ -144,41 +145,42 @@ async def get_processo(uuidProcesso: str) -> RpaProcesso:
|
|
|
144
145
|
RpaProcesso: O processo caso tenha sido encontrado.
|
|
145
146
|
"""
|
|
146
147
|
env_config, _ = load_env_config()
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
style="bold red",
|
|
148
|
+
x = 0
|
|
149
|
+
while x < 10:
|
|
150
|
+
try:
|
|
151
|
+
if not uuidProcesso:
|
|
152
|
+
raise ValueError("O uuid do processo deve ser informado")
|
|
153
|
+
|
|
154
|
+
headers_basic = {"Authorization": f"Basic {env_config["API_AUTHORIZATION"]}"}
|
|
155
|
+
timeout = aiohttp.ClientTimeout(total=600)
|
|
156
|
+
|
|
157
|
+
async with aiohttp.ClientSession(
|
|
158
|
+
connector=aiohttp.TCPConnector(verify_ssl=True), timeout=timeout
|
|
159
|
+
) as session:
|
|
160
|
+
async with session.get(
|
|
161
|
+
f"{env_config["API_BASE_URL"]}/processo/{uuidProcesso}",
|
|
162
|
+
headers=headers_basic,
|
|
163
|
+
) as response:
|
|
164
|
+
if response.status != 200:
|
|
165
|
+
x += 1
|
|
166
|
+
console.print(f"Erro ao obter o processo: {response.content}")
|
|
167
|
+
continue
|
|
168
|
+
else:
|
|
169
|
+
res = await response.json()
|
|
170
|
+
if type(res["campos"]) == str and res["campos"] == "{}":
|
|
171
|
+
res["campos"] = {}
|
|
172
|
+
return RpaProcesso(**res)
|
|
173
|
+
|
|
174
|
+
except ValueError as e:
|
|
175
|
+
x += 1
|
|
176
|
+
logger.error(f"Erro ao obter o processo: {str(e)}")
|
|
177
|
+
console.print(
|
|
178
|
+
f"{e}\n",
|
|
179
|
+
style="bold red",
|
|
180
180
|
)
|
|
181
|
-
|
|
181
|
+
continue
|
|
182
|
+
|
|
183
|
+
return None
|
|
182
184
|
|
|
183
185
|
|
|
184
186
|
async def get_workers():
|
|
@@ -232,30 +234,34 @@ async def get_config_by_name(name: str) -> RpaConfiguracao:
|
|
|
232
234
|
if "API_BASE_URL" not in env_config:
|
|
233
235
|
raise ValueError("URL da API não encontrada na configuração do ambiente")
|
|
234
236
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
237
|
+
x = 0
|
|
238
|
+
while x < 10:
|
|
239
|
+
try:
|
|
240
|
+
headers_basic = {"Authorization": f"Basic {env_config["API_AUTHORIZATION"]}"}
|
|
241
|
+
timeout = aiohttp.ClientTimeout(total=600)
|
|
242
|
+
|
|
243
|
+
async with aiohttp.ClientSession(
|
|
244
|
+
connector=aiohttp.TCPConnector(verify_ssl=True), timeout=timeout
|
|
245
|
+
) as session:
|
|
246
|
+
async with session.get(
|
|
247
|
+
f"{env_config["API_BASE_URL"]}/configuracao/api/{name}",
|
|
248
|
+
headers=headers_basic,
|
|
249
|
+
) as response:
|
|
250
|
+
if response.status != 200:
|
|
251
|
+
console.print(f"Erro ao obter a configuração: {response.content}")
|
|
252
|
+
x += 1
|
|
253
|
+
else:
|
|
254
|
+
data = await response.json()
|
|
255
|
+
return RpaConfiguracao(**data)
|
|
256
|
+
except Exception as e:
|
|
257
|
+
x += 1
|
|
258
|
+
err_msg = f"Erro ao obter a configuração: {e}"
|
|
259
|
+
logger.error(err_msg)
|
|
260
|
+
console.print(
|
|
261
|
+
f"{err_msg}\n",
|
|
262
|
+
style="bold red",
|
|
263
|
+
)
|
|
264
|
+
return None
|
|
259
265
|
|
|
260
266
|
|
|
261
267
|
def sync_get_config_by_name(name: str) -> RpaConfiguracao:
|
|
@@ -493,6 +499,89 @@ async def get_valor_remessa_cobranca(date: str):
|
|
|
493
499
|
logger.info(err_msg)
|
|
494
500
|
|
|
495
501
|
|
|
502
|
+
async def get_notas_produtos(codFornecedor: int, codEmpresa: int, itens: List[Dict[str, Any]]) -> Dict[str, Any]:
|
|
503
|
+
"""
|
|
504
|
+
Função única:
|
|
505
|
+
- Converte itens (aceita chaves codigo/codigoProduto e quantidade/qtd)
|
|
506
|
+
- Chama /nf-supplier/checker com Authorization: Basic
|
|
507
|
+
- Normaliza tipos do retorno
|
|
508
|
+
- Entrega:
|
|
509
|
+
{
|
|
510
|
+
"lista": [ {codItem, qtdTotal, notas, valorUnitario}, ... ],
|
|
511
|
+
"por_codigo": { codItem: {...}, ... }
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
Retorno esperado da API (ex):
|
|
515
|
+
[
|
|
516
|
+
{"codItem": 19969, "qtdTotal": 15, "notas": ["1418727","1410744"], "valorUnitario": 5.29},
|
|
517
|
+
{"codItem": 29272, "qtdTotal": 10, "notas": ["1418727"], "valorUnitario": 7.12}
|
|
518
|
+
]
|
|
519
|
+
"""
|
|
520
|
+
# --- Carrega config
|
|
521
|
+
env_config, _ = load_env_config()
|
|
522
|
+
url_base = env_config["API_BASE_URL"].rstrip("/")
|
|
523
|
+
url = f"{url_base}/nf-supplier/checker"
|
|
524
|
+
|
|
525
|
+
# --- Header Basic (aceita token puro ou já "Basic ...")
|
|
526
|
+
token = (env_config.get("API_AUTHORIZATION") or "").strip()
|
|
527
|
+
auth_header = token if token.lower().startswith("basic ") else f"Basic {token}"
|
|
528
|
+
|
|
529
|
+
# --- Converte itens de entrada
|
|
530
|
+
itens_convertidos: List[Dict[str, int]] = []
|
|
531
|
+
for it in itens or []:
|
|
532
|
+
codigo = re.findall(r"\d+", it.get("descricaoProduto"))[0]
|
|
533
|
+
quantidade = it.get("quantidade", it.get("qtd"))
|
|
534
|
+
if codigo is None or quantidade is None:
|
|
535
|
+
logger.warning(f"Item incompleto: {it}")
|
|
536
|
+
console.print(f"⚠️ Item incompleto: {it}", style="yellow")
|
|
537
|
+
continue
|
|
538
|
+
try:
|
|
539
|
+
itens_convertidos.append({"codigo": int(codigo), "quantidade": int(quantidade)})
|
|
540
|
+
except Exception:
|
|
541
|
+
logger.warning(f"Item inválido (não numérico): {it}")
|
|
542
|
+
console.print(f"⚠️ Item inválido (não numérico): {it}", style="yellow")
|
|
543
|
+
|
|
544
|
+
body = {
|
|
545
|
+
"codFornecedor": int(codFornecedor),
|
|
546
|
+
"codEmpresa": int(codEmpresa),
|
|
547
|
+
"itens": itens_convertidos,
|
|
548
|
+
}
|
|
549
|
+
headers = {"Authorization": auth_header, "Content-Type": "application/json"}
|
|
550
|
+
|
|
551
|
+
# --- Chamada HTTP
|
|
552
|
+
async with aiohttp.ClientSession(connector=aiohttp.TCPConnector(verify_ssl=False)) as session:
|
|
553
|
+
async with session.post(url, json=body, headers=headers) as resp:
|
|
554
|
+
text = await resp.text()
|
|
555
|
+
if resp.status != 200:
|
|
556
|
+
raise RuntimeError(f"HTTP {resp.status} ao chamar {url}: {text}")
|
|
557
|
+
try:
|
|
558
|
+
data = await resp.json()
|
|
559
|
+
except Exception:
|
|
560
|
+
raise RuntimeError(f"Resposta não-JSON do servidor: {text[:600]}")
|
|
561
|
+
|
|
562
|
+
console.print(f"✅ Resposta da API: {data}", style="bold green")
|
|
563
|
+
logger.info(f"nf-supplier/checker -> {data}")
|
|
564
|
+
|
|
565
|
+
if not isinstance(data, list):
|
|
566
|
+
raise ValueError(f"Formato inesperado da API: {type(data)} -> {data}")
|
|
567
|
+
|
|
568
|
+
# --- Normaliza tipos e monta índices
|
|
569
|
+
lista_norm: List[Dict[str, Any]] = []
|
|
570
|
+
por_codigo: Dict[int, Dict[str, Any]] = {}
|
|
571
|
+
|
|
572
|
+
for row in data:
|
|
573
|
+
cod = int(row.get("codItem"))
|
|
574
|
+
item_norm = {
|
|
575
|
+
"codItem": cod,
|
|
576
|
+
"qtdTotal": int(row.get("qtdTotal", 0)),
|
|
577
|
+
"notas": [str(n) for n in (row.get("notas") or [])],
|
|
578
|
+
"valorUnitario": float(row.get("valorUnitario", 0.0)),
|
|
579
|
+
}
|
|
580
|
+
lista_norm.append(item_norm)
|
|
581
|
+
por_codigo[cod] = item_norm
|
|
582
|
+
|
|
583
|
+
return {"lista": lista_norm, "por_codigo": por_codigo}
|
|
584
|
+
|
|
496
585
|
async def get_status_nf_emsys(chave: int):
|
|
497
586
|
"""
|
|
498
587
|
Procura o status de nota fiscal no EMSYS.
|
|
@@ -533,7 +622,7 @@ async def get_dados_nf_emsys(
|
|
|
533
622
|
chave: Optional[int] = None,
|
|
534
623
|
numero_nota: Optional[int] = None,
|
|
535
624
|
serie_nota: Optional[int] = None,
|
|
536
|
-
|
|
625
|
+
fornecedor: Optional[int] = None
|
|
537
626
|
):
|
|
538
627
|
"""
|
|
539
628
|
Consulta a NF no EMSYS (ahead-nota) e retorna os campos essenciais:
|
|
@@ -543,7 +632,7 @@ async def get_dados_nf_emsys(
|
|
|
543
632
|
chave (int, opcional): Chave de acesso da NF.
|
|
544
633
|
numero_nota (int, opcional): Número da NF.
|
|
545
634
|
serie_nota (int, opcional): Série da NF (obrigatória se numero_nota for informado).
|
|
546
|
-
|
|
635
|
+
fornecedor (int, opcional): Filial da NF (obrigatória se numero_nota for informado).
|
|
547
636
|
|
|
548
637
|
Returns:
|
|
549
638
|
list[dict]: Lista de notas no formato esperado.
|
|
@@ -560,14 +649,14 @@ async def get_dados_nf_emsys(
|
|
|
560
649
|
|
|
561
650
|
# Caso 2: veio numero_nota → exige serie e filial
|
|
562
651
|
elif numero_nota is not None:
|
|
563
|
-
if serie_nota is None or
|
|
564
|
-
raise ValueError("Para buscar por número da nota é obrigatório informar também 'serie_nota' e '
|
|
652
|
+
if serie_nota is None or fornecedor is None:
|
|
653
|
+
raise ValueError("Para buscar por número da nota é obrigatório informar também 'serie_nota' e 'fornecedor'.")
|
|
565
654
|
params["numeroNfe"] = numero_nota
|
|
566
655
|
params["serieNfe"] = serie_nota
|
|
567
|
-
params["
|
|
656
|
+
params["fornecedorCnpj"] = fornecedor
|
|
568
657
|
|
|
569
658
|
else:
|
|
570
|
-
raise ValueError("É necessário informar 'chave' ou ('numero_nota' + 'serie_nota' + '
|
|
659
|
+
raise ValueError("É necessário informar 'chave' ou ('numero_nota' + 'serie_nota' + 'fornecedor').")
|
|
571
660
|
|
|
572
661
|
headers_basic = {"Authorization": f"Basic {env_config['API_AUTHORIZATION']}"}
|
|
573
662
|
|
|
@@ -577,8 +666,9 @@ async def get_dados_nf_emsys(
|
|
|
577
666
|
) as session:
|
|
578
667
|
async with session.get(url, headers=headers_basic, params=params) as response:
|
|
579
668
|
if response.status != 200:
|
|
669
|
+
body = await response.text() # ✅ lê o conteúdo do body
|
|
580
670
|
raise Exception(
|
|
581
|
-
f"
|
|
671
|
+
f"({response.status}): {body}"
|
|
582
672
|
)
|
|
583
673
|
|
|
584
674
|
data = await response.json()
|
|
@@ -651,7 +741,7 @@ async def get_dados_nf_emsys(
|
|
|
651
741
|
return resultado
|
|
652
742
|
|
|
653
743
|
except Exception as e:
|
|
654
|
-
raise Exception(f"
|
|
744
|
+
raise Exception(f"{e}")
|
|
655
745
|
|
|
656
746
|
|
|
657
747
|
|
|
@@ -739,6 +829,8 @@ async def send_file(
|
|
|
739
829
|
elif file_extension == "xlsx":
|
|
740
830
|
filename = desArquivo
|
|
741
831
|
content_type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
|
|
832
|
+
elif file_extension == "csv":
|
|
833
|
+
content_type = "text/csv"
|
|
742
834
|
else:
|
|
743
835
|
raise ValueError(f"Extensão de arquivo não suportada: {file_extension}")
|
|
744
836
|
|
|
@@ -836,3 +928,29 @@ async def download_file_from_historico(uuid: str):
|
|
|
836
928
|
)
|
|
837
929
|
console.print(f"\n{err_msg}\n", style="bold green")
|
|
838
930
|
logger.info(err_msg)
|
|
931
|
+
|
|
932
|
+
async def get_mfa_code(key: str):
|
|
933
|
+
try:
|
|
934
|
+
env, _ = load_env_config()
|
|
935
|
+
headers = {
|
|
936
|
+
"Content-Type": "application/json",
|
|
937
|
+
"Authorization": "Basic " + env["API_AUTHORIZATION"],
|
|
938
|
+
}
|
|
939
|
+
payload = {"key": key}
|
|
940
|
+
|
|
941
|
+
response = requests.post(
|
|
942
|
+
env["API_BASE_URL"] + "/redis/get-redis-code",
|
|
943
|
+
json=payload,
|
|
944
|
+
headers=headers,
|
|
945
|
+
)
|
|
946
|
+
|
|
947
|
+
if response.status_code == 200 and response.json() is not None:
|
|
948
|
+
return {"code": response.json(), "status_code": 200}
|
|
949
|
+
else:
|
|
950
|
+
raise Exception(
|
|
951
|
+
f"Error to get mfa code, message: {response.text}, status_code {response.status_code}"
|
|
952
|
+
)
|
|
953
|
+
|
|
954
|
+
except Exception as e:
|
|
955
|
+
logger.error(f"Error to get mfa code: {str(e)}")
|
|
956
|
+
return {"code": None, "status_code": 500}
|
worker_automate_hub/cli.py
CHANGED
|
@@ -59,124 +59,110 @@ Existem 3 subcomandos disponíveis para essa aplicação
|
|
|
59
59
|
[green][b]worker[/][/] --version
|
|
60
60
|
|
|
61
61
|
[b]Para gerar o arquivo de configuração[/]
|
|
62
|
-
[green][b]worker[/][/]
|
|
62
|
+
[green][b]worker[/][/] configure
|
|
63
63
|
|
|
64
64
|
[b]Para informações detalhadas
|
|
65
65
|
[blue][link=https://github.com/SIM-Rede/worker-automate-hub]Repo no GIT Argenta[/][/] | [blue][link=https://pypi.org/project/worker-automate-hub/]Publicação no PyPI[/][/]
|
|
66
66
|
"""
|
|
67
67
|
|
|
68
68
|
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
@app.callback(invoke_without_command=True)
|
|
70
|
+
def main(
|
|
71
|
+
ctx: Context,
|
|
72
|
+
version: bool = Option(
|
|
73
|
+
False,
|
|
74
|
+
"--version",
|
|
75
|
+
help="Mostra a versão instalada",
|
|
76
|
+
is_flag=True,
|
|
77
|
+
),
|
|
78
|
+
):
|
|
79
|
+
"""Comando principal"""
|
|
80
|
+
if ctx.invoked_subcommand:
|
|
81
|
+
return
|
|
82
|
+
|
|
83
|
+
if version:
|
|
71
84
|
console.print(
|
|
72
85
|
importlib.metadata.version("worker-automate-hub"),
|
|
73
86
|
style="bold blue",
|
|
74
87
|
)
|
|
75
88
|
raise Exit(code=0)
|
|
76
89
|
|
|
90
|
+
console.print(HELP_MESSAGE)
|
|
77
91
|
|
|
78
|
-
def function_configure(flag: bool):
|
|
79
|
-
|
|
80
|
-
if flag:
|
|
81
|
-
console.clear()
|
|
82
|
-
environment_names = [
|
|
83
|
-
"local",
|
|
84
|
-
"qa",
|
|
85
|
-
"main",
|
|
86
|
-
]
|
|
87
|
-
q = [
|
|
88
|
-
inquirer.Text("vault_token", "Por favor digite o token do Vault"),
|
|
89
|
-
inquirer.List("env_list", "Selecione o ambiente", environment_names),
|
|
90
|
-
]
|
|
91
|
-
r = inquirer.prompt(q, theme=GreenPassion())
|
|
92
|
-
|
|
93
|
-
env_sel, credentials = load_environments(r["env_list"], r["vault_token"])
|
|
94
|
-
write_env_config(env_sel, credentials)
|
|
95
|
-
workers = asyncio.run(get_workers())
|
|
96
|
-
|
|
97
|
-
if workers == None:
|
|
98
|
-
console.print("\nNenhum worker encontrado.\n", style="yellow")
|
|
99
|
-
raise Exit(code=0)
|
|
100
|
-
else:
|
|
101
|
-
|
|
102
|
-
nomes_workers = [worker["nomRobo"] for worker in workers]
|
|
103
|
-
q2 = [
|
|
104
|
-
inquirer.List(
|
|
105
|
-
"worker_list", "Selecione um Worker", choices=nomes_workers
|
|
106
|
-
)
|
|
107
|
-
]
|
|
108
|
-
r2 = inquirer.prompt(q2, theme=GreenPassion())
|
|
109
|
-
worker_sel = next(
|
|
110
|
-
worker for worker in workers if worker["nomRobo"] == r2["worker_list"]
|
|
111
|
-
)
|
|
112
|
-
add_worker_config(worker_sel)
|
|
113
|
-
|
|
114
|
-
q3 = [
|
|
115
|
-
inquirer.Confirm(
|
|
116
|
-
"reg_config",
|
|
117
|
-
message="Adicionar configuração de inicialização aos registros do Windows?",
|
|
118
|
-
)
|
|
119
|
-
]
|
|
120
|
-
r3 = inquirer.prompt(q3, theme=GreenPassion())
|
|
121
|
-
|
|
122
|
-
if r3["reg_config"]:
|
|
123
|
-
add_start_on_boot_to_registry()
|
|
124
|
-
|
|
125
|
-
q4 = [
|
|
126
|
-
inquirer.Confirm(
|
|
127
|
-
"assets_config",
|
|
128
|
-
message="Atualizar a pasta assets?",
|
|
129
|
-
)
|
|
130
|
-
]
|
|
131
|
-
r4 = inquirer.prompt(q4, theme=GreenPassion())
|
|
132
|
-
|
|
133
|
-
if r4["assets_config"]:
|
|
134
|
-
update_assets_v2()
|
|
135
|
-
|
|
136
|
-
q5 = [
|
|
137
|
-
inquirer.Confirm(
|
|
138
|
-
"worker_bat", message="Criar o arquivo worker-startup.bat?"
|
|
139
|
-
)
|
|
140
|
-
]
|
|
141
|
-
r5 = inquirer.prompt(q5, theme=GreenPassion())
|
|
142
|
-
|
|
143
|
-
if r5["worker_bat"]:
|
|
144
|
-
create_worker_bat()
|
|
145
|
-
|
|
146
|
-
q6 = [
|
|
147
|
-
inquirer.Confirm(
|
|
148
|
-
"tesseract_install", message="Iniciar a instalação do Tesseract?"
|
|
149
|
-
)
|
|
150
|
-
]
|
|
151
|
-
r6 = inquirer.prompt(q6, theme=GreenPassion())
|
|
152
|
-
|
|
153
|
-
if r6["tesseract_install"]:
|
|
154
|
-
asyncio.run(download_tesseract())
|
|
155
|
-
|
|
156
|
-
console.print(
|
|
157
|
-
"\nConfiguração finalizada com sucesso!\n", style="bold green"
|
|
158
|
-
)
|
|
159
|
-
|
|
160
|
-
raise Exit(code=0)
|
|
161
92
|
|
|
93
|
+
@app.command()
|
|
94
|
+
def configure():
|
|
95
|
+
"""Executa o processo interativo de configuração"""
|
|
96
|
+
console.clear()
|
|
97
|
+
environment_names = [
|
|
98
|
+
"local",
|
|
99
|
+
"qa",
|
|
100
|
+
"main",
|
|
101
|
+
]
|
|
102
|
+
q = [
|
|
103
|
+
inquirer.Text("vault_token", "Por favor digite o token do Vault"),
|
|
104
|
+
inquirer.List("env_list", "Selecione o ambiente", environment_names),
|
|
105
|
+
]
|
|
106
|
+
r = inquirer.prompt(q, theme=GreenPassion())
|
|
107
|
+
|
|
108
|
+
env_sel, credentials = load_environments(r["env_list"], r["vault_token"])
|
|
109
|
+
write_env_config(env_sel, credentials)
|
|
110
|
+
workers = asyncio.run(get_workers())
|
|
111
|
+
|
|
112
|
+
if workers is None:
|
|
113
|
+
console.print("\nNenhum worker encontrado.\n", style="yellow")
|
|
114
|
+
raise Exit(code=0)
|
|
162
115
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
116
|
+
nomes_workers = [worker["nomRobo"] for worker in workers]
|
|
117
|
+
q2 = [inquirer.List("worker_list", "Selecione um Worker", choices=nomes_workers)]
|
|
118
|
+
r2 = inquirer.prompt(q2, theme=GreenPassion())
|
|
119
|
+
worker_sel = next(
|
|
120
|
+
worker for worker in workers if worker["nomRobo"] == r2["worker_list"]
|
|
121
|
+
)
|
|
122
|
+
add_worker_config(worker_sel)
|
|
123
|
+
|
|
124
|
+
q3 = [
|
|
125
|
+
inquirer.Confirm(
|
|
126
|
+
"reg_config",
|
|
127
|
+
message="Adicionar configuração de inicialização aos registros do Windows?",
|
|
128
|
+
)
|
|
129
|
+
]
|
|
130
|
+
r3 = inquirer.prompt(q3, theme=GreenPassion())
|
|
131
|
+
if r3["reg_config"]:
|
|
132
|
+
add_start_on_boot_to_registry()
|
|
133
|
+
|
|
134
|
+
q4 = [
|
|
135
|
+
inquirer.Confirm(
|
|
136
|
+
"assets_config",
|
|
137
|
+
message="Atualizar a pasta assets?",
|
|
138
|
+
)
|
|
139
|
+
]
|
|
140
|
+
r4 = inquirer.prompt(q4, theme=GreenPassion())
|
|
141
|
+
if r4["assets_config"]:
|
|
142
|
+
update_assets_v2()
|
|
143
|
+
|
|
144
|
+
q5 = [inquirer.Confirm("worker_bat", message="Criar o arquivo worker-startup.bat?")]
|
|
145
|
+
r5 = inquirer.prompt(q5, theme=GreenPassion())
|
|
146
|
+
if r5["worker_bat"]:
|
|
147
|
+
create_worker_bat()
|
|
148
|
+
|
|
149
|
+
q6 = [
|
|
150
|
+
inquirer.Confirm(
|
|
151
|
+
"tesseract_install", message="Iniciar a instalação do Tesseract?"
|
|
152
|
+
)
|
|
153
|
+
]
|
|
154
|
+
r6 = inquirer.prompt(q6, theme=GreenPassion())
|
|
155
|
+
if r6["tesseract_install"]:
|
|
156
|
+
asyncio.run(download_tesseract())
|
|
157
|
+
|
|
158
|
+
console.print("\nConfiguração finalizada com sucesso!\n", style="bold green")
|
|
159
|
+
|
|
160
|
+
raise Exit(code=0)
|
|
172
161
|
|
|
173
162
|
|
|
174
163
|
def is_command_running(command):
|
|
175
164
|
"""
|
|
176
165
|
Verifica se um comando CLI está sendo executado em outro terminal.
|
|
177
|
-
|
|
178
|
-
:param command: O comando CLI a ser verificado (lista de strings).
|
|
179
|
-
:return: True se o comando estiver sendo executado, False caso contrário.
|
|
180
166
|
"""
|
|
181
167
|
command_str = " ".join(command)
|
|
182
168
|
rep = 0
|
|
@@ -186,19 +172,11 @@ def is_command_running(command):
|
|
|
186
172
|
if cmdline and isinstance(cmdline, list):
|
|
187
173
|
cmdline_str = " ".join(cmdline)
|
|
188
174
|
if command_str in cmdline_str:
|
|
189
|
-
print(cmdline_str)
|
|
190
175
|
rep += 1
|
|
191
|
-
|
|
192
176
|
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
|
|
193
177
|
continue
|
|
194
178
|
|
|
195
|
-
|
|
196
|
-
return True
|
|
197
|
-
else:
|
|
198
|
-
return False
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
from typer import Option
|
|
179
|
+
return rep > 1
|
|
202
180
|
|
|
203
181
|
|
|
204
182
|
@app.command()
|
|
@@ -214,19 +192,21 @@ def run(
|
|
|
214
192
|
help="Executa o download da pasta assets atualizada.",
|
|
215
193
|
),
|
|
216
194
|
):
|
|
195
|
+
"""Inicializa o worker"""
|
|
217
196
|
if assets:
|
|
218
197
|
update_assets_v2()
|
|
219
|
-
|
|
198
|
+
|
|
220
199
|
command = ["worker", "run"]
|
|
221
200
|
if not force and is_command_running(command):
|
|
222
201
|
console.print(
|
|
223
202
|
"\nO script já está em execução. Saindo...\n", style="bold yellow"
|
|
224
203
|
)
|
|
225
|
-
raise Exit(code=0)
|
|
226
|
-
|
|
227
|
-
|
|
204
|
+
raise Exit(code=0)
|
|
205
|
+
|
|
206
|
+
run_worker(stop_event)
|
|
228
207
|
|
|
229
208
|
|
|
230
209
|
@app.command()
|
|
231
210
|
def update():
|
|
211
|
+
"""Força verificação/atualização do worker"""
|
|
232
212
|
check_for_update(stop_event)
|