#!/usr/bin/env python3 """ Sistema de envio automático de Ordens do Mestre para o Telegram. Lê a agenda diária, mapeia horário → categoria e envia ordens contextuais em intervalos variados. """ import logging import os import random import sys import time from datetime import datetime import requests # Importado com alias para nao colidir com o wrapper local de mesmo nome # (gerar_ordem_dinamica) definido mais abaixo neste modulo. from dados import gerar_ordem_dinamica as gerar_ordem_dinamica_dados, gerar_ordem_sozinho_completa from dados_plug import banco_plug from dados_picantes import banco_picantes from ia_llamacpp import ( estado_revisao_cron_ativo, revisar_ordem_ia, servidor_disponivel, ) # ── Logging ── logging.basicConfig( level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) logger = logging.getLogger("ordem_mestre") # ── Telegram ── BOT_TOKEN = os.environ.get("TELEGRAM_BOT_TOKEN", "") CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "") if not BOT_TOKEN or not CHAT_ID: logger.error("TELEGRAM_BOT_TOKEN e TELEGRAM_CHAT_ID devem estar definidos no .env") sys.exit(1) TELEGRAM_API = f"https://api.telegram.org/bot{BOT_TOKEN}/sendMessage" def enviar_telegram(texto): """Envia uma mensagem de texto para o Telegram com timestamp.""" agora = datetime.now().strftime("%d/%m/%Y %H:%M") texto_completo = f"{texto}\n\n📅 {agora}" try: resp = requests.post(TELEGRAM_API, json={ "chat_id": CHAT_ID, "text": texto_completo, "parse_mode": "HTML", }, timeout=15) if resp.status_code != 200: logger.warning("Telegram retornou %s: %s", resp.status_code, resp.text[:200]) else: logger.info("Mensagem enviada ao Telegram.") except requests.RequestException as exc: logger.error("Falha ao enviar Telegram: %s", exc) def revisar_com_ia_se_ativo(texto, tipo="ordem"): """Devolve *texto* possivelmente reescrito pela IA antes do envio. Quando o recurso "IA revisa o Cron" está ativado (pelo painel web), a IA analisa e reescreve a ordem escolhida. Em qualquer falha (recurso desligado, IA offline, resposta vazia ou erro) a ordem original é devolvida intacta, de forma que nenhuma ordem agendada deixe de ser enviada. """ if not estado_revisao_cron_ativo(): return texto try: if not servidor_disponivel(): logger.warning("🧠 Revisão de cron ativa, mas a IA está offline. " "Enviando ordem original.") return texto logger.info("🧠 IA está analisando e reescrevendo a ordem %s...", tipo) revisada = revisar_ordem_ia(texto) if revisada and revisada.strip(): logger.info("✅ Ordem %s reescrita pela IA.", tipo) return revisada.strip() logger.warning("IA retornou resposta vazia; enviando ordem original.") except Exception as exc: # noqa: BLE001 logger.error("Falha ao revisar ordem com a IA: %s. Enviando original.", exc) return texto # ── Agenda ── AGENDA = [ ("06:00", "07:30", "☀️ Matinal", ["banco_sozinho_masturbacao", "banco_sozinho_vibracao"]), ("07:30", "10:00", "💻 Home Office", ["banco_estudos_auto_ditadas"]), ("10:00", "11:30", "🧹 Doméstico", ["banco_trabalhos_domesticos"]), ("11:30", "13:00", "🧹 Doméstico", ["banco_trabalhos_domesticos"]), ("13:00", "16:00", "💻 Home Office", ["banco_estudos_auto_ditadas"]), ("16:00", "19:00", "📚 Estudos", ["banco_estudos_auto_ditadas"]), ("19:00", "19:30", "🚿 Banho", ["banco_banho"]), ("19:30", "20:30", "🧹 Doméstico", ["banco_trabalhos_domesticos"]), ("20:30", "22:00", "📚 Estudos / Áudio-books", ["banco_estudos_auto_ditadas"]), ("22:00", "06:00", "🌙 Noturna", ["banco_sozinho_edging"]), ] BANCOS_CATEGORIA = {} def _carregar_bancos(): """Carrega os bancos de dados sob demanda.""" from dados import ( banco_sozinho_masturbacao, banco_sozinho_vibracao, banco_sozinho_exposicao, banco_sozinho_humilhacao, banco_sozinho_plug, banco_sozinho_edging, banco_trabalhos_domesticos, banco_estudos_auto_ditadas, banco_banho, ) BANCOS_CATEGORIA.update({ "banco_sozinho_masturbacao": banco_sozinho_masturbacao, "banco_sozinho_vibracao": banco_sozinho_vibracao, "banco_sozinho_exposicao": banco_sozinho_exposicao, "banco_sozinho_humilhacao": banco_sozinho_humilhacao, "banco_sozinho_plug": banco_sozinho_plug, "banco_sozinho_edging": banco_sozinho_edging, "banco_trabalhos_domesticos": banco_trabalhos_domesticos, "banco_estudos_auto_ditadas": banco_estudos_auto_ditadas, "banco_banho": banco_banho, }) def categoria_atual(): """Retorna a categoria com base no horário atual.""" agora = datetime.now() hora_min = agora.hour * 100 + agora.minute for inicio, fim, cat, _ in AGENDA: h_ini = int(inicio[:2]) * 100 + int(inicio[3:]) h_fim = int(fim[:2]) * 100 + int(fim[3:]) if h_ini <= h_fim: if h_ini <= hora_min < h_fim: return cat else: if hora_min >= h_ini or hora_min < h_fim: return cat return "☀️ Matinal" def bancos_para_categoria(cat_nome): """Retorna os bancos de dados associados a uma categoria.""" for _, _, cat, bancos_nomes in AGENDA: if cat == cat_nome: bancos = [] for nome in bancos_nomes: b = BANCOS_CATEGORIA.get(nome) if b: bancos.append(b) return bancos return [] def gerar_ordem_contextual(): """Gera uma ordem baseada na categoria do horário atual.""" cat = categoria_atual() bancos = bancos_para_categoria(cat) if bancos: banco = random.choice(bancos) return f"🔥 ORDEM DO MESTRE [{cat}]\n\n{random.choice(banco)}" return f"🔥 ORDEM DO MESTRE [{cat}]\n\n{gerar_ordem_sozinho_completa()}" def gerar_ordem_plug(): """Pega uma ordem aleatória do banco de plugs.""" cat = categoria_atual() ordem = random.choice(banco_plug) return f"🔌 ORDEM DE PLUG [{cat}]\n\n{ordem}" def gerar_ordem_picante(): """Pega uma ordem aleatória do banco de picantes.""" cat = categoria_atual() ordem = random.choice(banco_picantes) return f"🔥 ORDEM PICANTE [{cat}]\n\n{ordem}" def gerar_ordem_dinamica(): """Gera uma ordem dinâmica aleatória (wrapper com cabeçalho de categoria).""" cat = categoria_atual() ordem = gerar_ordem_dinamica_dados() return f"⚡ ORDEM DINÂMICA [{cat}]\n\n{ordem}" # ── Timers ── ultimo_envio = { "contextual": 0, "plug": 0, "picante": 0, "dinamica": 0, } def deve_enviar(tipo, intervalo_min, intervalo_max=None): """Verifica se passou tempo suficiente desde o último envio.""" agora = time.time() if intervalo_max: intervalo = random.randint(intervalo_min, intervalo_max) else: intervalo = intervalo_min if agora - ultimo_envio[tipo] >= intervalo: ultimo_envio[tipo] = agora return True return False def loop_principal(): """Loop infinito que envia ordens nos intervalos definidos.""" logger.info("🧠 Sistema de Ordens do Mestre iniciado.") logger.info("Bot: @hermesjogo1000") logger.info("Intervalos: contextual 10-40min | plug 45min | picante 15min | dinâmica 20min") enviar_telegram("🧠 SISTEMA DE ORDENS DO MESTRE ATIVADO.\n" "Ordens automáticas serão enviadas conforme sua agenda diária.") _carregar_bancos() while True: try: agora = time.time() # ── Ordens picantes: a cada 15 min ── if deve_enviar("picante", 15 * 60): texto = gerar_ordem_picante() logger.info("Enviando ordem picante...") enviar_telegram(revisar_com_ia_se_ativo(texto, "picante")) # ── Ordens dinâmicas: a cada 20 min ── if deve_enviar("dinamica", 20 * 60): texto = gerar_ordem_dinamica() logger.info("Enviando ordem dinâmica...") enviar_telegram(revisar_com_ia_se_ativo(texto, "dinâmica")) # ── Ordens de plug: a cada 45 min ── if deve_enviar("plug", 45 * 60): texto = gerar_ordem_plug() logger.info("Enviando ordem de plug...") enviar_telegram(revisar_com_ia_se_ativo(texto, "plug")) # ── Ordens contextuais (normais): 10-40 min ── if deve_enviar("contextual", 10 * 60, 40 * 60): texto = gerar_ordem_contextual() logger.info("Enviando ordem contextual (%s)...", categoria_atual()) enviar_telegram(revisar_com_ia_se_ativo(texto, "contextual")) # Dorme 30 segundos antes de verificar novamente time.sleep(30) except KeyboardInterrupt: logger.info("Sistema encerrado pelo usuário.") enviar_telegram("⏹ SISTEMA DE ORDENS DO MESTRE DESATIVADO.") break except Exception as exc: logger.exception("Erro no loop principal: %s", exc) time.sleep(60) if __name__ == "__main__": loop_principal()