csc-cia-stne 0.0.43__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.
@@ -0,0 +1,89 @@
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from .logger_json import get_logger as get_logger_json
4
+ from .logger_rich import get_logger as get_logger_rich
5
+ from .karavela import Karavela
6
+ from .servicenow import ServiceNow
7
+ from .stne_admin import StoneAdmin
8
+ from .bc_sta import BC_STA
9
+ from .bc_correios import BC_Correios
10
+ from .gcp_bigquery import BigQuery
11
+ from .email import Email
12
+ from .provio import Provio
13
+ from .google_drive import GoogleDrive
14
+ from .slack import Slack
15
+
16
+ # Define os itens disponíveis para importação
17
+ __all__ = [
18
+ "Karavela",
19
+ "BigQuery",
20
+ "BC_Correios",
21
+ "BC_STA",
22
+ "StoneAdmin",
23
+ "ServiceNow",
24
+ "Util",
25
+ "logger",
26
+ "Provio",
27
+ "Email",
28
+ "GoogleDrive",
29
+ "Slack"
30
+ ]
31
+
32
+ _diretorio_inicial = os.getcwd()
33
+ _caminho_env = os.path.join(_diretorio_inicial, ".env")
34
+
35
+ # Carrega .env
36
+ load_dotenv(_caminho_env)
37
+ logger = None # Inicializa como None
38
+
39
+ def _running_in_container():
40
+ """
41
+ Verifica se o código está sendo executado dentro de um container.
42
+ Retorna True se estiver sendo executado dentro de um container e False caso contrário.
43
+ """
44
+
45
+ if os.environ.get("KUBERNETES_SERVICE_HOST") or os.path.exists("/.dockerenv"):
46
+
47
+ return True
48
+
49
+ try:
50
+
51
+ with open("/proc/1/cgroup", "rt") as file:
52
+
53
+ for line in file:
54
+
55
+ if "docker" in line or "kubepods" in line:
56
+
57
+ return True
58
+
59
+ except FileNotFoundError as e:
60
+
61
+ return False
62
+
63
+ return False
64
+
65
+ def logger():
66
+ """
67
+ Retorna um objeto logger com base no ambiente de execução.
68
+ Se a variável de ambiente 'ambiente_de_execucao' estiver definida e for igual a "karavela",
69
+ retorna um logger formatado em JSON usando a função get_logger_json().
70
+ Caso contrário, se estiver executando em um container, retorna um logger formatado em JSON
71
+ usando a função get_logger_json().
72
+ Caso contrário, retorna um logger formatado em texto usando a função get_logger_rich().
73
+ Exemplo de uso:
74
+ logger_obj = logger()
75
+ logger_obj.info("Mensagem de informação")
76
+ logger_obj.error("Mensagem de erro")
77
+ """
78
+
79
+ if os.getenv('ambiente_de_execucao') is not None and os.getenv('ambiente_de_execucao') == "karavela":
80
+
81
+ return get_logger_json()
82
+
83
+ elif _running_in_container():
84
+
85
+ return get_logger_json()
86
+
87
+ else:
88
+
89
+ return get_logger_rich()
@@ -0,0 +1,529 @@
1
+ import json
2
+ import logging
3
+ from zeep import Client
4
+ from zeep.transports import Transport
5
+ from requests import Session
6
+ from requests.auth import HTTPBasicAuth
7
+ from datetime import timedelta, datetime, time
8
+ from typing import List, Tuple, Union, Optional
9
+ from pydantic import BaseModel
10
+
11
+ class PastasAutorizadas(BaseModel):
12
+ MensagemErro: Optional[str] = None
13
+ OcorreuErro: bool
14
+ PastasAutorizadas: Optional[list] = None
15
+ QuantidadePastasAutorizadas: int
16
+
17
+ class ItemListaCorreio(BaseModel):
18
+
19
+ Assunto: str
20
+ Data:datetime
21
+ UnidadeDestinataria: str
22
+ DependenciaDestinataria: Optional[str] = None
23
+ UnidadeRemetente: str
24
+ DependenciaRemetente: Optional[str] = None
25
+ Grupo: Optional[str] = None
26
+ Status: str
27
+ TipoCorreio: str
28
+ NumeroCorreio: int
29
+ Pasta: dict
30
+ Setor: Optional[str] = None
31
+ Transicao: int
32
+ Versao: int
33
+
34
+ class ItemMsgCorreio(ItemListaCorreio):
35
+
36
+ OcorreuErro: bool
37
+ MensagemErro: Optional[str] = None
38
+ #NumeroCorreio = None
39
+ #Transicao = None
40
+ #Versao = None
41
+ #Assunto = None
42
+ Ementa: Optional[list] = None
43
+ Conteudo: str
44
+ #TipoCorreio = None
45
+ De: str
46
+ Para: str
47
+ EnviadaPor: str
48
+ EnviadaEm: datetime
49
+ RecebidaPor: str
50
+ RecebidaEm: datetime
51
+ Despachos: Optional[list] = None
52
+ Anexos: Optional[list] = None
53
+
54
+ class AnexoDict(BaseModel):
55
+
56
+ IdAnexo: int
57
+ NomeAnexo: str
58
+ Conteudo: str
59
+
60
+ class BC_Correios:
61
+
62
+ def __init__(self, wsdl_url:str, usuario:str, senha:str, correios_por_pasta_pasta_unidade_nome:str='40797', correios_por_pasta_pasta_unidade_ativa:bool=True, correios_por_pasta_pasta_unidade_tipo:str='InstituicaoFinanceira', correios_por_pasta_pasta_tipo:str='CaixaEntrada',correios_por_pasta_apenas_mensagens:bool=True, correios_por_pasta_pesquisar_em_todas_as_pastas:bool=True):
63
+ """
64
+ Inicializa a classe BC_Correios.
65
+ Parâmetros:
66
+ - wsdl_url (str): URL do WSDL do serviço dos Correios.
67
+ - usuario (str): Nome de usuário para autenticação no serviço dos Correios.
68
+ - senha (str): Senha para autenticação no serviço dos Correios.
69
+ - correios_por_pasta_pasta_unidade_nome (str, opcional): Nome da unidade da pasta dos Correios. Valor padrão é '40797'.
70
+ - correios_por_pasta_pasta_unidade_ativa (bool, opcional): Indica se a unidade da pasta dos Correios está ativa. Valor padrão é True.
71
+ - correios_por_pasta_pasta_unidade_tipo (str, opcional): Tipo da unidade da pasta dos Correios. Valor padrão é 'InstituicaoFinanceira'.
72
+ - correios_por_pasta_pasta_tipo (str, opcional): Tipo da pasta dos Correios. Valor padrão é 'CaixaEntrada'.
73
+ - correios_por_pasta_apenas_mensagens (bool, opcional): Indica se deve retornar apenas mensagens da pasta dos Correios. Valor padrão é True.
74
+ - correios_por_pasta_pesquisar_em_todas_as_pastas (bool, opcional): Indica se deve pesquisar em todas as pastas dos Correios. Valor padrão é True.
75
+ """
76
+
77
+ try:
78
+
79
+ session = Session()
80
+ session.auth = HTTPBasicAuth(usuario,senha)
81
+
82
+ transport = Transport(session=session,timeout=120,operation_timeout=120)
83
+
84
+ self.client = Client(wsdl_url, transport=transport)
85
+ self.is_connected = True
86
+ self.error = None
87
+ self.CorreiosPorPastaPastaUnidadeNome = correios_por_pasta_pasta_unidade_nome
88
+ self.CorreiosPorPastaPastaUnidadeAtiva = correios_por_pasta_pasta_unidade_ativa
89
+ self.CorreiosPorPastaPastaUnidadeTipo = correios_por_pasta_pasta_unidade_tipo
90
+ self.CorreiosPorPastaPastaTipo = correios_por_pasta_pasta_tipo
91
+ self.CorreiosPorPastaApenasMensagens = correios_por_pasta_apenas_mensagens
92
+ self.CorreiosPorPastaPesquisarEmTodasAsPastas = correios_por_pasta_pesquisar_em_todas_as_pastas
93
+
94
+ except Exception as e:
95
+
96
+ self.is_connected = False
97
+ self.error = e
98
+
99
+ def consultar_pastas_autorizadas(self)->Tuple[bool, Union[PastasAutorizadas, Exception]]:
100
+ """
101
+ Retorna as pastas de correio e os setores que o usuário tem permissão de acessar.
102
+ """
103
+
104
+ try:
105
+
106
+ response = self.client.service.ConsultarPastasAutorizadas()
107
+
108
+ if response.OcorreuErro:
109
+
110
+ raise Exception(response.MensagemErro)
111
+
112
+ pastas = PastasAutorizadas(MensagemErro=response.MensagemErro, OcorreuErro=response.OcorreuErro, QuantidadePastasAutorizadas=response.QuantidadePastasAutorizadas,PastasAutorizadas=response.PastasAutorizadas.PastaAutorizadaWSDTO)
113
+
114
+ return True, pastas
115
+
116
+ except Exception as e:
117
+
118
+ return False, e
119
+
120
+ def consultar_correios_por_pasta(self,ultimos_x_dias:int=None,data_inicial:datetime=None,data_final:datetime=None)->Tuple[bool, Union[List['ItemListaCorreio'], Exception]]:
121
+
122
+ """
123
+ Retorna uma lista com os cabeçalhos dos correios contidos em uma pasta.
124
+
125
+ A consulta pode ser realizada de 2 maneiras:
126
+ 1. Especificando um intervalo de dias relativos ao dia atual (com `ultimos_x_dias`).
127
+ 2. Informando explicitamente uma `data_inicial` E `data_final`.
128
+
129
+ Args:
130
+ ultimos_x_dias (int, opcional): O número de dias a contar para trás a partir da data atual. Se especificado, ignorará `data_inicial` e `data_final`.
131
+ data_inicial (datetime, opcional): Data inicial do intervalo para filtrar os correios.
132
+ data_final (datetime, opcional): Data final do intervalo para filtrar os correios.
133
+
134
+ Returns:
135
+ tuple: Um par contendo:
136
+ - bool: Indica se a operação foi bem-sucedida (True) ou falhou (False).
137
+ - Union[list[ItemListaCorreio], Exception]: Retorna uma lista de objetos `ItemListaCorreio` contendo os detalhes dos correios encontrados, ou uma exceção em caso de erro.
138
+ """
139
+
140
+ try:
141
+
142
+ if ultimos_x_dias is not None and isinstance(ultimos_x_dias,int):
143
+
144
+ agora = datetime.now()
145
+
146
+ # Pegando mensagens antigas, ja lidas, no desenvolvimento, para nao atrapalhar o time com as mensagens nao lidas atuais
147
+ #logger.warning("VERIFICAR DATA DO 'AGORA'!")
148
+ #agora = datetime.now() - timedelta(days=150)
149
+
150
+ dt_inicial_iso_format = agora - timedelta(days=ultimos_x_dias)
151
+ dt_inicial_iso_format = datetime.combine(dt_inicial_iso_format.date(), time.min)
152
+ dt_inicial_iso_format = dt_inicial_iso_format.isoformat()
153
+
154
+ dt_final_iso_format = datetime.combine(agora.date(), time.max)
155
+ dt_final_iso_format = agora.isoformat()
156
+
157
+ elif data_inicial is isinstance(data_inicial,datetime) and data_final is isinstance(data_final,datetime):
158
+
159
+ dt_inicial_iso_format = data_inicial.isoformat()
160
+ dt_final_iso_format = data_final.isoformat()
161
+
162
+ else:
163
+
164
+ raise ValueError("ultimos_x_dias se for informado, precisa ser um numero inteiro. Ou entao se for informado data_inicial E data_final, esses 2 parametros precisam ser datetime")
165
+
166
+ correios_filtrados = []
167
+ correios_repetidos = []
168
+ pagina_atual = 1
169
+
170
+ def objeto_ja_existe_na_lista(novo_item, lista_de_correios):
171
+
172
+ for item in lista_de_correios:
173
+
174
+ if (str(item.NumeroCorreio) == str(novo_item.NumeroCorreio)):
175
+
176
+ return True
177
+
178
+ return False
179
+
180
+ proxima_centena = 100
181
+ while True:
182
+
183
+ correios = None
184
+ params = {
185
+ 'Pasta': {
186
+ 'Unidade': {
187
+ 'Nome': self.CorreiosPorPastaPastaUnidadeNome,
188
+ 'Ativa': self.CorreiosPorPastaPastaUnidadeAtiva,
189
+ 'Tipo': self.CorreiosPorPastaPastaUnidadeTipo
190
+ },
191
+ 'Tipo': self.CorreiosPorPastaPastaTipo
192
+ },
193
+ 'ApenasMensagens': self.CorreiosPorPastaApenasMensagens,
194
+ 'PesquisarEmTodasAsPastas': self.CorreiosPorPastaPesquisarEmTodasAsPastas,
195
+ 'Pagina': pagina_atual,
196
+ 'DataInicial': dt_inicial_iso_format,
197
+ 'DataFinal': dt_final_iso_format,
198
+ }
199
+
200
+ response = self.client.service.ConsultarCorreiosPorPasta(params)
201
+
202
+ if response.OcorreuErro:
203
+ raise Exception(f"Erro ao consultar correios: {response.MensagemErro}")
204
+
205
+ # Verifica a quantidade total de correios na primeira iteração
206
+ try:
207
+
208
+ # Acessa a lista de correios diretamente
209
+ correios = response.Correios.ResumoCorreioWSDTO
210
+
211
+ if not correios:
212
+
213
+ # Se não houver mais itens, paramos a busca
214
+ break
215
+ except:
216
+
217
+ # Fim da listagem de correios
218
+ break
219
+
220
+ for correio in correios:
221
+
222
+ item_de_lista_de_correios = ItemListaCorreio(
223
+ Assunto=correio.Assunto,
224
+ Data=correio.Data,
225
+ UnidadeDestinataria=correio.UnidadeDestinataria,
226
+ DependenciaDestinataria=correio.DependenciaDestinataria,
227
+ UnidadeRemetente=correio.UnidadeRemetente,
228
+ DependenciaRemetente=correio.DependenciaRemetente,
229
+ Grupo=correio.Grupo,
230
+ Status=correio.Status,
231
+ TipoCorreio=correio.TipoCorreio,
232
+ NumeroCorreio=correio.NumeroCorreio,
233
+ Pasta={
234
+ 'Unidade': correio.Pasta.Unidade,
235
+ 'Dependencia': correio.Pasta.Dependencia,
236
+ 'Setor': correio.Pasta.Setor,
237
+ 'Tipo': correio.Pasta.Tipo
238
+ },
239
+ Setor=correio.Setor,
240
+ Transicao=correio.Transicao,
241
+ Versao=correio.Versao
242
+ )
243
+ if objeto_ja_existe_na_lista(novo_item=item_de_lista_de_correios,lista_de_correios=correios_filtrados) == False:
244
+
245
+ correios_filtrados.append(item_de_lista_de_correios)
246
+ else:
247
+ correios_repetidos.append(item_de_lista_de_correios)
248
+
249
+ if len(correios_filtrados) >= proxima_centena:
250
+
251
+ logging.info(f"Página #{pagina_atual}: {len(correios_filtrados)} correios armazenados no total")
252
+ proxima_centena = proxima_centena + 100
253
+
254
+ # Avança para a próxima página
255
+ pagina_atual += 1
256
+
257
+ return True, correios_filtrados
258
+
259
+ except Exception as e:
260
+
261
+ return False, e
262
+
263
+ def ler_correio(self, numero:int,data_rebimento:datetime,tipo:str,transicao:int,versao:int,pasta:str)-> Tuple[bool, Union[ItemMsgCorreio, Exception]]:
264
+ """
265
+ Retorna o conteúdo de um correio.
266
+
267
+ Args:
268
+ correio (ItemListaCorreio): objeto da classe ItemListaCorreio (item da listagem de mensagens)
269
+
270
+ Returns:
271
+ tuple: Um par contendo:
272
+ - bool: Indica se a operação foi bem-sucedida (True) ou falhou (False).
273
+ - Union[ItemMsgCorreio, Exception]: Retorna um objeto da classe ItemMsgCorreio contendo os detalhes do correio lido, ou uma exceção em caso de erro.
274
+ """
275
+
276
+ try:
277
+
278
+ # Substituir aspas simples por aspas duplas
279
+ pasta = pasta.replace("'", '"').replace("None", "null")
280
+ pasta = json.loads(pasta)
281
+ #params = {
282
+ # 'Correio': {
283
+ # 'NumeroCorreio': correio.NumeroCorreio,
284
+ # 'Data': correio.Data.isoformat(),
285
+ # 'TipoCorreio': correio.TipoCorreio,
286
+ # 'Transicao': correio.Transicao,
287
+ # 'Versao': correio.Versao,
288
+ # 'Pasta': correio.Pasta
289
+ # }
290
+ #}
291
+
292
+ params = {
293
+ 'Correio': {
294
+ 'NumeroCorreio': numero,
295
+ 'Data': data_rebimento.isoformat(),
296
+ 'TipoCorreio': tipo,
297
+ 'Transicao': transicao,
298
+ 'Versao': versao,
299
+ 'Pasta': {
300
+ 'Unidade': pasta["Unidade"],
301
+ 'Dependencia': pasta["Dependencia"],
302
+ 'Setor': pasta["Setor"],
303
+ 'Tipo': pasta["Tipo"],
304
+ }
305
+ }
306
+ }
307
+
308
+ response = self.client.service.LerCorreio(params)
309
+
310
+ #novo start
311
+
312
+ #print("antes")
313
+ #print("response type:",type(response))
314
+ #print("response:")
315
+ #print(response)
316
+ if response.OcorreuErro:
317
+ raise Exception(f"Erro ao detalhar correio: {response.MensagemErro}")
318
+
319
+ #msg_detail = ItemMsgCorreio()
320
+ #msg_detail.OcorreuErro = response.OcorreuErro
321
+ #msg_detail.MensagemErro = response.MensagemErro
322
+ ##msg_detail.NumeroCorreio = response.DetalheCorreio.NumeroCorreio
323
+ ##msg_detail.Transicao = response.DetalheCorreio.Transicao
324
+ ##msg_detail.Versao = response.DetalheCorreio.Versao
325
+ ##msg_detail.Assunto = response.DetalheCorreio.Assunto
326
+ #msg_detail.Ementa = response.DetalheCorreio.Ementa
327
+ #msg_detail.Conteudo = response.DetalheCorreio.Conteudo
328
+ ##msg_detail.TipoCorreio = response.DetalheCorreio.TipoCorreio
329
+ #msg_detail.De = response.DetalheCorreio.De
330
+ #msg_detail.Para = response.DetalheCorreio.Para
331
+ #msg_detail.EnviadaPor = response.DetalheCorreio.EnviadaPor
332
+ #msg_detail.EnviadaEm = response.DetalheCorreio.EnviadaEm
333
+ #msg_detail.RecebidaPor = response.DetalheCorreio.RecebidaPor
334
+ #msg_detail.RecebidaEm = response.DetalheCorreio.RecebidaEm
335
+ #msg_detail.Despachos = response.DetalheCorreio.Despachos
336
+ #if response.DetalheCorreio.Anexos:
337
+ # msg_detail.Anexos = response.DetalheCorreio.Anexos.AnexoWSDTO
338
+
339
+
340
+ #msg_detail = ItemMsgCorreio(
341
+ # **correio.model_dump(),
342
+ # OcorreuErro = response.OcorreuErro,
343
+ # MensagemErro = response.MensagemErro,
344
+ # #msg_detail.NumeroCorreio = response.DetalheCorreio.NumeroCorreio
345
+ # #msg_detail.Transicao = response.DetalheCorreio.Transicao
346
+ # #msg_detail.Versao = response.DetalheCorreio.Versao
347
+ # #msg_detail.Assunto = response.DetalheCorreio.Assunto
348
+ # Ementa = response.DetalheCorreio.Ementa,
349
+ # Conteudo = response.DetalheCorreio.Conteudo,
350
+ # #msg_detail.TipoCorreio = response.DetalheCorreio.TipoCorreio
351
+ # De = response.DetalheCorreio.De,
352
+ # Para = response.DetalheCorreio.Para,
353
+ # EnviadaPor = response.DetalheCorreio.EnviadaPor,
354
+ # EnviadaEm = response.DetalheCorreio.EnviadaEm,
355
+ # RecebidaPor = response.DetalheCorreio.RecebidaPor,
356
+ # RecebidaEm = response.DetalheCorreio.RecebidaEm,
357
+ # Despachos = response.DetalheCorreio.Despachos,
358
+ # Anexos = response.DetalheCorreio.Anexos.AnexoWSDTO
359
+ #)
360
+
361
+
362
+ msg_detail = {
363
+ "OcorreuErro": response.OcorreuErro,
364
+ "MensagemErro": response.MensagemErro,
365
+ #msg_detail.NumeroCorreio = response.DetalheCorreio.NumeroCorreio
366
+ #msg_detail.Transicao = response.DetalheCorreio.Transicao
367
+ #msg_detail.Versao = response.DetalheCorreio.Versao
368
+ #msg_detail.Assunto = response.DetalheCorreio.Assunto
369
+ "Ementa": response.DetalheCorreio.Ementa,
370
+ "Conteudo": response.DetalheCorreio.Conteudo,
371
+ #msg_detail.TipoCorreio = response.DetalheCorreio.TipoCorreio
372
+ "De": response.DetalheCorreio.De,
373
+ "Para": response.DetalheCorreio.Para,
374
+ "EnviadaPor": response.DetalheCorreio.EnviadaPor,
375
+ "EnviadaEm": response.DetalheCorreio.EnviadaEm,
376
+ "RecebidaPor": response.DetalheCorreio.RecebidaPor,
377
+ "RecebidaEm": response.DetalheCorreio.RecebidaEm,
378
+ "Despachos": response.DetalheCorreio.Despachos,
379
+ "Anexos": response.DetalheCorreio.Anexos.AnexoWSDTO
380
+ }
381
+
382
+
383
+ #print("depois")
384
+ #print("response novo type:",type(msg_detail))
385
+ #print("response novo:")
386
+ #print(msg_detail)
387
+ #print(msg_detail.Anexos)
388
+
389
+
390
+ """
391
+ xx = {
392
+ 'MensagemErro': None,
393
+ 'OcorreuErro': False,
394
+ 'DetalheCorreio': {
395
+ 'NumeroCorreio': 124311198,
396
+ 'Transicao': 46142046,
397
+ 'Versao': 670,
398
+ 'Assunto': 'SOLJUD 2024087211',
399
+ 'Ementa': None,
400
+ 'Conteudo': '\n<pre>\nOfício 026707/2024-BCB/Deati/Coadi-1\nPE 262353/e-BC 2024211930 Brasília, 23 de setembro de 2024.\nJUD/EXT - 2024/087211E\n\nA todas as instituições financeiras.\n\nAssunto: Ofício S\\N, de 13 de setembro de 2024\nProcesso: 5094191-48.2024.8.09.0142\n\nPrezados Senhores,\n\nAtendendo à requisição do(a) Juíz de Direito MARLI PIMENTA NAVES, do(a) Juizado Especial Cível, encaminhamos, em anexo, para exame e adoção das\nprovidências julgadas cabíveis, a determinação judicial exarada no ofício em epígrafe.\n\n\n2. A propósito, esclarecemos que eventuais dúvidas a respeito da ordem, inclusive com relação a número de CPF/CNPJ, somente serão dirimidas\njunto ao Juízo demandante, ou ao órgão por ele designado, para onde devem ser encaminhadas as correspondências alusivas ao assunto,\nmencionando-se os números do ofício e do processo.\n\n\n3. Finalmente, alertamos que a inobservância à norma do sigilo bancário contido na Lei Complementar 105, de 10 de janeiro de 2001, sujeitará os\nresponsáveis às sanções previstas no artigo 10 da mencionada Lei, cabendo ainda à instituição zelar por manter a privacidade das informações\nrelativas a clientes (artigo 5º, item X, da CF/88).\n\n\nAtenciosamente,\n\nDepartamento de Atendimento Institucional – DEATI\nGerência de Relacionamento Institucional – GERIN\n\n\nGILDO TEREZA DOS REIS\nTECNICO\n\nMAURO MAGNO MACHADO JUNIOR \nTECNICO \n\nDocumento transmitido por correio eletrônico, via BC Correio, dispensado de assinatura.\n</pre>\n',
401
+ 'TipoCorreio': 'MENSAGEM',
402
+ 'De': 'DEATI',
403
+ 'Para': '40797 (Transmissão para grupo geral F1)',
404
+ 'EnviadaPor': 'DEATI.GILDO',
405
+ 'EnviadaEm': datetime.datetime(2024, 9, 23, 10, 40, 19),
406
+ 'RecebidaPor': '407970001.PALCANTARA',
407
+ 'RecebidaEm': datetime.datetime(2024, 9, 25, 14, 45, 51),
408
+ 'Despachos': None,
409
+ 'Anexos': {
410
+ 'AnexoWSDTO': [
411
+ {
412
+ 'IdAnexo': 538648,
413
+ 'NomeAnexo': '-2024-171630-211930--20092024233504.PDF',
414
+ 'Conteudo': None
415
+ }
416
+ ]
417
+ }
418
+ }
419
+ }
420
+ """
421
+
422
+
423
+ #logger.debug("parou aqui 6757576")
424
+ #sys.exit(0)
425
+ #novo end
426
+
427
+ #return True, response
428
+ return True, msg_detail
429
+
430
+ # Serializa o objeto SOAP em um dicionário Python
431
+ #serialized_response = serialize_object(response)
432
+
433
+ # Converte o dicionário em um JSON formatado
434
+ #response_json = json.dumps(serialized_response, indent=4, default=str)
435
+
436
+ #return True, response_json
437
+
438
+ except Exception as e:
439
+
440
+ return False, e
441
+
442
+ def obter_anexo(self, numero:int, versao:int, transicao:int,pasta:str,anexo_id:int,file_name:str,conteudo:str)-> Tuple[bool,Union[dict, Exception]]:
443
+ """
444
+ Obtém um anexo de um correio eletrônico.
445
+
446
+ Args:
447
+ correio (ItemListaCorreio): objeto da classe ItemListaCorreio (item da listagem de mensagens)
448
+ anexo (AnexoDict): um item do dicionário da lista de anexos de ItemListaCorreio
449
+
450
+ Returns:
451
+ tuple: Um par contendo:
452
+ - bool: Indica se a operação foi bem-sucedida (True) ou falhou (False).
453
+ - Union[dict, Exception]: Retorna um dicionario com dados do anexo, ou uma exceção em caso de erro.
454
+
455
+ """
456
+ #logger.info("ANEXOS PARA OBTER")
457
+ #print(correio.Anexos)
458
+ try:
459
+
460
+ pasta = pasta.replace("'", '"').replace("None", "null")
461
+ pasta = json.loads(pasta)
462
+
463
+ # Monta os parâmetros para a requisição SOAP
464
+ params = {
465
+ 'NumeroCorreio': numero,
466
+ 'Versao': versao,
467
+ 'Transicao': transicao,
468
+ #'Pasta': pasta,
469
+ 'Pasta': {
470
+ 'Unidade': pasta["Unidade"],
471
+ 'Dependencia': pasta["Dependencia"],
472
+ 'Setor': pasta["Setor"],
473
+ 'Tipo': pasta["Tipo"],
474
+ },
475
+ #'Pasta': {
476
+ # 'Unidade': {
477
+ # 'Nome': pasta['Unidade']['Nome'],
478
+ # 'Ativa': pasta['Unidade']['Ativa'],
479
+ # 'Tipo': pasta['Unidade']['Tipo']
480
+ # },
481
+ # 'Dependencia': pasta['Dependencia'],
482
+ # 'Setor': {
483
+ # 'Nome': pasta['Setor']['Nome'],
484
+ # 'Ativo': pasta['Setor']['Ativo']
485
+ # },
486
+ # 'Tipo': pasta['Tipo']
487
+ #},
488
+ 'Anexo': {
489
+ 'IdAnexo': anexo_id,
490
+ 'NomeAnexo': file_name,
491
+ 'Conteudo': conteudo # Conteúdo em base64
492
+ }
493
+ }
494
+
495
+ # Faz a requisição SOAP para o método ObterAnexo
496
+ response = self.client.service.ObterAnexo(parametros=params)
497
+ #logger.info("response")
498
+ #logger.info(response)
499
+
500
+ # Acessa os dados da resposta (IdAnexo, NomeAnexo, Conteudo)
501
+ if response and hasattr(response, 'Anexo'):
502
+ id_anexo = response.Anexo.IdAnexo
503
+ nome_anexo = response.Anexo.NomeAnexo
504
+ conteudo_anexo = response.Anexo.Conteudo
505
+
506
+ # Retorna os dados capturados como um dicionário
507
+ return True, {
508
+ 'IdAnexo': id_anexo,
509
+ 'NomeAnexo': nome_anexo,
510
+ 'Conteudo': conteudo_anexo
511
+ }
512
+ else:
513
+ return False, Exception("Correio não possui anexo")
514
+
515
+ except Exception as e:
516
+
517
+ return False, e
518
+
519
+ def encerrar(self):
520
+ """Fecha o cliente e libera a sessão."""
521
+
522
+ try:
523
+
524
+ self.client.transport.session.close()
525
+
526
+ except:
527
+
528
+ pass
529
+