almeira-web/scripts/deploy_encargos_fix.py

139 lines
6.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import paramiko
import os
import urllib.request
import json
import ssl
import sys
import io
import time
import subprocess
if sys.platform == 'win32':
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8', errors='replace')
sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8', errors='replace')
HOST = "161.97.93.156"
USER = "carlos"
PASSWORD = "Innova1978+*?"
REMOTE_BASE = "/home/carlos/apps/dripzone-app"
LOCAL_APK = r"c:\Users\Carlos\dev\almeira-web\dripzone-app\public\DripZone.apk"
REMOTE_APK = f"{REMOTE_BASE}/public/DripZone.apk"
EVOLUTION_API_URL = "https://evolution.almeira.com.co"
STORE_INSTANCE_NAME = "DripZone"
STORE_API_KEY = "83B5BD230796-4324-AE73-3508F69E279D"
TARGET_PHONE = "573167455877"
APK_URL = "https://drip-zone.online/DripZone.apk"
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
def main():
print("[1/5] Verificando APK local...")
if not os.path.exists(LOCAL_APK):
print(f" [ERROR] El archivo {LOCAL_APK} no existe.")
sys.exit(1)
size_mb = os.path.getsize(LOCAL_APK) / (1024 * 1024)
print(f" -> APK local verificado: {LOCAL_APK} ({size_mb:.2f} MB)")
print("[2/5] Guardando cambios y pusheando a Gitea...")
try:
subprocess.run(["git", "add", "."], cwd=r"c:\Users\Carlos\dev\almeira-web", check=False)
msg = "feat: gestion completa de Encargos y Pedidos Especiales (editar, eliminar, crear, sincronizar con Appwrite)"
subprocess.run(["git", "commit", "-m", msg], cwd=r"c:\Users\Carlos\dev\almeira-web", check=False)
push_res = subprocess.run(["git", "push", "origin", "main"], cwd=r"c:\Users\Carlos\dev\almeira-web", capture_output=True, text=True)
print(" -> Git push:", push_res.stdout.strip() or push_res.stderr.strip())
except Exception as e:
print(" [WARN Git]:", e)
print("[3/5] Subiendo APK a VPS 161.97.93.156 vía SFTP...")
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname=HOST, username=USER, password=PASSWORD, timeout=30)
sftp = ssh.open_sftp()
try:
sftp.mkdir(f"{REMOTE_BASE}/public")
except:
pass
sftp.put(LOCAL_APK, REMOTE_APK)
sftp.close()
print(" [OK] Archivo APK subido por SFTP al VPS.")
print("[4/5] Copiando APK dentro de los contenedores Docker en VPS...")
cmd = f"""
docker cp {REMOTE_APK} dripzone-production:/app/public/DripZone.apk || true
docker cp {REMOTE_APK} dripzone-production:/app/public/dripzone.apk || true
docker cp {REMOTE_APK} dripzone-production:/app/DripZone.apk || true
for c in $(docker ps -q --filter "name=bfmnoga3"); do
docker cp {REMOTE_APK} $c:/app/public/DripZone.apk || true
docker cp {REMOTE_APK} $c:/app/public/dripzone.apk || true
docker cp {REMOTE_APK} $c:/app/DripZone.apk || true
done
docker exec dripzone-production ls -lh /app/public/DripZone.apk || true
"""
stdin, stdout, stderr = ssh.exec_command(cmd)
out = stdout.read().decode('utf-8', errors='replace')
print(" -> Salida Docker:\n", out.strip())
ssh.close()
time.sleep(2)
try:
req = urllib.request.Request(APK_URL, method='HEAD')
with urllib.request.urlopen(req, context=ctx, timeout=15) as res:
live_size_mb = int(res.headers.get('Content-Length', 0)) / (1024 * 1024)
print(f" [OK] APK online verificado en {APK_URL} (HTTP {res.status}, {live_size_mb:.2f} MB)")
except Exception as e:
print(f" [WARN] Verificación HEAD APK: {e}")
print("[5/5] Enviando notificación al WhatsApp de Carlos (+57 316 745 5877)...")
message_text = (
"👟 *DripZone - Módulo de Encargos Especiales Habilitado al 100%*\n\n"
"Hola Carlos, ya puedes *editar, eliminar, actualizar y crear* encargos y pedidos especiales:\n\n"
"🛠️ *Nuevas Funcionalidades en el Panel Administrativo:*\n"
"• ✏️ *Editar Todo:* Ahora puedes modificar cualquier dato del encargo (cliente, WhatsApp, ciudad, marca, modelo exacto, talla, colorway, presupuesto, notas, precio cotizado y estado).\n"
"• 🖼️ *Cambiar o Subir Foto:* Permite reemplazar o subir una nueva foto para el encargo directamente desde tu computador.\n"
"• 🗑️ *Eliminar con Confirmación:* Botón de papelera en cada tarjeta y en el modal para descartar solicitudes no deseadas o de prueba.\n"
"• ➕ *Crear Encargo Manual:* Botón '+ Nuevo Encargo' para registrar solicitudes recibidas directamente por llamada o chat.\n"
"• ☁️ *Persistencia en la Nube (Appwrite):* Creada y conectada la colección `custom_requests` en Appwrite Cloud, garantizando que nunca se pierdan los cambios al reiniciar el servidor.\n\n"
"👉 *Pruébalo ahora en el panel:* https://drip-zone.online/admin/encargos\n"
f"📲 *APK Android v2.5:* {APK_URL}"
)
req_text = urllib.request.Request(
f"{EVOLUTION_API_URL}/message/sendText/{STORE_INSTANCE_NAME}",
data=json.dumps({"number": TARGET_PHONE, "text": message_text, "delay": 500}).encode("utf-8"),
headers={"apikey": STORE_API_KEY, "Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req_text, context=ctx, timeout=20) as resp:
print(f" [OK] Notificación enviada a WhatsApp (Status: {resp.status})")
except Exception as e:
print(f" [WARN] Fallo enviando texto: {e}")
req_media = urllib.request.Request(
f"{EVOLUTION_API_URL}/message/sendMedia/{STORE_INSTANCE_NAME}",
data=json.dumps({
"number": TARGET_PHONE,
"mediatype": "document",
"mimetype": "application/vnd.android.package-archive",
"fileName": "DripZone-v2.5-Encargos-Fix.apk",
"caption": "📲 *DripZone Android v2.5 - Encargos y Pedidos Especiales CRUD*",
"media": APK_URL
}).encode("utf-8"),
headers={"apikey": STORE_API_KEY, "Content-Type": "application/json"}
)
try:
with urllib.request.urlopen(req_media, context=ctx, timeout=180) as resp:
print(f" [OK] Archivo APK enviado como documento (Status: {resp.status})")
except Exception as e:
print(f" [WARN] Fallo enviando documento APK: {e}")
print("\n[DESPLIEGUE Y NOTIFICACIÓN COMPLETADOS CON ÉXITO]")
if __name__ == "__main__":
main()