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.
Files changed (36) hide show
  1. worker_automate_hub/api/client.py +186 -68
  2. worker_automate_hub/api/rpa_historico_service.py +1 -0
  3. worker_automate_hub/cli.py +91 -111
  4. worker_automate_hub/tasks/jobs/abertura_livros_fiscais.py +112 -229
  5. worker_automate_hub/tasks/jobs/descartes.py +91 -77
  6. worker_automate_hub/tasks/jobs/devolucao_produtos.py +1386 -0
  7. worker_automate_hub/tasks/jobs/entrada_de_notas_15.py +3 -46
  8. worker_automate_hub/tasks/jobs/entrada_de_notas_22.py +833 -0
  9. worker_automate_hub/tasks/jobs/entrada_de_notas_36.py +29 -9
  10. worker_automate_hub/tasks/jobs/entrada_de_notas_37.py +619 -0
  11. worker_automate_hub/tasks/jobs/entrada_de_notas_39.py +1 -1
  12. worker_automate_hub/tasks/jobs/entrada_de_notas_9.py +63 -16
  13. worker_automate_hub/tasks/jobs/extracao_dados_nielsen.py +504 -0
  14. worker_automate_hub/tasks/jobs/extracao_saldo_estoque.py +242 -108
  15. worker_automate_hub/tasks/jobs/extracao_saldo_estoque_fiscal.py +688 -0
  16. worker_automate_hub/tasks/jobs/fidc_gerar_nosso_numero.py +2 -2
  17. worker_automate_hub/tasks/jobs/fidc_remessa_cobranca_cnab240.py +25 -16
  18. worker_automate_hub/tasks/jobs/geracao_balancetes_filial.py +330 -0
  19. worker_automate_hub/tasks/jobs/importacao_extratos.py +538 -0
  20. worker_automate_hub/tasks/jobs/importacao_extratos_748.py +800 -0
  21. worker_automate_hub/tasks/jobs/inclusao_pedidos_ipiranga.py +222 -0
  22. worker_automate_hub/tasks/jobs/inclusao_pedidos_raizen.py +174 -0
  23. worker_automate_hub/tasks/jobs/inclusao_pedidos_vibra.py +327 -0
  24. worker_automate_hub/tasks/jobs/notas_faturamento_sap.py +438 -157
  25. worker_automate_hub/tasks/jobs/opex_capex.py +540 -326
  26. worker_automate_hub/tasks/jobs/sped_fiscal.py +8 -8
  27. worker_automate_hub/tasks/jobs/transferencias.py +52 -41
  28. worker_automate_hub/tasks/task_definitions.py +46 -1
  29. worker_automate_hub/tasks/task_executor.py +11 -0
  30. worker_automate_hub/utils/util.py +252 -215
  31. worker_automate_hub/utils/utils_nfe_entrada.py +1 -1
  32. worker_automate_hub/worker.py +1 -9
  33. {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/METADATA +4 -2
  34. {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/RECORD +36 -25
  35. {worker_automate_hub-0.5.749.dist-info → worker_automate_hub-0.5.912.dist-info}/WHEEL +1 -1
  36. {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
- try:
148
- if not uuidProcesso:
149
- raise ValueError("O uuid do processo deve ser informado")
150
-
151
- headers_basic = {"Authorization": f"Basic {env_config["API_AUTHORIZATION"]}"}
152
- timeout = aiohttp.ClientTimeout(total=600)
153
-
154
- async with aiohttp.ClientSession(
155
- connector=aiohttp.TCPConnector(verify_ssl=True), timeout=timeout
156
- ) as session:
157
- async with session.get(
158
- f"{env_config["API_BASE_URL"]}/processo/{uuidProcesso}",
159
- headers=headers_basic,
160
- ) as response:
161
- if response.status != 200:
162
- error_content = await response.text()
163
- raise Exception(f"Erro ao obter o processo: {error_content}")
164
- res = await response.json()
165
- if type(res["campos"]) == str and res["campos"] == "{}":
166
- res["campos"] = {}
167
- return RpaProcesso(**res)
168
-
169
- except ValueError as e:
170
- logger.error(f"Erro ao obter o processo: {str(e)}")
171
- console.print(
172
- f"{e}\n",
173
- style="bold red",
174
- )
175
- except Exception as e:
176
- logger.error(f"Erro ao obter o processo: {str(e)}")
177
- console.print(
178
- f"{e}\n",
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
- return None
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
- try:
236
- headers_basic = {"Authorization": f"Basic {env_config["API_AUTHORIZATION"]}"}
237
- timeout = aiohttp.ClientTimeout(total=600)
238
-
239
- async with aiohttp.ClientSession(
240
- connector=aiohttp.TCPConnector(verify_ssl=True), timeout=timeout
241
- ) as session:
242
- async with session.get(
243
- f"{env_config["API_BASE_URL"]}/configuracao/api/{name}",
244
- headers=headers_basic,
245
- ) as response:
246
- if response.status != 200:
247
- raise Exception(f"Erro ao obter a configuração: {response.content}")
248
- data = await response.json()
249
- return RpaConfiguracao(**data)
250
-
251
- except Exception as e:
252
- err_msg = f"Erro ao obter a configuração: {e}"
253
- logger.error(err_msg)
254
- console.print(
255
- f"{err_msg}\n",
256
- style="bold red",
257
- )
258
- return None
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
- filial_nota: Optional[int] = None
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
- filial_nota (int, opcional): Filial da NF (obrigatória se numero_nota for informado).
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 filial_nota is None:
564
- raise ValueError("Para buscar por número da nota é obrigatório informar também 'serie_nota' e 'filial_nota'.")
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["empresaCodigo"] = filial_nota
656
+ params["fornecedorCnpj"] = fornecedor
568
657
 
569
658
  else:
570
- raise ValueError("É necessário informar 'chave' ou ('numero_nota' + 'serie_nota' + 'filial_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"Erro ao comunicar com endpoint do Simplifica: {await response.text()}"
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"Erro ao comunicar com endpoint do Simplifica: {e}")
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}
@@ -53,6 +53,7 @@ async def create_store_historico(
53
53
  or task.configEntrada.get("chaveCte")
54
54
  or task.configEntrada.get("empresa")
55
55
  or task.configEntrada.get("uuidSimplifica")
56
+ or task.configEntrada.get("identificador")
56
57
  or ""
57
58
  )
58
59
 
@@ -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[/][/] --configure
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
- def function_help(flag: bool):
70
- if flag:
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
- @app.callback(invoke_without_command=True)
164
- def main(
165
- ctx: Context,
166
- version: bool = Option(False, callback=function_help, is_flag=True),
167
- configure: bool = Option(False, callback=function_configure, is_flag=True),
168
- ):
169
- if ctx.invoked_subcommand:
170
- return
171
- console.print(HELP_MESSAGE)
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
- if rep > 1:
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
- else:
227
- run_worker(stop_event)
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)