Skip to content

Commit 79d6ddd

Browse files
committed
⚙️ Optimizando sistema de actualización y gestión
1 parent 77cef5c commit 79d6ddd

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2394
-158
lines changed

.github/workflows/deploy.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Deploy Bot
2+
on:
3+
push:
4+
branches: [ main ]
5+
6+
jobs:
7+
deploy:
8+
runs-on: ubuntu-latest
9+
steps:
10+
- uses: actions/checkout@v3
11+
12+
- name: Set up SSH
13+
uses: webfactory/[email protected]
14+
with:
15+
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
16+
17+
- name: Add SSH key fingerprint
18+
run: |
19+
mkdir -p ~/.ssh
20+
ssh-keyscan ${{ secrets.SSH_HOST }} >> ~/.ssh/known_hosts
21+
22+
- name: Deploy to VPS
23+
run: |
24+
ssh ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} "
25+
cd /ruta/a/tu/bot &&
26+
git pull origin main &&
27+
# Si usas requirements.txt:
28+
pip install -r requirements.txt &&
29+
# Reiniciar el bot (ajusta según tu configuración)
30+
systemctl --user restart telegrambot.service
31+
"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Blind

agenda.json

Lines changed: 0 additions & 1 deletion
This file was deleted.

blind/manager.py

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import argparse
2+
from watchdog.observers import Observer
3+
from watchdog.events import FileSystemEventHandler
4+
import subprocess
5+
import time
6+
7+
class BotHandler(FileSystemEventHandler):
8+
def __init__(self, script_name):
9+
self.script_name = script_name
10+
self.process = None
11+
self.start_bot()
12+
13+
def start_bot(self):
14+
if self.process:
15+
self.process.kill()
16+
self.process = subprocess.Popen(["python3", "-m", self.script_name])
17+
18+
def on_modified(self, event):
19+
if event.src_path.endswith(".py"):
20+
print(f"Cambio detectado en {event.src_path}. Reiniciando bot...")
21+
self.start_bot()
22+
23+
def stop_bot(self):
24+
if self.process:
25+
self.process.kill()
26+
27+
def main():
28+
parser = argparse.ArgumentParser()
29+
parser.add_argument("--dev", action="store_true", help="Modo desarrollo (auto-reload)")
30+
args = parser.parse_args()
31+
32+
script_name = "blind.src.main"
33+
bot_handler = BotHandler(script_name)
34+
35+
if args.dev:
36+
print("Modo desarrollo activado (con auto-reload)")
37+
observer = Observer()
38+
observer.schedule(bot_handler, path="./blind", recursive=True)
39+
observer.start()
40+
41+
try:
42+
while True:
43+
time.sleep(1)
44+
except KeyboardInterrupt:
45+
print("Deteniendo el bot...")
46+
bot_handler.stop_bot()
47+
observer.stop()
48+
observer.join()
49+
else:
50+
print("Modo producción activado")
51+
try:
52+
while True:
53+
time.sleep(1)
54+
except KeyboardInterrupt:
55+
print("Deteniendo el bot...")
56+
bot_handler.stop_bot()
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.

src/apps/llm/lib/functions/calculadora.py renamed to blind/src/apps/llm/lib/functions/calculadora.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from src.utils.utilities import printTest
1+
from blind.src.utils.utilities import printTest
22

33
from pyrogram import Client
44
from pyrogram.types.messages_and_media.message import Message

src/apps/llm/lib/functions/cronjobs/core.py renamed to blind/src/apps/llm/lib/functions/cronjobs/core.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from src.utils.utilities import printTest
1+
from blind.src.utils.utilities import printTest
22
import json
33
from .objects import Rutina
44

src/apps/llm/lib/functions/cronjobs/rutine.py renamed to blind/src/apps/llm/lib/functions/cronjobs/rutine.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from pyrogram import Client
22
from pyrogram.types import Message
33
from .core import Agenda, Rutina
4-
from src.utils.utilities import printTest
4+
from blind.src.utils.utilities import printTest
55

66
async def crear_rutina(nombre_horario:str, hora:str, dias_semana:list[str], zona_horaria:str, **kwargs) -> str:
77
"""

src/apps/llm/lib/functions/cronjobs/temporizador.py renamed to blind/src/apps/llm/lib/functions/cronjobs/temporizador.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ async def temporizador(time_value: float, postdata: str, time_unit: str = "hours
5959

6060

6161
async def enviar_mensaje_despues(client: Client, chat_id: int, postdata: str, delay: float, message):
62-
from src.apps.llm.lib.objects import CHAT
63-
from src.apps.llm.lib.handler import HandlerResponseJSON
62+
from blind.src.apps.llm.lib.objects import CHAT
63+
from blind.src.apps.llm.lib.handler import HandlerResponseJSON
6464

6565
AICUVO = CHAT(message, client)
6666

src/apps/llm/lib/functions/graficarfuncion.py renamed to blind/src/apps/llm/lib/functions/graficarfuncion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import tempfile
66
from pyrogram import Client
77
from pyrogram.types.messages_and_media.message import Message
8-
from src.utils.utilities import upload_to_gemini
8+
from blind.src.utils.utilities import upload_to_gemini
99

1010
async def graficar(function_code_python_function: str, nombre_funcion:str="Función de CuVo", **kwargs):
1111
"""

src/apps/llm/lib/functions/search.py renamed to blind/src/apps/llm/lib/functions/search.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from pyrogram import Client
22
from pyrogram.types.messages_and_media.message import Message
3-
from src.utils.vars import GOOGLE_KEY_CX, GOOGLE_KEY_SEARCH_ENGINE_CUSTOM
3+
from blind.src.utils.vars import GOOGLE_KEY_CX, GOOGLE_KEY_SEARCH_ENGINE_CUSTOM
44
from googleapiclient.discovery import build
55

66
class objectSearch:

src/apps/llm/lib/functions/web.py renamed to blind/src/apps/llm/lib/functions/web.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from pyrogram import Client
55
from pyrogram.types.messages_and_media.message import Message
66

7-
from src.utils.utilities import printTest
7+
from blind.src.utils.utilities import printTest
88

99
async def visitarURL(url:str, **kwargs):
1010
"""

src/apps/llm/lib/functions/youtube.py renamed to blind/src/apps/llm/lib/functions/youtube.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from youtube_transcript_api import YouTubeTranscriptApi
1+
#from youtube_transcript_api import YouTubeTranscriptApi
22
from urllib.parse import urlparse, parse_qs
33

44
from pyrogram import Client
@@ -31,10 +31,10 @@ async def youtube_obtener_video_transcripcion(url:str, **kwargs):
3131

3232
# Obtiene la transcripción del video
3333
try:
34-
transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['es', 'en'])
34+
# transcript = YouTubeTranscriptApi.get_transcript(video_id, languages=['es', 'en'])
3535
# Convierte la transcripción en un texto simple
36-
texto = "\n".join([item['text'] for item in transcript])
37-
return {"results":texto}
36+
# texto = "\n".join([item['text'] for item in transcript])
37+
return {"results":"Funcionalidad en mantenimiento"}
3838
except Exception as e:
3939
print (f"Ocurrió un error en la transcripción -> {e}")
4040
return {"results": f"Error al obtener la transcripción, error: {e}"}

src/apps/llm/lib/handler.py renamed to blind/src/apps/llm/lib/handler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,15 @@
77

88
from .path import functions
99
from .functions.chat import main
10-
from src.utils.utilities import printTest, printError
10+
from blind.src.utils.utilities import printTest, printError
1111

1212
class HandlerResponseJSON:
1313
def __init__(self, data:GenerateContentResponse, messsage:Message, client:Client):
1414
self.message = messsage
1515
self.client = client
1616
self.data = data
1717

18-
async def execute(self) -> dict:
18+
async def execute(self, functions:dict=functions) -> dict:
1919
for part in self.data.parts:
2020
printTest(part) # -- Debug
2121
if part.text:

src/apps/llm/lib/objects.py renamed to blind/src/apps/llm/lib/objects.py

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from src.utils.vars import AI_TOKEN
2-
from src.utils.utilities import printError
1+
from blind.src.utils.vars import AI_TOKEN
2+
from blind.src.utils.utilities import printError
33
import google.generativeai as genai
44
from google.generativeai.types import HarmCategory, HarmBlockThreshold
55
from google.api_core.exceptions import InternalServerError
@@ -96,31 +96,33 @@ def partModel(prompt:str) -> genai.protos.Part:
9696
)
9797

9898
class CHAT:
99-
def __init__(self, user:Message, client:Client):
99+
def __init__(self, user:Message, client:Client, PROMPT:str=AI_ACTITUDE, name_model="", tools:dict=functions):
100+
self.tools = tools
100101
self.client = client
101102
self.user = user
102-
self.model = self.createModel()
103-
self.CHAT_OPERATIONS = CHAT_USER_ACTIONS(self.user)
103+
self.model = self.createModel(PROMPT=PROMPT, tools=tools)
104+
self.CHAT_OPERATIONS = CHAT_USER_ACTIONS(self.user, ai_model=name_model)
104105
self.CHAT_USER = self.CHAT_OPERATIONS.loadChat()
105106

106107
self.chat = self.model.start_chat(history=self.CHAT_USER.get("history", []))
107108
self.TOKENS_CONSUMIDOS = self.count_tokens()
108109

109-
def createModel(self, data:dict={}, cache=None) -> genai.GenerativeModel:
110+
def createModel(self, data:dict={}, cache=None, PROMPT:str=AI_ACTITUDE, tools=functions) -> genai.GenerativeModel:
110111
MODEL = data.get("model", "gemini-1.5-flash-001")
111-
NAME_MODEL = data.get("name", "CuVo")
112112
CONFIG_TEMPERATURE = data.get("temperature", 1)
113113

114+
tools = [tools.values()] if type(tools) is dict else tools
115+
114116
model = genai.GenerativeModel(
115117
model_name=MODEL,
116-
tools=[functions.values()],
118+
tools=tools,
117119
generation_config={
118120
"temperature": CONFIG_TEMPERATURE,
119121
"top_p": 0.95,
120122
"top_k": 40,
121123
"max_output_tokens": 8192,
122124
},
123-
system_instruction=AI_ACTITUDE.format(NAME_MODEL)
125+
system_instruction=PROMPT
124126
) if not cache else genai.GenerativeModel.from_cached_content(
125127
cached_content=cache
126128
)
@@ -191,8 +193,8 @@ def count_tokens(self):
191193
return self.model.count_tokens(history).total_tokens
192194

193195
class CHAT_USER_ACTIONS:
194-
def __init__(self, user:Message):
195-
self.fileChat = f"{str(user.chat.title)+'_' if user.chat.title else ''}{user.chat.id}.pkl"
196+
def __init__(self, user:Message, ai_model:str=""):
197+
self.fileChat = f"{ai_model+str(user.chat.title)+'_' if user.chat.title else ''}{user.chat.id}.pkl"
196198
self.user = user
197199
self.chatName = user.chat.title if user.chat.title else user.from_user.username or user.from_user.first_name
198200
self.isGroup = True if user.chat.type in ["group", "supergroup"] else False
File renamed without changes.

src/apps/llm/llmactions.py renamed to blind/src/apps/llm/llmactions.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,15 @@
33
from pyrogram import Client, filters
44
from pyrogram.types.bots_and_keyboards.callback_query import CallbackQuery
55
from pyrogram.types.messages_and_media.message import Message
6-
#from src.apps.llm.lib.objects import AICUVO
6+
#from blind.src.apps.llm.lib.objects import AICUVO
77

8-
from src.utils.vars import ADMIN_ID
9-
from src.apps.llm.lib.objects import CHAT_USER_ACTIONS
8+
from blind.src.utils.vars import ADMIN_ID
9+
from blind.src.apps.llm.lib.objects import CHAT_USER_ACTIONS
1010

1111
async def main(client:Client, CallbackQuery:CallbackQuery, postdata=0):
1212
if postdata == "clear":
1313
if CallbackQuery.from_user.id:
1414
CHAT_USER_ACTIONS(CallbackQuery.message).deleteChat(CallbackQuery.from_user.id)
15-
# AICUVO.chat = AICUVO.model.start_chat(history=[])
1615
await CallbackQuery.answer("Memoria limpia con exito")
1716
await CallbackQuery.message.reply_text("[⚠️] LA MEMORIA DE CUVO ESTÁ LIMPIA.")
1817
else:

src/apps/llm/main.py renamed to blind/src/apps/llm/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from google.generativeai.types.generation_types import GenerateContentResponse
66
from pyrogram import enums
77

8-
from src.utils.utilities import clearComand
9-
from src.utils.buttons import keymakers
8+
from blind.src.utils.utilities import clearComand
9+
from blind.src.utils.buttons import keymakers
1010

1111
@Client.on_message((filters.command("cuvo") & filters.text) | (filters.private & filters.text))
1212
async def CUVO(client: Client, message: Message):

src/apps/llm/main_audio.py renamed to blind/src/apps/llm/main_audio.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .lib.objects import CHAT
55
from pyrogram import enums
66

7-
from src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
7+
from blind.src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
88
import os
99

1010
@Client.on_message(filters.audio & (filters.command("cuvo") | filters.private))

src/apps/llm/main_documents.py renamed to blind/src/apps/llm/main_documents.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from .lib.objects import CHAT
55
from pyrogram import enums
66

7-
from src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
7+
from blind.src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
88
import os
99

1010
@Client.on_message(filters.document & (filters.command("cuvo") | filters.private))

src/apps/llm/main_image.py renamed to blind/src/apps/llm/main_image.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
from google.generativeai.types.generation_types import GenerateContentResponse
66
from pyrogram import enums
77

8-
from src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
9-
from src.utils.buttons import keymakers
8+
from blind.src.utils.utilities import upload_to_gemini, clearComand, downloadMedia, printTest
9+
from blind.src.utils.buttons import keymakers
1010
import os
1111

1212
@Client.on_message(filters.photo & (filters.command("cuvo") | filters.private))

src/apps/postdata_controler.py renamed to blind/src/apps/postdata_controler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from pyrogram import Client
22
from pyrogram.types.bots_and_keyboards.callback_query import CallbackQuery
33

4-
from src.apps.llm import llmactions
5-
from src.utils.utilities import printTest
4+
from blind.src.apps.llm import llmactions
5+
from blind.src.utils.utilities import printTest
66

77
@Client.on_callback_query()
88
async def controler(client:Client, CallbackQuery:CallbackQuery):
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from pyrogram import Client
2+
from pyrogram.types.messages_and_media.message import Message
3+
4+
async def ejecutar(file_name:str, **kwargs):
5+
"""
6+
Ejecuta esta función para poder ejecutar el script de python, está diseñado para probar el output para que el asistente pueda comprender si el script está listo o necesita mejorar algo.
7+
8+
Args:
9+
file_name (str): El nombre del archivo de desarrollo (ejemplo: script.py)
10+
11+
Returns:
12+
El output del archivo de desarrollo.
13+
"""
14+
message:Message = kwargs.get("message", None)
15+
client:Client = kwargs.get("client", None)
16+
17+
await message.reply_text(f"[⚡️] <b>Conda</b> está ejecutando el script.")
18+
19+
try:
20+
with open(file_name, "r") as f:
21+
code = f.read()
22+
output = exec(code)
23+
return {"results": output}
24+
except FileNotFoundError:
25+
return {"results":"Archivo script.py no encontrado."}
26+
except Exception as e:
27+
return {"results":f"Error al ejecutar el código: {e}"}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from pyrogram import Client
2+
from pyrogram.types.messages_and_media.message import Message
3+
import re
4+
5+
async def ide(code: str, file_name: str, **kwargs):
6+
"""
7+
Permite escribir en el archivo de desarrollo código en python, para poder ser ejecutado luego con la función "ejecutar".
8+
9+
IMPORTANTE: No se tiene que usar funciones como "input" ni cualquier otra cosa que requiera interacción con la terminal, ya que esto causará que el sistema espere respuesta del usuario, en su lugar establece variables.
10+
11+
Args:
12+
code (str): El código a escribir en el archivo de desarrollo, ejemplo: 'import random\\n# Genera un número aleatorio entre 1 y 10\\nnumero_aleatorio = random.randint(1, 10)\\n\\nprint("Número aleatorio generado: ", numero_aleatorio)'
13+
14+
file_name (str): El nombre del archivo de desarrollo (ejemplo: script.py)
15+
Returns:
16+
True o False dependiendo del éxito al guardar el código en el archivo de desarrollo.
17+
"""
18+
message = kwargs.get("message", None)
19+
client = kwargs.get("client", None)
20+
21+
await message.reply_text(f"[⚡️] <b>Conda</b> está verificando el script.")
22+
23+
# Validar que el código no contenga funciones problemáticas
24+
prohibited_patterns = [r'\binput\b', r'\bgetpass\b'] # Palabras clave prohibidas
25+
for pattern in prohibited_patterns:
26+
if re.search(pattern, code):
27+
return {"results": "[⚠️] El script contiene funciones problemáticas como 'input'. Por favor, elimínalas y vuelve a intentarlo. (consejo: reemplaza el valor de los input por constantes)"}
28+
29+
try:
30+
with open(file_name, "w") as f:
31+
code = code.replace("\\n", "\n")
32+
code = code.replace("\\", '')
33+
f.write(str(code))
34+
await message.reply_text(f"[✅] Script guardado correctamente en {file_name}.")
35+
return {"results": True}
36+
except FileNotFoundError:
37+
return {"results": "Archivo no encontrado."}
38+
except Exception as e:
39+
return {"results": f"Error al guardar el código: {e}"}

0 commit comments

Comments
 (0)