From 04fa648e7c2d73adf2615cf23508dc2d0f6ec12e Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Mon, 23 Feb 2026 14:33:04 -0300 Subject: [PATCH 01/10] doc: melhoria readme. --- .gitignore | 1 + README.md | 174 +++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 158 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index 8498f4e..d0dd079 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ node_modules/ ## cache python __pycache__/ *.py[cod] +*.pyc diff --git a/README.md b/README.md index b30a3b7..ba8f038 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,184 @@ # Bot de notificações no Discord -**Branch: developer** -## Instruções Para Dev -A versão do Python utilizada é: `python:3.10` +Bot que monitora lançamentos de capítulos em um site de mangás/webtoons e realiza postagens automáticas de anúncio em canais do Discord. + +--- + +## Arquitetura do Projeto + +```mermaid +flowchart TD + MAIN["Main.py\n(Ponto de entrada)"] + + subgraph classes_io ["classes_io"] + GESTOR["GestorTXT\nLê/grava data anterior\ne modo de teste (TXT)"] + DOWNLOAD["DownloadImagens\nBaixa imagens das obras\nregistradas no Atlas"] + end + + subgraph controller ["controller"] + CTRL_POST["ControllerPostagem\nOrquestra o fluxo\nde postagem"] + CTRL_OBRA["ControllerObras\nFiltra e valida\nlistas de obras"] + end + + subgraph dao ["dao"] + ATLAS["AtlasDAO\nMongoDB Atlas\n(obras registradas,\nanunciadas, etc.)"] + SCRAPER["WebScreperSite\nWeb scraping dos\ncapítulos diários do site"] + DISCORD["ConexaoDiscord\nEnvia embeds para\ncanais do Discord"] + GEMINI["GeminiDAO\nIntegração com\nGoogle Gemini AI"] + end + + subgraph model ["model"] + OBRA["Obra"] + CAPITULO["Capitulo"] + POST_DC["PostDiscord\nMonta o embed\ndo anúncio"] + POST_FB["PostFacebook\n(desativado)"] + MSGS["Mensagens\nLogs e prints"] + LOGGER["LoggerConfig\nConfiguração de logs"] + end + + subgraph assets ["assets (volume)"] + TXT_DATA["registro_horario/\ndata_anterior.txt"] + TXT_MODE["config/\ntest_mode.txt"] + IMGS["imagens/\n(cache local de imagens)"] + end + + MAIN --> GESTOR + MAIN --> DOWNLOAD + MAIN --> CTRL_POST + MAIN --> LOGGER + + GESTOR --> TXT_DATA + GESTOR --> TXT_MODE + + DOWNLOAD --> ATLAS + DOWNLOAD --> IMGS + + CTRL_POST --> ATLAS + CTRL_POST --> SCRAPER + CTRL_POST --> CTRL_OBRA + CTRL_POST --> POST_DC + CTRL_POST --> DISCORD + + SCRAPER --> OBRA + SCRAPER --> CAPITULO + + POST_DC --> OBRA + POST_DC --> CAPITULO + + CTRL_OBRA --> OBRA +``` + +### Fluxo principal + +1. **GestorTXT** lê a data da última execução e o modo de teste. +2. **DownloadImagens** sincroniza o cache local de imagens com os dados do MongoDB Atlas. +3. **WebScreperSite** faz scraping do site e retorna a lista de obras com capítulos lançados no dia. +4. **ControllerObras** filtra obras não registradas no Atlas e remove capítulos já anunciados. +5. **ControllerPostagem** itera sobre as obras restantes, monta um `PostDiscord` e envia o embed via **ConexaoDiscord**. +6. O registro de obras anunciadas é persistido no MongoDB Atlas para evitar duplicatas. -Para criar o ambiente, utilize: +### Variáveis de ambiente (`.env`) + +| Variável | Descrição | +|---|---| +| `URI_ATLAS` | URI de conexão com o MongoDB Atlas | +| `API_KEY` | Token do bot Discord | +| `CANAL_LANCAMENTOS` | ID do canal de lançamentos | +| `CANAL_TAGS` | ID do canal de tags/cargos | +| `CANAL_TESTES` | ID do canal usado em modo de teste | +| `GEMINI_API` | Chave da API do Google Gemini | + +--- + +## Estrutura de diretórios + +``` +bot-notification/ +├── src/ +│ ├── Main.py # Ponto de entrada +│ ├── classes_io/ +│ │ ├── download_imagens.py # Download de imagens das obras +│ │ └── gestor_txt.py # Leitura/escrita de arquivos TXT +│ ├── controller/ +│ │ ├── controller_obras.py # Filtragem e validação de obras +│ │ └── controller_postagem.py # Orquestração do fluxo de postagem +│ ├── dao/ +│ │ ├── atlas_dao.py # Acesso ao MongoDB Atlas +│ │ ├── conexao_discord.py # Envio de mensagens ao Discord +│ │ ├── conexao_facebook.py # Integração Facebook (desativada) +│ │ ├── gemini_dao.py # Integração Google Gemini AI +│ │ └── web_screper_site.py # Web scraping do site de mangás +│ ├── endpoint/ +│ │ ├── bot_endpoint.py +│ │ └── pagination.py +│ └── model/ +│ ├── capitulo.py # Entidade Capítulo +│ ├── logger_config.py # Configuração de loggers +│ ├── mensagens.py # Mensagens de log/console +│ ├── obra.py # Entidade Obra +│ └── posts/ +│ ├── post_discord.py # Modelo do embed Discord +│ └── post_facebook.py # Modelo do post Facebook (desativado) +├── assets/ # Volume Docker (persistente) +│ ├── config/ +│ │ └── test_mode.txt # "true" para modo de teste +│ ├── imagens/ # Cache local de capas das obras +│ └── registro_horario/ +│ └── data_anterior.txt # Data da última execução +├── tests/ # Testes unitários (pytest) +├── Dockerfile +├── Dockerfile-dev +└── requirements.txt ``` + +--- + +## Instruções para desenvolvimento + +A versão do Python utilizada é: `python:3.10` + +Para criar o ambiente, utilize: +```bash python3 -m venv venv source venv/bin/activate ``` Para instalar as dependências do projeto: -``` +```bash pip install -r requirements.txt ``` Para executar os testes: -``` +```bash pytest ``` -## Para buildar a imagem com docker -A imagem utiliza volume, então é necessário criar um: -``` -docker volume create -``` +--- + +## Docker -Após isso, para criar a imagem: +A imagem utiliza volume para persistir os dados em `assets/`. Crie o volume antes de rodar: + +```bash +docker volume create ``` + +Construir a imagem: +```bash docker build -t bot-notif: . ``` -E por fim, para executar o container: -``` +Executar o container: +```bash docker run -d -v :/home/project/assets bot-notif: ``` -Caso queira acompanhar a saída do bot, pode usar: -``` +Acompanhar a saída do bot: +```bash docker attach ``` -Pode encontrar o ID do container a partir do comando: `docker ps` \ No newline at end of file +Encontrar o ID do container: +```bash +docker ps +``` \ No newline at end of file From 55d3aeb0b6b6350e7c9e0ac4419dd8e1d778a875 Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 11:56:57 -0300 Subject: [PATCH 02/10] =?UTF-8?q?feat(facebook):=20implementa=20integra?= =?UTF-8?q?=C3=A7=C3=A3o=20completa=20com=20a=20Graph=20API=20do=20Faceboo?= =?UTF-8?q?k?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## conexao_facebook.py - Reescrito do zero usando requests + Graph API v25.0 diretamente, removendo dependência do facebook-sdk (deprecated) - Fluxo de postagem em 2 passos: upload da imagem (published=false) para obter photo_id, seguido de publicação no feed via attached_media - Passa URL da imagem via parâmetro 'url' em vez de upload de arquivo binário local - Adicionado suporte à flag ENABLE_FB_TEST: quando true, usa credenciais da página de teste (API_TOKEN_PAGINA_TESTE / API_ID_PAGINA_FACEBOOK_TESTE); se as credenciais de teste estiverem ausentes, retorna sem postar - Logging de erros detalhado em cada etapa ## controller_postagem.py - Descomentado e corrigido o bloco de postagem no Facebook (estava comentado como docstring) - Corrigido import de ConexaoFacebook e PostFacebook que estavam ausentes - Chamada real a ConexaoFacebook.postar_anuncio_facebook() restaurada ## post_facebook.py - Corrigido bug de TypeError ao iterar dados_unicos_obras como lista de dicts em vez de indexar como dict diretamente ## tests/test_dao_conexao_facebook.py (novo arquivo) - TestRegraDeNegocioFacebook: testes unitários de remover_obras_que_nao_pode_postar - TestFlagEnableFbTest: valida que sem credenciais de teste nenhuma chamada à API é feita quando ENABLE_FB_TEST=true - TestConexaoFacebook: testes de integração reais, protegidos por pytest.skip quando ENABLE_FB_TEST != true ## requirements.txt - Removido facebook-sdk==3.1.0 (não mais utilizado) ## README.md - Documentação das variáveis de ambiente do Facebook - Guia passo a passo para configurar o App no Meta for Developers, gerar Page Access Token e configurar o .env --- README.md | 120 ++++++++++++++- requirements.txt | 1 - src/controller/controller_postagem.py | 14 +- src/dao/conexao_facebook.py | 100 +++++++++++-- src/model/posts/post_facebook.py | 19 ++- tests/test_dao_conexao_facebook.py | 204 ++++++++++++++++++++++++++ 6 files changed, 426 insertions(+), 32 deletions(-) create mode 100644 tests/test_dao_conexao_facebook.py diff --git a/README.md b/README.md index ba8f038..097ab07 100644 --- a/README.md +++ b/README.md @@ -79,14 +79,122 @@ flowchart TD ### Variáveis de ambiente (`.env`) +#### Discord + +| Variável | Descrição | +|---|---| +| `API_KEY` | Token do bot Discord. Obtido em https://discord.com/developers/applications → Bot → Token | +| `CANAL_LANCAMENTOS` | ID do canal onde os anúncios de lançamentos são postados em produção | +| `CANAL_TESTES` | ID do canal usado quando o bot é executado em modo de teste | +| `CANAL_TAGS` | ID do canal de tags/cargos, usado para menções nos embeds | + +#### MongoDB Atlas + +| Variável | Descrição | +|---|---| +| `URI_ATLAS` | URI de conexão com o cluster MongoDB Atlas. Formato: `mongodb+srv://:@.mongodb.net/` | + +#### Google Gemini + | Variável | Descrição | |---|---| -| `URI_ATLAS` | URI de conexão com o MongoDB Atlas | -| `API_KEY` | Token do bot Discord | -| `CANAL_LANCAMENTOS` | ID do canal de lançamentos | -| `CANAL_TAGS` | ID do canal de tags/cargos | -| `CANAL_TESTES` | ID do canal usado em modo de teste | -| `GEMINI_API` | Chave da API do Google Gemini | +| `GEMINI_API` | Chave da API do Google Gemini AI. Obtida em https://aistudio.google.com/app/apikey | + +#### Facebook + +| Variável | Descrição | +|---|---| +| `API_ID_PAGINA_FACEBOOK` | ID numérico da página do Facebook de produção onde os posts serão publicados | +| `API_TOKEN_PAGINA` | Page Access Token da página de produção. Deve ter as permissões `pages_manage_posts` e `pages_read_engagement` | +| `API_ID_PAGINA_FACEBOOK_TESTE` | ID numérico da página de teste (usada apenas quando `ENABLE_FB_TEST=true`) | +| `API_TOKEN_PAGINA_TESTE` | Page Access Token da página de teste | +| `ENABLE_FB_TEST` | `"true"` para habilitar os testes unitários de postagem no Facebook. Por padrão `"false"` para evitar postagens acidentais | + +--- + +## Configuração do Facebook + +### Pré-requisitos + +- Conta de desenvolvedor Meta: https://developers.facebook.com +- App criado no painel de desenvolvedores (tipo: **Business**) +- Página do Facebook onde os posts serão publicados +- A conta deve ser **Administrador** da página + +### 1. Criar o App no Meta for Developers + +1. Acesse https://developers.facebook.com/apps +2. Clique em **Create App** → selecione o tipo **Business** +3. Preencha o nome do app e o e-mail de contato +4. O app começa no modo **Desenvolvimento** — suficiente para testes + +### 2. Configurar permissões do App + +1. No painel do app, vá em **App Review → Permissions and Features** +2. Certifique-se de que as seguintes permissões estão presentes: + - `pages_manage_posts` ✅ + - `pages_read_engagement` ✅ + - `pages_show_list` ✅ +3. **Remova** `publish_actions` se estiver listado — está **deprecated** e bloqueia qualquer postagem com erro 403 + +### 3. Gerar o Page Access Token + +O token necessário é um **Page Access Token**, não um User Token. + +1. Acesse https://developers.facebook.com/tools/explorer +2. Selecione o seu app no dropdown **"App da Meta"** +3. Em **Permissions**, adicione: + - `pages_manage_posts` + - `pages_read_engagement` + - `pages_show_list` +4. Clique em **Generate Access Token** e autorize +5. No campo da query, coloque `/me/accounts` e clique **Enviar** +6. Na resposta JSON, localize a página desejada dentro de `data[]`: + ```json + { + "data": [ + { + "name": "Nome da Página", + "id": "110041288738055", + "access_token": "EAACxxx..." + } + ] + } + ``` +7. Copie o `access_token` e o `id` da página + +> ⚠️ O token gerado pelo Explorer é de **curta duração** (~1h). Para produção, converta para long-lived token via: +> ``` +> GET https://graph.facebook.com/v25.0/oauth/access_token +> ?grant_type=fb_exchange_token +> &client_id={app_id} +> &client_secret={app_secret} +> &fb_exchange_token={short_lived_token} +> ``` + +### 4. Atualizar o `.env` + +```ini +API_ID_PAGINA_FACEBOOK = "ID_DA_PAGINA" +API_TOKEN_PAGINA = "PAGE_ACCESS_TOKEN" + +# Para testes (pode ser a mesma página ou uma página separada) +API_ID_PAGINA_FACEBOOK_TESTE = "ID_DA_PAGINA_TESTE" +API_TOKEN_PAGINA_TESTE = "PAGE_ACCESS_TOKEN_TESTE" +ENABLE_FB_TEST = "false" +``` + +### 5. Testar a integração + +```bash +# Habilitar testes de Facebook no .env: +ENABLE_FB_TEST = "true" + +# Executar apenas os testes de Facebook: +pytest tests/test_dao_conexao_facebook.py -v +``` + +> Ao terminar os testes, retorne `ENABLE_FB_TEST = "false"` para evitar postagens acidentais nas próximas execuções do `pytest`. --- diff --git a/requirements.txt b/requirements.txt index 8836f72..801b3b7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,7 +11,6 @@ certifi==2023.5.7 charset-normalizer==3.1.0 discord.py==2.3.1 dnspython==1.16.0 -facebook-sdk==3.1.0 frozenlist==1.3.3 google-ai-generativelanguage==0.6.2 google-api-core==2.19.0 diff --git a/src/controller/controller_postagem.py b/src/controller/controller_postagem.py index fb8df3a..e438e34 100644 --- a/src/controller/controller_postagem.py +++ b/src/controller/controller_postagem.py @@ -3,9 +3,10 @@ from src.dao.web_screper_site import WebScreperSite from src.dao.conexao_discord import ConexaoDiscord from src.dao.atlas_dao import AtlasDAO -#from src.dao.conexao_facebook import ConexaoFacebook +from src.dao.conexao_facebook import ConexaoFacebook from src.controller.controller_obras import ControllerObras from src.model.posts.post_discord import PostDiscord +from src.model.posts.post_facebook import PostFacebook from src.classes_io.gestor_txt import GestorTXT from model.mensagens import Mensagens @@ -65,21 +66,22 @@ def execucao_principal(): time.sleep(10) - """ Postagem do FB + # Postagem do FB lista_de_obras_nao_permitidas = atlas_dao.listar_obras_nao_permitidas_fb() - lista_de_obras_facebook = ControllerObras.remover_obras_que_nao_pode_postar(lista_de_obras_atualizada,lista_de_obras_nao_permitidas) + lista_de_obras_facebook = ControllerObras.remover_obras_que_nao_pode_postar( + lista_de_obras_atualizada, lista_de_obras_nao_permitidas + ) for obra in lista_de_obras_facebook: try: Mensagens.post_facebook(obra.titulo_obra) post_obra_Facebook = PostFacebook(obra, atlas_dao.receber_obras()) - #Conexao_Facebook.postar_anuncio_facebook(post_obra_Facebook) - + ConexaoFacebook.postar_anuncio_facebook(post_obra_Facebook) + except Exception as e: Mensagens.erro_no_codigo(e) Mensagens.nao_foi_possivel_postar_facebook() Mensagens.mensagem_nao_foi_possivel_postar_obra(obra.titulo_obra) time.sleep(10) - """ diff --git a/src/dao/conexao_facebook.py b/src/dao/conexao_facebook.py index 9076716..a994906 100644 --- a/src/dao/conexao_facebook.py +++ b/src/dao/conexao_facebook.py @@ -1,27 +1,95 @@ +import logging import os +import requests from dotenv import load_dotenv -import facebook + class ConexaoFacebook: def postar_anuncio_facebook(post_obra): - def receber_caminho_imagem(titulo_obra): - diretorio_imagens = "imagens" - caminho_imagem = os.path.join(diretorio_imagens, f"{titulo_obra}.png") - - return caminho_imagem + """ + Publica uma foto com legenda na página do Facebook via Graph API v25.0. + + Parameters: + post_obra: objeto com titulo_obra, imagem_obra e método + retornar_mensagem_post(). + + Raises: + requests.HTTPError: se alguma chamada à Graph API retornar erro. + """ + logger_infos = logging.getLogger("logger_infos") + logger_erros = logging.getLogger("logger_erros") + + load_dotenv(override=True) + + # Em modo de teste, usa credenciais de teste se ENABLE_FB_TEST=true + is_test_mode = ( + os.getenv("ENABLE_FB_TEST", "false").lower() == "true" + ) + + if is_test_mode: + token_de_acesso_fb = os.getenv("API_TOKEN_PAGINA_TESTE") + id_pagina_fb = os.getenv("API_ID_PAGINA_FACEBOOK_TESTE") + if not token_de_acesso_fb or not id_pagina_fb: + logger_infos.info( + "[MODO TESTE] Credenciais de teste ausentes. " + "Postagem ignorada." + ) + return + logger_infos.info( + "[MODO TESTE] Usando credenciais de teste do Facebook" + ) + else: + token_de_acesso_fb = os.getenv("API_TOKEN_PAGINA") + id_pagina_fb = os.getenv("API_ID_PAGINA_FACEBOOK") + + logger_infos.info(f"Postando no Facebook: {post_obra.titulo_obra}") + + # Passo 1: envia a URL da imagem como foto não publicada → obtém photo_id. + # Usar URL em vez de upload binário evita criar entradas duplicadas + # na galeria da página a cada nova postagem da mesma obra. + url_photos = ( + f"https://graph.facebook.com/v25.0/{id_pagina_fb}/photos" + ) + + response_upload = requests.post( + url_photos, + params={"access_token": token_de_acesso_fb}, + data={ + "url": post_obra.imagem_obra, + "published": "false", + }, + ) + + if not response_upload.ok: + logger_erros.error( + f"Erro no upload da imagem: " + f"{response_upload.status_code} — {response_upload.text}" + ) + response_upload.raise_for_status() - load_dotenv() - token_de_acesso_fb = os.getenv('API_TOKEN_PAGINA') - id_pagina_fb = os.getenv("API_ID_PAGINA_FACEBOOK") + photo_id = response_upload.json().get("id") + logger_infos.info(f"Imagem enviada. photo_id: {photo_id}") - graph = facebook.GraphAPI(access_token=token_de_acesso_fb, version="3.0") + # Passo 2: publica no feed com a imagem anexada via photo_id + url_feed = f"https://graph.facebook.com/v25.0/{id_pagina_fb}/feed" - # Faz a postagem - # graph.put_object(parent_object=id_pagina_fb, connection_name='feed', message=post_obra.retornar_mensagem_post()) + response_post = requests.post( + url_feed, + params={"access_token": token_de_acesso_fb}, + json={ + "message": post_obra.retornar_mensagem_post(), + "attached_media": [{"media_fbid": photo_id}], + }, + ) - caminho_imagem = receber_caminho_imagem(post_obra.titulo_obra) - with open(caminho_imagem, 'rb') as imagem: - graph.put_photo(image=imagem, message=post_obra.retornar_mensagem_post()) + if not response_post.ok: + logger_erros.error( + f"Erro ao publicar post: " + f"{response_post.status_code} — {response_post.text}" + ) + response_post.raise_for_status() - return + logger_infos.info( + f"Postagem no Facebook concluída: {post_obra.titulo_obra}" + ) diff --git a/src/model/posts/post_facebook.py b/src/model/posts/post_facebook.py index bce1d2b..8f02920 100644 --- a/src/model/posts/post_facebook.py +++ b/src/model/posts/post_facebook.py @@ -11,9 +11,22 @@ def __init__(self, obra, dados_unicos_obras): self.lista_de_capitulos = obra.lista_de_capitulos - self.imagem_obra = dados_unicos_obras[self.titulo_obra]['url_imagem'] - - self.logger_infos.info(f"Construindo Post {self.titulo_obra }...") + # Itera sobre a lista de obras (mesmo padrão do PostDiscord) em vez de + # indexar como dict, o que causaria TypeError pois dados_unicos_obras é list. + obra_encontrada = None + for dados_obra in dados_unicos_obras: + if dados_obra.get('titulo') == self.titulo_obra: + obra_encontrada = dados_obra + break + + if obra_encontrada: + self.imagem_obra = obra_encontrada['url_imagem'] + else: + self.logger_infos.warning( + f"Obra '{self.titulo_obra}' não encontrada em dados_unicos_obras." + ) + + self.logger_infos.info(f"Construindo Post {self.titulo_obra}...") def retornar_mensagem_post(self): diff --git a/tests/test_dao_conexao_facebook.py b/tests/test_dao_conexao_facebook.py new file mode 100644 index 0000000..5955722 --- /dev/null +++ b/tests/test_dao_conexao_facebook.py @@ -0,0 +1,204 @@ +import os +import pytest +from unittest.mock import patch, MagicMock +from dotenv import load_dotenv +from src.dao.conexao_facebook import ConexaoFacebook +from src.dao.atlas_dao import AtlasDAO +from src.controller.controller_obras import ControllerObras +from src.model.capitulo import Capitulo +from src.model.obra import Obra +from src.model.posts.post_facebook import PostFacebook + + +class TestRegraDeNegocioFacebook: + """ + Testes de regra de negócio para postagem no Facebook. + Estes testes não fazem chamadas à API — sempre executam. + """ + + def test_obras_nao_permitidas_sao_removidas_da_lista(self): + """ + Garante que obras na lista de não permitidas são excluídas + da lista de obras a postar no Facebook. + """ + lista_para_postar = [ + Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), + Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), + Obra("Obra C", "http://img.com/c.png", "http://site.com/c"), + ] + nao_permitidas = [ + {"titulo_obra": "Obra B"}, + {"titulo_obra": "Obra C"}, + ] + + resultado = ControllerObras.remover_obras_que_nao_pode_postar( + lista_para_postar, nao_permitidas + ) + + assert len(resultado) == 1 + assert resultado[0].titulo_obra == "Obra A" + + def test_lista_vazia_de_nao_permitidas_retorna_todas_as_obras(self): + """ + Com lista de não permitidas vazia, todas as obras devem ser retornadas. + """ + lista_para_postar = [ + Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), + Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), + ] + + resultado = ControllerObras.remover_obras_que_nao_pode_postar( + lista_para_postar, [] + ) + + assert len(resultado) == 2 + + def test_todas_obras_nao_permitidas_retorna_lista_vazia(self): + """ + Se todas as obras estiverem na lista de não permitidas, + o resultado deve ser uma lista vazia. + """ + lista_para_postar = [ + Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), + Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), + ] + nao_permitidas = [ + {"titulo_obra": "Obra A"}, + {"titulo_obra": "Obra B"}, + ] + + resultado = ControllerObras.remover_obras_que_nao_pode_postar( + lista_para_postar, nao_permitidas + ) + + assert len(resultado) == 0 + + def test_obra_nao_listada_como_nao_permitida_permanece(self): + """ + Obras cujo título não consta na lista de não permitidas devem + ser mantidas na lista de postagem. + """ + lista_para_postar = [ + Obra("Obra Permitida", "http://img.com/p.png", "http://site.com/p"), + ] + nao_permitidas = [{"titulo_obra": "Outra Obra"}] + + resultado = ControllerObras.remover_obras_que_nao_pode_postar( + lista_para_postar, nao_permitidas + ) + + assert len(resultado) == 1 + assert resultado[0].titulo_obra == "Obra Permitida" + + +class TestFlagEnableFbTest: + """ + Testes que validam o comportamento da flag ENABLE_FB_TEST. + + Quando true sem credenciais de teste: não posta em lugar nenhum. + Quando true com credenciais de teste: posta na página de teste. + """ + + def test_sem_credenciais_de_teste_nao_faz_chamada_api( + self, monkeypatch + ): + """ + Quando ENABLE_FB_TEST=true mas as variáveis de ambiente da + página de teste estão ausentes, nenhuma chamada à API deve + ser feita. + """ + monkeypatch.setenv("ENABLE_FB_TEST", "true") + monkeypatch.delenv("API_TOKEN_PAGINA_TESTE", raising=False) + monkeypatch.delenv("API_ID_PAGINA_FACEBOOK_TESTE", raising=False) + + obra = Obra("Teste", "http://img.com/a.png", "http://site.com/a") + post_facebook = PostFacebook(obra, []) + capitulo = Capitulo("1", "http://site.com/cap1", "março 7, 2026") + post_facebook.lista_de_capitulos.append(capitulo) + + with patch("src.dao.conexao_facebook.requests.post") as mock_post: + with patch("src.dao.conexao_facebook.load_dotenv"): + ConexaoFacebook.postar_anuncio_facebook(post_facebook) + + assert mock_post.call_count == 0 + + +class TestConexaoFacebook: + """ + Testes para postagem no Facebook. + + Por padrão, os testes estão DESABILITADOS para evitar postagens acidentais. + Para habilitar, defina ENABLE_FB_TEST=true no .env e execute: + pytest tests/test_dao_conexao_facebook.py + """ + + def test_postagem_facebook_esta_funcionando(self): + """ + Testa a postagem de dois capítulos no Facebook. + Requer ENABLE_FB_TEST=true no .env para executar. + """ + load_dotenv(override=True) + if os.getenv("ENABLE_FB_TEST", "false").lower() != "true": + pytest.skip("ENABLE_FB_TEST não está true no .env") + atlas_dao = AtlasDAO() + + # Cria uma obra de teste + obra = Obra( + "Teste de Postagem", + "https://tsundoku.com.br/wp-content/uploads/2022/02/Gosu_The_Master1.png", + "https://tsundoku.com.br/manga/teste-de-postagem/" + ) + + post_facebook = PostFacebook(obra, atlas_dao.receber_obras()) + + # Adiciona capítulos de teste + capitulo_um = Capitulo( + "9998", + "https://tsundoku.com.br/teste-cap-9998/", + "março 4, 2026" + ) + + capitulo_dois = Capitulo( + "9999", + "https://tsundoku.com.br/teste-cap-9999/", + "março 4, 2026" + ) + + post_facebook.lista_de_capitulos += [capitulo_um, capitulo_dois] + + # Executa a postagem + ConexaoFacebook.postar_anuncio_facebook(post_facebook) + + # Se chegou aqui sem exceção, o teste passou + assert True + + def test_postagem_facebook_um_capitulo(self): + """ + Testa a postagem de um único capítulo no Facebook. + Requer ENABLE_FB_TEST=true no .env para executar. + """ + load_dotenv(override=True) + if os.getenv("ENABLE_FB_TEST", "false").lower() != "true": + pytest.skip("ENABLE_FB_TEST não está true no .env") + atlas_dao = AtlasDAO() + + obra = Obra( + "Teste de Postagem", + "https://tsundoku.com.br/wp-content/uploads/2022/02/Gosu_The_Master1.png", + "https://tsundoku.com.br/manga/teste-de-postagem/" + ) + + post_facebook = PostFacebook(obra, atlas_dao.receber_obras()) + + capitulo = Capitulo( + "100", + "https://tsundoku.com.br/teste-cap-100/", + "março 4, 2026" + ) + + post_facebook.lista_de_capitulos.append(capitulo) + + # Executa a postagem + ConexaoFacebook.postar_anuncio_facebook(post_facebook) + + assert True From c060db7c5df61765fa0001f41b1ca4780003327d Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 12:22:26 -0300 Subject: [PATCH 03/10] =?UTF-8?q?refactor(facebook):=20blacklist=20?= =?UTF-8?q?=E2=86=92=20whitelist=20de=20obras=20permitidas=20no=20FB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Motivação A lógica anterior bloqueava obras explicitamente (blacklist). A nova lógica exige permissão explícita para postar (whitelist): obras ausentes da lista são ignoradas por padrão. ## atlas_dao.py - Removido: inserir_obra_nao_permitida_fb() e listar_obras_nao_permitidas_fb() que operavam na coleção 'obrasNaoPermitidasFB' - Adicionado: inserir_obra_permitida_fb() — insere na coleção 'obrasPermitidasFB' - Adicionado: listar_obras_permitidas_fb() — lê da coleção 'obrasPermitidasFB' ## controller_obras.py - Removido: remover_obras_que_nao_pode_postar() (lógica de blacklist) - Adicionado: filtrar_obras_permitidas_fb() — retorna apenas obras cujo titulo_obra consta na whitelist recebida como parâmetro ## controller_postagem.py - Atualizado o bloco de postagem do FB para usar listar_obras_permitidas_fb() e filtrar_obras_permitidas_fb() no lugar dos métodos antigos ## bot_endpoint.py - Comando /adicionar_obra_nao_permitida_fb renomeado para /adicionar_obra_permitida_fb, agora chama inserir_obra_permitida_fb() - Comando /listar_obras_nao_permitidas_fb renomeado para /listar_obras_permitidas_fb, agora chama listar_obras_permitidas_fb() - Embed de /informacoes_postagem atualizado com os novos nomes de comandos ## tests/test_dao_conexao_facebook.py - TestRegraDeNegocioFacebook reescrito para whitelist: testa que whitelist vazia retorna zero obras, que obras ausentes são removidas e que obras presentes são mantidas - Adicionado TestWhitelistFluxoPostagem: simula o trecho do ControllerPostagem que consulta a whitelist e chama ConexaoFacebook, garantindo que apenas obras autorizadas chegam à API do Facebook ## Atlas (manual) - Criar coleção 'obrasPermitidasFB' no banco 'DadosPostagem' - Documentos no formato: { "titulo_obra": "Nome Exato Da Obra" } - Coleção 'obrasNaoPermitidasFB' pode ser removida --- src/controller/controller_obras.py | 37 ++++--- src/controller/controller_postagem.py | 8 +- src/dao/atlas_dao.py | 35 +++++-- src/endpoint/bot_endpoint.py | 23 ++--- tests/test_dao_conexao_facebook.py | 140 +++++++++++++++++++++----- 5 files changed, 177 insertions(+), 66 deletions(-) diff --git a/src/controller/controller_obras.py b/src/controller/controller_obras.py index 955d43e..09342f6 100644 --- a/src/controller/controller_obras.py +++ b/src/controller/controller_obras.py @@ -30,22 +30,33 @@ def remove_obras_nao_registradas(lista_de_obras_recebidas, dados_unicos_obras): return obras_registradas - """ - Remove obras que não podem ser postadas. - Args: - lista_de_obras_para_postar (list): Lista de obras para postar. - lista_de_obras_nao_permitidas (list): Lista de obras não permitidas. - Returns: - list: Lista de obras filtradas, sem as obras não permitidas. - """ - def remover_obras_que_nao_pode_postar(lista_de_obras_para_postar, lista_de_obras_nao_permitidas): - titulos_obras_nao_permitidas = [obra['titulo_obra'] for obra in lista_de_obras_nao_permitidas] + def filtrar_obras_permitidas_fb( + lista_de_obras_para_postar: list, + lista_de_obras_permitidas: list + ) -> list: + """ + Retorna apenas as obras que possuem permissão explícita de + postagem no Facebook (whitelist). + + Obras que não estiverem na lista de permitidas são removidas, + independente de qualquer outro critério. + + Args: + lista_de_obras_para_postar (list): obras candidatas à postagem. + lista_de_obras_permitidas (list): documentos com 'titulo_obra' + das obras autorizadas. + + Returns: + list: obras presentes em lista_de_obras_permitidas. + """ + titulos_permitidos = { + obra['titulo_obra'] for obra in lista_de_obras_permitidas + } - obras_filtradas = [ + return [ obra for obra in lista_de_obras_para_postar - if obra.titulo_obra not in titulos_obras_nao_permitidas + if obra.titulo_obra in titulos_permitidos ] - return obras_filtradas """ diff --git a/src/controller/controller_postagem.py b/src/controller/controller_postagem.py index e438e34..0546787 100644 --- a/src/controller/controller_postagem.py +++ b/src/controller/controller_postagem.py @@ -66,11 +66,11 @@ def execucao_principal(): time.sleep(10) - # Postagem do FB - lista_de_obras_nao_permitidas = atlas_dao.listar_obras_nao_permitidas_fb() + # Postagem do FB — apenas obras com permissão explícita (whitelist) + lista_de_obras_permitidas_fb = atlas_dao.listar_obras_permitidas_fb() - lista_de_obras_facebook = ControllerObras.remover_obras_que_nao_pode_postar( - lista_de_obras_atualizada, lista_de_obras_nao_permitidas + lista_de_obras_facebook = ControllerObras.filtrar_obras_permitidas_fb( + lista_de_obras_atualizada, lista_de_obras_permitidas_fb ) for obra in lista_de_obras_facebook: diff --git a/src/dao/atlas_dao.py b/src/dao/atlas_dao.py index 2d6986b..93205cf 100644 --- a/src/dao/atlas_dao.py +++ b/src/dao/atlas_dao.py @@ -225,15 +225,22 @@ def remover_capitulos_de_uma_obra(self, titulo_obra, lista_de_capitulos): Mensagens.erro_no_banco_de_dados(f"Erro ao remover registros do MongoDB: {e}") - def inserir_obra_nao_permitida_fb(self, dicionario_obra): + def inserir_obra_permitida_fb(self, dicionario_obra: dict) -> None: + """ + Insere uma obra na whitelist de postagem do Facebook. + + Parameters: + dicionario_obra (dict): documento com a chave 'titulo_obra'. + """ db = self.client.DadosPostagem - colecao = db.obrasNaoPermitidasFB + colecao = db.obrasPermitidasFB - # Inserir os dados na coleção try: colecao.insert_one(dicionario_obra) except Exception as e: - Mensagens.erro_no_banco_de_dados(f'Erro ao inserir obra não permitida: {e}') + Mensagens.erro_no_banco_de_dados( + f'Erro ao inserir obra permitida no FB: {e}' + ) def receber_obras(self): @@ -252,21 +259,27 @@ def receber_obras(self): return [] - def listar_obras_nao_permitidas_fb(self): + def listar_obras_permitidas_fb(self): + """ + Retorna a lista de obras com permissão explícita de postagem + no Facebook, lida da coleção 'obrasPermitidasFB'. + + Returns: + list: lista de documentos com a chave 'titulo_obra'. + """ try: db = self.client.DadosPostagem - colecao = db.obrasNaoPermitidasFB + colecao = db.obrasPermitidasFB projection = {'_id': 0} todos_documentos = colecao.find({}, projection=projection).sort('titulo_obra', 1) - - # Convertendo o cursor em uma lista - lista_documentos = list(todos_documentos) - return lista_documentos + return list(todos_documentos) except Exception as e: - Mensagens.erro_no_banco_de_dados(f"Erro ao listar obras não permitidas do MongoDB: {e}") + Mensagens.erro_no_banco_de_dados( + f"Erro ao listar obras permitidas do MongoDB: {e}" + ) return [] diff --git a/src/endpoint/bot_endpoint.py b/src/endpoint/bot_endpoint.py index 0664e45..213c246 100644 --- a/src/endpoint/bot_endpoint.py +++ b/src/endpoint/bot_endpoint.py @@ -127,16 +127,16 @@ async def atualizar_mensagem_obra(interaction: discord.Interaction, titulo: str, @app_commands.describe( titulo='Titulo que esta no site' ) -async def adicionar_obra_nao_permitida_fb(interaction: discord.Interaction, titulo: str): - """Obras nessa lista não são postadas no Facebook, por questões de direitos autorais.""" +async def adicionar_obra_permitida_fb(interaction: discord.Interaction, titulo: str): + """Obras nessa lista têm permissão explícita para serem postadas no Facebook.""" try: dicionario_obra = { - "titulo_obra" : titulo + "titulo_obra": titulo } - atlas_dao.inserir_obra_nao_permitida_fb(dicionario_obra) + atlas_dao.inserir_obra_permitida_fb(dicionario_obra) - await interaction.response.send_message(f'{titulo} adicionada com sucesso!') + await interaction.response.send_message(f'{titulo} adicionada à whitelist do FB com sucesso!') except Exception as e: await interaction.response.send_message(f'Erro ao adicionar {titulo}: {e}') @@ -183,16 +183,15 @@ async def get_page(page: int): #Comando para listar obras que estão no banco @client.tree.command() -async def listar_obras_nao_permitidas_fb(interaction: discord.Interaction): - """Listar obras não permitidas para postagem no FB.""" +async def listar_obras_permitidas_fb(interaction: discord.Interaction): + """Listar obras com permissão para postagem no FB (whitelist).""" - cursor_obras = atlas_dao.listar_obras_nao_permitidas_fb() - colecao_obras = list(cursor_obras) # Convertendo o cursor para uma lista de obras + colecao_obras = atlas_dao.listar_obras_permitidas_fb() max_docs_por_pagina = 10 async def get_page(page: int): - emb = discord.Embed(title="Obras Não Permitidas FB", description="Obras que estão salvas no banco de dados.") + emb = discord.Embed(title="Obras Permitidas no FB", description="Obras com permissão explícita de postagem no Facebook.") offset = (page - 1) * max_docs_por_pagina parte_documentos = colecao_obras[offset:offset + max_docs_por_pagina] @@ -202,7 +201,7 @@ async def get_page(page: int): total_pages = Pagination.compute_total_pages(len(colecao_obras), max_docs_por_pagina) emb.set_footer(text=f"Página {page} de {total_pages}") - + return emb, total_pages await Pagination(interaction, get_page).navegate() @@ -272,7 +271,7 @@ async def informacoes_postagem(interaction: discord.Interaction): embed.add_field(name="Horários de verificação", value="12h, 16h, 18h, 20h e 22h", inline=False) embed.add_field(name="Adicionar obras novas", value="Use /adicionar_obra(Também atualiza os já adicionados se o título for o mesmo), /listar_obras e /remover_obra.", inline=False) embed.add_field(name="Gerenciar Postagem", value="Use /forcar_postagem e /excluir_registros.", inline=False) - embed.add_field(name="Gerenciar obras não permitidas no FB", value="Use /adicionar_obra_nao_permitida_fb e /listar_obra_nao_permitida_fb .", inline=False) + embed.add_field(name="Gerenciar whitelist do FB", value="Use /adicionar_obra_permitida_fb e /listar_obras_permitidas_fb .", inline=False) embed.add_field(name="Comandos utilitários", value="/ping, /joined e /informacoes_postagem .", inline=False) embed.add_field(name="Versão em execução", value="3.0.0", inline=False) diff --git a/tests/test_dao_conexao_facebook.py b/tests/test_dao_conexao_facebook.py index 5955722..8dc0720 100644 --- a/tests/test_dao_conexao_facebook.py +++ b/tests/test_dao_conexao_facebook.py @@ -12,79 +12,77 @@ class TestRegraDeNegocioFacebook: """ - Testes de regra de negócio para postagem no Facebook. + Testes de regra de negócio para postagem no Facebook (whitelist). Estes testes não fazem chamadas à API — sempre executam. """ - def test_obras_nao_permitidas_sao_removidas_da_lista(self): + def test_somente_obras_permitidas_sao_retornadas(self): """ - Garante que obras na lista de não permitidas são excluídas - da lista de obras a postar no Facebook. + Apenas obras cujo título consta na whitelist devem ser retornadas. """ lista_para_postar = [ Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), Obra("Obra C", "http://img.com/c.png", "http://site.com/c"), ] - nao_permitidas = [ - {"titulo_obra": "Obra B"}, - {"titulo_obra": "Obra C"}, + permitidas = [ + {"titulo_obra": "Obra A"}, ] - resultado = ControllerObras.remover_obras_que_nao_pode_postar( - lista_para_postar, nao_permitidas + resultado = ControllerObras.filtrar_obras_permitidas_fb( + lista_para_postar, permitidas ) assert len(resultado) == 1 assert resultado[0].titulo_obra == "Obra A" - def test_lista_vazia_de_nao_permitidas_retorna_todas_as_obras(self): + def test_whitelist_vazia_retorna_lista_vazia(self): """ - Com lista de não permitidas vazia, todas as obras devem ser retornadas. + Com a whitelist vazia, nenhuma obra deve ser retornada. """ lista_para_postar = [ Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), ] - resultado = ControllerObras.remover_obras_que_nao_pode_postar( + resultado = ControllerObras.filtrar_obras_permitidas_fb( lista_para_postar, [] ) - assert len(resultado) == 2 + assert len(resultado) == 0 - def test_todas_obras_nao_permitidas_retorna_lista_vazia(self): + def test_todas_obras_permitidas_retorna_lista_completa(self): """ - Se todas as obras estiverem na lista de não permitidas, - o resultado deve ser uma lista vazia. + Se todas as obras estiverem na whitelist, todas devem ser retornadas. """ lista_para_postar = [ Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), ] - nao_permitidas = [ + permitidas = [ {"titulo_obra": "Obra A"}, {"titulo_obra": "Obra B"}, ] - resultado = ControllerObras.remover_obras_que_nao_pode_postar( - lista_para_postar, nao_permitidas + resultado = ControllerObras.filtrar_obras_permitidas_fb( + lista_para_postar, permitidas ) - assert len(resultado) == 0 + assert len(resultado) == 2 - def test_obra_nao_listada_como_nao_permitida_permanece(self): + def test_obra_nao_listada_na_whitelist_e_removida(self): """ - Obras cujo título não consta na lista de não permitidas devem - ser mantidas na lista de postagem. + Obra ausente da whitelist não deve aparecer no resultado, + mesmo que não esteja em nenhuma lista de bloqueio. """ lista_para_postar = [ Obra("Obra Permitida", "http://img.com/p.png", "http://site.com/p"), + Obra("Obra Sem Permissao", "http://img.com/s.png", "http://site.com/s"), ] - nao_permitidas = [{"titulo_obra": "Outra Obra"}] + permitidas = [{"titulo_obra": "Obra Permitida"}] - resultado = ControllerObras.remover_obras_que_nao_pode_postar( - lista_para_postar, nao_permitidas + resultado = ControllerObras.filtrar_obras_permitidas_fb( + lista_para_postar, permitidas ) assert len(resultado) == 1 @@ -123,6 +121,96 @@ def test_sem_credenciais_de_teste_nao_faz_chamada_api( assert mock_post.call_count == 0 +class TestWhitelistFluxoPostagem: + """ + Testes que validam o fluxo completo: whitelist do Atlas → postagem. + + Simula o trecho do ControllerPostagem que consulta a whitelist e + chama ConexaoFacebook, garantindo que apenas obras autorizadas + chegam à API do Facebook. + """ + + def _simular_fluxo_fb( + self, + lista_obras: list, + whitelist: list, + mock_fb, + ) -> list: + """ + Reproduz o trecho de postagem do FB de execucao_principal, + retornando os títulos das obras que foram efetivamente postadas. + """ + obras_postadas = [] + + obras_permitidas = ControllerObras.filtrar_obras_permitidas_fb( + lista_obras, whitelist + ) + + for obra in obras_permitidas: + post = PostFacebook(obra, []) + cap = Capitulo("1", "http://site.com/cap1", "março 7, 2026") + post.lista_de_capitulos.append(cap) + mock_fb(post) + obras_postadas.append(obra.titulo_obra) + + return obras_postadas + + def test_obra_fora_da_whitelist_nao_e_postada(self): + """ + Obra ausente da whitelist do Atlas não deve gerar chamada ao + Facebook, mesmo que tenha capítulos novos. + """ + lista_obras = [ + Obra("Obra Sem Permissao", "http://img.com/s.png", "http://site.com/s"), + ] + whitelist = [] # Atlas retorna vazio — nenhuma obra autorizada + + mock_fb = MagicMock() + postadas = self._simular_fluxo_fb(lista_obras, whitelist, mock_fb) + + assert mock_fb.call_count == 0 + assert postadas == [] + + def test_obra_na_whitelist_e_postada(self): + """ + Obra presente na whitelist do Atlas deve ser postada no Facebook. + """ + lista_obras = [ + Obra("Obra Permitida", "http://img.com/p.png", "http://site.com/p"), + ] + whitelist = [{"titulo_obra": "Obra Permitida"}] + + mock_fb = MagicMock() + postadas = self._simular_fluxo_fb(lista_obras, whitelist, mock_fb) + + assert mock_fb.call_count == 1 + assert postadas == ["Obra Permitida"] + + def test_apenas_obras_da_whitelist_sao_postadas(self): + """ + Com múltiplas obras, apenas as presentes na whitelist devem + ser postadas; as demais devem ser ignoradas. + """ + lista_obras = [ + Obra("Obra A", "http://img.com/a.png", "http://site.com/a"), + Obra("Obra B", "http://img.com/b.png", "http://site.com/b"), + Obra("Obra C", "http://img.com/c.png", "http://site.com/c"), + ] + # Apenas A e C estão autorizadas + whitelist = [ + {"titulo_obra": "Obra A"}, + {"titulo_obra": "Obra C"}, + ] + + mock_fb = MagicMock() + postadas = self._simular_fluxo_fb(lista_obras, whitelist, mock_fb) + + assert mock_fb.call_count == 2 + assert "Obra A" in postadas + assert "Obra C" in postadas + assert "Obra B" not in postadas + + class TestConexaoFacebook: """ Testes para postagem no Facebook. From 1ff582518eee914f1d410ea40c62e26bbde470d8 Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 12:53:12 -0300 Subject: [PATCH 04/10] =?UTF-8?q?docs:=20adiciona=20guia=20de=20configura?= =?UTF-8?q?=C3=A7=C3=A3o=20do=20Facebook=20e=20atualiza=20vari=C3=A1veis?= =?UTF-8?q?=20de=20ambiente?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - docs/configuracao_facebook.md: guia completo passo a passo para criar app Meta, configurar caso de uso 'Gerenciar tudo na sua Página', adicionar as 5 permissões necessárias (pages_show_list, pages_read_engagement, pages_read_user_content, pages_manage_posts, pages_manage_engagement), gerar Page Access Token via /me/accounts no Graph API Explorer e converter para token de longa duração - .envExample: reescrito com todas as 12 variáveis documentadas e organizadas em seções (Discord, MongoDB Atlas, Facebook produção, Facebook testes, Gemini, scraper) - README.md: seção de configuração do Facebook substituída por link para o novo guia; referências '(desativado)' removidas do módulo conexao_facebook - src/dao/web_screper_site.py: locale.setlocale encapsulado em try/except para compatibilidade com ambientes sem pt_BR.UTF-8 (ex: WSL) - tests/test_controller_obras.py: atualizado para usar filtrar_obras_permitidas_fb() (whitelist) no lugar do método blacklist removido - tests/test_dao_web_screper.py: adicionado load_dotenv() no topo; teste de data reescrito sem dependência de locale, usando lista fixa de meses em português - tests/test_postagem.py: adicionado load_dotenv() para garantir que URL_SITE esteja disponível durante os testes --- .envExample | 78 ++++++++++++++-- README.md | 90 +----------------- docs/configuracao_facebook.md | 165 +++++++++++++++++++++++++++++++++ src/dao/web_screper_site.py | 12 ++- tests/test_controller_obras.py | 17 ++-- tests/test_dao_web_screper.py | 44 ++++----- tests/test_postagem.py | 3 + 7 files changed, 287 insertions(+), 122 deletions(-) create mode 100644 docs/configuracao_facebook.md diff --git a/.envExample b/.envExample index f951550..cf7b298 100644 --- a/.envExample +++ b/.envExample @@ -1,9 +1,75 @@ +# ============================================================================= +# DISCORD +# ============================================================================= + +# Token de autenticação do bot Discord. +# Obtido em: https://discord.com/developers/applications → Bot → Token API_KEY = token_bot_discord -CANAL_LANCAMENTOS = channel_id -CANAL_TESTES = channel_id_tests -CANAL_TAGS = channel_id_tags -API_ID_PAGINA_FACEBOOK = api_facebook -API_TOKEN_PAGINA = token_facebook_page +# ID do canal Discord onde as postagens de lançamentos reais serão enviadas. +# Para obter o ID: ative o Modo Desenvolvedor no Discord, clique com botão direito +# no canal → Copiar ID +CANAL_LANCAMENTOS = channel_id_canal_lancamentos + +# ID do canal Discord usado para postagens em modo de teste. +# As mensagens de teste são enviadas aqui em vez do canal de produção. +CANAL_TESTES = channel_id_canal_testes + +# ID do canal Discord onde as postagens com tags/menções de obras são enviadas. +CANAL_TAGS = channel_id_canal_tags + +# ============================================================================= +# MONGODB ATLAS +# ============================================================================= + +# URI de conexão com o cluster do MongoDB Atlas. +# Obtida em: Atlas Console → Database → Connect → Drivers +# Formato: mongodb+srv://:@.mongodb.net/?retryWrites=true&w=majority +URI_ATLAS = mongodb+srv://usuario:senha@cluster.mongodb.net/?retryWrites=true&w=majority + +# ============================================================================= +# FACEBOOK (Produção) +# ============================================================================= + +# ID numérico da página do Facebook onde os anúncios serão publicados. +# Obtido em: Configurações da Página → Informações da Página → ID da Página +API_ID_PAGINA_FACEBOOK = id_numerico_da_pagina_facebook + +# Token de acesso de longa duração da página do Facebook (produção). +# Gerado via: https://developers.facebook.com/tools/explorer/ +# Permissões necessárias: pages_manage_posts, pages_read_engagement, publish_to_groups +API_TOKEN_PAGINA = token_de_acesso_da_pagina_facebook + +# ============================================================================= +# FACEBOOK (Testes) +# Usadas apenas quando ENABLE_FB_TEST=true. Permitem testar a integração com o +# Facebook sem publicar na página de produção. +# ============================================================================= + +# ID numérico da página do Facebook de testes. +API_ID_PAGINA_FACEBOOK_TESTE = id_numerico_da_pagina_de_teste + +# Token de acesso de longa duração da página do Facebook de testes. +API_TOKEN_PAGINA_TESTE = token_de_acesso_da_pagina_de_teste + +# Ativa o modo de teste do Facebook. +# Quando "true", as postagens são feitas na página de teste (acima) em vez da produção. +# Quando "false" ou ausente, usa as credenciais de produção. +# Padrão: false +ENABLE_FB_TEST = false + +# ============================================================================= +# GOOGLE GEMINI +# ============================================================================= + +# Chave de API do Google Gemini, usada para geração de descrições das obras. +# Obtida em: https://aistudio.google.com/app/apikey +GEMINI_API = chave_de_api_do_gemini + +# ============================================================================= +# WEB SCRAPER +# ============================================================================= -URL_SITE = url_do_site_sem_https//: \ No newline at end of file +# URL base do site alvo do scraper, sem protocolo (http:// ou https://). +# Exemplo: tsundoku.com.br +URL_SITE = url_do_site_sem_protocolo \ No newline at end of file diff --git a/README.md b/README.md index 097ab07..29b81cd 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ flowchart TD OBRA["Obra"] CAPITULO["Capitulo"] POST_DC["PostDiscord\nMonta o embed\ndo anúncio"] - POST_FB["PostFacebook\n(desativado)"] + POST_FB["PostFacebook"] MSGS["Mensagens\nLogs e prints"] LOGGER["LoggerConfig\nConfiguração de logs"] end @@ -105,7 +105,7 @@ flowchart TD | Variável | Descrição | |---|---| | `API_ID_PAGINA_FACEBOOK` | ID numérico da página do Facebook de produção onde os posts serão publicados | -| `API_TOKEN_PAGINA` | Page Access Token da página de produção. Deve ter as permissões `pages_manage_posts` e `pages_read_engagement` | +| `API_TOKEN_PAGINA` | Page Access Token de longa duração da página de produção. Veja [configuracao_facebook.md](docs/configuracao_facebook.md) para instruções de geração | | `API_ID_PAGINA_FACEBOOK_TESTE` | ID numérico da página de teste (usada apenas quando `ENABLE_FB_TEST=true`) | | `API_TOKEN_PAGINA_TESTE` | Page Access Token da página de teste | | `ENABLE_FB_TEST` | `"true"` para habilitar os testes unitários de postagem no Facebook. Por padrão `"false"` para evitar postagens acidentais | @@ -114,87 +114,7 @@ flowchart TD ## Configuração do Facebook -### Pré-requisitos - -- Conta de desenvolvedor Meta: https://developers.facebook.com -- App criado no painel de desenvolvedores (tipo: **Business**) -- Página do Facebook onde os posts serão publicados -- A conta deve ser **Administrador** da página - -### 1. Criar o App no Meta for Developers - -1. Acesse https://developers.facebook.com/apps -2. Clique em **Create App** → selecione o tipo **Business** -3. Preencha o nome do app e o e-mail de contato -4. O app começa no modo **Desenvolvimento** — suficiente para testes - -### 2. Configurar permissões do App - -1. No painel do app, vá em **App Review → Permissions and Features** -2. Certifique-se de que as seguintes permissões estão presentes: - - `pages_manage_posts` ✅ - - `pages_read_engagement` ✅ - - `pages_show_list` ✅ -3. **Remova** `publish_actions` se estiver listado — está **deprecated** e bloqueia qualquer postagem com erro 403 - -### 3. Gerar o Page Access Token - -O token necessário é um **Page Access Token**, não um User Token. - -1. Acesse https://developers.facebook.com/tools/explorer -2. Selecione o seu app no dropdown **"App da Meta"** -3. Em **Permissions**, adicione: - - `pages_manage_posts` - - `pages_read_engagement` - - `pages_show_list` -4. Clique em **Generate Access Token** e autorize -5. No campo da query, coloque `/me/accounts` e clique **Enviar** -6. Na resposta JSON, localize a página desejada dentro de `data[]`: - ```json - { - "data": [ - { - "name": "Nome da Página", - "id": "110041288738055", - "access_token": "EAACxxx..." - } - ] - } - ``` -7. Copie o `access_token` e o `id` da página - -> ⚠️ O token gerado pelo Explorer é de **curta duração** (~1h). Para produção, converta para long-lived token via: -> ``` -> GET https://graph.facebook.com/v25.0/oauth/access_token -> ?grant_type=fb_exchange_token -> &client_id={app_id} -> &client_secret={app_secret} -> &fb_exchange_token={short_lived_token} -> ``` - -### 4. Atualizar o `.env` - -```ini -API_ID_PAGINA_FACEBOOK = "ID_DA_PAGINA" -API_TOKEN_PAGINA = "PAGE_ACCESS_TOKEN" - -# Para testes (pode ser a mesma página ou uma página separada) -API_ID_PAGINA_FACEBOOK_TESTE = "ID_DA_PAGINA_TESTE" -API_TOKEN_PAGINA_TESTE = "PAGE_ACCESS_TOKEN_TESTE" -ENABLE_FB_TEST = "false" -``` - -### 5. Testar a integração - -```bash -# Habilitar testes de Facebook no .env: -ENABLE_FB_TEST = "true" - -# Executar apenas os testes de Facebook: -pytest tests/test_dao_conexao_facebook.py -v -``` - -> Ao terminar os testes, retorne `ENABLE_FB_TEST = "false"` para evitar postagens acidentais nas próximas execuções do `pytest`. +Consulte o guia completo em [docs/configuracao_facebook.md](docs/configuracao_facebook.md). --- @@ -213,7 +133,7 @@ bot-notification/ │ ├── dao/ │ │ ├── atlas_dao.py # Acesso ao MongoDB Atlas │ │ ├── conexao_discord.py # Envio de mensagens ao Discord -│ │ ├── conexao_facebook.py # Integração Facebook (desativada) +│ │ ├── conexao_facebook.py # Integração Facebook (Graph API v25.0) │ │ ├── gemini_dao.py # Integração Google Gemini AI │ │ └── web_screper_site.py # Web scraping do site de mangás │ ├── endpoint/ @@ -226,7 +146,7 @@ bot-notification/ │ ├── obra.py # Entidade Obra │ └── posts/ │ ├── post_discord.py # Modelo do embed Discord -│ └── post_facebook.py # Modelo do post Facebook (desativado) +│ └── post_facebook.py # Modelo do post Facebook ├── assets/ # Volume Docker (persistente) │ ├── config/ │ │ └── test_mode.txt # "true" para modo de teste diff --git a/docs/configuracao_facebook.md b/docs/configuracao_facebook.md new file mode 100644 index 0000000..ad833da --- /dev/null +++ b/docs/configuracao_facebook.md @@ -0,0 +1,165 @@ +# Configuração da Integração com o Facebook + +Este guia cobre o processo completo para criar um app Meta, configurar as permissões necessárias e gerar o Page Access Token para publicações automáticas na página do Facebook. + +--- + +## Pré-requisitos + +- Conta no [Meta for Developers](https://developers.facebook.com) (pode usar conta Facebook pessoal) +- Página do Facebook que você **administra** (onde os posts serão publicados) + +--- + +## 1. Criar o App no Meta for Developers + +1. Acesse https://developers.facebook.com/apps +2. Clique em **Criar App** +3. Em **Qual é o caso de uso do seu app?**, selecione **"Outros"** e clique em Próximo +4. Selecione o tipo **Business** e clique em Próximo +5. Preencha o **Nome de exibição do app** e o e-mail de contato +6. Clique em **Criar App** + +--- + +## 2. Adicionar o caso de uso "Gerenciar tudo na sua Página" + +1. Após criar o app, você será redirecionado para o painel **Adicionar produtos ao seu app** +2. Localize o caso de uso **"Gerenciar tudo na sua Página"** (_Manage everything on your Page_) +3. Clique em **Configurar** nesse caso de uso + +--- + +## 3. Configurar as permissões + +1. No menu lateral, vá em **Casos de uso** (ou _Use Cases_) +2. Localize **"Gerenciar tudo na sua Página"** e clique em **Personalizar** +3. Na aba **Permissões**, clique em **Adicionar** para cada uma das permissões abaixo: + + | Permissão | Finalidade | + |---|---| + | `pages_show_list` | Listar as páginas gerenciadas pela conta | + | `pages_read_engagement` | Ler métricas e engajamento da página | + | `pages_read_user_content` | Ler conteúdo publicado por usuários na página | + | `pages_manage_posts` | Criar, editar e excluir posts na página | + | `pages_manage_engagement` | Gerenciar comentários e interações da página | + +4. Após adicionar todas as permissões, confirme que as cinco aparecem listadas na seção **Permissões** da personalização do caso de uso + +> ℹ️ Não é necessário submeter o app para revisão da Meta enquanto você for **Administrador** da página e estiver testando com contas de desenvolvedor listadas no app. + +--- + +## 4. Gerar o Page Access Token via `/me/accounts` + +O token necessário é um **Page Access Token** (não User Token). A forma mais simples de obtê-lo é pela rota `/me/accounts`: + +1. Acesse o [Graph API Explorer](https://developers.facebook.com/tools/explorer/?method=GET&path=me%2Faccounts&version=v25.0) +2. No dropdown **"App da Meta"**, selecione o app que você criou +3. Certifique-se de que **"User Token"** está selecionado em **"User or Page"** +4. Certifique-se de que as seguintes permissões estão marcadas no campo **Permissões**: + - `pages_show_list` + - `pages_read_engagement` + - `pages_read_user_content` + - `pages_manage_posts` + - `pages_manage_engagement` +5. Clique em **Gerar token de acesso** e autorize no popup +6. O caminho `/me/accounts` já estará preenchido — clique em **Enviar** + +### Obtendo o ID e o token da página + +O `access_token` e o `id` corretos são os da **página**, não do usuário. Para obtê-los: + +1. No [Graph API Explorer](https://developers.facebook.com/tools/explorer/?method=GET&path=me%2Faccounts&version=v25.0), certifique-se de que o **User Access Token** está selecionado (não Page Token) +2. O caminho `/me/accounts` já estará preenchido — clique em **Enviar** +3. A resposta listará todas as páginas que você administra: + ```json + { + "data": [ + { + "access_token": "EAACxxx...", + "category": "Entretenimento", + "name": "Nome da Página", + "id": "110041288738055", + "tasks": ["ANALYZE", "ADVERTISE", "MODERATE", "CREATE_CONTENT"] + } + ] + } + ``` +4. Copie o `access_token` e o `id` do objeto correspondente à sua página + - `id` → valor de `API_ID_PAGINA_FACEBOOK` + - `access_token` → valor de `API_TOKEN_PAGINA` + +> ⚠️ **Importante:** use o `access_token` que vem dentro de `data[]` (token da página), não o User Access Token exibido no topo do Explorer. Tokens de usuário não têm permissão para publicar na página. + +--- + +## 5. Converter para token de longa duração (produção) + +O token gerado pelo Explorer tem validade de **~1 hora**. Para uso em produção, converta para um token de longa duração (~60 dias): + +``` +GET https://graph.facebook.com/v25.0/oauth/access_token + ?grant_type=fb_exchange_token + &client_id={APP_ID} + &client_secret={APP_SECRET} + &fb_exchange_token={TOKEN_CURTA_DURACAO} +``` + +- `APP_ID` e `APP_SECRET`: encontrados em **Painel do App → Configurações → Básico** +- Substitua `{TOKEN_CURTA_DURACAO}` pelo token gerado no Explorer + +O token retornado tem validade de ~60 dias. Para renovação automática, consulte a [documentação de tokens da Meta](https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived/). + +--- + +## 6. Atualizar o `.env` + +Adicione as variáveis ao arquivo `.env` na raiz do projeto: + +```ini +# Facebook — Produção +API_ID_PAGINA_FACEBOOK = "110041288738055" +API_TOKEN_PAGINA = "EAACxxx..." + +# Facebook — Testes (opcional, necessário apenas para rodar testes de integração) +API_ID_PAGINA_FACEBOOK_TESTE = "ID_DA_PAGINA_DE_TESTE" +API_TOKEN_PAGINA_TESTE = "EAACxxx..." +ENABLE_FB_TEST = "false" +``` + +> ⚠️ Nunca commite o `.env` com tokens reais. O arquivo `.env` já está no `.gitignore`. + +--- + +## 7. Testar a integração + +Para rodar os testes de integração com Facebook (faz postagens reais na página de teste): + +```bash +# No .env, habilite o modo de teste: +ENABLE_FB_TEST = "true" + +# Execute apenas os testes de Facebook: +venv/bin/python -m pytest tests/test_dao_conexao_facebook.py -v +``` + +> Após os testes, retorne `ENABLE_FB_TEST = "false"` para evitar postagens acidentais em execuções futuras do pytest. + +--- + +## Whitelist de obras permitidas no Facebook + +Nem todas as obras são postadas no Facebook — apenas as que estiverem na coleção `obrasPermitidasFB` do MongoDB Atlas. + +Para adicionar uma obra via bot Discord, use o comando: +``` +/adicionar_obra_permitida_fb +``` + +Para listar as obras atualmente permitidas: +``` +/listar_obras_permitidas_fb +``` + +O nome deve ser **exatamente igual** ao `titulo_obra` registrado no Atlas. diff --git a/src/dao/web_screper_site.py b/src/dao/web_screper_site.py index 7066667..47195ae 100644 --- a/src/dao/web_screper_site.py +++ b/src/dao/web_screper_site.py @@ -19,8 +19,16 @@ def __init__(self): logger_infos = logging.getLogger('logger_infos') logger_infos.info(" Iniciando Web Screper ") - # Definir o locale como "pt_BR.UTF-8" - locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8') + # Definir o locale como "pt_BR.UTF-8". + # Em ambientes sem o locale instalado (ex: WSL sem pt_BR gerado) + # a configuração é ignorada com um aviso — o Docker tem o locale. + try: + locale.setlocale(locale.LC_ALL, 'pt_BR.UTF-8') + except locale.Error: + logger_infos.warning( + "Locale pt_BR.UTF-8 não disponível neste ambiente. " + "Datas podem não ser formatadas em português." + ) def recebe_capitulos_diarios(self): diff --git a/tests/test_controller_obras.py b/tests/test_controller_obras.py index 63cbb19..a0bec18 100644 --- a/tests/test_controller_obras.py +++ b/tests/test_controller_obras.py @@ -25,21 +25,24 @@ def test_remove_obras_nao_registradas(self): def test_remover_obras_que_nao_pode_postar(self): - # Mock data + """ + Valida a lógica de whitelist: apenas obras presentes na lista + de permitidas devem ser retornadas. + """ lista_de_obras_para_postar = [ Obra("Obra Teste 1", "Teste", "Teste"), Obra("Obra Teste 2", "Teste", "Teste"), Obra("Obra Teste 3", "Teste", "Teste") ] - lista_de_obras_nao_permitidas = [ - {'titulo_obra': 'Obra Teste 2'}, - {'titulo_obra': 'Obra Teste 3'} + # Apenas Obra Teste 1 está na whitelist + lista_de_obras_permitidas = [ + {'titulo_obra': 'Obra Teste 1'}, ] - # Call the function - obras_filtradas = ControllerObras.remover_obras_que_nao_pode_postar(lista_de_obras_para_postar, lista_de_obras_nao_permitidas) + obras_filtradas = ControllerObras.filtrar_obras_permitidas_fb( + lista_de_obras_para_postar, lista_de_obras_permitidas + ) - # Assert the results assert len(obras_filtradas) == 1 assert obras_filtradas[0].titulo_obra == 'Obra Teste 1' diff --git a/tests/test_dao_web_screper.py b/tests/test_dao_web_screper.py index 36f6e77..db35763 100644 --- a/tests/test_dao_web_screper.py +++ b/tests/test_dao_web_screper.py @@ -2,14 +2,23 @@ import datetime import logging +from dotenv import load_dotenv from src.dao.web_screper_site import WebScreperSite +load_dotenv() + +MESES_PORTUGUES = [ + 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', + 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' +] + + class TestWebScreper: def test_valida_se_esta_recebendo_dados_obras(self): web_screper = WebScreperSite() dados_obra = web_screper.receber_conteudo(5) - [print(dado) for dado in dados_obra ] + [print(dado) for dado in dados_obra] assert len(dados_obra[0]) > 0 assert len(dados_obra[1]) > 0 @@ -17,39 +26,30 @@ def test_valida_se_esta_recebendo_dados_obras(self): assert len(dados_obra[3]) > 0 assert len(dados_obra[4]) > 0 - def test_valida_se_esta_recebendo_capitulos_obras(self): web_screper = WebScreperSite() dados_obra = web_screper.recebe_capitulos_diarios() - [print(obra) for obra in dados_obra ] + [print(obra) for obra in dados_obra] assert len(dados_obra) > 0 - def test_verifica_se_data_esta_em_portugues(self): + """ + Verifica se as datas retornadas pelo scraper estão no formato + em português (ex: 'março 7, 2026'). + Usa lista fixa de meses para não depender do locale do sistema. + """ web_screper = WebScreperSite() datas = web_screper.receber_datas() logger_infos = logging.getLogger('logger_infos') logger_infos.info(datas) - locale.setlocale(locale.LC_TIME, 'pt_BR.utf8') - for data in datas: - try: - # Tenta fazer o parse da data - dt = datetime.datetime.strptime(data, '%B %d, %Y') - logger_infos.info(f"A data {dt} está em um formato válido") - - except ValueError: - assert False, f"A data {data} está em um formato inválido" - - # Verifica se o nome do mês está em português - mes_numero = dt.month - nome_mes_portugues = datetime.date(1900, mes_numero, 1).strftime('%B').lower() - - assert nome_mes_portugues in [ - 'janeiro', 'fevereiro', 'março', 'abril', 'maio', 'junho', - 'julho', 'agosto', 'setembro', 'outubro', 'novembro', 'dezembro' - ], f"A data {data} não está em português" \ No newline at end of file + partes = data.split() + assert len(partes) >= 1, f"Formato de data inesperado: {data}" + mes = partes[0].lower().rstrip(',') + assert mes in MESES_PORTUGUES, ( + f"Mês '{mes}' não está em português na data '{data}'" + ) \ No newline at end of file diff --git a/tests/test_postagem.py b/tests/test_postagem.py index 2da74be..38a08e6 100644 --- a/tests/test_postagem.py +++ b/tests/test_postagem.py @@ -1,9 +1,12 @@ +from dotenv import load_dotenv from src.dao.atlas_dao import AtlasDAO from src.model.obra import Obra from src.model.capitulo import Capitulo from src.controller.controller_obras import ControllerObras from src.dao.web_screper_site import WebScreperSite +load_dotenv() + class TestPostagem: def test_verifica_remocao_obras_nao_registradas(self): atlas_dao = AtlasDAO() From 7505cc585ac9cef786b8de5821f6c455e0f8d6a0 Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 12:58:06 -0300 Subject: [PATCH 05/10] =?UTF-8?q?ci:=20adiciona=20git-cliff=20e=20workflow?= =?UTF-8?q?=20de=20release=20autom=C3=A1tico?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - cliff.toml: configuração do git-cliff com categorias em português (Novidades, Correções, Refatorações, Performance, Testes, Documentação, Manutenção, CI/CD, Build); ignora commits de merge e bump; ativa somente para tags no padrão vX.X.X - .github/workflows/release.yml: workflow disparado no push de tags v*; faz checkout completo (fetch-depth: 0), gera release notes com git-cliff (orhun/git-cliff-action@v3) e publica o GitHub Release automaticamente; tags com sufixo -rc/-beta/-alpha são marcadas como pre-release - .github/workflows/test-pytest.yaml: adicionadas variáveis de ambiente faltantes (GEMINI_API, URL_SITE, API_ID_PAGINA_FACEBOOK_TESTE, API_TOKEN_PAGINA_TESTE, ENABLE_FB_TEST=false) --- .github/workflows/release.yml | 40 ++++++++++++++++++++++++ .github/workflows/test-pytest.yaml | 17 +++++++++-- cliff.toml | 49 ++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+), 3 deletions(-) create mode 100644 .github/workflows/release.yml create mode 100644 cliff.toml diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..91e0711 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,40 @@ +name: Release + +on: + push: + tags: + - "v*" + +permissions: + contents: write + +jobs: + release: + name: Gerar Release Notes e publicar Release + runs-on: ubuntu-latest + steps: + - name: Checkout (histórico completo para o git-cliff) + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Gerar CHANGELOG com git-cliff + uses: orhun/git-cliff-action@v3 + id: git_cliff + with: + config: cliff.toml + args: --verbose --latest --strip header + env: + OUTPUT: CHANGELOG_RELEASE.md + GITHUB_REPO: ${{ github.repository }} + + - name: Criar GitHub Release + uses: softprops/action-gh-release@v2 + with: + tag_name: ${{ github.ref_name }} + name: Release ${{ github.ref_name }} + body_path: CHANGELOG_RELEASE.md + draft: false + prerelease: ${{ contains(github.ref_name, '-rc') || contains(github.ref_name, '-beta') || contains(github.ref_name, '-alpha') }} + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-pytest.yaml b/.github/workflows/test-pytest.yaml index 34ffaaa..e382189 100644 --- a/.github/workflows/test-pytest.yaml +++ b/.github/workflows/test-pytest.yaml @@ -35,13 +35,24 @@ jobs: - name: Run Pytest with secrets env: - API_ID_PAGINA_FACEBOOK: ${{ secrets.API_ID_PAGINA_FACEBOOK }} + # Discord API_KEY: ${{ secrets.API_KEY }} - API_TOKEN_PAGINA: ${{ secrets.API_TOKEN_PAGINA }} CANAL_LANCAMENTOS: ${{ secrets.CANAL_LANCAMENTOS }} - CANAL_TAGS: ${{ secrets.CANAL_TAGS }} CANAL_TESTES: ${{ secrets.CANAL_TESTES }} + CANAL_TAGS: ${{ secrets.CANAL_TAGS }} + # MongoDB Atlas URI_ATLAS: ${{ secrets.URI_ATLAS }} + # Facebook — produção + API_ID_PAGINA_FACEBOOK: ${{ secrets.API_ID_PAGINA_FACEBOOK }} + API_TOKEN_PAGINA: ${{ secrets.API_TOKEN_PAGINA }} + # Facebook — testes de integração (desabilitado na CI por padrão) + API_ID_PAGINA_FACEBOOK_TESTE: ${{ secrets.API_ID_PAGINA_FACEBOOK_TESTE }} + API_TOKEN_PAGINA_TESTE: ${{ secrets.API_TOKEN_PAGINA_TESTE }} + ENABLE_FB_TEST: "false" + # Google Gemini + GEMINI_API: ${{ secrets.GEMINI_API }} + # Web scraper + URL_SITE: ${{ secrets.URL_SITE }} run: | export PYTHONPATH=$(pwd) LC_ALL=pt_BR.UTF-8 LANG=pt_BR.UTF-8 python -m pytest -v diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000..c632667 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,49 @@ +[changelog] +header = """ +# Changelog\n +Todas as mudanças relevantes deste projeto estão documentadas aqui.\n +""" +body = """ +{% if version %}\ +## [{{ version | trim_start_matches(pat="v") }}] — {{ timestamp | date(format="%d/%m/%Y") }} +{% else %}\ +## [Não versionado] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} +### {{ group }} +{% for commit in commits %} +- {% if commit.scope %}**{{ commit.scope }}:** {% endif %}{{ commit.message | upper_first }}\ +{% if commit.breaking %} ⚠️ BREAKING CHANGE{% endif %}\ + +{% endfor %} +{% endfor %}\n +""" +footer = "" +trim = true + +[git] +conventional_commits = true +filter_unconventional = true +split_commits = false + +# Ordenação dos commits dentro de cada grupo +commit_parsers = [ + { message = "^feat", group = "🚀 Novidades" }, + { message = "^fix", group = "🐛 Correções" }, + { message = "^refactor", group = "♻️ Refatorações" }, + { message = "^perf", group = "⚡ Performance" }, + { message = "^test", group = "🧪 Testes" }, + { message = "^docs?", group = "📝 Documentação" }, + { message = "^chore", group = "🔧 Manutenção" }, + { message = "^ci", group = "⚙️ CI/CD" }, + { message = "^build", group = "📦 Build" }, + # ignora commits de merge e bump de versão + { message = "^Merge", skip = true }, + { message = "^bump", skip = true }, +] + +protect_breaking_commits = false +filter_commits = true +tag_pattern = "v[0-9].*" +topo_order = false +sort_commits = "newest" From 1cd5e406b5ae7d85aa2bc2b3b5c51d769aebc80b Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 15:27:14 -0300 Subject: [PATCH 06/10] chore: adiciona ambiente de desenvolvimento local - docker-compose.yml com servicos mongo e app (named volumes) - scripts/seed_dev_db.py para criar colecoes e indices no MongoDB local - dev.sh e dev.bat com menu interativo de utilitarios de dev - .gitignore atualizado para ignorar .env.dev --- .gitignore | 1 + dev.bat | 114 +++++++++++++++++++++++++++++++++++++++++ dev.sh | 101 ++++++++++++++++++++++++++++++++++++ docker-compose.yml | 31 +++++++++++ scripts/seed_dev_db.py | 111 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 358 insertions(+) create mode 100644 dev.bat create mode 100755 dev.sh create mode 100644 docker-compose.yml create mode 100644 scripts/seed_dev_db.py diff --git a/.gitignore b/.gitignore index d0dd079..0346373 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,7 @@ node_modules/ # Credenciais de Ambiente .env +.env.dev ## cache python diff --git a/dev.bat b/dev.bat new file mode 100644 index 0000000..279a0b8 --- /dev/null +++ b/dev.bat @@ -0,0 +1,114 @@ +@echo off +chcp 65001 >nul +setlocal enabledelayedexpansion + +:: ============================================================================= +:: dev.bat — Utilitários de desenvolvimento +:: ============================================================================= + +:MENU +cls +echo. +echo ======================================== +echo Bot Notification — Dev Utils +echo ======================================== +echo 1. Criar ambiente virtual e instalar dependencias +echo 2. Subir MongoDB local (Docker) +echo 3. Criar colecoes e indices no banco local +echo 4. Executar testes +echo 5. Subir aplicacao completa (Docker Compose) +echo 6. Derrubar containers +echo 7. Construir imagem Docker de producao +echo 0. Sair +echo ======================================== +set /p opcao="Escolha uma opcao: " + +if "%opcao%"=="1" goto VENV +if "%opcao%"=="2" goto MONGO_UP +if "%opcao%"=="3" goto SEED +if "%opcao%"=="4" goto TESTS +if "%opcao%"=="5" goto COMPOSE_UP +if "%opcao%"=="6" goto COMPOSE_DOWN +if "%opcao%"=="7" goto BUILD_PROD +if "%opcao%"=="0" goto SAIR + +echo Opcao invalida. +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:VENV +echo. +echo ^>^> Criando ambiente virtual... +python -m venv venv +call venv\Scripts\activate.bat +echo ^>^> Instalando dependencias... +pip install -r requirements.txt +echo ^>^> Pronto! O venv ja esta ativado nesta sessao. +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:MONGO_UP +echo. +echo ^>^> Subindo MongoDB local... +docker compose up mongo -d +echo ^>^> MongoDB disponivel em localhost:27017 +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:SEED +echo. +echo ^>^> Criando colecoes e indices no banco local... +python scripts\seed_dev_db.py +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:TESTS +echo. +echo ^>^> Executando testes... +pytest +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:COMPOSE_UP +echo. +echo ^>^> Criando volume de assets (se nao existir)... +docker volume create assets_dev +echo ^>^> Subindo aplicacao completa via Docker Compose... +docker compose up -d +echo ^>^> Containers rodando. Acompanhe com: docker attach bot-notification-app +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:COMPOSE_DOWN +echo. +echo ^>^> Derrubando containers... +docker compose down +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:BUILD_PROD +echo. +set /p versao="Informe a versao da imagem (ex: 1.0.0): " +if "%versao%"=="" ( + echo Versao nao informada. Operacao cancelada. + pause + goto MENU +) +echo ^>^> Construindo imagem bot-notif:%versao%... +docker build -t "bot-notif:%versao%" . +echo ^>^> Imagem criada: bot-notif:%versao% +pause +goto MENU + +:: ----------------------------------------------------------------------------- +:SAIR +echo Saindo... +endlocal +exit /b 0 diff --git a/dev.sh b/dev.sh new file mode 100755 index 0000000..79367c1 --- /dev/null +++ b/dev.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# ============================================================================= +# dev.sh — Utilitários de desenvolvimento +# ============================================================================= + +set -e + +# Cores para output +RED='\033[0;31m' +GREEN='\033[0;32m' +CYAN='\033[0;36m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +print_menu() { + printf "\n${CYAN}========================================${NC}\n" + printf "${CYAN} Bot Notification — Dev Utils${NC}\n" + printf "${CYAN}========================================${NC}\n" + printf " ${YELLOW}1.${NC} Criar ambiente virtual e instalar dependências\n" + printf " ${YELLOW}2.${NC} Subir MongoDB local (Docker)\n" + printf " ${YELLOW}3.${NC} Criar coleções e índices no banco local\n" + printf " ${YELLOW}4.${NC} Executar testes\n" + printf " ${YELLOW}5.${NC} Subir aplicação completa (Docker Compose)\n" + printf " ${YELLOW}6.${NC} Derrubar containers\n" + printf " ${YELLOW}7.${NC} Construir imagem Docker de produção\n" + printf " ${YELLOW}0.${NC} Sair\n" + printf "${CYAN}========================================${NC}\n" + printf "Escolha uma opção: " +} + +cmd_venv() { + printf "${GREEN}>> Criando ambiente virtual...${NC}\n" + python3 -m venv venv + . venv/bin/activate + printf "${GREEN}>> Instalando dependências...${NC}\n" + pip install -r requirements.txt + printf "${GREEN}>> Pronto! Ative o venv com: source venv/bin/activate${NC}\n" +} + +cmd_mongo_up() { + printf "${GREEN}>> Subindo MongoDB local...${NC}\n" + docker compose up mongo -d + printf "${GREEN}>> MongoDB disponível em localhost:27017${NC}\n" +} + +cmd_seed() { + printf "${GREEN}>> Criando coleções e índices no banco local...${NC}\n" + python3 scripts/seed_dev_db.py +} + +cmd_tests() { + printf "${GREEN}>> Executando testes...${NC}\n" + pytest +} + +cmd_compose_up() { + printf "${GREEN}>> Criando volume de assets (se não existir)...${NC}\n" + docker volume create assets_dev + printf "${GREEN}>> Subindo aplicação completa via Docker Compose...${NC}\n" + docker compose up -d + printf "${GREEN}>> Containers rodando. Acompanhe com: docker attach bot-notification-app${NC}\n" +} + +cmd_compose_down() { + printf "${YELLOW}>> Derrubando containers...${NC}\n" + docker compose down +} + +cmd_build_prod() { + printf "Informe a versão da imagem (ex: 1.0.0): " + read -r versao + if [ -z "$versao" ]; then + printf "${RED}Versão não informada. Operação cancelada.${NC}\n" + return + fi + printf "${GREEN}>> Construindo imagem bot-notif:${versao}...${NC}\n" + docker build -t "bot-notif:${versao}" . + printf "${GREEN}>> Imagem criada: bot-notif:${versao}${NC}\n" +} + +# Loop principal +while true; do + print_menu + read -r opcao + case "$opcao" in + 1) cmd_venv ;; + 2) cmd_mongo_up ;; + 3) cmd_seed ;; + 4) cmd_tests ;; + 5) cmd_compose_up ;; + 6) cmd_compose_down ;; + 7) cmd_build_prod ;; + 0) + printf "${CYAN}Saindo...${NC}\n" + exit 0 + ;; + *) + printf "${RED}Opção inválida.${NC}\n" + ;; + esac +done diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..a13e803 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,31 @@ +services: + mongo: + image: mongo:7 + container_name: bot-notification-mongo + restart: unless-stopped + ports: + - "27017:27017" + volumes: + - mongo_dev_data:/data/db + environment: + MONGO_INITDB_DATABASE: DadosPostagem + + app: + build: + context: . + dockerfile: Dockerfile-dev + container_name: bot-notification-app + restart: unless-stopped + depends_on: + - mongo + env_file: + - .env.dev + environment: + # Sobrescreve a URI para usar o serviço 'mongo' do compose + URI_ATLAS: mongodb://mongo:27017/ + volumes: + - assets_dev:/home/project/assets + +volumes: + mongo_dev_data: + assets_dev: diff --git a/scripts/seed_dev_db.py b/scripts/seed_dev_db.py new file mode 100644 index 0000000..14530c9 --- /dev/null +++ b/scripts/seed_dev_db.py @@ -0,0 +1,111 @@ +""" +seed_dev_db.py +============== +Script de setup para ambiente de desenvolvimento local. + +Cria as coleções do banco 'DadosPostagem' no MongoDB local com +os índices necessários, espelhando a estrutura usada em produção +pelo AtlasDAO. Nenhum dado de exemplo é inserido. + +Uso: + # Sobe apenas o MongoDB local: + docker compose up mongo -d + + # Executa o setup: + python scripts/seed_dev_db.py + +Coleções criadas: + - dadosObras → catálogo de obras + - registroObrasPostadas → controle de capítulos já anunciados + - obrasPermitidasFB → whitelist de obras para postagem no Facebook +""" + +import os +import sys +import logging +from typing import Any + +from pymongo import MongoClient, ASCENDING +from dotenv import load_dotenv + +# --------------------------------------------------------------------------- +# Configuração básica de log +# --------------------------------------------------------------------------- +logging.basicConfig( + level=logging.INFO, + format="%(levelname)s | %(message)s", +) +logger = logging.getLogger(__name__) + + +# --------------------------------------------------------------------------- +# Funções de setup +# --------------------------------------------------------------------------- + +def _criar_indices(db: Any) -> None: + """ + Cria índices nas coleções para garantir unicidade e performance, + replicando o comportamento esperado em produção. + + Parameters: + db: Instância do banco de dados MongoDB. + """ + db.dadosObras.create_index( + [("titulo", ASCENDING)], unique=True, name="titulo_unico" + ) + logger.info("Índice 'titulo_unico' criado em 'dadosObras'.") + + db.registroObrasPostadas.create_index( + [("titulo_obra", ASCENDING)], unique=True, name="titulo_obra_unico" + ) + logger.info( + "Índice 'titulo_obra_unico' criado em 'registroObrasPostadas'." + ) + + db.obrasPermitidasFB.create_index( + [("titulo_obra", ASCENDING)], unique=True, name="titulo_obra_fb_unico" + ) + logger.info( + "Índice 'titulo_obra_fb_unico' criado em 'obrasPermitidasFB'." + ) + + +def seed(uri: str) -> None: + """ + Cria as coleções e índices no banco 'DadosPostagem'. + + Conecta ao MongoDB pelo URI fornecido e cria os índices necessários + nas coleções. As coleções são criadas automaticamente pelo MongoDB + ao receber o primeiro índice. + + Parameters: + uri (str): URI de conexão com o MongoDB. + """ + logger.info("Conectando ao MongoDB: %s", uri) + client = MongoClient(uri) + + try: + client.admin.command("ping") + logger.info("Conexão com MongoDB estabelecida com sucesso.") + except Exception as exc: + logger.error("Falha ao conectar com MongoDB: %s", exc) + sys.exit(1) + + db = client.DadosPostagem + + _criar_indices(db) + + client.close() + logger.info("Setup concluído.") + + +# --------------------------------------------------------------------------- +# Ponto de entrada +# --------------------------------------------------------------------------- + +if __name__ == "__main__": + # Carrega o .env.dev se existir; caso contrário usa as variáveis do ambiente + load_dotenv(dotenv_path=os.path.join(os.path.dirname(__file__), "..", ".env.dev")) + + mongo_uri = os.getenv("URI_ATLAS", "mongodb://localhost:27017/") + seed(mongo_uri) From 991c1ac4e4e4e158df1d8a9cb9bcc88a42095b2a Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 18:31:48 -0300 Subject: [PATCH 07/10] =?UTF-8?q?docs:=20documenta=20gera=C3=A7=C3=A3o=20d?= =?UTF-8?q?e=20token=20permanente=20do=20Facebook=20via=20ferramenta=20UI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Renomeia seção 5 para 'Obter token permanente de página' - Adiciona Opção 1 (chamada OAuth direta em dois passos) - Adiciona Opção 2 (fluxo pela Ferramenta de Token do Explorer, sem código) - Inclui fix do venv no dev.sh e dev.bat (opções 3 e 4) --- .github/instructions/python.instructions.md | 56 ++++++++++++++++++ dev.bat | 12 ++++ dev.sh | 11 ++++ docs/configuracao_facebook.md | 33 +++++++++-- scripts/seed_dev_db.py | 2 + src/__pycache__/__init__.cpython-310.pyc | Bin 160 -> 145 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 171 -> 156 bytes .../__pycache__/gestor_txt.cpython-310.pyc | Bin 1638 -> 2590 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 171 -> 156 bytes .../controller_obras.cpython-310.pyc | Bin 3287 -> 3904 bytes src/dao/__pycache__/__init__.cpython-310.pyc | Bin 164 -> 149 bytes src/dao/__pycache__/atlas_dao.cpython-310.pyc | Bin 8145 -> 9507 bytes .../conexao_discord.cpython-310.pyc | Bin 2371 -> 4321 bytes .../web_screper_site.cpython-310.pyc | Bin 3423 -> 4188 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 166 -> 151 bytes .../__pycache__/capitulo.cpython-310.pyc | Bin 1733 -> 1718 bytes .../__pycache__/mensagens.cpython-310.pyc | Bin 8348 -> 9853 bytes src/model/__pycache__/obra.cpython-310.pyc | Bin 1689 -> 1697 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 172 -> 157 bytes .../__pycache__/post_discord.cpython-310.pyc | Bin 2792 -> 3516 bytes tests/__pycache__/__init__.cpython-310.pyc | Bin 162 -> 147 bytes ...troller_obras.cpython-310-pytest-7.1.2.pyc | Bin 4668 -> 4768 bytes ...est_dao_atlas.cpython-310-pytest-7.1.2.pyc | Bin 3832 -> 6941 bytes ...nexao_discord.cpython-310-pytest-7.1.2.pyc | Bin 1663 -> 1506 bytes ...o_web_screper.cpython-310-pytest-7.1.2.pyc | Bin 3253 -> 4570 bytes ...odel_capitulo.cpython-310-pytest-7.1.2.pyc | Bin 4864 -> 4849 bytes ...st_model_obra.cpython-310-pytest-7.1.2.pyc | Bin 5960 -> 5955 bytes ...t_model_posts.cpython-310-pytest-7.1.2.pyc | Bin 6115 -> 4948 bytes 28 files changed, 110 insertions(+), 4 deletions(-) create mode 100644 .github/instructions/python.instructions.md diff --git a/.github/instructions/python.instructions.md b/.github/instructions/python.instructions.md new file mode 100644 index 0000000..df688f8 --- /dev/null +++ b/.github/instructions/python.instructions.md @@ -0,0 +1,56 @@ +--- +description: 'Python coding conventions and guidelines' +applyTo: '**/*.py' +--- + +# Python Coding Conventions + +## Python Instructions + +- Write clear and concise comments for each function. +- Ensure functions have descriptive names and include type hints. +- Provide docstrings following PEP 257 conventions. +- Use the `typing` module for type annotations (e.g., `List[str]`, `Dict[str, int]`). +- Break down complex functions into smaller, more manageable functions. + +## General Instructions + +- Always prioritize readability and clarity. +- For algorithm-related code, include explanations of the approach used. +- Write code with good maintainability practices, including comments on why certain design decisions were made. +- Handle edge cases and write clear exception handling. +- For libraries or external dependencies, mention their usage and purpose in comments. +- Use consistent naming conventions and follow language-specific best practices. +- Write concise, efficient, and idiomatic code that is also easily understandable. + +## Code Style and Formatting + +- Follow the **PEP 8** style guide for Python. +- Maintain proper indentation (use 4 spaces for each level of indentation). +- Ensure lines do not exceed 79 characters. +- Place function and class docstrings immediately after the `def` or `class` keyword. +- Use blank lines to separate functions, classes, and code blocks where appropriate. + +## Edge Cases and Testing + +- Always include test cases for critical paths of the application. +- Account for common edge cases like empty inputs, invalid data types, and large datasets. +- Include comments for edge cases and the expected behavior in those cases. +- Write unit tests for functions and document them with docstrings explaining the test cases. + +## Example of Proper Documentation + +```python +def calculate_area(radius: float) -> float: + """ + Calculate the area of a circle given the radius. + + Parameters: + radius (float): The radius of the circle. + + Returns: + float: The area of the circle, calculated as π * radius^2. + """ + import math + return math.pi * radius ** 2 +``` \ No newline at end of file diff --git a/dev.bat b/dev.bat index 279a0b8..5aebf43 100644 --- a/dev.bat +++ b/dev.bat @@ -60,6 +60,12 @@ goto MENU :: ----------------------------------------------------------------------------- :SEED echo. +if not exist venv\Scripts\activate.bat ( + echo Venv nao encontrado. Execute a opcao 1 primeiro. + pause + goto MENU +) +call venv\Scripts\activate.bat echo ^>^> Criando colecoes e indices no banco local... python scripts\seed_dev_db.py pause @@ -68,6 +74,12 @@ goto MENU :: ----------------------------------------------------------------------------- :TESTS echo. +if not exist venv\Scripts\activate.bat ( + echo Venv nao encontrado. Execute a opcao 1 primeiro. + pause + goto MENU +) +call venv\Scripts\activate.bat echo ^>^> Executando testes... pytest pause diff --git a/dev.sh b/dev.sh index 79367c1..94878e4 100755 --- a/dev.sh +++ b/dev.sh @@ -37,6 +37,15 @@ cmd_venv() { printf "${GREEN}>> Pronto! Ative o venv com: source venv/bin/activate${NC}\n" } +_ativar_venv() { + if [ -f "venv/bin/activate" ]; then + . venv/bin/activate + else + printf "${RED}Venv não encontrado. Execute a opção 1 primeiro.${NC}\n" + return 1 + fi +} + cmd_mongo_up() { printf "${GREEN}>> Subindo MongoDB local...${NC}\n" docker compose up mongo -d @@ -44,11 +53,13 @@ cmd_mongo_up() { } cmd_seed() { + _ativar_venv || return printf "${GREEN}>> Criando coleções e índices no banco local...${NC}\n" python3 scripts/seed_dev_db.py } cmd_tests() { + _ativar_venv || return printf "${GREEN}>> Executando testes...${NC}\n" pytest } diff --git a/docs/configuracao_facebook.md b/docs/configuracao_facebook.md index ad833da..637bea6 100644 --- a/docs/configuracao_facebook.md +++ b/docs/configuracao_facebook.md @@ -94,9 +94,13 @@ O `access_token` e o `id` corretos são os da **página**, não do usuário. Par --- -## 5. Converter para token de longa duração (produção) +## 5. Obter token permanente de página (produção) -O token gerado pelo Explorer tem validade de **~1 hora**. Para uso em produção, converta para um token de longa duração (~60 dias): +O token de Usuário gerado pelo Explorer tem validade de **~1 hora**. Para uso em produção você precisa de um **Page Access Token permanente** (sem expiração). Há duas formas de obtê-lo: + +### Opção 1: Via chamada OAuth direta + +**Passo 1 — Converter o User Token em token de longa duração (~60 dias):** ``` GET https://graph.facebook.com/v25.0/oauth/access_token @@ -107,9 +111,30 @@ GET https://graph.facebook.com/v25.0/oauth/access_token ``` - `APP_ID` e `APP_SECRET`: encontrados em **Painel do App → Configurações → Básico** -- Substitua `{TOKEN_CURTA_DURACAO}` pelo token gerado no Explorer +- Substitua `{TOKEN_CURTA_DURACAO}` pelo User Token gerado no Explorer + +**Passo 2 — Obter o Page Token permanente a partir do token longo:** + +Com o token de 60 dias em mãos, repita a chamada da seção 4 (`GET /me/accounts`) usando esse token no cabeçalho de autorização. O `access_token` retornado dentro de `data[]` para a sua página será **permanente** (sem data de expiração). + +Para renovação automática, consulte a [documentação de tokens da Meta](https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived/). + +--- + +### Opção 2: Via Ferramenta de Token do Facebook (sem código — mais rápido) + +O Facebook possui um botão "escondido" que executa toda a troca OAuth por você direto na interface do Explorador de API. + +1. No **Explorador de API do Graph**, gere um User Token curto como descrito na seção 4. +2. Clique no **ícone azul de informação (ⓘ)** que fica logo ao lado do token exibido na caixa azul. +3. No balão que abrir, clique em **"Abrir na Ferramenta de Token de Acesso"**. +4. Uma nova aba será aberta. Role até o final da página e clique no botão azul **"Estender token de acesso"**. +5. O token de 60 dias será gerado na hora — **copie-o**. +6. Volte para o Explorador de API, **cole esse token longo** na caixa azul (substituindo o token antigo). +7. No seletor **"Usuário ou Página"**, escolha a sua Página. +8. O token gerado após a seleção da página é o **Page Access Token permanente** (sem expiração). Copie-o. -O token retornado tem validade de ~60 dias. Para renovação automática, consulte a [documentação de tokens da Meta](https://developers.facebook.com/docs/facebook-login/guides/access-tokens/get-long-lived/). +> ℹ️ Esse é o mesmo token que a Opção 1 produziria — a ferramenta apenas automatiza a chamada `oauth/access_token` por baixo dos panos. --- diff --git a/scripts/seed_dev_db.py b/scripts/seed_dev_db.py index 14530c9..0d888ee 100644 --- a/scripts/seed_dev_db.py +++ b/scripts/seed_dev_db.py @@ -70,6 +70,8 @@ def _criar_indices(db: Any) -> None: ) + + def seed(uri: str) -> None: """ Cria as coleções e índices no banco 'DadosPostagem'. diff --git a/src/__pycache__/__init__.cpython-310.pyc b/src/__pycache__/__init__.cpython-310.pyc index 469893b6b6adfbff5b99b565b08d4d3201f938b0..8abf730eebfecd311ef694d2354da2de9ac2be1f 100644 GIT binary patch delta 44 ycmZ3$IFXSjpO=@50SNdi+A=5dSc{nGXXNLm>SyN{mFgE1X&8aWhQ5q7VD;@mg%RY7N_Qw<>!=T N=BDPASyN{mFgE1X&8aWhQ5q7VD;@mg%RY7N_Qw<>!=T N=BDPABAt51Es8y?0LM1m;Dvdy+Y3$8Tnv7GA zw_BoALfVR3ULk=icn#jdw_Nc6+#s>#98Z$XYv4CE-I|6lGC?x+K;_0JSfw zFk8)*@5$6C{ovaNT?)|_5599Kx1prpfia{{r*4uNn~<=OwI`$x6FLuH_TaAVEqi#v zbDp9pO?^?EQ5avIkZEN`D8K^CD7D9>C{3kFTjLEadvR*C3ip(bbgaMyNJL?j7zs_? zG|$br)K$rD+-r@i2G$=Am5}JS!9ewTQipM}tJ21rWh%9N6q!BC`zlWC)+kCL*2y{S zTis|FCwnT4^wa(LnF?`A8)Ut+x$MTG&vHsz!s+6qXUjcl?z^cq!e+OgMT1yGI+S5o z$56XSDbUJOIoSP;=ymA!&#l&;8p_rarT1GSt@^SH5Ik09Cs8Kejk}SFRnkgzx78gW zKxqhg^c-U$Y_~c3!TKR=Ha21CBUJ&Ib-GEh1T0|V%_YChMaLY`sMRIWpF#sD#X@`R z1)b14~*4xmdqgdTOO?g_GFqHXpZAKmv2BPKgJ1kHT z?{$)1I{-BB_h>F?hYN38s>kQ=fRO47?bfyI%Eus#=GfnUw6i_j*%pmp6|*?qjR#Ug zS|OIJkxVStG7{EadA|)#w=icaE~xaSdQspjwwgOMCqT9vpjW5y<*|An z!lj6Pjn-%YzZ$*rFMl`f z)X~EgJP|oS^wLR08wEh~V0g`+{@IhkM=U~O-%GXM$I%G7}wA|=@`S<7G zzLn+5x{!59z^b17@vExK1k$C^5p=EJhSZnf2lY(V=b5#s>oD|gW9?Y=dJ8;y4UOaQ zZG5|c1~b!~$bmYLT7LkJ1(C?1<(T?UGU=mI@xwLflA;h6qOO3b0}q+3yy9&Ai03lo zV%XWb{sm&?_}f|GFH^ZUEiP4FGXDRl{AvzwP(JX6qa8mhacgjT*t8@ZpSjcGIo`g? z#Q|TV*mfw7*Bx&Qkpd-p8#bV?fVtZ!pUuD$cL%t>4E-0Ve}n-}J3iILG!FSMpj(PW zX2|2Y33v|o^T&xLH?rL*L2h__pU8? z^XMP&2Y4596+DYaPwvKp1sCSc+nG0S2ljscBb)OyEsez41if`bM!66wquVNJB0W8N zEyLdEYptk`6Be03h>T>2#&m)JSx6{U-h{1ulX5Idl4c)v^aQ%l2(|;B^O1&vpZk8~A`wA?A;`zFQF_L><(IA%t**PP8Eo zpo7Osh$rCB1u!O(0lG@WTR=ls8RZMg%8n*xqr|1@2c{pXab|LhUzm|BD_~ZHF9`*T zp95tBK;sXjkeSl*7gB&CeB>qH79~uH#5F3ILEr2;*QQ~afoYg-U^B;K%luQ_ zRvLPepQg$ec{wOwWJ?lOCH(osEZ$BLjf4na{s~1C(-fsy%4A(9OcjaA7Q+%`^`FgM Gy7U8ijbhaR diff --git a/src/controller/__pycache__/__init__.cpython-310.pyc b/src/controller/__pycache__/__init__.cpython-310.pyc index 4c09486edb8ee8bbb2fc117723ad2bd6fe115669..f1c80bf1193b88e2cc03ff17bf77ee9b96ed842f 100644 GIT binary patch delta 44 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 D($IBz delta 1178 zcmaKrU2NM_6vyvz65DAK$4QsQZIaemvUO%GVSt2&G`g-sgMFl8-Bz|yD!12LouziM z-A;=fh6EANzTQ!ZRiU-6vH~SJF!dL#?51(`H zx&L#0^T^#X#Z9I92tHdg#`(>IC5u0cQvB^#dls@#kswBXTxD`{_39lQc&MuusuE z)v#CSARWR!O$$@RD0aVu98}(@FSv_VeZ_X{d3)L4L#>rMwS3E2aa$|)qU8i`cU@58 z&}R1%zrhAuPhQi0z#T)kSQHgv==(v(6GXM80_ zV>bjUhA}D*5-L&ohF}AY<60k0tVTK#MwHj$G#N_GKJOr>BOnvk$ydTR0A!lH7mt!4 zd3hd4M+VYXg4CKqQ=$CK;tXMFB@YT4RW@Jp0P{42cC2cd^9${Gb;3J$WodJ$Ciq56BaXV7YSRSf9uK(yIvrUX9w zHd6qD-N{sNyqVdLDjC@_@@V!o4D)IB9{WyBvTm*hg#D7+ahi0Z??)+_BD6QU1eY+u z#xf82y63sN>FPF5$@X-2&NFpq{idrgS>7V%P0d$zL-P804hCXl8#nPArpq1<)G^@wT#PVLm6Qx?VADEAX@_S0L zABQx}h(D9ao8*qWIZl63(6*y||8W3s8VxqoUO09~)9v9$k$W2Ye;3h56@Nu@UqcAM zb(DnxL5_%m0xC9C^UwC^Q#JoT61!U(>fS0G02Fw$IEKI1?ot7HxO7<9BJA_hAMg%a z9sXFI;YUbt6gl2y)sY&QY;Q$l7f0$KcCU|Ifqz>)SFS#`x=`K;dG=Yk5os7IyH=SP xY4AXAalFlOj$@8vo`W*6TGshyGF}!rEhpqrY^uCVF5*~~v$C4Zu%p$V{{lN;FrEMa diff --git a/src/dao/__pycache__/conexao_discord.cpython-310.pyc b/src/dao/__pycache__/conexao_discord.cpython-310.pyc index b20a1ed7660b15d1fea74e971069445c58de382d..8aa903f89b80c5e08acf1915529110aecdc3cf47 100644 GIT binary patch literal 4321 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 W+9B_urgnH;%nRq&^hOx-MgCv+=vET| delta 1225 zcmZvc&u`pB6vzF>Ki9k2kTgwG1gJl0S4$fpC7>z=wkfnl?IO`4q+TquGfBO8J!tG* ziO8!3r4r!~q-ahEAvO}1+&K5jffM40G?%LX0DnL)nR)Z(z3;rS{qXp2 z^G!K36I%GRp|$Z#u-AMER`=Skyv$O2;M{S*x@vKoJNGQ^Y_mHqhg(+5-TU=Cgw`9{guk8a^J8ar09U5^96NdUPIJscv);rzKjp#6|KyIn0;UWVu^qc#D_InltY7Euj*W?+AM6A7b{SY` zok5Q#_jfUQY4vAIuVg&fW!F*4HPnyNUf8$(omKK`-L2+r{f2#bX=^4t_Mhhw95Ysn zsk+wosiiqn-xNjEyBlYjNR7{vyeAbm`cM04Y+NN%k(=2}4n&m6D9(miFOkL{h^$Ct zW_)yxlB_UZPo{FHOfBX-+DJso&7u;8R9UPd^v>f=F^ImDd0}cfCQJrsF#21kJ(-;5 zzzJXxnrPD#f7MkY=3nXi{t6t@fBPpUhRNJ`SW66TY$}N>MkL2cvJGi$HOyL`dX0`5 zifA~93XvB=IcQKGS=~Z@Au_d0hI53og!8ntNGHNNJ}rOr^pa}0mcNJyAw0?&;MpPS zYl6e5EkJmr30tT25AJFGNAP={z6<3OLj7~?)A#0Sc${zo(E@c6y8~Ob$kaxd#M5s#m9F=bR zD^LM)iWyh|YqS;F@M0>#bdE})@wlXme4?3L{x6;h)&`OfQ}HgKM~;82Iz@#58f>2Z E1Fs=8sQ>@~ diff --git a/src/dao/__pycache__/web_screper_site.cpython-310.pyc b/src/dao/__pycache__/web_screper_site.cpython-310.pyc index 2133a179bff223da7d115607496ce02dec8426bf..a41668d7534ac9793057b8fd2a77d8112f11c8bf 100644 GIT binary patch literal 4188 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 diff --git a/src/model/__pycache__/__init__.cpython-310.pyc b/src/model/__pycache__/__init__.cpython-310.pyc index 327b6f9d220de85dbafc6b7c1c2c5fa230f83fcb..7cc4c0a3b2fbb77a8bbd716de5c7bc8f80427eb9 100644 GIT binary patch delta 44 ycmZ3+IGvFvpO=@50SNdi+A=5dSc_QcXXNLm>SyN{mFgE1X&8aWhQ5q7VD;@mg%RY7N_Qw<>!=T N=BDPA1X8Urs`+s7nSN46y;~7CYKa%4q+-}0RSZI B4Z8pU delta 62 zcmdnSdz6SyHVrs|hv=4B>lmKN)#q?YNYq!y>lmE>=BWh!I=02THVTL1t6 diff --git a/src/model/__pycache__/mensagens.cpython-310.pyc b/src/model/__pycache__/mensagens.cpython-310.pyc index 698961f4584f3dd4edb805c7798637215c801192..db344007b871f04b35813ce40c5260f010fd6dab 100644 GIT binary patch delta 1813 zcmb_d&ubGw6yCQ<(==@&)LN}Jn-LX_O5(5B+WMnv)mCj0TSTH#wwY;NYcuWau4rjl zP>*7fxrv7sPa+7CqZhGw@ZulPf54L$JqUu}yv+|4H}&E|zJ1yGzW42$c{BU$m_dlktl z&$(^#tf5lOR<35!qJE2cLO0Klx$cqLM$FT&$F=-l`D;XD! zJ&=`ej6?Euvcvm&OO4NK6sB|$q51--IHckh8usG`6}QreA2+Ia6OHKE_;Al%go zb4~_EM=y=^kSk1B6V|NDi0zucMhkqJn8YeNOca?zxJztCII%5<5oS9p%VdHJlTc1f zky#C+k$Vk&f^5*m`wupa)Upd)P?|o{N-D<_3HRmg+a#Dbj)$nX0BV`c-$-&{Dq|^<#t{Bf)~7?f69Yi!m-^VRmIn@ z-Xx(MF~(F!30s^}Q;-g=wm8-dAM=~oz=!%0Ud(4#SE*(kzlBpngWNbtV~x{C60kc|8UVp=I? delta 356 zcmezCGslrHpO=@50SLAPYNk!moya$f(PiUGXGXRZ(_jWov(0Qw8yJh&ON(_=Qp@yHQj1gb%JOr{GILY&O7b_KV&>pyytVnV&~rvc-N_eOg(sgAF<{i5 z{9j}pqrv2LqMI3SO->T)XEdDrNi2m?dvmz>L?(#B&3`047#Xc58>+}|PLh^p1S+hP zkz=$48?r$rjL~K?yR1LAEzprgb|AuGa-yt0qx0m6vWIm+qMEElydZHt5Md7@m_dX9 zkkDiGib;V>lck6SsJe(1 zM6iJfuE{5uv>DYVe_{G05XGC5nU@`(oLG=qQks(=HTfI!14i-51#F^|->_6NMoms* PUCkx|(j_-poUI7}`Gqb5 delta 161 zcmZ3;JCm0$pO=@50SNX6Yo< zKc_4+H#M&$fAV9-94>aCHfJC%mYW>OB+E9JJ(xk0b#e=njv$i)mnL%&3sA0z6-2O2 zzQCl-C^z{J(SyN{mFgE1X&8aWhQ5q7VD;@mg%RY7N_Qw<>!=T N=BDPALd$NvlOi8 z#Y>r^7A)eylZYPmq!%yZK~w^IP!z?hdhnqBlhU;!&XE80{r^n<$9$?hTxW)bf`MR} z7q0lnR?V9y@yL8@eV!_pk)5OJ6sl_T*GBP^`3HMvNrD`W%0P9BdL)r1&?&Qr6MWO4 zxka3yrreU)?gaM;Mgcy*H6hGS2vsZuF#~ZPWYt1co0C8Rqc#EhxdbWOMwhi6zvDK%PHIt?hLPh^zwU>D>qkz<3nBp>>+S&O$;Y?&Z9I;P z`~^O~iD_U;t$G;5UZ?Nbk8bmA(vdN{7@lFS;|0QvxzxRb*cyoYF;P1gcD!0EWZl{{ z3!7d&j`)3P|E_UB^Ei(+NyD%u1uIwvxrAld(ob17KsLmd3@raD5pIzkgYPgxu_zIq z!xTdc#`#WpBcCB-rQlH?&;jrP*v8+Jy`|t%AIJl64}go6;=)jm1bbE>GW!C^meG=h zda7uBGj|=)9B>7AIZ>NxrmIa2_#iLlDnmmH#U6?Egv>#&5&|Q%>V7R(!T1?Js9fc* zmBYNIE=t`L)HnRO`cmqC1d;Q%s>MGj`-ZDVO4?q)OehBoN$@Tc1F zY?_;9eh^nRRso}}#%{xL&$y{pcc+(HZ!R~{IqL^*+b%;u$Mad}^j%7k*XRaxg{2&O ztp2xCvD=RQ&L5wwk7`Dl#asG1Wf=Y-y1}pM>t*A+S>ku~&9d>$Eb~|TcG>u94uWMw z*2*&GHDhG94lV01A&WE*z!!<6sd!5W3W^s*`J~Ai(=axzSXG=&ATW{n(tn82Viu5e zbwBInac(=)VHD2+7%4!cF)>y@XNHf0bz;g^Hm<~mxFVsaZj(AIE_x0xmF;25pYF5z=AUXw8L@uPFG z#OGtlqGKpVMj=wbm&cHm+aSP;!19?QTc`yQE7G=Vu^o(2%JsrRqPjt+V{^mtmxJ(# z*_;P+VUmlSsOJVrscrI3U|3Gr4!D&_fZr4meF-EUZSX#4%Z?K__BM}eqGw=SNC zU=^#F5r$z93bukN4Dy#!1$+%xhEbhs*Yn3>^lHWv@43>c%iRph%Gp@xL zX4zKxu#R4R^GdE^yeGaCggB5(;+b+IvrqCnB3JlS&x|dZHs>R=W0*^3!rJEQ;g)F7sW9!kvF!M!n~bb-Xr99Z<0zyO+MS+n4b6;1HgBH{ zD)-#T@s4A%O*({eIsJBBm}*^}1UK9U&~W{^T2qO_e$hqkT^%b#V0Ds_BKt|_wfEvr zaYkc5=!~|PY6>Qj_*@*PpjJgoy&x^SyN{mFgE1X&8aWhQ5q7VD;@mg%RY7N_Qw<>!=T N=BDPADs3m;H7wY>t2gUZ ziEO1(kG(NSTsVYN)e3HCe)K%>v65eRVabB>5 z*cI(7Vb>mVd#RW^RJcm@d{zFWNGwd}=v9<&#I@b236K&s#4yR4yR*?jaiQ#V zW7_^x?N_$7s`leEFMdq@fz5hfzkY&8mn-;IfjXH-mnwsaQl37R8%_)q)dPL~OrE@B z{$`b6IqdU2Tz#{Z6;j#|7^TzxW~EY=Tp5{1Kldks+*b(B!xBko=v5siEhCAxmj|+6 z2&ab^gyqy7&lOH>pw{dtJSHhI)=4)~4d9GgOOXEBvp}x@aEW5ct>b>Hr_xb7E|0Jgi G)BgdlkYlg_ delta 1174 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 p5Fc?&3_Fuo5Em71BojVpC6RGC-ju6!)Z zs|U**rP35HUV7<8{0D+ZPlH17=0A{v;LI-c16|l>X5MGtm-l`4nZ5bnSL1dp78cku z1=NlA%5MBKnArVNkRA!Daufzp04T|b2Q?bG)7ffl*r=sDa~}niW+^8trRR1FmU?E} zY?@s>W58a?fEc!Ww$(FRu<9zk2K!(i426OCRA`qa!4bC>fiMUF z!JRO`K z2|JEyw^587N|`GOMxi8!6azJgF7bVk0VT)MWReTysf02-Rv?yKAh%^%;W+~>FJg6(yhz_1(@Jg0{4Jyr!wS6`t4nsuvzVf?sRp_bag|g5)ZK1LcGB&?~P4gM|f?=DOUOtUBbc6ZUZtEsSlVm(H{&Lp0x!?XGjdIWX z2TeOq&HI#p9kl9&(;OP*EqM3E&#hhHHQyDUKRjy`9ro87J%~*5DO&(z zurkIcy~g1_hci!|W+Ryq+;y1$4Mk9Z5{yQ?s2Zorde^iZvyD-Nz+6@KR3>}5<=g_V N$8-NFO8(^Xe*p*=8|DB2 diff --git a/tests/__pycache__/test_dao_conexao_discord.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_dao_conexao_discord.cpython-310-pytest-7.1.2.pyc index 22620fb2f3abe2c13cd25b211b56c0f58dd42d46..36d574186921c9c696aa3e01c342967610271ffa 100644 GIT binary patch delta 436 zcmYjNK}*9h7){cyt6NvQ9i|7tGMO+u3{S2wMW?uvBDjkMDW!>8U6<0dpu?NuedZ6S z7x7h@)TL`9IP~Ux49g<*14QhJC{} zx&Y^~dJC|6gY5F?{z+Fvvn;SJz--=udseJG^N1k8;1Dzl`@>p~u$Y*bmA>~bu*(B9&mqE!EnAk=;_s-V#ZJ8Z&Pg`olsjg>})$GNVS z7B<7HSR~-M5r55L@uRv@>!iv=9k)&yX6r?nYpS*bijzLsfSGl+(=yQDq*Pcze?{_Y AA^-pY delta 569 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�G8km37CFx(@ES4xz45UIUI;>IHiJPJ#{sa79AwEjl)^M& zI_T$7tfN#JH_pIAnVmpA&hnUB*I*Q9{V)#FFcGF6sBkDSf@!~L0Y+K+mXw(^=YnA- zlTZiZqj4Ojp@x}m-8f3bL(_O7`hhBm&iFj!nF_ML3{3+8l&M}@H?FT6x7LlDrBQzD zPMJYzT)X-?k*`74|N7bf<17*TlPHY_QLe6VG1=!riFA_1lPD3X&i4D6zLI7-8b$+) zbsv{WSsCy!3)T?tjgL*&uHqz&BOV4y1mGOP`rw+UJcBn@DJc&Ss5S_f`gG3bz_EX( zU(o5Duk!QW{~hovOpbw(%`KDv0uID;CSQ;l(`;U`j9w{#5ewj9N|2>>^{B?#f>Bbi zACjN{cIHgCw0Gpq>jm)U0@)rJ6qx<@gjfFnoK4C5B)#kq?H|8Kq2fWcb8RhnS2yNO ztODR!Lr?BqB)krzt-@VU%jPxR2K$wwwqo;{`vFPm6H-)K>m$Njf21?Ns2Bc(%o;^QeGYNX^LEjI%JT}2+sd<{FU+@X<@q(tUo7fSd46LN zfCiOk!|Fa@+x(0{b!mdV!n|cMp99S2i>5`}TB2>O&_c~=%=`~uwKx63p=rk1XasjF zN{5-6`ePm3e|Im}!#mUZ?)}a#|6XVJgK6!}4i9zM$+1><;C!4cIwI-hNvAxXS!Z&x zfa8<>DF5cyc|_^bXS(6vU1NZ2B?DZGVyNP>39nDt?)`4l)Q-YbL^3n=p_stM1U1Kt zpM>({FPW)^eHq2ZNx}$>qda|VyBIn*9A!#p##2Izqz@r#S*~+byfmAXLmn4Xs{zHa zC*-fYq++`)Nm)FbY$uyq2IQ0 zcv)z;_>irZW2^b^g>fz{cganJy162-a@`X(lG`vYFQV8%k7@$k`q(%a%|;s9NYyxd zBBb0xzjG+gqqqQ~+m@KSd=-SL+6?3_>KGz4jO%q~ySmP72gb(*P4h$myI#ka*0}OO z;vrl2zp-xIvNTwVZ=vINO0p5s(jD>_0w_sLB+s`E;j2d=TG;sKaj6c!4cIL16qK zNHU(s0`z7Oe3*wZmZl((-v-?B5Cs;2HGxYYv0~zpRCql+;?ZWqj=?4JRu#~0pScv2 zHFK{#2vEoNq?fF?)FA_wf^Nptudf>?k?dgDSGORz(5@5$vJ1-(ACJ a;o5!jeo*Fi7c0HO|0u5kQozc#*na^1N}P%S diff --git a/tests/__pycache__/test_model_capitulo.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_model_capitulo.cpython-310-pytest-7.1.2.pyc index 4adca9a1734d1c716c656a88c6fafb30c720b323..f1286fb39c5f249d0a9986654040b9a7b8d22cf4 100644 GIT binary patch delta 47 zcmZor`>4v3&&$ij00ev$ZJ8T+YB)q3^)vEwQ}wg+i%Rtiit@8klS_&>ujUBl0suEp B4vhc+ delta 62 zcmeyU+Mvdh&&$ij00i2MnrRz(YB-bw^fU5vQ}xR-^D>h&ON(_=Qp@yHQj1gb%JOr{ QGILY&O7b_);Rxjd044Mj?*IS* diff --git a/tests/__pycache__/test_model_obra.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_model_obra.cpython-310-pytest-7.1.2.pyc index 747111c85801cb8642b23b3fd8a7ce26a355c2be..f0177cb7b56b50adba1963d69a08a8cd119ae289 100644 GIT binary patch delta 70 zcmX@1cUX@%pO=@50SNdi+A>`?@?K&UvDMGW&rQ|O&Mzv}FDS~-N=+^)-ps_t$HaJf YvLMHCE*%Bu#DZcgh3MGLH#iFT0N#NWn*aa+ delta 95 zcmX@CcS4UhpO=@50SL4iHPfs&@?K(9_R-JC&rQ`Y%goD6&MYm~O-U`&Pf0CK%`3~# yDa*`F%`3^@{F#-HiSguQH%^twY8;Ds6u4G0{$jGV)nu$Pn0%2%eDgOBUp@eUT^^JG diff --git a/tests/__pycache__/test_model_posts.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_model_posts.cpython-310-pytest-7.1.2.pyc index 167ad49c21e2963ce93ac63537d2eb5a8acbb804..a137f3b242336b82072a95eb277f9be33c803c45 100644 GIT binary patch delta 638 zcmYk&y>HV%7zS`Vb{r=tAB8rdZJ;4Er3bYBNKu3+Eu>;$U|~U7Dl4`ULuy-huGDy8 zLG0D3%nV4KtBeeY{{faTAy~Q~u`+Rwi)bzR=kt5#=ic)V1(qt-aM%%yHYRX%5LV3)Kgr=RmD?vv(F`>O^ULfl?ktEzw$}_sZSlh5%BNooJ!=R z!UV8XxSnXWjlE?jN^!LODBsPhS@Q?P7ru>ZD;5Y9qOz{ z!9eWO#y*oHy&%gA{C$48HiO*q$Y-&$+jk;A-XDdGR`|F4hxrF$?$4Gn4EH?aRY>=Z zh=wn{e#|Dvg;VtgTAwN`rX-uTjH6kg{jcxINjZ;wK34W#UlWU|3a*1Cum!e36Wjz1 zunbyY1>6FwfPmXz0o)M~o!-TG4d66%9i+`&dK8U!)4z2!wyBA_4REkCHuJW|H%u>P}2muxY^l2&+y;XS-HuzTD#Z~^=WPt4hDWO;N4nSIsZ5vZSv2x F=3o9>kZb?| delta 1718 zcmb7^OKjX!6o!309*^h!$Rz12rLCGYZb>FHp$!BgLR(4;v{XviWHU^2or&qh9^LCi zB=Tq^$_iK%xyvpx5<;4FBsMHqvZ^W}kYKhfP&Wv+kwBc^Nl26wBrM&}zwhJtKi59@ zhml`O88@9yD0E$7=F*e&7nvU~o~I{ESzugQP&wo3C(1&EN4Q3JjYqjo_b89eDW~naMM5vqT)(`XsYz)G@67OMbA8H`=$z^q6Cd3O zuV*=$*bP35eK6bA_m_%(1Q`GZ5lL&VmnXKf2SSxA6bs#z?OV&9*PJc|EP7$6Qkp22 zuGSpK64h(V_Hs?ss`GNy8E-oE?$&){l(DnHqxkv30>Wk+w)AS%#ah$$RvWGq`QT~% z%h4M&wtc&_?5XJ40VQApC<7H>5_k!?44eh7 z5KKc%LB9+jN%0C0noQ0%*Q?upcpjPZDfwW5A>)8L5?V+xe7eHf>fpqA`JsE?joI#0G@zV65Ft1ZJf zr01nJ(>&!HON^({zod3Fp7Ao9*^aWN$oFYH=W87%7D(lx97f~NdWX@yo%drM#!??Wbs={0+KoH)9{G((3yZ0tiOlA)=i zoBSVpe43U#cayn7hs4R?*NoZjr5bL%PUUDjORn6A-gTunEsoJoB(lJ90Kca=0h|Jc zfYZPWz!@O?!_PtCloG?h2ylU5_KPUA3Pgat0&DM7ST6<_wo~uL>z4O!=%}Z`(t#pE z{p?iSi%|Pj_`CvyA2au_#U|cEh-sxwd>!&NU>0}-2&?ZZ6zWM_2i^n@72~*PNw2!- zI?}4IT2;#->4}=C@)~z#)xAdtoa0u7Ri~p&xHuamHd0qpk%XFH^V(ktEu%sf*{ACF z>=E0TnWvbyU2Zk-G35Vz#T`=*5{2P+Zo=&yU=G;#9V(n8LMIs1Bw#3pY7|q&u-DA> hjC-qg!?PVJ#sXQGjE6_vU78qd72Mq6a6zT-+~4PMnf3qx From 66170bf897c59a88bcee54429fcdec377da43b5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Gabriel?= <62671194+Vincius-dev@users.noreply.github.com> Date: Sat, 7 Mar 2026 18:45:33 -0300 Subject: [PATCH 08/10] Update .envExample Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- .envExample | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.envExample b/.envExample index cf7b298..2189da6 100644 --- a/.envExample +++ b/.envExample @@ -37,7 +37,7 @@ API_ID_PAGINA_FACEBOOK = id_numerico_da_pagina_facebook # Token de acesso de longa duração da página do Facebook (produção). # Gerado via: https://developers.facebook.com/tools/explorer/ -# Permissões necessárias: pages_manage_posts, pages_read_engagement, publish_to_groups +# Permissões necessárias: pages_manage_posts, pages_read_engagement API_TOKEN_PAGINA = token_de_acesso_da_pagina_facebook # ============================================================================= From 8b3696c50de70be787442abd8c0e61c90030fc0e Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 18:55:16 -0300 Subject: [PATCH 09/10] =?UTF-8?q?fix(facebook):=20adiciona=20valida=C3=A7?= =?UTF-8?q?=C3=B5es=20e=20robustez=20nas=20chamadas=20=C3=A0=20Graph=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Valida photo_id após upload: aborta com ValueError se ausente ou inválido - Configura timeout de 30s em ambas as requisições (upload e feed) - Adiciona Session com retry automático (3 tentativas, backoff exponencial) para status 429/5xx - Valida credenciais de produção ausentes antes de chamar a API, lançando EnvironmentError com mensagem explícita --- src/dao/conexao_facebook.py | 46 +++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/src/dao/conexao_facebook.py b/src/dao/conexao_facebook.py index a994906..e580f68 100644 --- a/src/dao/conexao_facebook.py +++ b/src/dao/conexao_facebook.py @@ -1,8 +1,28 @@ import logging import os import requests +from requests.adapters import HTTPAdapter +from urllib3.util.retry import Retry from dotenv import load_dotenv +_TIMEOUT_SEGUNDOS = 30 +_MAX_RETRIES = 3 + + +def _criar_sessao_com_retry() -> requests.Session: + """Cria uma Session com retry automático e backoff exponencial.""" + retry = Retry( + total=_MAX_RETRIES, + backoff_factor=1, + status_forcelist=[429, 500, 502, 503, 504], + allowed_methods=["POST"], + raise_on_status=False, + ) + adapter = HTTPAdapter(max_retries=retry) + session = requests.Session() + session.mount("https://", adapter) + return session + class ConexaoFacebook: @@ -42,9 +62,21 @@ def postar_anuncio_facebook(post_obra): else: token_de_acesso_fb = os.getenv("API_TOKEN_PAGINA") id_pagina_fb = os.getenv("API_ID_PAGINA_FACEBOOK") + if not token_de_acesso_fb or not id_pagina_fb: + logger_erros.error( + "[MODO PRODUÇÃO] Credenciais do Facebook ausentes " + "(API_TOKEN_PAGINA / API_ID_PAGINA_FACEBOOK). " + "Postagem abortada." + ) + raise EnvironmentError( + "Variáveis API_TOKEN_PAGINA e/ou API_ID_PAGINA_FACEBOOK " + "não estão definidas no ambiente." + ) logger_infos.info(f"Postando no Facebook: {post_obra.titulo_obra}") + session = _criar_sessao_com_retry() + # Passo 1: envia a URL da imagem como foto não publicada → obtém photo_id. # Usar URL em vez de upload binário evita criar entradas duplicadas # na galeria da página a cada nova postagem da mesma obra. @@ -52,13 +84,14 @@ def postar_anuncio_facebook(post_obra): f"https://graph.facebook.com/v25.0/{id_pagina_fb}/photos" ) - response_upload = requests.post( + response_upload = session.post( url_photos, params={"access_token": token_de_acesso_fb}, data={ "url": post_obra.imagem_obra, "published": "false", }, + timeout=_TIMEOUT_SEGUNDOS, ) if not response_upload.ok: @@ -69,18 +102,27 @@ def postar_anuncio_facebook(post_obra): response_upload.raise_for_status() photo_id = response_upload.json().get("id") + if not photo_id or not isinstance(photo_id, str): + logger_erros.error( + f"Resposta inesperada no upload da imagem " + f"(photo_id ausente): {response_upload.text}" + ) + raise ValueError( + f"photo_id inválido após upload: {photo_id!r}" + ) logger_infos.info(f"Imagem enviada. photo_id: {photo_id}") # Passo 2: publica no feed com a imagem anexada via photo_id url_feed = f"https://graph.facebook.com/v25.0/{id_pagina_fb}/feed" - response_post = requests.post( + response_post = session.post( url_feed, params={"access_token": token_de_acesso_fb}, json={ "message": post_obra.retornar_mensagem_post(), "attached_media": [{"media_fbid": photo_id}], }, + timeout=_TIMEOUT_SEGUNDOS, ) if not response_post.ok: From c87a614180e10976d6b7ca0ab21efa57cddf79c4 Mon Sep 17 00:00:00 2001 From: Vincius-dev Date: Sat, 7 Mar 2026 18:59:55 -0300 Subject: [PATCH 10/10] =?UTF-8?q?chore:=20remove=20arquivos=20=5F=5Fpycach?= =?UTF-8?q?e=5F=5F=20e=20.pyc=20do=20reposit=C3=B3rio?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/__pycache__/__init__.cpython-310.pyc | Bin 145 -> 0 bytes src/__pycache__/__init__.cpython-311.pyc | Bin 172 -> 0 bytes .../Download_Imagens.cpython-310.pyc | Bin 1238 -> 0 bytes .../Download_Imagens.cpython-311.pyc | Bin 2028 -> 0 bytes .../__pycache__/Gestor_JSON.cpython-310.pyc | Bin 2323 -> 0 bytes .../__pycache__/Gestor_JSON.cpython-311.pyc | Bin 7326 -> 0 bytes .../__pycache__/Gestor_TXT.cpython-310.pyc | Bin 1647 -> 0 bytes .../__pycache__/Gestor_TXT.cpython-311.pyc | Bin 3256 -> 0 bytes .../__pycache__/Gestor_TXT.cpython-38.pyc | Bin 1596 -> 0 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 156 -> 0 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 183 -> 0 bytes .../download_imagens.cpython-311.pyc | Bin 2421 -> 0 bytes .../__pycache__/gestor_txt.cpython-310.pyc | Bin 2590 -> 0 bytes .../__pycache__/gestor_txt.cpython-311.pyc | Bin 5641 -> 0 bytes .../__pycache__/Controller_IO.cpython-310.pyc | Bin 893 -> 0 bytes .../__pycache__/Controller_IO.cpython-311.pyc | Bin 1124 -> 0 bytes .../Controller_Postagem.cpython-310.pyc | Bin 5159 -> 0 bytes .../Controller_Postagem.cpython-311.pyc | Bin 8459 -> 0 bytes .../__pycache__/__init__.cpython-310.pyc | Bin 156 -> 0 bytes .../__pycache__/__init__.cpython-311.pyc | Bin 183 -> 0 bytes .../controller_obras.cpython-310.pyc | Bin 3904 -> 0 bytes .../controller_obras.cpython-311.pyc | Bin 5038 -> 0 bytes .../controller_postagem.cpython-311.pyc | Bin 3391 -> 0 bytes src/dao/__pycache__/Atlas_Dao.cpython-310.pyc | Bin 5915 -> 0 bytes .../__pycache__/Conexao_Discord.cpython-310.pyc | Bin 2360 -> 0 bytes .../__pycache__/Conexao_Discord.cpython-311.pyc | Bin 4290 -> 0 bytes .../Conexao_Facebook.cpython-310.pyc | Bin 1202 -> 0 bytes .../Conexao_Facebook.cpython-311.pyc | Bin 1921 -> 0 bytes .../Web_Screper_Site.cpython-310.pyc | Bin 3420 -> 0 bytes .../Web_Screper_Site.cpython-311.pyc | Bin 6021 -> 0 bytes .../__pycache__/Web_Screper_Site.cpython-38.pyc | Bin 3414 -> 0 bytes src/dao/__pycache__/__init__.cpython-310.pyc | Bin 149 -> 0 bytes src/dao/__pycache__/__init__.cpython-311.pyc | Bin 176 -> 0 bytes src/dao/__pycache__/atlas_dao.cpython-310.pyc | Bin 9507 -> 0 bytes src/dao/__pycache__/atlas_dao.cpython-311.pyc | Bin 16121 -> 0 bytes .../__pycache__/conexao_discord.cpython-310.pyc | Bin 4321 -> 0 bytes .../__pycache__/conexao_discord.cpython-311.pyc | Bin 8138 -> 0 bytes src/dao/__pycache__/gemini_dao.cpython-311.pyc | Bin 2458 -> 0 bytes .../web_screper_site.cpython-310.pyc | Bin 4188 -> 0 bytes .../web_screper_site.cpython-311.pyc | Bin 6543 -> 0 bytes .../__pycache__/pagination.cpython-310.pyc | Bin 3107 -> 0 bytes .../__pycache__/pagination.cpython-311.pyc | Bin 5790 -> 0 bytes src/model/__pycache__/Capitulo.cpython-310.pyc | Bin 1717 -> 0 bytes src/model/__pycache__/Capitulo.cpython-311.pyc | Bin 1613 -> 0 bytes .../__pycache__/Logger_Config.cpython-310.pyc | Bin 1907 -> 0 bytes src/model/__pycache__/Mensagens.cpython-310.pyc | Bin 8371 -> 0 bytes src/model/__pycache__/Mensagens.cpython-311.pyc | Bin 13065 -> 0 bytes src/model/__pycache__/Mensagens.cpython-38.pyc | Bin 1793 -> 0 bytes src/model/__pycache__/Obra.cpython-310.pyc | Bin 1449 -> 0 bytes src/model/__pycache__/Obra.cpython-311.pyc | Bin 2065 -> 0 bytes src/model/__pycache__/__init__.cpython-310.pyc | Bin 151 -> 0 bytes src/model/__pycache__/__init__.cpython-311.pyc | Bin 178 -> 0 bytes src/model/__pycache__/capitulo.cpython-310.pyc | Bin 1718 -> 0 bytes src/model/__pycache__/capitulo.cpython-311.pyc | Bin 2589 -> 0 bytes .../__pycache__/logger_config.cpython-311.pyc | Bin 3574 -> 0 bytes src/model/__pycache__/mensagens.cpython-310.pyc | Bin 9853 -> 0 bytes src/model/__pycache__/mensagens.cpython-311.pyc | Bin 16581 -> 0 bytes src/model/__pycache__/obra.cpython-310.pyc | Bin 1697 -> 0 bytes src/model/__pycache__/obra.cpython-311.pyc | Bin 2563 -> 0 bytes .../__pycache__/Post_Discord.cpython-310.pyc | Bin 2779 -> 0 bytes .../__pycache__/Post_Discord.cpython-311.pyc | Bin 4424 -> 0 bytes .../__pycache__/Post_Facebook.cpython-310.pyc | Bin 2198 -> 0 bytes .../__pycache__/Post_Facebook.cpython-311.pyc | Bin 3633 -> 0 bytes .../posts/__pycache__/__init__.cpython-310.pyc | Bin 157 -> 0 bytes .../posts/__pycache__/__init__.cpython-311.pyc | Bin 184 -> 0 bytes .../__pycache__/post_discord.cpython-310.pyc | Bin 3516 -> 0 bytes .../__pycache__/post_discord.cpython-311.pyc | Bin 5399 -> 0 bytes tests/__pycache__/__init__.cpython-310.pyc | Bin 147 -> 0 bytes tests/__pycache__/__init__.cpython-311.pyc | Bin 174 -> 0 bytes ...conexao_discord.cpython-310-pytest-7.1.2.pyc | Bin 1737 -> 0 bytes ...ontroller_obras.cpython-310-pytest-7.1.2.pyc | Bin 4768 -> 0 bytes ...ontroller_obras.cpython-311-pytest-7.1.2.pyc | Bin 10968 -> 0 bytes .../test_dao_atlas.cpython-310-pytest-7.1.2.pyc | Bin 6941 -> 0 bytes .../test_dao_atlas.cpython-311-pytest-7.1.2.pyc | Bin 16271 -> 0 bytes ...conexao_discord.cpython-310-pytest-7.1.2.pyc | Bin 1506 -> 0 bytes ...conexao_discord.cpython-311-pytest-7.1.2.pyc | Bin 2105 -> 0 bytes ...dao_web_screper.cpython-310-pytest-7.1.2.pyc | Bin 4570 -> 0 bytes ...dao_web_screper.cpython-311-pytest-7.1.2.pyc | Bin 9828 -> 0 bytes ...test_gestor_txt.cpython-311-pytest-7.1.2.pyc | Bin 5283 -> 0 bytes .../test_model.cpython-310-pytest-7.1.2.pyc | Bin 3898 -> 0 bytes ..._model_capitulo.cpython-310-pytest-7.1.2.pyc | Bin 4849 -> 0 bytes ..._model_capitulo.cpython-311-pytest-7.1.2.pyc | Bin 12490 -> 0 bytes ...test_model_obra.cpython-310-pytest-7.1.2.pyc | Bin 5955 -> 0 bytes ...test_model_obra.cpython-311-pytest-7.1.2.pyc | Bin 14192 -> 0 bytes ...test_model_post.cpython-310-pytest-7.1.2.pyc | Bin 153 -> 0 bytes ...est_model_posts.cpython-310-pytest-7.1.2.pyc | Bin 4948 -> 0 bytes ...est_model_posts.cpython-311-pytest-7.1.2.pyc | Bin 15995 -> 0 bytes .../test_postagem.cpython-311-pytest-7.1.2.pyc | Bin 2635 -> 0 bytes ...est_web_screper.cpython-310-pytest-7.1.2.pyc | Bin 3166 -> 0 bytes 89 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/Download_Imagens.cpython-310.pyc delete mode 100644 src/classes_io/__pycache__/Download_Imagens.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/Gestor_JSON.cpython-310.pyc delete mode 100644 src/classes_io/__pycache__/Gestor_JSON.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/Gestor_TXT.cpython-310.pyc delete mode 100644 src/classes_io/__pycache__/Gestor_TXT.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/Gestor_TXT.cpython-38.pyc delete mode 100644 src/classes_io/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/classes_io/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/download_imagens.cpython-311.pyc delete mode 100644 src/classes_io/__pycache__/gestor_txt.cpython-310.pyc delete mode 100644 src/classes_io/__pycache__/gestor_txt.cpython-311.pyc delete mode 100644 src/controller/__pycache__/Controller_IO.cpython-310.pyc delete mode 100644 src/controller/__pycache__/Controller_IO.cpython-311.pyc delete mode 100644 src/controller/__pycache__/Controller_Postagem.cpython-310.pyc delete mode 100644 src/controller/__pycache__/Controller_Postagem.cpython-311.pyc delete mode 100644 src/controller/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/controller/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/controller/__pycache__/controller_obras.cpython-310.pyc delete mode 100644 src/controller/__pycache__/controller_obras.cpython-311.pyc delete mode 100644 src/controller/__pycache__/controller_postagem.cpython-311.pyc delete mode 100644 src/dao/__pycache__/Atlas_Dao.cpython-310.pyc delete mode 100644 src/dao/__pycache__/Conexao_Discord.cpython-310.pyc delete mode 100644 src/dao/__pycache__/Conexao_Discord.cpython-311.pyc delete mode 100644 src/dao/__pycache__/Conexao_Facebook.cpython-310.pyc delete mode 100644 src/dao/__pycache__/Conexao_Facebook.cpython-311.pyc delete mode 100644 src/dao/__pycache__/Web_Screper_Site.cpython-310.pyc delete mode 100644 src/dao/__pycache__/Web_Screper_Site.cpython-311.pyc delete mode 100644 src/dao/__pycache__/Web_Screper_Site.cpython-38.pyc delete mode 100644 src/dao/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/dao/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/dao/__pycache__/atlas_dao.cpython-310.pyc delete mode 100644 src/dao/__pycache__/atlas_dao.cpython-311.pyc delete mode 100644 src/dao/__pycache__/conexao_discord.cpython-310.pyc delete mode 100644 src/dao/__pycache__/conexao_discord.cpython-311.pyc delete mode 100644 src/dao/__pycache__/gemini_dao.cpython-311.pyc delete mode 100644 src/dao/__pycache__/web_screper_site.cpython-310.pyc delete mode 100644 src/dao/__pycache__/web_screper_site.cpython-311.pyc delete mode 100644 src/endpoint/__pycache__/pagination.cpython-310.pyc delete mode 100644 src/endpoint/__pycache__/pagination.cpython-311.pyc delete mode 100644 src/model/__pycache__/Capitulo.cpython-310.pyc delete mode 100644 src/model/__pycache__/Capitulo.cpython-311.pyc delete mode 100644 src/model/__pycache__/Logger_Config.cpython-310.pyc delete mode 100644 src/model/__pycache__/Mensagens.cpython-310.pyc delete mode 100644 src/model/__pycache__/Mensagens.cpython-311.pyc delete mode 100644 src/model/__pycache__/Mensagens.cpython-38.pyc delete mode 100644 src/model/__pycache__/Obra.cpython-310.pyc delete mode 100644 src/model/__pycache__/Obra.cpython-311.pyc delete mode 100644 src/model/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/model/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/model/__pycache__/capitulo.cpython-310.pyc delete mode 100644 src/model/__pycache__/capitulo.cpython-311.pyc delete mode 100644 src/model/__pycache__/logger_config.cpython-311.pyc delete mode 100644 src/model/__pycache__/mensagens.cpython-310.pyc delete mode 100644 src/model/__pycache__/mensagens.cpython-311.pyc delete mode 100644 src/model/__pycache__/obra.cpython-310.pyc delete mode 100644 src/model/__pycache__/obra.cpython-311.pyc delete mode 100644 src/model/posts/__pycache__/Post_Discord.cpython-310.pyc delete mode 100644 src/model/posts/__pycache__/Post_Discord.cpython-311.pyc delete mode 100644 src/model/posts/__pycache__/Post_Facebook.cpython-310.pyc delete mode 100644 src/model/posts/__pycache__/Post_Facebook.cpython-311.pyc delete mode 100644 src/model/posts/__pycache__/__init__.cpython-310.pyc delete mode 100644 src/model/posts/__pycache__/__init__.cpython-311.pyc delete mode 100644 src/model/posts/__pycache__/post_discord.cpython-310.pyc delete mode 100644 src/model/posts/__pycache__/post_discord.cpython-311.pyc delete mode 100644 tests/__pycache__/__init__.cpython-310.pyc delete mode 100644 tests/__pycache__/__init__.cpython-311.pyc delete mode 100644 tests/__pycache__/test_conexao_discord.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_controller_obras.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_controller_obras.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_atlas.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_atlas.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_conexao_discord.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_conexao_discord.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_web_screper.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_dao_web_screper.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_gestor_txt.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_capitulo.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_capitulo.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_obra.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_obra.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_post.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_posts.cpython-310-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_model_posts.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_postagem.cpython-311-pytest-7.1.2.pyc delete mode 100644 tests/__pycache__/test_web_screper.cpython-310-pytest-7.1.2.pyc diff --git a/src/__pycache__/__init__.cpython-310.pyc b/src/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 8abf730eebfecd311ef694d2354da2de9ac2be1f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 145 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd2KczG$ O)edA@F%ytrVE_O|vmjLf diff --git a/src/__pycache__/__init__.cpython-311.pyc b/src/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 7b422db02627911aa714c535df19b5b5b11b5017..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 172 zcmZ3^%ge<81RoZfr-A6lAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnFMIur{M=Oi zvdp~9{iOU7-Msvg%(Tqp#FEVXJpJOLWc~Pfpz@OV pc)fzkUmP~M`6;D2sdh!IK=VL07V`s%56p~=j2{?aL=iJk3;=%pDyjeg diff --git a/src/classes_io/__pycache__/Download_Imagens.cpython-310.pyc b/src/classes_io/__pycache__/Download_Imagens.cpython-310.pyc deleted file mode 100644 index 91335d9db22c0d81e18fc55a3c385c9e46dd40d3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1238 zcmaJ>&5I;86i-sAub!IO-c}HC!4kYQxYKy?u!!uk!-}wsporKaMY@vd$yinCNm4Uw zQ+=Af?`kCt-BgP4;0aJG1ZJJbhTv>}{q0!uH#KI(!kHg8+n$G(SAM^4ap^9}82pK$PO z!l6f@7j>atb&*~TE7LCMLLR<_wqz6EV#QmmA9uJP@u-Vmp&yAyynM$V^hp;1LeeFD zwnZ4(!!G9W4S8|2NxQT^>XM5)e(u*mEQRkTz^F++L}qafUjKaqG9V}W$b%={Md1h- z8lAeVQp=^#g>250SsyWDgf%m{qsv8B+O|?|)at4job{R>ubO512JkhITIUx(Z*%cX z8Y>>;j$AL+mnsbrwkf&qqH`T>H zCD|-px)k>5ke)l#q7)0rQ!O+zjws{kirI4)4UvsYYWBV0QX3b*Dn~DrY#jAfxkQW0 zRv2sCSTkuvai(-(EVC_usFi43c&()sE-qDLA<5~;rEEBOoGDFxP6wQEWr_-_WbQ7+ z5msrb3J$okQ7+}L3v}U7orcSST-K;s6ii>X@@h!LtW;wl(yi+!q~C>ke?FO=!^GK@ zY-A~0GvnfFwovwdqpUoWC9_gBGo#B{3D?00Q%E)Y_t`#P{owAMu{DsyUmyE{*v9Nw z^Jm?B04l;Gk_41w!3ZZHpveSh!59-if-`c2@BK9iGD3e}-~UgX|BG=7w=OA)hC$hd z8x=*Zcw6~?Ruq>lt9B#$JxF6HeNW}y=iiSQ#CX~hl##(Rjr4&Zop_aia(97^W7wYK l+ZO^h${(I#_8z8ZSLc2~^6@T}PcT@<-~9w7*cUq?e*+IIRiXd@ diff --git a/src/classes_io/__pycache__/Download_Imagens.cpython-311.pyc b/src/classes_io/__pycache__/Download_Imagens.cpython-311.pyc deleted file mode 100644 index 64f3a2bf49db5ccfcfd58100e3e0a80b38387683..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2028 zcmaJCT~FIq^xCmQ0EZY#OIc_@?HCKRm}zB*5A`WiH=y*Pnx4|zMM5F6S_S{D@ zvrQwk18)VQj7;4^VfG)w&V?zb^}2#h-4Lg5-JFY6mE4J{GW(rCY$62_2T@w4?xUzj zroo8E;UjuROX!j;ewdUN6%997Xo8I%c=s)EzlqG6MG(ag>22V4;H^LoQp!ju!YsK9L zBfP~lYUaF_H{V*6i$DFoPgzy5sZ8`abY?!wR~P0bbybq3iN0{aAdTq+4Fyh*CK;kE$vPI( zni_*ipEo4z&^mUQlw>YBUe_9Sd`amuMOF>$u&SvfVL7g=n!~0HRWlu*p)9B2IAX`M zsF)6KNGevu1vs79l*}|}>nR1aGX`vSnqswEC*>>Zb4!RtzjC2~~(FD@p=F zFoe`yb4k~PdELCC>884%#w1e(0XAYnEI~?*MO7DGzaEBDcb%REDXT!aYBxvqgH%eE zy>e{J|EZHm@iLtKHMGYEZGNoCkK6qCI{Uoma>3XAuNUzh8<{WfeQ~c45{iKlJ1|m4 zRP)d-*S0ZJI3F%@gElu<;0DWHbm8LTnTIpq+<0`Oi~`N0F8X|S{rv}{rS8y{Wp`g* zpWY2#cr^BS>fu!3?eSkme|zuOYsKKS9h_dDJ>qIBQ49>(fuS;@{oT9#*}}PrC$oUy zDe{vxKUv@>OZ@r0uHLV${B*HPu)Boy4@z9;A6)aDYl30 z_ArF)A9?a|iSOF%I+L>(L)oFs-!{2hgk zck_1u!Bga}+T7KG`;>cYmBAfQ`ln;TNQiwFVj>rtpY>CK=faHR6Gcse4ilXgQB3M` zIzebo6qnOdqOxN2!tS5YK44^o2qO2ii^!FXF9BLR9A)MW7QV-EWV~716=n@`s~O}n zbk5Z~aQMjI%{{OcN5p<*GjaaPH&qGqn(-E}d<>uX!=zkFE>dC9ekhs2Avmdh>u$y}Qs_MO0@4Gr{G^zxipFjOB zy4)b-51hOieoSF+Gp>q+cC=sAXoaqy4b9P50u@owd!hwq6YiYG|K^;>O)&Wvj7wIT@ z_>!mv*m-rM_b3}iy`4CX2k}_@L>3}$N?7IB70OiFL>z{&a_f^mhU{suTE=) zgEK3;jwedK&r1LBEFaE_^2W4j1GZ53(%oaW015TdFZ}7^J}E2n{AmE(~W z^3z`^DXWxBF6U=tWe+WwKLfRF*fUzlN6CLq`RVj2cZmnuN|5r~6OLs}(fM2_% zm!B;>SzRFjYZlg5h-`fAfX6-ATp>VprmW@Xike)2{hDl9xCm5jpsHgO!1HzM`QHl; zxNGs>K>sDwzu-^?%cpAz3lei^1BQMVz$PTcy&9&(7J-3ZCdmuuTei)BoxXI;LOLEs zbG2g{Nt`}DE)LU>0?KBTLGf%xL)8YU9cEbfBNH5zo2`Z!Xu-CrUQM7L2ib6R?GkFz z1mF?o@z-!=GWBtGU&PX>yO!L^aS{$RiU=W@lLin5=yM9 zXb?S!)M}sk&e?rETqs1?;C}E z)-0tW3uhKWH=K1&!!rM&5651xZ%1tsMwW)maWDt$8p&56i;xt!yMJY_U zPD5dUjW=tWu#b(_EFZ_=48I){2;dp=1>h0PT`uTua44OpF4DSO6wz&OL4^eFfEEAMr^QFmIkI>QzWGzXlu z{^o3%Rq4e8?l9J*P1sw8y^9Ae7Cd9G1D^r6ec#l*6TIo76iz3X{y)>#Ixb!WsTf9K zXsTg2%;Y#hydH+zW0A~u)FN7iw#?aQEyb!+Soj!ady51FjP&eUr=~u@eM~LWhU=&c z;-jQ{^RP5*5KZ%BV;w?b!)umK7LR`kW=XV&J8&g-kN*zrWoZw5n|3C+Iy34T-uJd6 NfQqyZk${)A*+2Z!QW^jN diff --git a/src/classes_io/__pycache__/Gestor_JSON.cpython-311.pyc b/src/classes_io/__pycache__/Gestor_JSON.cpython-311.pyc deleted file mode 100644 index 7ec55bde9b30d2d6a142be7b946d7273e44d4dfd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7326 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 diff --git a/src/classes_io/__pycache__/Gestor_TXT.cpython-310.pyc b/src/classes_io/__pycache__/Gestor_TXT.cpython-310.pyc deleted file mode 100644 index d032b0c6083b2c5bc9b08b7e0c0dc74e23665881..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1647 zcmZuxzi%5i6ef8*>7+=mofK|^28~n1!vVF0wp&pY1{xqsprrxQ2q=ilk&>yN?qrg- zQ$Yp_I8&Eyolj%`C8ArWPTdRi$9q&{OOAQqBOiY}@_qcitGeAbf%5xbzp9@(A%CE= zULtUgpxV#DNFr%L2FsQXDEO>k6E1~r z)9KHenYGH<-fYLHk+#lM;C*2`GYfle#`5py*+iGemB`G=sXnU&hW1U2rpu9Ujg)&9BAXae^1EkQp=D-- z61maPhOjoJo?BH6e2rmL607Y5A9h+fb+eL}wP zUNA?;td8bvLG3+9YmPliP8tDw+D~KCf?cM8rU}M3)N6PG>yt_LgOb|VG%{OZVwt~> zLmQG`nr+?i*3?9o~dw?q0)MuH|s=({9LPU&lz&BzOx`N2m`Kh_%0&~ocj#Ka1JQo_wp?d10KBZ zshNH71bDHxqTHTQxq1aeIGiQ>FAw%72m3PZtOKU)P#4Oe>OHTfs`T8bO!^p@tfxyd zaU`ojE&2q8r$MzG^}B+X4t;ln>o*YgJHXFC*(){Nhj13(W{Ymo4t!hm@jv{(*@HF2 z-`SMoB~}ILa|QM@a2yhdN`!YeKnmnpLON$PhF||q-g|jp3m-Y z!kM{K(A6vhK+}f#5Y7z91(?i7;QIL7Xs3JxIK2hOJj7)mqe0DG)6Va%!fhh+2v!9p zAuikWlT8-hzNeoyQHo_YQ9}5(5R*!t7TE6yaRQfK&KP8Qpu5?_-eWY^w+g+W2$Utt w$|5lmlCY$eB%Q?IILIz2?hf<=D-6Cwn7S>NPrh1S=4<@(hQuHs-DY>$|H-|NW&i*H diff --git a/src/classes_io/__pycache__/Gestor_TXT.cpython-311.pyc b/src/classes_io/__pycache__/Gestor_TXT.cpython-311.pyc deleted file mode 100644 index 89d306072c1311cef5ea10b3c381736ca1970659..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3256 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 LPihcAMi1EEf^L$O diff --git a/src/classes_io/__pycache__/__init__.cpython-310.pyc b/src/classes_io/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index a629be0372a1cd98c4dab18baf57782075c2e615..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd8AD@|*SrQ+w ZS5SG2!zMRBr8Fni4rFjK6OdqG008ulB(wkk diff --git a/src/classes_io/__pycache__/__init__.cpython-311.pyc b/src/classes_io/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index a8e4e40f81dac7dd3499ed12a570d199078942dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 183 zcmZ3^%ge<81RoZfr-A6lAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnFE9O!{M=Oi zvdp~9{iOU7-Msvg%(Tqp#FEVXJpJOLWc}ov#Ny)A z;`q#b{rGsG&XV|ey@JYL95%W6DWy57c15f}qd}Gz^8<+w%#4hT9~fXn5i?K>0N6G! A2><{9 diff --git a/src/classes_io/__pycache__/download_imagens.cpython-311.pyc b/src/classes_io/__pycache__/download_imagens.cpython-311.pyc deleted file mode 100644 index 4c7faffbc9efa5d1b904978cd0075e3c02730cb2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2421 zcmaJ?Uu@Gx7(XY@zcy`La2rBfFzpJY|H3E}2r(qIpsg)*64M^2Hd$`$7H5fFd``nE z2lau6YO1sjAr&zu!V6>Kg-7-_Y2!VvEHyd_t<%KA-h#>`#M8cWl7^IaclPJ+?tb6j zyYKvSTU!f)R(W`OHsVL#eu6~(m#vOa6J@EBpyjgadWsnDb zie&FCB(sk^2t9$f+NOOn^973g{-MLEI75OL%#4JS7d}tb5blSm4Yqh-){ugz6|lhE zLepN^0~)*}lGO8BMwjIAtTd-+xJf|(~w&ek{wj^T?ip*9d+N&`w_feN0ABS}ju~oYCjz6hlyFBYsmga~Ykq zE%NwexkU&b;OmH&ZLP8R~tVCJT4O*6@RhDEOiy4SgA{}5yF?B=LMH%#}nodG; zJwW1fqcdpLkg%p_6;U#-=hOw)5j?MJ7%bJMFg@$Sc6)mzaSa3#3#z83)ErJE6|86r zdS*d&lb4v$%@IvE)mb$qnX0ZOu#rlnz*DSXQPmT2?V_yim4-*>za>4h(jp{o=TbG3 zi^Dta*3th%)0nUWH{}v~!T0{fOJQlK=kZcQ;Fi5_aT-6FE^qOlasuxP4`^bRcer2c7U>DLe=& z4h~chADUoZxpaBF%=fNczJ0lP+~$WIerWk(Io9`}_g-(&vSX*5*s0}-%?MvXT-yY5 z_h9w=;_#9C`3KfLt2F%av)peBzuvSDPdSIDR>R;4-*xBo+WFh(i^KN*gtI?UL7tA@ zGB0fK1MB=i>FC6>OF-bU`ALVLEb)_NzUO6k|NV21TkP&Jr+aKQSmq9FaPf66ZgWEp zH&o(=UUtUr4nJn?&Jm|`1Y+wr^)y=MyQ`i%eJ5>x%;CpM{8+^cYc9YguPF32C5^e= zxHoU!>^2Sg>ge6zj;wP>N`0R^{R#*?HkWj`WQj`xv&r?;*FUqlafcf(apS;L;xx(C zRO5ZHyMLVQz8Ld8kFghfL(c^U=v15~K~dBsILIPt5yh-7=Q5NJi{ka1l&P*5{UH4d z+5(D5UBsX@W6Xxwkmo7U*0q!kG1fD=CoWjWd?Pq3-TZ NU%B(I_gHoP`41x9HOK$} diff --git a/src/classes_io/__pycache__/gestor_txt.cpython-310.pyc b/src/classes_io/__pycache__/gestor_txt.cpython-310.pyc deleted file mode 100644 index 9f8124c51a24b710092f8b9b6132e92032ff1763..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2590 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 diff --git a/src/controller/__pycache__/Controller_IO.cpython-310.pyc b/src/controller/__pycache__/Controller_IO.cpython-310.pyc deleted file mode 100644 index 60bc7d3710101d05de3adbe5715c48a9616c64e9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 893 zcma)4O>Yx15VgIVbW^2#OK?F7J&^-hi32B8Q3VMhL3-$Ig=D#FcUj@JTic1CN>1r- z;GBpPe}QZNg|D3W3!IqQR8@Mz(u~Kp{N9^q+r7PA0wa9-t|p9--?-Qw2`t_~_?M6* zkyMicXQpYx3P!O`bkd|nO36DSQ`xyBva@7GN77?5?EZm!WHO|&cNnzr{O#cpETh{nM zu8+>X#pg57E(PDXfVz-yBhjMP03BJUdsN+y^S9M>jvXeaiOs76*FlkSJ!aH_{I9ljA6n+;cm0KsR+CpI?1VIUE6Ct6L0kME+iy$2;mN1-L-%(r~U$}D$tw8F~ zfqzhm6;VLl7+L!V9F(E5R0#<&umy#w6YuOMB`O2YzIX5Wz3<)k{Ok|8+z6n&c>kHT z3BY&l^dx<3bZ?@u0}L4PpiXLpXglSl>PF2Vkb-$&#x}6@ZVF%zS0c4E%Pd22=%;pz zB(mnY3WTKhmzS#O4nO3+vR6?#$AEZ460vm8;I;!CYJ@>8#mF|)43@%zMwGiF{6GrN zD7H3!-HNq^w#?JE_!>o5+M*|dNyWhbS#5euOS%jMF3vGE>_#?S7hW_ z+_xMLtdlI38q6ZF3d@MqO;n`@Gz+Mz`|m`azjRf=^OCRPE=8X4yzTFQ@f}yFi^U39RDf@@E;aw?yyOmF!PnzqHJgeRX)C&>gdZ6m z_oGZhx_*E|IG4m3KTe5ZF0+;HEPwQ%{77-B%G`6yclkQ^M1#w6V_tC&z(3&~Sj)xPK zR(7tPoeQ&b2a{*tEPk6PhE}nQ6`@*8M<%7dUFVcWBb3$!YkJzwQu@4Udr3r&V(ur9 zW4OtjR+?0-^aRxi;r`;oyA$m&3uklO7?+_O$w?pZ)$vAU^yL DwfP_s diff --git a/src/controller/__pycache__/Controller_Postagem.cpython-310.pyc b/src/controller/__pycache__/Controller_Postagem.cpython-310.pyc deleted file mode 100644 index 17ceabe2455c883917a5003bfbc1652ea172b2ab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5159 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 diff --git a/src/controller/__pycache__/__init__.cpython-310.pyc b/src/controller/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index f1c80bf1193b88e2cc03ff17bf77ee9b96ed842f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 156 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd{iOU7-Msvg%(Tqp#FEVXJpJOLWc}p)ypp2) zoSf7m{rGsG&XV|ey@JYL95%W6DWy57c15f}qd}Gz^8<+w%#4hT9~fXn5i?K>0N=VV AC;$Ke diff --git a/src/controller/__pycache__/controller_obras.cpython-310.pyc b/src/controller/__pycache__/controller_obras.cpython-310.pyc deleted file mode 100644 index ac63f50b49689238ab1d28f62f94ce27ed0a4a13..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3904 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 diff --git a/src/dao/__pycache__/Conexao_Discord.cpython-311.pyc b/src/dao/__pycache__/Conexao_Discord.cpython-311.pyc deleted file mode 100644 index f7d63494c1cb0e68b86693adfac75536ddeb0dc6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4290 zcmb_fU1%HG6~6PQKg+f(E3%!xDiCj0l_S|n<7P{`#A^$aCTnlkP9ZL3I?;?Bc}Fwu zol$69nHm~u$pm({b#S1&pofrVNgn!8%F>5E_n{9OGhj1dFqFdfO^Y|M>{HJjX+|D7 zE~ee9nKS3yd(Qp+&bdc_?CcC7DDV9BFXG?)2>p`?PGOtO{xx7Wk%&Y}Mg?k)q6kmR z^c-z}nK_0=lSpJ9B9VPYBlH5^Mww$pdIlxAe-klDSsk(}h`gxkl5&44*Hp4UR8!bL z3Ct#v&>STq7=U_+<`|I%%8Cqh#ai9tsv`YTQ2B|xmQ%5qb4LS94qgV{{jZ?IHMGX9 z`PTfKNQWw?EILD>>Oo7V89f8;g)6Plx~q@SBI(;MCHf`x3|d~et?Pb0=(M7?UMQq@ zwAvPZ4lmN)K2{jL+i62b*)U!kue8n`qX*V&=O9eMVXSyaEu@HOoKt z-VOd{_KwvvJ~lOWi@!BCH9q!kc4~Hd#tJp6X2&LHtZ}aw1dWS~&OvM2HgWk(p1q72omJ4kNi9R-$lPzZYOY+1HAm`#@>y=*&outL=Xp6uu$RPsUO z2zbZ%4IuYd%umoJ^II119;`-M`Yq0j1h0*a{NU7b*Q_cES^^&RE*3P1xU3=+q~*>~ z;y|&egoTncCeydL`+{7QK$9tAIZ0dooND`y#Yu&`l9=qVIu<0I&)pLgMUpMQ*oe9o zmnF>>w@}Q>@G0tfS+f{WwK%NGl4f-)YC+-^l^2wvlFO@>zW^?oR~0e@=D|ZPUrv?P zBDR8pDDv}p2|9{nNmsEVU>>wJVL>YJORA<@K@BF6FF=LWVSfrdS)#>ik^;l$WL1-r z9nf`io~$k`XgCHd#QkKMJvjj{sJu@0$F|hKh*VkK?m)I|*DHc-1#$v>_`C?yl=Cok zD@bP2FeZ3w?&vC%ZzeOhH3@4ONzP{`r2CSrE=f4E^gzF-Dw(^geo;~N{CqwqkPXOa zIF}IxHPd#JrI#L90af9#B!~}|uO4cJ(P3Yj+sQW%B7IF(bAqhBopvnAqO}`vFMa(5 z`U0(@z4+GkPq^!Z!csheA=n}479$1Nju$4uQRPaEMmGdx!d&pBE_GjWAfkDB4pT6lCX zIqvN&kYo5JmKhgU*y^*ek6GuJ!u%l@C8}Nblo!Hg43;ju^2^X6%v?xok!*Lw#@jG2VDkJ#F-* z&AxOKh=IM16LmxdFYm_sKBYeiR?|lRh}qw?1#kwtADyn#eZg~e^xw#r3<|}Yny-dY zu&dVfT_cb(1F2ddwG-(2Fti@}=!y{-FarZM=fNYe=$xCTKZ06FDA_gc|4JvR zBhpFgP&&zd3+W_%j5Mw-jq+ZH>ulw~^<8Emkwf#0$R0}Km8GWZ0Hg3l8&2qekkHwbTgDsfUP>|Qgnx}cF{FTd69o34Q<@nCaw z!2bbsrinm~4*1P@_@rb+hs@|uE&Q5i=UB1Oc9CSrj(7MH42mxk@;ySxvEeI(j1uyF zLaq`*W|;Kh>x3uK3X{K-2V$8W#z>}3!k81p`i|IuiB*^o@@nK*R^4Bny}+HUBbUrl5h5QZjs8dvFc)9ruX^KP$qm;y zU3;J`5y=+YgMSma)|l(tcoOP}`)NM~QfDZN+CgV)-e(7Ot=hjG6kN4`b@mzs6FN-3 MBz0fCrokTkKOJ_b&Hw-a diff --git a/src/dao/__pycache__/Conexao_Facebook.cpython-310.pyc b/src/dao/__pycache__/Conexao_Facebook.cpython-310.pyc deleted file mode 100644 index 07f5d4a79c53eb2622a4d1f19cd5f3619ae0e56f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1202 zcma)6&u`N(6t*2F&AJYaX&M|5;z$p)AP!unu`#wWP3k5M3DJw?#$KDQiG!UEsM1q+ zow#sANZXMM690~`ocI@z5IpyXw80KIdN1~i-+SNto*lKYP)0Dm-Tf%PdI)`Yi^~IS zXdT4VKnWyp4>jGJ^l(C&1W#;U)7wG96Z8}bIwDOf@FA-DKfnhys@Tr=6c(YVn7CHzJVGp{%ih}+ErEWi+12=tdlP`7co|bNc=4~VGC9|br~NbnoJZ3x)>eBe;ytrgyFRd8 z+&I`}FZcJh8thy8cD(w$Bl&al~VNAs)$>9niQQk6l(xvZbFtfO+} z$N<(;C@X<(LA-=zP-e9Ro8Ucej$UxCOJg)lNCtHq1NFCTB^E5>?KtIb<+oif?e3xt z#we3<%OCCAEMz9FOfgvr9Yqm diff --git a/src/dao/__pycache__/Conexao_Facebook.cpython-311.pyc b/src/dao/__pycache__/Conexao_Facebook.cpython-311.pyc deleted file mode 100644 index 9cba802c847914fa96879c5f4c7bb093c82bc89a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1921 zcma)7+e;i*82{$7H=Wfr5v{_u+62uC?pjLjiqwo^Q_i?&tS? zGy7vO*Z?@zfA~fDSpfKp9jZgDYz~KU^B5FRxHKf$lTULQKFM=so{$uHm;gn11d6!J z1MJ}{kEEz@_aNf=haKY)&S^|jSs@CwRDCT~QF0$#<#5=Fo5!F+l2ahbE8HVU3JQ-- z1SfQh>gq$8l5shuE>QX)RkdQqUR-zuI9x<7ri+$aoOMED7lnJc%7X)oX;;QdEoFt@ zMVq~v-4=g=o^VP}uzXc-04r7SAjd1>Q%^lCTOtoRE(a@~s>LZ^9xGUt0OUN1x8D9b zYZ|wZ78474nyWWnfp@?Z*ZGISJgjpZ%mas00j!BX zURMHkoy)imr;xA`U;&Qf!%7X*of_OH#4aS?V0V4T*C(;X=iCN}J3cKVFR8k@DMqvU z61D_SO-Ibi*0Lk6P)$cpqorA^X-epVAv-OKW~df5G)gL#PE$(GX!>%6kug~lbai#T zz7v}>Rl|&_X)ShJT~pIEs~WNFhP6!f*aEfsb!usgT1vJwWSB-OrpPpQx+A064X4de zu{~9T)JNL9b5@y}mTVANU)58X;$o$(qr+*MlGEnR==q*lb99T8@9hkh9Ae&XAabhzRRWAiHXj>@u||0}gAYBO)2BG5X7pEFu)~ zp%Ombk{Tgqddba(C@Mk7OcSA7a3oD3S$Rp*Wp?r`u~&~*5(HX54SpWX2U&UM?cN)O@K7;4Wcxc0+B?45 zu)A**+J}nmLwV`%&>O{2w;db#{kk2RE`+9wq3OJ*)Bv3Wc1P@4pg1sA=ol|{jOUvU zf-PT0cdizKy~SW}3An(A+)wZAOD$g{K1=NMJd6A>IP+p~rZ6~L9GuN33esFrnzN<3 zlE5^}`epjkwSDE%ll+VJM@L5&iAr7wH0QnMB?RNQfxgim;dzfZ+UI-T&moORM8{8v zE@xCioCZQNR9Q{4y+p_-t8%(5F|MNZ6EIrv;a10BUlW(Gjd=yhc5Rl#R!?&Y&XTe{ zvxs;qeOUgtDR*XP)u(Zd?P|eZ`-jVE-8A}8z&=#w$4C%2j@yU8wmbLXO}qZL56#=| UEQxI#CUlm(WV~1B2;AWR0it2m$^ZZW diff --git a/src/dao/__pycache__/Web_Screper_Site.cpython-310.pyc b/src/dao/__pycache__/Web_Screper_Site.cpython-310.pyc deleted file mode 100644 index 41416b81fc2427e247c67a8ecd0f27e9e3b885a2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3420 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 diff --git a/src/dao/__pycache__/Web_Screper_Site.cpython-38.pyc b/src/dao/__pycache__/Web_Screper_Site.cpython-38.pyc deleted file mode 100644 index 75a0d170c37c3f7214b6f3492f1935068eabe652..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3414 zcmb7`ORw9;6~{SziJ~Z8*-jnbHcjO=*Qwe>>LV$FA}x%hXn`zl7e-N(XiM;FC|$~w zC=W+&qEaho>rFm^1ay;pgnp1NX4_5gwu>&j>i-O>`?7C{bi2NR z-+%w{SAPGtVf>pamwy&24{?>hfZ+ybxiL2)W6mPRsBY$FWTLckYi>t2Gk#}qn>(Ky z+<9h34mTee1NRK?8Us^#Jdvr)=Ba9vokuFmaKgwh} zX6S7Hqk9|I$GFOSFcK@>vdY-8XISUdsEin^L{H}N`tajoQA)AO7QE;eC$m%*{o!!f z|NCZODQ79Ng;egO5c5Q;J1`2~m!Bywjni%rdxF|LT|_TEzCBof~s4EQ)_cj z8M9#9tqyiH(=VuoF?{$B`0ZaAPyR<9eDXWT1N)4&=FBBSyL;xr2%_eU1ad~3{i1U! z=lO7%h%yz*;@MN>jPs-{m6tB_td#JYtNew3^ilsP=I`{6{-n%20}IP!p*rK!WQiuE zkT02X^_#Ks8~0*0S1eKXsYoYhH0~f&J&}&n6W}~97BXG&LeTuwTj%aQa52vkkricJ z0-;HkOHn9Kq)%3$t5nuBm4X(aY?*#4l|2F2f;6YBMe#S~f%SchqZya;_4ZVY!6T zQtS|-f(q*%_gYXGK_>NR;t&%MZ<6^A&1}D!dA4}09NPOtORY8?YI3jMr3+Q=H;JB> zLl}d3rf+&o|4pCyw$B3dt{K7~ve#G-|B(4Cw0wBhgO_A>(+FeQ+x@SL8~SWocK^YR zG!S>R+$01yvp9obtO_#XkR7+RU=Zyf5qnDFL)?2t;&=erx!cyxkX{98J!kifO{;RY z?WzSyc{}t8%s-HwMy&QWAlYeIL69?>`@F*g$jaJwcgCh&wJYbbD@60GTR+?Q5UQp}3bs(oec4SzGf!P5@4fJ>dB0A8r3aWtjAgh0o2eP_#Ebd^v;x#hgB6F9_ z>tt@hP?+S&XQiNcTz}zj(;a>OnyLY!h%%c6>^8e?)~tCAYaR=< zxd_ysG`>#l17TO%G-QDr-qmEa!ImZq1n+tJq-veh6oRI&suox}_!^eJ5kCHn_*~*f z(?XzVcrLRMb#+kUX_?Lvo?Jsk{EXhwspD$E5;w7--o81QUm5B5=(!|4?D^@L_LV3V zScqfh`h#!4&6NRO3R>sre1$ezAhEMBO?iOJS zAG(EF>%8WnhTw%~2u%EU9W){u|6etnau8)Veaa!PkMyOSXr^=f;I2TYh z?;fvTKb3M>{&F;;;}kC*uZH7dK0FZ@@hGxR%1?1%wHFC;+IO+SwKJ5mpC|{pEKha7 zS-V5D>L+V&I6j?ZPjTlD<>_jE($D78$STEn;J%V4Vkh!(2295?E*5EnP;}I!P@ExT zCgN3&v|F4jx;_T-BC?P*FVKoS95u=qQ;BZrH=3lFt%<;QFq95k(H+XQ*Sd`EHX~m1 zi+5>;Z`2vL>68+7oo?%%ed<{oN}1yOFsHa03T?$zqI-gb;YIP9gOCRUInt!+Ki3rW097`J;#9LSX(M>6Add diff --git a/src/dao/__pycache__/__init__.cpython-310.pyc b/src/dao/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index 34fed817a7abc0b78306808d2de8ff41f970c15c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 149 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd2 SKczG$)edB0F%ytrVE_Qu(;>V7 diff --git a/src/dao/__pycache__/__init__.cpython-311.pyc b/src/dao/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index 8e1e39fb0cc2c157a404955f2646ecef93c44cf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 176 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

F_vmq^P-~0zU?ytG_47B#%t9+< z_w2|03@sv3JQAy#D$xo3t!h{WwEObU`0D6fiO~O=klC~Q?a<5>AHruDy^?#&@u|bd zLo6hxa+z(W24wa$DzzDyq$Cev(y9=b%ir4QVvfrBm?XqZROa$G$K^_nNxp$ws}RXA z;c#C>^2=0Nc=7Mk-hSx&4?1}TCRuv`dqt##G>z{Ld!7K}EEmp+1N<7yxU7(lancF$ zhrq_6P6Wy-kN0rcJYK+N=AHf<`im$YAncGHCBG(-(;h?4aUkajp(T=MA8iOYx!?@m zHy-l-#)PY*P`HHBTR50>b%`w^HRJ+CA`0s-mVHAcq6|2y`IrqJ?P0lHJtn-)bh)S$U3?{Li1xA2qf=hTlwL=yixqNaxtU}6O^63_%bRew zuKx;C6;Ue8t`S!9kX>E8PZ~3Ms>H><9ZV3B^jC?3E)J4oIS%rK7>P@WNF8xJQer9c z*&l02P-3aWq6UdcQ8bWYj$VSZK+Zl{5GhJ4H49{HBYkDb#FTkkrYW%%*g(9YLt=2s zMkCZ{7d_D)(=;d+_YI{gR&X|MRuABq06?0$@{}Y!jX>i4lLk?bgj>u;bD+R;_ zg#-?xNXB%7?&qI%g4i1;ZrKfyB`5In=n3?}|5%v#0Byj;vN7%f?rMtUbUSO+O;t1X zDCFjUfoBvj<3FN3hs zn+<8m$e%{NEhMJzprvD5f|p(oe{JeRCPI5PC_-M|vTVCnHv!Yhmnl z#hZz$by;=I8JO@5-bU;Ig9w3IrmGYDy4ImgX?B zN3Z8FIvCgY8pvUky0qBe7dmF1dS$r5WTw$hW8nS*pn`k4k@X7C<1Sc~JNh ztx}rsKtgqvK!D~HJ_K8-I5(2Z*JwF+#EYe3MgKnmqIwTnI1M2fCa*B%Dg+cB0R_1# ztN^g@+&{DL42`F*zD-k3%Z-dC8iM+yOY#X{eSrKAKxw?Yj)AU<&qVI}rzp+mnUal~ z$WGqF?`R@dO|uU@38#>+37_Vf>pbwZMt_dEr`+}7Sn8On zZcQW_#p}{4kDUjhc_w?smTL(AGu&R%TrX2;PO{|qy~z}{csG)%tI1-)_9FGhokYWg zjxYG<(IKCT5~moQXTwOnBBSi};3!_BR@LMRc3+^fS?r!KFOL_hXpL31noApRAvAm) z(D$^A1CN$-In{9GApKOKk9f&-vxe&;i8t)he#>=lBDpBfa9SnAi*^1o?fog4i)7v; z^8+$(!DI%7RD6?;Ju)3KH^>BJcF0ipFs5}%!NVzQ(ZV-!U~ItBp0}I!GX56q=j;=U zkJ*dZJBsgt)|{w~tYsT@`2m>h&|uV~-|nmm>&l;ah#!4qi^ZwxHzfHFLFA8l L@e>7U7q#C5k>Me; diff --git a/src/dao/__pycache__/atlas_dao.cpython-311.pyc b/src/dao/__pycache__/atlas_dao.cpython-311.pyc deleted file mode 100644 index 93c2c5e7b1dd7a7847f0a65b4b3716d52ed2f0ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16121 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 diff --git a/src/dao/__pycache__/conexao_discord.cpython-310.pyc b/src/dao/__pycache__/conexao_discord.cpython-310.pyc deleted file mode 100644 index 8aa903f89b80c5e08acf1915529110aecdc3cf47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4321 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 W+9B_urgnH;%nRq&^hOx-MgCv+=vET| diff --git a/src/dao/__pycache__/conexao_discord.cpython-311.pyc b/src/dao/__pycache__/conexao_discord.cpython-311.pyc deleted file mode 100644 index b88a753aefcb79ee42ccf322482a560f7fcaa4c6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8138 zcmcIJZEPFodGC>T?jN0u*+6q~awS#j%+%uXy@lB3v>8h><^9Op*!PBI;e zr{0mW&5^FQ1v6zBXtT+1wl*z+1)dALKnk=#er!OxVOW0*7*9Ar!~p^f48b~JKWHcg z3IhZ7Ja^=gM@x%PY%fpGy`Rs$@AE$2`n%TF0DOwvEc zPO}tZ_9eNwz;wW>yRrEJ8{34fMWQZ{DEFU;d?HGjElDLNiIS3*Qw#CxC#@G%ZLIHv z$^#-3+&*lb`jEiJJpgIR3#e#w+i4{w-;60E2`#RuQry`(EcC&j7yi~SLhl`N$9Knn zhrPo+An6)@7`*P(CF&v6A3N>4T)IY5oQIgKQf%n0^%3$As*jy!-jimW2D$FkbDk%j zrmwK+*7{607K)^|*T=52wYubW~r%$~maqh2E zWQi^E_3?Tw*FGlbHU`R_0bC#M=!Xf0QvW?;BWoEfPe2ZX9)$e0B5Oh ztD&~!cb_G{`AoKHCY5%08~EIjpeAa2at$&79Ouk~HI76S9Zql98p(OD<5{dCQ6K@Z zwytFI^zVynspY!AhW7=mOpf_ePmW&fT?!N($*Il8ce50Mv^7Xk^XQ*Z5}jk}y!k^S zF*(}RraxiwzOB&`cJ6Rw&LcWJm-7@Gv_XBhl5eS{xUJr<*K$;S5AJ(?;&;=TB7nU? zpVV={Zi2PelP2zfRip@}=Eaipfi~mZ-}rNoi$C#xn>_IT1r5@~6+bL$?I~qW7E_8COJ!2=gaQavRZ&fD^k!V1PbZX=>7RoS zSrxESpexd*FRmn&3`~kik~ou)0d+)`(~6pksUpnQVzcs`IIn1Flha^Zi8<&nTddcd zh%_;2O-{jv;z>o5qdc6ax^p@mo7L0~IJ3F~58f6>dWmTysI^jqMc8F-cRpmbt^QOj zX|nMcyu^eA+e{{4>nh5b$>DZv49KxnLN8)@{`TNCpu*rnB9(|IGTPvX47*!Uk_!nu zx-xiGNgqfl>BLMT9z#kDYHEB?iYbF|3uwT_D!B*dZ<(x;5>+`S-O3(uoA&|S0MMsO zXlKpwq!N!MwKoQ83-R3AO)%xZ`wjUGStL&*-K&v(E0KMVI`qh(5g9C;DTjBghWl2+ zeZ^~fc+dzB7Dm2oe`)!hk0zHV3!_i5S{Pju_I}#BDh#a%L!b5iVt;AmVo4a%g-eET zsl@NH=C8K*t+e+QGVE1Zp&q{Dl>6JJ2 z;7KERvJ^bI7TH}Aj_Z*VM&v{(c%njkb_dI?p?g;_7YKk$*j>@1HXEPZcJ0e%j!tOZ;?g z7H0_G#O}ief4IaSej3{Gp#LxXi{JbF(hvIe&}k!dy2NkrJPmc>ypIN!2THuK*|QE8 zK;n)s1r6k&pTOU`1ikmYRcq!eLf4C>*%t%d++d@cER#3qEjC!AI<_T$-D`uoW2M|W z3-lDTvE6F)%r^1Fn!Gu;26ngdbdD}^_1)EL&9=s^5n*?ZM^s<41uaTXWcN&hzES0j zkeL%uDG4z}uw_Vy$L161Oj1$N;ACgMeqz6{Agdt1-_6K^CJPE+Ks79bL<(^=0qR#s zDKMfgBqT-c7nF>E>Q#o`1<>438xW!`Y7czQWQWtqm^LyzY3@?xIRy}lwf$(KB#W83 zn62Yl($*&JMktwpkKwp8S&bk%FKSeeqM1HW%b<4Dz0j-f0}y3F8!y1eO&WF!6F#_M zy}1}}Km-M(Mse;z1jwT55C9Dw21~txYExf>hNY7%wf_6)Bx~VeMEq|6YC4JUTIG9I z_@2`45uG13_|XzS`em2!*MT1e3gczIW0gO&!XNr<-1x@$ua6mLXLbIX!Cx!!*Bov3 zv+&Q(KbiXMwtisDI54J1&lu4&dgLu5@)qbfTb?U$ka5p5Lc(u*zOo?nw7%`x3f!8g ztKWb#Wp{oHR5LO_H4+m*fhQALG|JId(~n+qA~kDra6#uRk6G27pl^~?MtoqS_`df!O$}Iaa0fX z8o}NIvla~BKeaqw>KW48Uo+ZY(}RbM;34P_NA9c3w~F0*=YY{UP_<_4)0U13p}0e9 z?VX=^e#8|A^sXVJtGX7f6Sw_dcg3@ld$~fs7CiHkK%_SPC+BJOJyK$il-X_H58Ms>;F~(T!+@dMWAT&AbYSp+?6AHJw1q&Px#QbB zh?hK)_X+(F=0A2!MxOeA3FVstVhExeoOid8+BB4J3Wv88$~T32ZZmV2S@P9Gf&v3U zG@02bET)%y8;8X?Z;na>xohRR6P`%ilfXkTqmLa^S`CC-CbBIx2M$C%3tsZffukmM zBkDETnM6`X-`!-?A@#g zA%~QdA&kLB5-e@fY*7^@jT?rvNVHWwg=cRW10HzGo@*(7bp*QAQ3PWM@V+Srx&ufC0IEnV*rTSHTBDfgOY@7#o%*;ltlb=;-)F90mf z4w~Eu^*zdeaietUJEhQ+9-1;jQw9J3jfVd?rMDk2+7IZ#0V6n2V5+K`Mt!>paP%#X z^Mu=OtJdP|KXm^6?$Wm}7Xmu_p25CXsy)^NjHQaX9t)rxYexYrI=>2ijM-Ts4!B8$nJZL$-8}hHE|N1E-l0%+uSLj;B+{aoZL5U_1GO&1qs;(VBww=Os%sSPSU&dgWj!1()3S+1gyrN`{MFG_&!}jvT@)l`E$N{%JqljlP31Ft@bM<-H=l3CF-uc zzmc^hHs{}H?Gz;W^8VX?WE;D7gStU(dZ)+@D#}f$s0p%6?|deiRF6R&5@eYV|xt8OY2_v9v5g7R{EmGq7268z^!J)n!SHD;Y@N?Z!@KUWGV0%Br)_ zvTn(~9*=Ytlc7mD9#c#ocx!M7)2GTBhGUdm4~8LFvNit^K#+ZPYgAQWuJ#`Q7D>6a z?cQah_0@u>9BMa0e^BsO=yvWT^)&KI@p7qSs4!OXk;tyqj=d`#d&|KHB;m?k{pIch zWudQ1?RVo)(f3NmUJ0^d2YV`BdT?jO>+6YBylh+O8PgKk_7wpDxOS4(HiO@_%I{g> zA@O$Qiy33=GQ8o@`S%U}{Zj4u-P-mpjFnD;g{s3fzO58`E67<@f%hpMg3UTy+}8)yoLpLvRfN64YYt2J?z` z%Q9Y9p`u~@yXgEXo&a+OHroKZx)|L4#?VHK7^A%Hf1z7uIb5b!y9Id>`@gWZMn^+z zw$I<1Lqj}ZL9v<#Mon&pYD0BnU~6}4%P67sV?1Y%+fKzBY90nq+>B!5@HTlWryt^0o_p^3K64KI z7K=p@tnZXm?o<;(fAK?o$u(qq5|9VTK!#92S$`L@0-VKyXh~T~@M*FY%7#5$Dl}P2 zRuPbh29Y7(Lq=#-L}(3u{>nxSVFD$>&-pQv5ZvYh(GATY4BK;Xlt-tiK3!w>wz}xH z3daWsBkn*}G=zI7D;Xk|bD|;Lld~a12E`#aGKekHHV0Cp(?WxuFyIpWw!Z=D1H>Bc zR)M@0unLHAzS^3tn}-~%g3MYVw}`ZWk45VI2+fA-xFPP5;9hv^9TL(W38;;~4A}@7 zVWY`V9?D=_3Fr|cYBWC-jh5OTtL?4+p6A?wf2^Y}2c9<9@kKNn#PYOlrw@>iMwynn zjIj@-0xtj$Y&>mW1#N4AMz9|Xq!1Kof5wdtrbmV{Lt1KV$ZaW*d>&H`Q%aoRWZF66 zJm=}o=e+gL7nB#nL@GiF*==UnDq^a$62)$ak)l@gx7%*JrQgv=i4{vsW8^lr9rw`n z)cAqxI?^p*Hat^PP`a0b=LoD1k2mLo~mYlu;?0{`jm@_SGGtxIj zSg%c(nKL2H5I~$FBI< z9IU*5q8bT(5UnBroWG~KA9a6P=}uHbQmnO#IEbR|i+dJ5Fz07^$4UP(FXXa`xl$*@0?EJa|obfjE5WK?p3m49_+M zkKp?^S*buY!UtwBrQn8_p8vMT0KoJX7KI!x+^V8 zZ)PC$u9zup0bgoXSEq?Z)RLvE(1s4Nbts~0U{$xF+Ul%cB=-96j_R0Jas6io6+fdo zz~Nx3S|yVab&5=x_6(3M-Qmg_brnoQ2VFTr8BVH`!~hm}oe}_O%OY_YUGcpYh}$@#N#h&G@Bq{L-@W ztnIy(yBkUu{SdTd5@Ft1e28e88`U)E;8KC(Et>XqNiX;}^dxs!au}saz@8va*b9U5 zKVKf;bKkiNU@3U2;>pl8p^6&dxX={pe(Y2cZ0`iVdagMUrAN4d9sq9G|ChiYWbr&9 z`2tSXvSiL-m`*K?C#rIxR+uMAZ!jf!TTosE-|3Gy#;p%2Y-cL1RC!I=UV_( xNf3kziY$3g1+^}DPX+aC?0hTe*v8KH89KVL^R3F~1PFUCc)@8e-*VwO_#gYId~W~% diff --git a/src/dao/__pycache__/web_screper_site.cpython-310.pyc b/src/dao/__pycache__/web_screper_site.cpython-310.pyc deleted file mode 100644 index a41668d7534ac9793057b8fd2a77d8112f11c8bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4188 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 W?^s0~hb7rv{!35)cavOw2L1h_R~ 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 dZ^d(*%(`!4gzjD3zDQo?Di#}{8{{_0v-#!2U diff --git a/src/model/__pycache__/Capitulo.cpython-310.pyc b/src/model/__pycache__/Capitulo.cpython-310.pyc deleted file mode 100644 index 7b57b1c47764984bb7a8cbdede2362c0d29b4969..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1717 zcma)7!H(ND5G5&D)_QHPy_;-AQWiPgD-??a$Rm@$)V&0 zV)zvAH}p~jNRIm*J@yZD?J4IR3Is^nH}cB0y;~qOW;i5=oS8Q>a@uM&7{;r=f75@u zjQvH6_2FRg7?gbprkLU}8?f(~63RJa%2|j3SNuoTbKl{dg+t=&!^7e+D2u@~gEkuo z#kHdZ$kEQRr(9J#a|f=jDNohU*n$r{$iCVsYHE~0zmTKe1&c$j^b+Brv zYieH|K-yJZcyzt+pF|UrPvf-MOQvIOQ#q_QTCqu1d>_G|6$A^>&Je$xH$Vlc6r0EVo7D=O~`)r`D#n z=*aB|+j29+w%mxZsMGT%85KJtoj)s0SxQ#VE!<4U$CiS&6uqs1oip3P^x=O0*L1A= zrzSB&GtK%+pZ0%A^Lt5}n`1MKa+4L?W(&LjwPxwMy#@wLyCh#HM!>AuAB!DEQ%`iyj08Z}gn4I=U*FqAn#0TFP(WPDa_e#b=$$+R??~r6@?TjDk?A zqIfOfvj{CE07;^pUuhD>X!Qg(Z$qQB+1xC=I%D?xR@{P@)A3I5`mnv@Hjq{ z@WKse{t`I=Rxj~_&6P7+QVXsO3mqcSN zWzmol?KzD}Zc6!L8pX>K>qFP>gBAY7rW0-Rm)ma9AA$XfSXqGo6@Mv}okp1<d*TNXM4i((S1f4|?L52`wlWAs~)SFaUt>pH+!Csusy@*f#1RpyII08P2@0IzqC(pTQLe|aO=F2(f-rRf6_nrG8mFg!jUcLXK ze-a4!g-$rcu5qA%(INu5O?0wObh-^Ici{=fGSP(xB%3IO0esW0b8s1q7BR>&)ycA; z({-|(&;>wIPXJ1~2-v4futT3O&udlFt(EOkcs6b$!IOaJzy)ZL25k@(tY9<*@WRtb zBLQBNnVSq(5y*NgzGpPiAlvZuZnVQuk3z+enNX~c&)b&cvYKh>wi2eP-WebF(>D-0`TeF&Jj zg9$4z4(IX@9fLV}qip6EjF(2)t{N;~U2~t=R{n|YPFl8Wu9zjwH6h@zQodsAMmZnm znX9h(vZ|Vv>8ffy6NSSNvg_OcXp;R4xed{i&+VVTg72~L{aa48(-S|^Q{U55pQrcI zGhTXTPcC?Jp&kAYU;|Q$m;?u_;L6Q_(E<$`WEHGnyo0_0KUxnysJ9xa2fnzO1ooxk zVW!CGjfkIB>Y1y`5>VU|S^%1r`(2u66`%HJ6Fs!n$k3v&HSJxz)*)yH`0bK+=W#sHww=F(ROwuIL3|GEQ;Pyi!G=eO!lF4* zqhK5-Y7;M*P-KHJo25ZL8L;CufWFMAVi9qDgAjh_3&B5tyAi1CDOfze4& UN;|?Z#a&OvKRo{TKePOZe@GBzt^fc4 diff --git a/src/model/__pycache__/Logger_Config.cpython-310.pyc b/src/model/__pycache__/Logger_Config.cpython-310.pyc deleted file mode 100644 index b459a5fa063d5f4a011190f16a09c18c164c911a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1907 zcmbUiO>g5wbY}b!$4%O@NM!{G1!$x-Vw)pUwW=z*lp>X^)N-nXEaRD^4tCs~nN(mo z5>ofdm2-03zcg1)`~?n(_r^_|mOU}jym?=K^FGIAw;K{zH={p<@Cf-6iS^|GaR^&| z0e}-ub8^v~^nzNNU9fKnXWV&1xO2lU98S+kdiLdHksbd-%#3SX`k;@~zpf~`&gXfmM-YjDYG5<4|n zxJyC_oE`^i0#|%Mv_EMrfr(qzh<7jjKdHdQ0RMkbfTxF3Um;uCr;D zW-~S5;(G8?sh>|vosF_I(OEeiD47n5l8bzBx}M~{t6xnJ$MC6+V;`)k0Khg4=u`GF zt#%$NuM{7Y2E9YKY-zp(1d>d~bWUsflKj}6GfgLK;nZwN)%%(*T*N4O?PKcS(qZID zyi;O%CAwgI@k^$(GC`62EO;hWQ009kHhlZ5>=KfRd zJ`CgCg-9`o)k0f$LFGVbvVee=bne#fg4GU&0OMdAnltD|=f;_PHT2#Mo%^6|!<@J3 z*21fO)CQivB=evSRvfSda+FytXfPbA|IQO;`4G0+0dO}@uAN7EJBwcR)x$s^ch=sE zyiAi^9qb*=lrD?oQWlBULJm{3zgieL?sM3x2LQr@ajT(@80f_1^mjIQY6nIQY6%WI zLug8-t7`N6{eIDVx!>o#ll}flXzKwec&g>hy& zHG$G{gsjNDt-2IxDY;IXNy?cZ52^fo9 zoReu%h&VQ39K$Tla>P4v{Cbw;jYNJ5s%yUCd`fIiv-K$B9|F^Q8IVmX`#@Du|5>6^ z8@cK|@AaSM;#ye4QA0!KR5BKkiUPTTM%!bdoA@AWfTF%>-&NIY9A~*WNv1r9SEU0Q z_oD8(hV&OJVVH1!i%0Dy?HhUXP+(*x03sfNHPc4SdS?7a!+LMpO~Rm=Oa~R?%iDXm zpbJ%b&sa;39b5b_VN=`A4xwgGSm1>$gaHN$w#%wdP9Hp4kNbKU`SLR`AwNg3i{L#3 zIK>j}uibf95{bVke01!S7vPH#bOOtT&cpmRPtsGwQ1@L%Oz@)VgaiCT-CKen{sj+T B=6L`B diff --git a/src/model/__pycache__/Mensagens.cpython-310.pyc b/src/model/__pycache__/Mensagens.cpython-310.pyc deleted file mode 100644 index 43d179a6c03ecfb5a2b3b2bf75cf00809b9c41a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8371 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 MP1uK=Dd&juKSaA`j{pDw diff --git a/src/model/__pycache__/Mensagens.cpython-311.pyc b/src/model/__pycache__/Mensagens.cpython-311.pyc deleted file mode 100644 index c25b4ef429130c067d078333fa913a34863f60a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13065 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 JF@|l){tJy}uKEA~ diff --git a/src/model/__pycache__/Obra.cpython-310.pyc b/src/model/__pycache__/Obra.cpython-310.pyc deleted file mode 100644 index 1651772245389b56e52c6ea2a796ac77e3b67dff..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1449 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 F_8+0QfZqTB diff --git a/src/model/__pycache__/obra.cpython-311.pyc b/src/model/__pycache__/obra.cpython-311.pyc deleted file mode 100644 index 8693fb30adcba849d3fee45f955bff443e34e3b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2563 zcmah~O>Epm6dwO=oK3dbCX_ZQC8m@jSDS2#P!nhs2^9n>bbCmJ&e-bkoYI1q?ZB#u2Iap?tV7g-{*gcJ$&z->{=r6=Bucdd2Oz^wPpdvE4> z-h1DBr=~?vOjoUICbU2qP@ms3w#J0g32cgvC{arA-l`ZTQEd zEMj>c>B?VB)P+dBY}PG5u-!^$1D`S-VQ&_gdx)U2fDxDqM8YEcB_dTbSYDOOGFDbm zS-}~g89addLDvU!7G@QzaMWNVUt6GNG~n}d43`U5&0Hk4SWp9MbFR`2h#k*(3I2N# zkbB4%VCsw&!A}B0C>;hnrAF&i12fOQ5-PJJBu!&vGa+ZGi*0!)asrN-$%d;HMH=PQJ zB+sW&_CwPS$UBs}l(KixK1Ng^(Xeg7P6HF8(!tf!13k`2P?uIXJz0^6Z)%swZ~3^9gND{yMjN`V3Q#H~F&%XQE015eWV8=jHSs zFwiRi*-hZ$@eT9}$jN??0k)e-k%26OoInh+a=#zI%aop~*LhvPsVxr`v=1!jmNv(0 z8x*;Yg5?B6wV*+_dBBNUR+skyLUZ8DmOzidsICid$7#q`vuZI`k?^QI*H^TB_N^?7S0+l1obxeBKfbTDf^e7yW$|K7O z&*SsJ9L(c=k(V?bfmL0IL*%~pL^^5mCP;527=v*#R^)Vx3%pgggpw{%_9Bi| zlrigd;$U6jm_MUtg9|T!sW%0rf&Lgdxqj`3Paa-vja&&wuB@p$>LB#P@9Np#)Uz9RTIy7&PBptv z3~X=kNg6+e*X>Uu7T{ANKG>hiRMQ-iO7U5#)a6pDs#sDP@_XkF9^Qji`c?CYj=^?a zqysQfmJ2AkahQ7g=c#(hHfsymoLxT8lSoO0ED&lOyeTIy!DrC4y;)#llb6}MSPL}J zuOp8>3a^sZTs54lHW1I>bzO|4TjXxkN68YQ9?_*Jj>HGM z6cfk9rpH20upc|zyXEo!asMUe>>J$K$D`v-?X~7il|6O8IU2M^gK#uhJF?qb6koK| z3!!?U*?o9WkWSW!CB2_r>yB9?h7n~A18)4lX8fRG+zw1TUWrqm2LpPH5%wvg8Y4Q8 ztvFBoBBQLpIAIZcUjb<(zqUN6ys~k*jbQqz!l$3-`Lv(BC@AcP>!GTkOfW@ijk bf*|amSDWdlEuR*^jf3QGrhD>?1%A}O9F0E_ diff --git a/src/model/posts/__pycache__/Post_Discord.cpython-310.pyc b/src/model/posts/__pycache__/Post_Discord.cpython-310.pyc deleted file mode 100644 index a84c9cc03307fffc2a8e3237203f3b326a6c2d08..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2779 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 diff --git a/src/model/posts/__pycache__/Post_Facebook.cpython-310.pyc b/src/model/posts/__pycache__/Post_Facebook.cpython-310.pyc deleted file mode 100644 index 3fa9a8c945c1efc96e832eff49f65bae08bfc708..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2198 zcmd5-PjB2r6d#YrUT3qr$p#VBio+mPh($_#fKx!IZ7SeEBTy>@Ibb=S$;KP6XFD^F z=xTdv58RQsph(HF2gH>FC;9=n`^trU0%!rjdv=np14QD+So7ZedGGz^z2|wOy4^N` z=0#u0&$@*Cgp>K^!sI%1a}|gn!pX=sd5;Jx+($&X59zieoI7N|PGFyGB}nHRg~@g3 z=4Bv~fHc{r!V&Zl*>;617;q*$u;7>750$aeyKy3Sl-f@a`mEvDgT4vfdro_U8K2C9M8(9?)v)rAShd?ljg&6VJPhfmA=L! zmy0&FMW!OPqvLY1wo^|6G+ZsOWT~-nBxIDtlSzmk7ol#{x3+z!A9aK~}2l0rw$`E#R%g)&n}Dcb?k|z}}~q*mJ-h=D4=Z z<}AA-A1p4+SjGLBdy24d0ig{DUtWR`oFgDsct{^1f#j8g5@ zB8+^|0a=V!cji}?d*BUv=bz4(4o|%rEN`7)qNZ(3e+>Wd2G_Vyybq+!=UQX38Bd;k zgFi9f)zaL9zkg5hNvvajSHb`IO1mLFU2aU**7&s7lqkMMxQ5h?iB<%0+bfsacF*(69HeKPbHdev86TIaoe?lwXx){a(7P#WtMSZ+%c;h*g zg*pR<3%OCe2!edAagrPM$>R-Pe2*rY8~^vnHcktb)XikB@ky%cr^ZTBx=?gA)|GN8 zFUC@<^Fmp6vozm7pAK5OgJQv1Auao3nHwzL(eCN9QuZf09m{my%CeEe0xrb4p|WqK zPMShXMP}3SbD660)?^t$SGBZC=dq5?G4Z0k0DEQvr01;CwnHgn?04p|-&iYn%0B6R zx9YT;>ppwNg5Xznv-e}Y*U-Y<7JJGTf?wF{y`N9DUFNbs8kYOhYt3r?&&S&ucv$!I zcr2r+Y)28i5JiULP88iM;;i1$eeghYB>3RW5%gW-^}w58d>{b{Xs1`L4XDPqq#DoZ VR3@sR1#j1Q?_eP^tkPbge*xOrD!Tvx diff --git a/src/model/posts/__pycache__/Post_Facebook.cpython-311.pyc b/src/model/posts/__pycache__/Post_Facebook.cpython-311.pyc deleted file mode 100644 index f7804410822c49cdf009f15ea2ac89efe4cbbc5d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3633 zcmd58OKcNIbk=Jpj_vg)P(BSIlaK_gCU$9QX;Mg)f?6&~i%Ks!bhYtrk_CI$ncaoP zawMd3$e{;rIkZUh01ZN@sHdvxp%PNh4w^%>5)x9yA-AnkE?n9-{!BbkXhAAc$KE&Z zy?OI~^XButqQnriE4O~se@-CuJ0n^x+(fo8Agd^ZK1MpahIHw62%)?1HQEf)L!Y6n zTxc;^FExp+*8y2Y2AYv{G!xRLYiLH+Ljc3N470+%@~Q2(>PK3^n6>Ro1-UtqbrJX& zz4aS_RaBKOLf>drq_$ATZ<#~D-^Qhj+)3bXC&Zo`H*Rs6=k#OA-A)IBPhM+&8~ous8154b$PqM zmL)w5np%4gK`BL`z`0eRJAm$J*#)}uM(1+qx@3Lzg0V!Ku@qiOENz=*S#HmX5M_9m zC}knau4-7IJF4=IsJrS>M_(}NSTpJ?uO#Yd+X{+Nx95YcEUz#jACZ^NM^`oSFZqct zhpeR+&Q87Ji1tdd(_Y_VcH(V$>(CQBDqpE~2r(w12E?5pj;C%wO;p)!l%C#XiLS)h zDW$>TI*vElmhsL3h{3VPn?Rh=$`9_bV;9d6!&!u5dBMhIjcE9S4F_m{Opvam1#)y0 zSCXQH_X9I0NKKZBec3Qw4I7}@aWq_f@Ex{neAaXdHqjgA3bu6_4rPttf?dKIo;NJl z7#9>RxNg}Q&*$~VyxjbJ{>u|nOAAxh+ZWD@Hb1n%3fS}@5DmL56hW0hY_gNC(v61& zE(Ev9j?K-#pn31_%;L)>&Kul0pIsH~io$S_HCDjEx-ss(27-80@MO|`aAzEQzc3Zz z!2dn7g16aDUoILJVUGyH9$~%=4*|jsc0Xl#C4<=fR`->nX+z#Best~l!}v%oKJp}yxju4h&&>;T z=+t`uY1)5!z5DcfVuB_nYKe)B{XKMlZf%k7KfZD<2q*i~K@=sssnQ#CF#<6VLz#m# zeJqG`P7)>eQRPUG;v6PeOZ2WMdY@vH%v|3~Gso7IELE~==N~G$nv#3;kB&UXgA||q zNuqch)NJ$}p?&Y(U!;9wwZx$yoND)r5r_fsYk;PY2XW3xpiDnazZoc;lSauts*D5~ z&S6uVo(}xio^A+H1mSeM-;6*EaKAZ+`^`DYW^5_W>25}{hjW-Rhy?ym2X{m=`A`|H zDWfly^TPx5@H_Ws>EW@JPl67Xua0IZbn@gy(a;GxcqZuLoEX|WME9I%TLdVMUY7C{ zmuaRv7yyrJQB2ZMwA1h=hqtYzl?+w&W2y?TV6VvVgsLujTCp)gSb>v%0C!M*UVYCH zc68POyOo@i0Iu?15blbM2Z)0MUr3Su0PPMNI+?oZtkh6D#B?(k>!zMXPc=N7Aj80` c+nWR=kR?e9LPbde-Mhm->ij>SGg>$CH)aGXS^xk5 diff --git a/src/model/posts/__pycache__/__init__.cpython-310.pyc b/src/model/posts/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index c9fad27b38a870fde40f7c3f91d82de24bb58e2f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 157 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd<{9 diff --git a/src/model/posts/__pycache__/__init__.cpython-311.pyc b/src/model/posts/__pycache__/__init__.cpython-311.pyc deleted file mode 100644 index e149f771bc73c33d55825ce95bd98c90f001627c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 184 zcmZ3^%ge<81RoZfr-A6lAOZ#$p^VRLK*n^26oz01O-8?!3`I;p{%4TnFK_*f{M=Oi zvdp~9{iOU7-Msvg%(Tqp#FEVXJpJOLWc}Ryl++yk zg8br=V*U7dpw^Q3c)fzkUmP|-nbMq8yCPPg*&y4C`GLd-W=2NF4-7D(h#4pb01WXj AUH||9 diff --git a/src/model/posts/__pycache__/post_discord.cpython-310.pyc b/src/model/posts/__pycache__/post_discord.cpython-310.pyc deleted file mode 100644 index 06f7874e97e3a5d077f0b95b42396d8e78906a73..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3516 zcmd59%Z}Vc&~AHXyq?Ft@?b$AhoHcWlzn7(_Ay#T0V24-3Mo0jM3M2jdnTUsxF_9q z1f$st8}S9)V5LMHqDbVx2XI=>e1MN2A+5NQfH)*n**lY&O~^wCk+!MB()C}n*g=9LW> z;cy{Y@VuqC*Gk zyHMqi07B&kh`*`!6q_V{lJvEn+R|Z6hc*Lk2HGsNS!i?6=BNhHphz=Dm2Is@&MTKo z+iFj}VbTopXz5!-EcMiFO;rN*>ZzV4>OGBSXB1eI4-3%G%_!8^A%GVF8%t&~&@+>s z0Xz(qXZQO>WcFG<6LOv_Ao6sGE`SZLjS#Sv#Jg4&~BzsONe-a6DE2bB*~H3tS$A!VwnV6pj^eX$jW!WC-$S%j0nl)$@X8Jl1642Z^cz{UXpA zaX!_~#gK$*eulaiF&!YalEh4|to|0k@qX z3SdLA<^^G#gPnu1!Z?FA5@kKsCG#7xo(fAX5CxtKhQJ|NAIHY-Z74Z_t|LgqR z6%a7D#YHsN5xm9RP|j`g@N~dKui?2)2u7Tf!kue#%KSMn8W14tyJ5ETd2HCAjThQ> z26)O@00p(68pKfHBUv@8>d>E1b@<4AT{od`;zvwXe=wnSj|?68**-HDFHgUqwWgsa zXa8pv&pw1%y_NY|p>Q8sS!lC8(#j<` zX&KPwdMZF;H@~d~KMZ(}0dEghJc)NAk*Xji^B5`mffPNFV)ilzcqYN~2U5pD>K6m4 z1(5pvvr7d^74P46_POO3d)WhhvWY&WM4$29Y0#%Oq>nCsdnSD*K#SZXT1@tG2U2p0 zl&RjRRZ^+byI_TItf%du=QId~M>h7s(Ms3E^X3GU*DR3?ylPrQWdx~IE_KP}x1z6L zVYyNnnHxbWl~1_!p%(p22URj%8Tv(_sEw3%Yw>p2;JS6i{wEi^3k^qG=+1@RuZBb@n(zegXy- zvm7bC078}{Eg2!$yDdB>t%h@r3onF`4rnV`yCWEcGnZ{LU~_P*_ikYnyc(fVE#?Dp zgA3NSd?x^*)RD8+dd&f92&1s`+SOyt#%+mbA(n__ux^#AgXdf?n_b9l_IyEu@&P-x9I&x&?VE-wyX~r}MwQfKK~w99TAE&1Zoq!H$#6B-SyNiZw`KL>>o=03ex&+D!04 z4iXoAFW7pBW;z0rin1Y&0(CtXI!zmbPHgmZmU^k5O4$vFJ$`)>7POf+#IimiSu=vD zGT>UD44H68iN+&8^x6+;l3XMOGpOh>!9p$|x;@N`@Ci5xbMhMiCG{9&4}|DMzn@e? z|5JxbO!Ho80_GsEcyv}D)BnIq^5)&rWJ>iUI^ERoVI>9g_tMnUxf*wkNnP!}KAg)u zej_fvV*P@Bj8{o!gC3-qe=CrUsJr+Il8tU@G+LF_Bzc4e9d+1v#|KX8=fJ*=*4qJE znFT;F8@t~r07iM*}FnmQ{8TBIGi66su0 zL1)NV9tuny0xSatq`)@RK)1$0SHLd=_U?Z`HZCxMKnDYR@?ORv%S(Y_JC_nEQc0F< zK+#ar z--k$KKl355rE9JGMV8Jr zLf=<4eO1;nDi$-WYYl1)r62tb7Q2shdr4qzJAIM)4EmotbOG^>dC!>Pdt!#8wZLrK z5Fl8o)@QZ@wq?Mt^_lGk7r)kLwi{i1r!TTFJ7|xHXpb%UR?&MSdrX1ZZ?gIByXddC zwr1h`mZ#WXVD?xBDa_qh3M^hNuwtOwSpxJ~+f5mIr^7}d)licX8@(F~v%=-OW&{+%=7|nT{<>j2PCFP86Q4m#)7eqNDtBN3Nd`?m{I+ULV z+4Rw;Dz~Z1+>WYgM_=5QvYe!3R7J-E=F|-=aEhvNSlW^`9kfp-qDCV%PFA*zrY%Xo zY8i^@&SSdGMyO&OPv;t;iV+neNUgHityx%2;6;hg2s@T9n$astx{$poJ=Ii$1yx2= zQF9WnsJx)$74XJjWkoj{!EFFa#}s2DKtaNgR(?&&ZW{iIz6u6;Ma}>el%*L_dgEr#4i5LQ!>jQ_cuFU^=DY%v4Sl zrR)@dsB2bh@5y-0d57X2jH z{S?+|&j9IpjgEGeUEQwU-$aW3yOGnOQ8KhlhX=|RCh0wKdcMCHEw_)Fh;2G&HO19( zwCxuk{QQHDgU8W95*^%so4k@di6%?YWO-=xUbGzRxEC-3D7Ih*QMkuM4NcdX^6>28 zx5@Au#Z?mKzU=A$_@@VXGLSsP$2}?1lPa#>y;>faJSdQX6)MtOo>(beyiO+GrPO%I z`ksbkB;5Ds@bF1^xHR&kS&nr;H~luU$KGRsh_Zt%HPbVmKGM5 zr{`v7lJg78bMRT3zSLZ&^G1HvJwWSbGR>w2Tbe%s(TA?dP4946!>*}ZN|leY4ZPR`Os zT$gahD-_LVbvaj)(P*h;2Lm3U+RtH0S21L^^M=FI<8OD!U35QPrXS{Oe}U+M5U7U6_ zF>iJ_0$r%3l|)`MyB!W)xS0MZ{dfem#P79}_}FnIK_ZERADl!cOOeSJwEmPEA>87h z7{aAW;lA>~Fd0}lyhR3O1Vp;naq4nyXD=wh9tE_XT-=c_LFI2@|pa(VP?bGht+!}Pb-0D!KEC|v=-CTjq= zI5q$d%K^Z}u>o*c?Nul{T%77kHC7izsoRn0t)kTDaHx&NbTR#StPZ8iCy|L#Wa9q| zjQ%0gpFG?k{maEQvjH~34sv^Uo{Wpc5*fSV3W6BA%G_Ycn>Ss&R@6C0&Mms4pcSoL zW5~DGU91-jjK`y>simkK2m45{uN3SnM`?=(AckvgTQb45k&S)zC+cmV)Mv^D+IMf$NNkT86X-Y5)7#3jbj5@Z zN9~32675k-Esb9VS1JZx!pp#;Wu5jtXiS!2m@;a)V|`5jWgi2Ip5Fe$;{Wp*qn57! E0DQdDm;e9( diff --git a/tests/__pycache__/__init__.cpython-310.pyc b/tests/__pycache__/__init__.cpython-310.pyc deleted file mode 100644 index e6bd995a981e7408a4fbc595972c1328a36923ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 147 zcmd1j<>g`k0=|m2Oc4DTL?8o3AjbiSi&=m~3PUi1CZpd{iOU7-Msvg%(Tqp#FEVXJpGc?;*w(h_;{d( rlK6PNg34bUHo5sJr8%i~MXW#*L3S4N1BnmJjEsyQ7+^#ZGf)fw@M|lV diff --git a/tests/__pycache__/test_conexao_discord.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_conexao_discord.cpython-310-pytest-7.1.2.pyc deleted file mode 100644 index 50e7e4c0b280b9c875921eb9ff28d018ba87fe47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1737 zcmbtU&2J+$6t`z4$)uU2Y!?;rArTI&s6=MkbkS0TP^*F}t+d^hwx?VyCwAK@Gvlf4 z>9$dFA^RtA<*{Yt(YQpM`mQ)OLK3t>m3i$MKCU%Dbbk zMlH7vAVShF_zN_U~W~9d2OLIp9hQNuIxcX~orjQSeJD$oHw5 z2+3e8+^1!#t4shNyc|mkYxGJeeS2nN?|L{q5O!gz_knO1&&Xq#d2i9kXFk{u%-Rvy zT^d{3nqWA7J3?R@F!y1qUw~+|Ky$3Iy@&Y=f9`2-=FRZ6e}fj@+}8mMSc5e|695kp zJH9dV19aAy1+&J9_Y8T6G+2A)lcsL5l?BE~hu0vp&W#6ri$!*ib>_`kQ$1&0*3&E3 zomuk+r+6LBTRH-{J8RwG1^x-@G;cBl@vI(BAK8F-pYguU4L#xc^x#zMQhk#oT2%!T zKUVQX%rRD>AUh#|$#@uA8z!eCx|M?f?)z*eG zzFm6KLQPtn$R-f;vE%^ef=a?D6N*$tI)Oz1YL$fcLuM^Yp*n0(D~!Uq{?)_0a9mW zvlePg!(Wm76g>ZPFFA#{l8Y3QkX9;T{300(Jt%}ukJE{BC9xqWM+rdEwf-`~xV$n? zU4$20x*v$*#AO2@ai2Z{H&AlyGFMQ*c^izYbs$YI@_H~MZ_R7s(2H=0H}UkqcFNyd zKmIRv4&fOI2`MNPkC+uga>1(1@)05D70qgm{0v-i8F@hZcCQ7*zB9@qBSaB)I~$Ko zIIhx6r-d?+P4b=eA*pK~*J+1R#*)90sph7Aw`E$(J^2`}H6JNCi6@y=E0T)%!F%h_ zYd)|C7!~m{CAZIN4Zk(3g}`_g?=Jyc1G#svu#d890`tlJrY)3;Us*IQ-&fZnF2o0k but<@8>uC6GoxktwGpr&YPaq}rx90x^E4>fs diff --git a/tests/__pycache__/test_controller_obras.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_controller_obras.cpython-310-pytest-7.1.2.pyc deleted file mode 100644 index df5662227e62329fe2fa6b42a7d0a616b6f5db06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4768 zcmcIoTW{RP73Pp!?k;z=H^~>-PRulo>usW4?Mm{kRpHhM+9$P1ilE>NLG4fyWiH7K zxlXN;MN#FwdFZ2oN{<2pzcl|K|AIhY+Lt;%!9bFpGbC4BT`UJdSD3>y*YnMA=9`c5 z=H^rZe#758T9801=gt4rb2-b*>GA`?7?n_Q( zT-B@GmmPIn(`!WdwLnW$`Ane7zNptJ`AF!NU%;rsMwcYbN1hup&v7jF+f8N$P$Z)R z&&ngyx5J6!jj(a?Cqm{Sq~OP3EDlT;DWT$Lf-X^s%J7uapn8dxAz&q$|GgE2CxVR# z^v{2|9%V?6AO-)0nh<79MJnz~;7LSEK4~9Wav_%wIsS9CI_r%;QwEc*VG_XVPoLt*Vm88-ts%Q{iiG4K>btZXzLn! z%iZ8MJ_p^PtH#=TT6(7&B$8vfN!!DnZ!l}y4nk&9GdPkH3A&*fpjkn4=VikT0*i%w z%zN0|e|nGM9){Q}=fsAXy%ei~VP?V~Nvs3C**uyBFfVYh?i|C@&v0t`4Q7qKCl>D; z7_R9RVX_7^Nz{k_(-2n9Fj>+zMyBIH8=sB5v2QXfsYA7~IkBD4c7sHL<7_%Xa@7cS zyop13Q)AolHcbbHA6rS)2+S=DM@SmK z*Hsfau$(RZssl@D8Z-yatdX^8!^-L%YEmySCayh#2VZ&C#A(zJXS%?{VrH$FSxqx3 zjJw6m{bIA_BZ2)C27URczvGRq{$r0#`abh^tx*{CH@$Gl^+J2g9`PykarFXjjnR}2 zQ*1r|Y4R3d-B-N`1!4u4!Kji-R3d+)C<>9ktt-!^i2Q}@t>K0~L4LgpM?Ie&x4s8G zZj;v{#&O}GpGA!8P@fXxuaJ7qAjS=B!HMxBZ1Dq#u`xqV%>p^i65|oX$%(ObAu+Zu zBu0!|AV%6ia+*Z=UbXD^vFX4z)=bU$>Yv-Ne>7@opYGV9g&Y2XX8M+E1{&Yin$N7j za^W>=F0{u3F&zea`4$`7A)W~sO*A*rXlUL-gYdd4dmA45wG&(btYjL#2g||q#glc@MPW-g4hjtR4w_qNeuCyU znl2hV;;DHTyyRBlMCEh%WMXmF^gZCBG$_JP537xR0U+%TP?UGcnbn^HVWZhuXPw#1yO|7gLQG;zufAFVTe< z#)@hn1nW`#a}vnVAJNwV{Uxm7Qt%l4zo0%v|8K;RqenkN;e}827$eWu0PE#vB@ke9 z^a{Ni&2iz^2ve+$g78D0Q6ZHe)d87=ZzgU=&D};UNAhkHj2hi&f57Bo3{UX*NdXAx)VanG}$?~o22^e|1HekK>OaZL(^g6u}&2y{^8Px^&&g#XA8;_i4O-yLTn#5eqA#?G&P!&4;iK2bW} z+&GgRQAX+F>hj*tcEZpP9`yTRFmb8(c+vw|)Z1kJU7MNql54uu3MP-urO}SP1H7~p znC{ZZ^p{qb`+Kdx3a#-b^R(6XwBhn_1%@0z8Z!J=(Z%J#Ipq6S=WT+p-kLEV;E8=-+P9imy~suFeT{k>*E zybeH>>N1Gi0igLD(Lm=E4LDiIyLk~fS>mDQc} z6&Wc^eq|;lpV{y&jGFp&?>W75dY-V_p077g%rLzXFQqqPW7>;H*597Za}kQdz;LH> z-(!8mb>4lb7u55hm{}=i?iDk4b^c|LO6kG!Om4{U*JA5CX??nf27{U0Y~Pick=9OL z(pUH;eR}zaFuedT`CLMGln#ME5%co5ol=L?rHc4m`jUJJAJ2R5o_kB59($v!Bo%{y z-WW!r8phb86UPF-ZWy0TOb0)F41>LgOWZ@Vg63FWa1S*GD}lijpcJbJ6;ioWzrstq zb4ext%;M@OSv1lQvtGJtun&98`jmlKOsdnOq@0!UJ*VFc*a$c(|DR03&AyfRS78HN p!6YoFhdU_S?8k-qxngpT`K-w#m7k{z@eAZjKBHSgoz!8`{|CwI0s#O3 diff --git a/tests/__pycache__/test_controller_obras.cpython-311-pytest-7.1.2.pyc b/tests/__pycache__/test_controller_obras.cpython-311-pytest-7.1.2.pyc deleted file mode 100644 index 12867b45794f5ee876423f0b0d8463e8c37c569d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10968 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 Cg;x>) diff --git a/tests/__pycache__/test_gestor_txt.cpython-311-pytest-7.1.2.pyc b/tests/__pycache__/test_gestor_txt.cpython-311-pytest-7.1.2.pyc deleted file mode 100644 index f3c00f0177d0bcedfc7c8019f99f5c0927660287..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5283 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 ivreVE=d@cj7z diff --git a/tests/__pycache__/test_model_capitulo.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_model_capitulo.cpython-310-pytest-7.1.2.pyc deleted file mode 100644 index f1286fb39c5f249d0a9986654040b9a7b8d22cf4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4849 zcmb_gO^@5g8Rn3bNKqeauMs;=gGM!)#7cIx-(IhqEu5x7F3F-mil$Xj5L}V#<*p>k zGb1Nfr2_2+IpmTYdNj}#dWkPV5THeY_Am4UJ@VL|0`$_W4^5wUC~2vWZ5r5G@Z}6= z_|7w&ci!ijjfzD_!>{z-2jOpQP5UQR(mw;0+qeW7U-MZ*t1)%gn})72t!dUWENRKs zvS`s8R@1K8OnXD~4c~lU^UV{zmh;)$S|#%Zyl8tB7Td3R?ND|aQJtQoe>y6+afwZs zK#f+@edg=$Yc(VBSTp^MpG7_6TfU8Z*3bD4?v|g&D24dq4+A0Jiu|B49)`i&=ton= zWVP3DiN9fr5)<=v-#9V)tjCU69|QJ{p58N#^}g9N#p_Z(#bkQs0rNBT{6HU=epZ^N znSpjs6EC1W+hYU9Uq;EIQj4LT%KCt*yD?zC^}x8S^)tTh=X#ltp`4XAT64YZfSs^k z;nSL0U&m!)e0Jmji9UhkL-ZaYapoX7Mtg#!tww!PNb*2pOd$Dd3Q2wrlF!CSe)mL? zu)ZY=Jxdl(^uFD*KW5@3zu*_gYw<4{R~E1q|E6)NgtaK9R_i|_WFIqb%wV&yPNk7I zcz;UyD-IZXKchUN438!Crj6bU4>DNE+;Amxsg<;VkXCUT@dy5eGsGC<4K)UkVvIM{ z7&EBRt46&jw$RH}qo-GQ8uwl0Gr@gN`TV-L^E0^r;a{A<{aZCgg8LIS#ys4=r(Q$c zf23X$`(qmSpOw!9_urMzuZ7#!kOCI>VtsS<(RU7|Y>QhfD^he?estWa)}v;1pRXK+ z+zXdmUds_m+j%TCRKT<;~TVM;AmOgXTVu%9~5&_0{!_hwPEQyIW!1 z?dPwz@2^*c^YdY$yj!NyYDH9Aoo2uz7fw`qbNc1oq;abvVte$sV#EgelUXOT)h&5K z1Y9aV+vtji+Zbx=e+<m8`*9y0V$BY$TOr%p2*-&2+c*bY&~u zZTq3duVc7JudWT?kB)-66f66YTy8}&JP7M*CM)z2g|cpw$bB6A)%N{( zQGMdD71l$q5q7=07iHmE&;$$YL-qGL`vdzE>wbGi9#m&vuBR0PmB)(V6;z~l3RWMm zj~19Fjgfj_+B=X!CjL$g5=C!oYnr(7E@Kc%O#2Bgm7UDJFKE_0Lxw;;G~;X%BXJgq zNdzKxe&jVefm&7-Ru36}j=HNCm8qZ_Us1qi*p6J^^CLHG-NWqt=pq^gxh}90yY^+b za?X@z-<+7Y1rKy7rPRPzNGl}?t#m?KiL}a@R(c0H+ki?Ut&|<>0&B#m;zgC;!CZVv zW%q=`Amqk9Zc-282);`_hHODPX;Mw)9+*l^Iez}D)s%FGXbTf)KZVy>v}bDK7lcJR zz;Z(4Q%R|bGqfL34~6#E)Z@vZRdG_<<0d}-S)6o#xu@u*Jd(Ay%A2c819rEZosaydfA?Z6ADzY_^HgCX0hvRwd?R)olq=k zo!aVzvWfOw4`&d*gOWof#IdEyCQc~yEHk|0ETZb9%dg43tSC;!qgs zm~(Vp)R9iViiHf@PXBr;w0DNOPIh?U4~t4Wl4cFtBQ~LX)+)tB zH5A)CY{}8SjvXE#op)rwd2HYwXVlRA{|t0&4q}Tq3&APw3$^X|4Z>3hK|T|t`w4uFNw=g(R~_1k zXw#(IvO&3*)08{)77ow8KKHG)xo;%|PZV!XzcnQIx6<#a(9i6hZG zqcFqbS5;Q=5M28m842jT$ffme-JwMi6iCG5&wg3ZM;4s^@;TXNo}ayn9ow!Fkggj$ zE(xekBS5*}x_3KXgQTVF@|OtR8ksFJ-y=ihpIY*<_~7`@38W4H7GP}6*6qBVwXK4! zS|BLxk*rl|Ilk&9BBz?{1c=ir58maWgs2@qimlihx!Jt0ego Xf_czl`;}yZ-=!c@Df${d;iCRuhrtZR diff --git a/tests/__pycache__/test_model_capitulo.cpython-311-pytest-7.1.2.pyc b/tests/__pycache__/test_model_capitulo.cpython-311-pytest-7.1.2.pyc deleted file mode 100644 index ea3ed9896de9ff1d8161a39b34628b1611ce76bb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12490 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 TQjaUx;r{e42VQuL5aM^v*v`aBLrd4zoH=vv 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 diff --git a/tests/__pycache__/test_model_obra.cpython-311-pytest-7.1.2.pyc b/tests/__pycache__/test_model_obra.cpython-311-pytest-7.1.2.pyc deleted file mode 100644 index 4667856762e19f2ffc705c857124ffb7fa9a085d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14192 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 b1NVL9U`M_;ld~%HLYRDuvhVw3P`~~Ux2cm# diff --git a/tests/__pycache__/test_model_post.cpython-310-pytest-7.1.2.pyc b/tests/__pycache__/test_model_post.cpython-310-pytest-7.1.2.pyc deleted file mode 100644 index af18eee2f1bc28c82ea8830a7c70370bc5bf3ffd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 153 zcmd1j<>g`kf}|-^QbF`%5P=LBfgA@QE@lA|DGb33nv8xc8Hzx{2;!HGenx(7s(x8! zUS@J;X|aAvYMFjgeu-{geo1CpW^!UlW`3T2NosLPF_?_c%}+_qi7&`6F3~Hfyv1Py RSLAk6;@T)xdnfs5tB>f#5>0bsKH{f9e1d)jBNex-Nm3Bsv zWT~w-vT{74H8dDeyj(lq$cw&=S7_@EUFfP;Y?m4(p=Z5vyV9u0(kl|tNbW6(df6zH^iP4t z4S3jD5RL%dP>4*Fx1>gfWQYoHm1JQ;Evnpe7{3z`$3yR|DZ?kpZxWOOJh$LszlLyd zX-DeITt;6cvysl)ldoLN7-FzN9n7fx~cWE zp#oA1v!S-7^mAd3QJ#C0CxtM#E)yO5*OgtB6nWv1zAL>Uv6o=H7^=H6eFd}a>+dDG7eHc1&I@x)!ejTm()UFKHKSXQP zVfRmqFJbq^yF7STU`=NpYOtm%`6@XZR>hho25XuaUlU}622UB*pl(jX+MXGU^Pj+b z66a?R#u@Pa4lG1o0KWGHmM%-yiYiT+{B%EzO&I6U^aG zdyNLOOBZJW;v%@LAH!wcG~_*HWyO$t_s(DFY%ds0e{-PBuFRq~Z?GB{H?bAK)vWht zSK@)oi7hAt+of^asMLYW)gtlT9jWNSP@@dEMX`Wl3B~1J#b(T*T+DgJVAy#DV67ej zt4qBvhG}Tn8|2FV294wj%(r~Re16b&EI+Vpzw0;MU>J%^1~W2r3aSO227%ZwjVx$6 zUeIzQKmWj4ny)W7pHF}x%=d#M=7V}?xjrAxQ-{rn_Xo9M&@Z49*oKQq^bEZpW#Cgo z8=|5!i0=f7lL%7nY}e;|)l}H)u>GQYq4)BWvh?tyvSiLLn=jeE@6i3j((zlczQrTf z=eF&Z(;nMGjO7f?B1|mj6v;?*hB{4W&7qd(GHzSMvEW3Aq-0b@gK}bk8OEYwDq|!4 zMrWHtvA1j*O~QwsXHlm^;p}&8>O>_Nw${3?$6cRAniqfti%wZ=Bj|cWm|86_ShGFL zx7$usu$aB>poge(Q{=20_%Bl$&}iCP4`|!wmh+(F*}lzTB+4h*7gfg+D9R0Xn4ZBk z6jSjqCL@(O-g;E9k?dH+4k)scs2WFLxO~i`sEBKbce0*tTuL_<<3p;R`gu0nsw%fLW;eIbMO$Y6vq8d7t2X zz@kQweg^;27sfHHGzW z!arjDr|^Fe>%Y-LVEr#zJQ*wa)`d5~2>hig{5>t+sR7>UI0wMzn`B~$7uvY{A`f7W zn_`Xwn8E5US|L`jx`$Q=a8D+g1=j1r=d`fi5y~eSej+Lx2-`_iy?|pug#w%*!F}EaDNJjx1C&ris zeFn1tDFl5M#W@t$P+Ujx9Ez`@m__k*6z5TV1I0H{TtH!<_!bJR@<51No2gCvxxn zVMXtNpH(9pYvK`B!D~Jj!VhW!?iXf>50*@GrmAq1# z5q-u)lut;N2xD~GifLFa&KaOaHR{}_E(c1r-xcKseInpd&I?*C*Kb7?Mw>Ok2WrUh z1T~DNhMfr?is|Cn;lO}Br2Yzt3F9Q10IRAE`IX?DxQxRV8s)FX@wtZoQN-{Dc}^-R KB^m!sDgOtelYJZj diff --git a/tests/__pycache__/test_model_posts.cpython-311-pytest-7.1.2.pyc b/tests/__pycache__/test_model_posts.cpython-311-pytest-7.1.2.pyc deleted file mode 100644 index 2c9d30b81087a7c5684ff1c0d8772b19eb109e79..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15995 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 Ynh)gtx?a|GU7Cdl;uYi(4=