csc-cia-stne 0.1.19__tar.gz → 0.1.21__tar.gz

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 (51) hide show
  1. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/PKG-INFO +1 -1
  2. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/pyproject.toml +1 -1
  3. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/bc_sta.py +80 -72
  4. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne.egg-info/PKG-INFO +1 -1
  5. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/LICENCE +0 -0
  6. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/README.md +0 -0
  7. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/README_PYPI.md +0 -0
  8. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/setup.cfg +0 -0
  9. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/__init__.py +0 -0
  10. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/bc_correios.py +0 -0
  11. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/email.py +0 -0
  12. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/ftp.py +0 -0
  13. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/gcp_bigquery.py +0 -0
  14. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/gcp_bucket.py +0 -0
  15. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/google_drive.py +0 -0
  16. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/karavela.py +0 -0
  17. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/logger_json.py +0 -0
  18. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/logger_rich.py +0 -0
  19. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/provio.py +0 -0
  20. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/servicenow.py +0 -0
  21. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/slack.py +0 -0
  22. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/stne_admin.py +0 -0
  23. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/__init__.py +0 -0
  24. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/__init__.py +0 -0
  25. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_b64.py +0 -0
  26. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_converters.py +0 -0
  27. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_datetime.py +0 -0
  28. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_delete.py +0 -0
  29. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_get_secret.py +0 -0
  30. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_recriar_pastas.py +0 -0
  31. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_settings.py +0 -0
  32. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_titulo.py +0 -0
  33. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/functions/func_validate_json.py +0 -0
  34. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/GcpBigQueryValidator.py +0 -0
  35. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/GoogleDriveValidator.py +0 -0
  36. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/ServiceNowValidator.py +0 -0
  37. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/__init__.py +0 -0
  38. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/ftp.py +0 -0
  39. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/gcp_bucket.py +0 -0
  40. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/waccess.py +0 -0
  41. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/validations/web_validator.py +0 -0
  42. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/web_screen/__init__.py +0 -0
  43. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/web_screen/web_screen_abstract.py +0 -0
  44. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/web_screen/web_screen_botcity.py +0 -0
  45. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/utilitarios/web_screen/web_screen_selenium.py +0 -0
  46. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/wacess.py +0 -0
  47. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne/web.py +0 -0
  48. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne.egg-info/SOURCES.txt +0 -0
  49. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne.egg-info/dependency_links.txt +0 -0
  50. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne.egg-info/requires.txt +0 -0
  51. {csc_cia_stne-0.1.19 → csc_cia_stne-0.1.21}/src/csc_cia_stne.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csc_cia_stne
3
- Version: 0.1.19
3
+ Version: 0.1.21
4
4
  Summary: Biblioteca do time CSC-CIA utilizada no desenvolvimento de RPAs
5
5
  License: MIT
6
6
  Keywords: karavela,csc,cia,stone,rpa,botcity,stne
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "csc_cia_stne"
7
- version = "0.1.19"
7
+ version = "0.1.21"
8
8
  license = { text = "MIT" }
9
9
  description = "Biblioteca do time CSC-CIA utilizada no desenvolvimento de RPAs"
10
10
  keywords = ["karavela", "csc", "cia", "stone", "rpa", "botcity", "stne"]
@@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET
6
6
  from xml.dom.minidom import parseString
7
7
  from pydantic import BaseModel, ValidationError, field_validator, Field, HttpUrl
8
8
  from typing import Literal, Dict, Union, Optional, List
9
- from datetime import datetime
9
+ from datetime import datetime, timedelta
10
10
 
11
11
  log = logging.getLogger('__main__')
12
12
 
@@ -499,90 +499,99 @@ class BC_STA:
499
499
  #return f"Failed to create protocol. Status code: {response.status_code}, Reason: {response.reason}"
500
500
  return resposta
501
501
 
502
- def listar_arquivos(self, nivel: Literal['RES', 'BAS', 'COMPL'], inicio: str, fim: str = None,situacao: Optional[Literal['REC', 'A_REC']] = None, identificadorDocumento: Optional[str] = None, qtd: int = 100, tipo_arquivo:list=None):
503
- """Lista os arquivos do STA com os parâmetros informados.
504
-
505
- Args:
506
- nivel (Literal['RES', 'BAS', 'COMPL']): nivel de detalhamento da consulta
507
- inicio (str): data de inicio, no padrao 'AAAA-MM-DDTHH:MM:SS'
508
- fim (str, optional): data de fim da consulta, no padrao 'AAAA-MM-DDTHH:MM:SS'
509
- situacao (Optional[Literal['REC', 'A_REC']], optional): Arquivos recebidos ou ainda não recebidos. Default=None (Todos).
510
- identificadorDocumento (Optional[str], optional): Identificador documento. Default=None (Todos).
511
- qtd (int, optional): Quantidade de arquivos na resposta. Default=100 (máximo=100).
512
- tipo_arquivo (list, optional): Tipo de arquivo para fazer download. Default=None (Todos). Opções: ['ACCS002', 'ACCS003', 'AJUD301', 'AJUD302', 'AJUD303', 'AJUD304', 'AJUD305', 'AJUD308', 'AJUD309', 'AJUD310', 'AJUD331', 'AMES102', 'AMTF102', 'ASVR9810', 'ATXB001'].
513
-
514
- Returns:
515
- list: Lista de arquivos do STA
516
- """
502
+ def listar_arquivos(self,
503
+ nivel: Literal['RES', 'BAS', 'COMPL'],
504
+ inicio: str,
505
+ fim: str = None,
506
+ situacao: Optional[Literal['REC', 'A_REC']] = None,
507
+ identificadorDocumento: Optional[str] = None,
508
+ qtd: int = 100,
509
+ tipo_arquivo: list = None):
517
510
  resultados = []
518
- ultima_data = inicio
519
511
 
520
- while True:
521
- params = ListarArquivosParams(nivel=nivel, inicio=ultima_data, fim=fim, situacao=situacao, identificadorDocumento=identificadorDocumento, qtd=qtd, tipo_arquivo=tipo_arquivo)
522
-
523
- url = f"{self.base_url}/arquivos?tipoConsulta=AVANC&nivelDetalhe={params.nivel}"
524
- url += f"&dataHoraInicio={params.inicio}&situacaoTransmissao={params.situacao}" if params.situacao else ""
525
- url += f"&identificadorDocumento={params.identificadorDocumento}" if params.identificadorDocumento else ""
526
- url += f"&dataHoraFim={params.fim}" if params.fim else ""
527
- url += f"&qtdMaxResultados={params.qtd}"
528
-
529
- response = requests.get(
530
- url,
531
- headers=self.headers,
532
- auth=self.auth,
533
- timeout=60,
534
- )
512
+ try:
513
+ # Parse seguro para datetime (assume formato ISO 'AAAA-MM-DDTHH:MM:SS')
514
+ dt_inicio = datetime.fromisoformat(inicio)
515
+ dt_fim = datetime.fromisoformat(fim) if fim else None
516
+ ultima_dt = dt_inicio
517
+
518
+ while True:
519
+ # Se já passamos do fim, encerra antes de chamar a API
520
+ if dt_fim and ultima_dt >= dt_fim:
521
+ break
522
+
523
+ # Monta a URL usando a data atual do cursor
524
+ _inicio_str = ultima_dt.strftime("%Y-%m-%dT%H:%M:%S")
525
+ url = f"{self.base_url}/arquivos?tipoConsulta=AVANC&nivelDetalhe={nivel}"
526
+ url += f"&dataHoraInicio={_inicio_str}"
527
+ if situacao:
528
+ url += f"&situacaoTransmissao={situacao}"
529
+ if identificadorDocumento:
530
+ url += f"&identificadorDocumento={identificadorDocumento}"
531
+ if dt_fim:
532
+ _fim_str = dt_fim.strftime("%Y-%m-%dT%H:%M:%S")
533
+ url += f"&dataHoraFim={_fim_str}"
534
+ url += f"&qtdMaxResultados={qtd}"
535
+
536
+ response = requests.get(
537
+ url, headers=self.headers, auth=self.auth, timeout=60,
538
+ )
539
+
540
+ if response.status_code != 200:
541
+ log.error(f"Erro ao listar arquivos: response code {response.status_code}\n{response.text}")
542
+ return False
535
543
 
536
- if response.status_code == 200:
537
-
538
544
  try:
539
-
540
545
  dados = xml_response_to_json(response.text)
546
+ if not dados:
547
+ break # sem mais resultados
541
548
 
542
- if not dados: # Verifica se a lista está vazia
543
-
544
- break # Sai do loop se não houver mais dados
545
-
546
- # Filtra apenas os arquivos do tipo 'AJUD308'
547
- if tipo_arquivo is not None:
548
-
549
- if isinstance(dados, list):
550
- dados_filtrados = [arquivo for arquivo in dados if arquivo.get("TipoArquivo") in tipo_arquivo]
551
- elif dados.get("TipoArquivo") in tipo_arquivo:
552
- dados_filtrados = [dados]
553
-
554
- resultados.extend(dados_filtrados)
555
-
556
- else:
557
-
558
- resultados.extend(dados)
549
+ # Normaliza dados para lista
550
+ itens = dados if isinstance(dados, list) else [dados]
559
551
 
560
- # Verifica se o campo 'DataHoraDisponibilizacao' existe no último registro
561
- if dados and isinstance(dados, list) and 'DataHoraDisponibilizacao' in dados[-1]:
552
+ # (opcional) filtra por tipo_arquivo
553
+ if tipo_arquivo is not None:
554
+ itens = [a for a in itens if a.get("TipoArquivo") in tipo_arquivo]
555
+
556
+ resultados.extend(itens)
557
+
558
+ # Atualiza o cursor a partir do último item retornado
559
+ # Busca o último com DataHoraDisponibilizacao
560
+ ultimo = None
561
+ for cand in reversed(itens):
562
+ if "DataHoraDisponibilizacao" in cand and cand["DataHoraDisponibilizacao"]:
563
+ ultimo = cand["DataHoraDisponibilizacao"]
564
+ break
565
+
566
+ if not ultimo:
567
+ # fallback: se o JSON bruto vier como dict/list diferente, tente no original
568
+ if isinstance(dados, list) and dados and "DataHoraDisponibilizacao" in dados[-1]:
569
+ ultimo = dados[-1]["DataHoraDisponibilizacao"]
570
+ elif isinstance(dados, dict) and "DataHoraDisponibilizacao" in dados:
571
+ ultimo = dados["DataHoraDisponibilizacao"]
572
+
573
+ if not ultimo:
574
+ log.error("Campo 'DataHoraDisponibilizacao' não encontrado ou estrutura inesperada.")
575
+ return False
562
576
 
563
- ultima_data = dados[-1]['DataHoraDisponibilizacao'] # Atualiza a data para a próxima requisição
577
+ # Cursor: último + 1s para evitar repetir o mesmo registro
578
+ proxima_dt = datetime.fromisoformat(ultimo) + timedelta(seconds=1)
564
579
 
565
- elif dados and isinstance(dados, dict) and 'DataHoraDisponibilizacao' in dados:
566
-
567
- ultima_data = dados['DataHoraDisponibilizacao'] # Atualiza a data para a próxima requisição
568
-
569
- else:
580
+ # Se a próxima dt já ultrapassa o fim, encerramos sem nova chamada
581
+ if dt_fim and proxima_dt > dt_fim:
582
+ break
570
583
 
571
- log.error("Campo 'DataHoraDisponibilizacao' não encontrado ou estrutura inesperada.")
572
- return False
584
+ ultima_dt = proxima_dt
573
585
 
574
586
  except ET.ParseError as e:
575
-
576
587
  log.error(f"Erro ao processar XML: {e}")
577
588
  return False
578
-
579
- else:
580
-
581
- log.error(f"Erro ao listar arquivos: response code {response.status_code}\n{response.text}")
582
- return False
583
-
584
- return resultados
585
-
589
+
590
+ return resultados
591
+ except Exception as e:
592
+ log.error(f"Erro em BC_STA:listar_arquivos: {e}")
593
+ return False
594
+
586
595
  def download_arquivo(self,protocolo:str,filename:str=None):
587
596
  """Faz o download de um arquivo de um protocolo especifico
588
597
 
@@ -631,7 +640,6 @@ class BC_STA:
631
640
 
632
641
  return {"success": False, "status_code": int(response.status_code), "content": response.text}
633
642
 
634
-
635
643
  def qs_gerar_xml_string_responder_nao_cliente(self,protocolo_inicial_ordem:str,numctrlccs:str,cnpj_cpf:str,numctrlenvio:str,numprocjud:str,identdemissor:str,identddestinatario:str,domsist:str,nuop:str,dtmovto:datetime,cnpjbaseentrespons:str):
636
644
 
637
645
  """Gera a string do arquivo XML de resposta para nao-cliente para ser enviado ao STA
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: csc_cia_stne
3
- Version: 0.1.19
3
+ Version: 0.1.21
4
4
  Summary: Biblioteca do time CSC-CIA utilizada no desenvolvimento de RPAs
5
5
  License: MIT
6
6
  Keywords: karavela,csc,cia,stone,rpa,botcity,stne
File without changes
File without changes
File without changes