bot-mwsm 3.0.4 → 3.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bash/mwsm.sh CHANGED
@@ -28,24 +28,56 @@ pause_and_restore() {
28
28
  tput civis >/dev/null 2>&1 || true
29
29
  }
30
30
 
31
+
32
+ fix_wwjs() {
33
+ local BASE_PATH="/var/api/Mwsm/node_modules/whatsapp-web.js/src/util/Injected"
34
+ local STORE_FILE="${BASE_PATH}/Store.js"
35
+ local UTILS_FILE="${BASE_PATH}/Utils.js"
36
+
37
+ if [ -f "$STORE_FILE" ] && grep -q '() => false' "$STORE_FILE"; then
38
+ sed -i 's/() => false/() => true/' "$STORE_FILE"
39
+ fi
40
+
41
+ # if [ -f "$UTILS_FILE" ] && grep -q 'window.Store.SocketWap.USER_JID' "$UTILS_FILE"; then
42
+ # sed -i '/window\.WWebJS\.rejectCall\s*=\s*async/,/};/c\
43
+ # window.WWebJS.rejectCall = async (peerJid, id) => {\
44
+ # let userId = window.Store.User.getMaybeMePnUser()._serialized;\
45
+ # const stanza = window.Store.SocketWap.wap("call", {\
46
+ # id: window.Store.SocketWap.generateId(),\
47
+ # from: userId,\
48
+ # to: peerJid,\
49
+ # }, [\
50
+ # window.Store.SocketWap.wap("reject", {\
51
+ # "call-id": id,\
52
+ # "call-creator": peerJid,\
53
+ # count: "0",\
54
+ # })\
55
+ # ]);\
56
+ # await window.Store.Socket.deprecatedCastStanza(stanza);\
57
+ # };' "$UTILS_FILE"
58
+ # fi
59
+
60
+ # Fix sendSeen
61
+ [ -f "$UTILS_FILE" ] && cp "$UTILS_FILE" "$UTILS_FILE.backup" && sed -i 's|await window\.Store\.SendSeen\.sendSeen(chat);|await window.Store.SendSeen.markSeen(chat);|g' "$UTILS_FILE"
62
+ }
63
+
64
+
31
65
  # ===============================
32
66
  # Diretórios dinâmicos globais
33
67
  # ===============================
34
- if [[ "$DISTRO_DETECT" == "docker" ]]; then
35
- BASE_DIR="/app/Mwsm"
36
- LOG_DIR="/app/logs"
37
- else
38
68
  BASE_DIR="/var/api/Mwsm"
39
- LOG_DIR="/var/log/Mwsm"
69
+ LOG_DIR="/var/log"
70
+ LOG_FILE="$LOG_DIR/mwsm.log"
71
+ TMP_SCRIPT="/tmp/mwsm.sh"
72
+ mkdir -p "$BASE_DIR" "$LOG_DIR"
73
+ touch "$LOG_FILE"
74
+ chmod 644 "$LOG_FILE"
75
+
76
+ if [ -s /proc/$$/fd/0 ]; then
77
+ cat /proc/$$/fd/0 > "$BASE_DIR/mwsm.sh"
78
+ chmod +x "$BASE_DIR/mwsm.sh"
40
79
  fi
41
80
 
42
- LOG_FILE="$LOG_DIR/mwsm.log"
43
-
44
- mkdir -p "$BASE_DIR" "$LOG_DIR"
45
- touch "$LOG_FILE"
46
- chmod 644 "$LOG_FILE"
47
-
48
-
49
81
  uninstall_concluido() {
50
82
  local dirs=(
51
83
  "$BASE_DIR"
@@ -105,6 +137,8 @@ Setup_Mwsm() {
105
137
  local SRC=""
106
138
  local LOG_PREFIX
107
139
  LOG_PREFIX="$(date '+%Y-%m-%d %H:%M:%S') - [SETUP]"
140
+
141
+ # Detectar origem real do script
108
142
  if [ -n "${BASH_SOURCE[0]:-}" ]; then
109
143
  SRC="${BASH_SOURCE[0]}"
110
144
  fi
@@ -113,29 +147,29 @@ Setup_Mwsm() {
113
147
  SRC="$(realpath "$SRC")"
114
148
  fi
115
149
 
150
+ # Evitar usar STDIN (terminal) como fonte
116
151
  if [ ! -f "$SRC" ] || [ -z "$SRC" ]; then
117
- if [ -r "/proc/$$/fd/0" ]; then
118
- SRC="/proc/$$/fd/0"
119
- elif [ -r "/proc/self/fd/0" ]; then
120
- SRC="/proc/self/fd/0"
152
+ if [[ -r "$0" && "$0" != "bash" ]]; then
153
+ SRC="$0"
154
+ elif [ -r "/proc/self/exe" ]; then
155
+ SRC="/proc/self/exe"
156
+ else
157
+ echo "$LOG_PREFIX ⚠️ Não foi possível determinar o caminho real do script, ignorando restauração" >>"$LOG_FILE"
158
+ return 0
121
159
  fi
122
160
  fi
123
-
124
- if [ -z "$SRC" ]; then
125
- echo "$LOG_PREFIX ⚠️ Não foi possível localizar o script em execução para restaurar mwsm.sh" >>"$LOG_FILE"
126
- return 1
127
- fi
128
-
161
+ # Se o script destino não existir, restaura a partir da origem detectada
129
162
  if [[ -d $BASE_DIR && ! -f "$SCRIPT_PATH" ]]; then
130
163
  echo "$LOG_PREFIX 🔁 Restaurando mwsm.sh a partir de $SRC" >>"$LOG_FILE"
164
+
131
165
  if [ "$(id -u)" -eq 0 ]; then
132
- cp -- "$SRC" "$SCRIPT_PATH" 2>>"$LOG_FILE" || {
166
+ cp -f "$SRC" "$SCRIPT_PATH" 2>>"$LOG_FILE" || {
133
167
  echo "$LOG_PREFIX ❌ Falha ao copiar $SRC -> $SCRIPT_PATH" >>"$LOG_FILE"
134
168
  return 1
135
169
  }
136
170
  chmod +x "$SCRIPT_PATH" 2>>"$LOG_FILE" || true
137
171
  else
138
- $SUDO bash -c "cp -- '$SRC' '$SCRIPT_PATH' && chmod +x '$SCRIPT_PATH'" 2>>"$LOG_FILE" || {
172
+ $SUDO bash -c "cp -f '$SRC' '$SCRIPT_PATH' && chmod +x '$SCRIPT_PATH'" 2>>"$LOG_FILE" || {
139
173
  echo "$LOG_PREFIX ❌ Falha ao copiar (sudo) $SRC -> $SCRIPT_PATH" >>"$LOG_FILE"
140
174
  return 1
141
175
  }
@@ -143,14 +177,15 @@ Setup_Mwsm() {
143
177
 
144
178
  if [ -f "$SCRIPT_PATH" ]; then
145
179
  echo "$LOG_PREFIX ✅ mwsm.sh restaurado em $SCRIPT_PATH" >>"$LOG_FILE"
146
- return 0
147
180
  else
148
181
  echo "$LOG_PREFIX ❌ Após copiar, $SCRIPT_PATH ainda não existe." >>"$LOG_FILE"
149
182
  return 1
150
183
  fi
151
184
  fi
185
+
152
186
  return 0
153
187
  }
188
+
154
189
  silent_menu() {
155
190
  local local_file="$BASE_DIR/mwsm.sh"
156
191
  local remote_url="https://raw.githubusercontent.com/MKCodec/Mwsm/refs/heads/main/bash/mwsm.sh"
@@ -186,6 +221,7 @@ NODE_REPO_FAILED=false
186
221
  NODE_INSTALL_FAILED=false
187
222
  NPM_INSTALL_FAILED=false
188
223
  LAST_SUCCESS=""
224
+ detect_distro
189
225
 
190
226
  # =================================
191
227
  # Modo de log completo
@@ -367,13 +403,39 @@ install() {
367
403
  -o Dpkg::Options::='--force-confdef' \
368
404
  -o Dpkg::Options::='--force-confold'" "Instalando pacotes extras..." install
369
405
  else
370
- run_step "$SUDO apt update -y; $SUDO apt upgrade -y \
371
- -o Dpkg::Options::='--force-confdef' \
372
- -o Dpkg::Options::='--force-confold'" "Atualizando pacotes..." install
373
- run_step "$SUDO apt-get install -y git wget curl jq build-essential libnss3-dev \
374
- libgdk-pixbuf2.0-dev libgtk-3-dev libxss-dev libasound2 \
375
- -o Dpkg::Options::='--force-confdef' \
376
- -o Dpkg::Options::='--force-confold'" "Instalando dependências..." install
406
+ run_step "(
407
+ $SUDO apt update -y >>\"$LOG_FILE\" 2>&1
408
+ $SUDO apt upgrade -y \
409
+ -o Dpkg::Options::='--force-confdef' \
410
+ -o Dpkg::Options::='--force-confold' >>\"$LOG_FILE\" 2>&1
411
+ $SUDO apt install -y curl git wget \
412
+ -o Dpkg::Options::='--force-confdef' \
413
+ -o Dpkg::Options::='--force-confold' >>\"$LOG_FILE\" 2>&1
414
+ )" "Instalando pacotes base..." install
415
+
416
+ run_step "$SUDO apt install -y \
417
+ ca-certificates fonts-liberation libappindicator3-1 \
418
+ libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 \
419
+ libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 \
420
+ libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 \
421
+ libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
422
+ libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \
423
+ libxss1 libxtst6 lsb-release xdg-utils \
424
+ -o Dpkg::Options::='--force-confdef' \
425
+ -o Dpkg::Options::='--force-confold'" "Instalando pacotes extras..." install
426
+
427
+ run_step '(
428
+ set -e
429
+ if ! '"$SUDO"' apt-get install -y git wget curl jq build-essential libnss3-dev \
430
+ libgdk-pixbuf2.0-dev libgtk-3-dev libxss-dev libasound2 \
431
+ -o Dpkg::Options::="--force-confdef" \
432
+ -o Dpkg::Options::="--force-confold" >/dev/null 2>&1; then
433
+ '"$SUDO"' apt-get install -y libgdk-pixbuf-xlib-2.0-dev \
434
+ -o Dpkg::Options::="--force-confdef" \
435
+ -o Dpkg::Options::="--force-confold" >/dev/null 2>&1
436
+ fi
437
+ )' "Instalando dependências..." install
438
+
377
439
  fi
378
440
 
379
441
  # -------------------------
@@ -384,12 +446,12 @@ install() {
384
446
  # -------------------------
385
447
  # Node.js - Configurar repositório
386
448
  # -------------------------
387
- run_step "$SUDO bash -c '
388
- cd /root || exit 1
389
- apt-get update -y
390
- apt-get install -y curl gnupg ca-certificates --no-install-recommends
391
- curl -fsSL https://deb.nodesource.com/setup_20.x | bash - || exit 1
392
- '" "Configurando repositório Node.js" install
449
+ run_step "$SUDO bash -c '
450
+ cd /root || exit 1
451
+ apt-get update -y
452
+ apt-get install -y curl gnupg ca-certificates lsb-release apt-transport-https --no-install-recommends
453
+ curl -fsSL https://deb.nodesource.com/setup_20.x | bash - || exit 1
454
+ '" "Configurando repositório Node.js" install
393
455
 
394
456
  if [ "$NODE_REPO_FAILED" = true ]; then
395
457
  printf "❌ Instalando Node.js\n"
@@ -410,77 +472,141 @@ install() {
410
472
  printf "❌ Iniciando serviços\n"
411
473
  INSTALL_FAILED=true
412
474
  else
413
- # -------------------------
414
- # 🐍 Python + Pip + Libs
415
- # -------------------------
416
- run_step "$SUDO apt update -y >/dev/null 2>&1 && \
417
- $SUDO apt install -y python3 python3-pip python3-venv \
418
- -o Dpkg::Options::='--force-confdef' \
419
- -o Dpkg::Options::='--force-confold' >/dev/null 2>&1" \
420
- 'Instalando Python' install
421
-
422
- if ! command -v pip3 >/dev/null 2>&1; then
423
- run_step "$SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1" \
424
- 'Restaurando pip' install
425
- fi
426
475
 
427
- run_step "cd /tmp && \
428
- PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
429
- $SUDO python3 -m pip install --quiet --no-input --upgrade pip setuptools wheel" \
430
- 'Atualizando Python' install
431
476
 
432
- # Instala libs Python dependendo da distro detectada
433
- if [[ "$DISTRO_DETECT" == "devuan" ]]; then
434
- run_step "cd /tmp && \
435
- PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
436
- $SUDO python3 -m pip install --quiet --no-input \
437
- 'flask==2.2.5' \
438
- 'sentence-transformers==2.2.2' \
439
- 'transformers==4.25.1' \
440
- 'safetensors==0.3.1' \
441
- 'huggingface_hub==0.10.1'" \
442
- 'Instalando libs Python' install
477
+ # -------------------------
478
+ # 🐍 Python + Pip + Libs
479
+ # -------------------------
443
480
 
444
- else
445
- run_step "cd /tmp && \
446
- PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
447
- $SUDO python3 -m pip install --quiet --no-input \
448
- 'flask==2.2.5' \
449
- 'sentence-transformers==2.2.2' \
450
- 'huggingface_hub==0.10.1'" \
451
- 'Instalando libs Python' install
452
- fi
481
+ if python3 -m pip install --help 2>&1 | grep -q -- '--break-system-packages'; then
482
+ PIP_BREAK_OPT="--break-system-packages"
483
+ else
484
+ PIP_BREAK_OPT=""
485
+ fi
453
486
 
454
- run_step "python3 -m pip show flask >/dev/null 2>&1 && \
455
- python3 -m pip show sentence-transformers >/dev/null 2>&1 && \
456
- python3 -m pip show huggingface_hub >/dev/null 2>&1" \
457
- 'Verificando integridade Python' install
487
+ if [[ "$DISTRO_DETECT" == "devuan" ]]; then
488
+ # --- Instalação simplificada (Devuan possui CUDA + PyTorch nativo) ---
489
+ run_step "$SUDO apt update -y >/dev/null 2>&1 && \
490
+ $SUDO apt install -y python3 python3-pip python3-venv \
491
+ -o Dpkg::Options::='--force-confdef' \
492
+ -o Dpkg::Options::='--force-confold' >/dev/null 2>&1" \
493
+ 'Instalando Python' install
494
+
495
+ if ! command -v pip3 >/dev/null 2>&1; then
496
+ run_step "$SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1" \
497
+ 'Restaurando pip' install
498
+ fi
458
499
 
459
- # -------------------------
460
- # Repositório Mwsm
461
- # -------------------------
462
- run_step "rm -rf $BASE_DIR && mkdir -p $BASE_DIR && cd $BASE_DIR && \
463
- git init && git remote add origin https://github.com/MKCodec/Mwsm.git && \
464
- git config core.sparseCheckout true && echo -e 'fonts/\\nicon.png\\nindex.html\\njquery.js\\nmwsm.db\\nmwsm.js\\nmwsm.json\\nnodemon.json\\npackage.json\\nscript.js\\nsocket.io.js\\nstyle.css\\nversion.json\\nmwsm.py' > .git/info/sparse-checkout && \
465
- git pull origin main || git pull origin master" "Baixando repositório Mwsm" install
466
- CURRENT_USER=$(logname 2>/dev/null || echo "$USER")
467
- $SUDO chown -R "$CURRENT_USER":"$CURRENT_USER" $BASE_DIR
468
- Setup_Mwsm
469
- if [ -f $BASE_DIR/mwsm.sh ]; then
470
- ln -sf $BASE_DIR/mwsm.sh /usr/local/bin/mwsm 2>/dev/null || $SUDO ln -sf $BASE_DIR/mwsm.sh /usr/local/bin/mwsm
471
- chmod +x /usr/local/bin/mwsm 2>/dev/null || $SUDO chmod +x /usr/local/bin/mwsm
472
- fi
500
+ run_step "cd /tmp && \
501
+ PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
502
+ $SUDO python3 -m pip install --quiet --no-input --upgrade pip setuptools wheel" \
503
+ 'Atualizando Python' install
504
+
505
+ run_step "PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
506
+ $SUDO python3 -m pip install --quiet --no-input \
507
+ 'flask==2.2.5' \
508
+ 'sentence-transformers==2.2.2' \
509
+ 'transformers==4.25.1' \
510
+ 'safetensors==0.3.1' \
511
+ 'huggingface_hub==0.10.1'" \
512
+ 'Instalando libs Python' install
513
+
514
+ else
515
+ # --- Caminho completo para Debian/Ubuntu (sem CUDA) ---
516
+ run_step "$SUDO apt update -y >/dev/null 2>&1 && \
517
+ $SUDO apt install -y python3 python3-pip python3-venv \
518
+ -o Dpkg::Options::='--force-confdef' \
519
+ -o Dpkg::Options::='--force-confold' >/dev/null 2>&1" \
520
+ 'Instalando Python' install
521
+
522
+ if ! command -v pip3 >/dev/null 2>&1; then
523
+ run_step "$SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1" \
524
+ 'Restaurando pip' install
525
+ fi
526
+
527
+ run_step "cd /tmp && \
528
+ PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
529
+ $SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1 && \
530
+ $SUDO python3 -m pip install --no-input --quiet --upgrade setuptools wheel >/dev/null 2>&1 || true" \
531
+ 'Atualizando Python' install
532
+
533
+ run_step "PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
534
+ $SUDO env PIP_EXTRA_INDEX_URL='https://download.pytorch.org/whl/cpu' \
535
+ python3 -m pip install --quiet --no-input $PIP_BREAK_OPT \
536
+ --target=/usr/lib/python3/dist-packages \
537
+ 'filelock<3.13.0' \
538
+ 'typing-extensions<4.6.0' \
539
+ 'flask==2.2.5' \
540
+ 'sentence-transformers==2.2.2' \
541
+ 'transformers==4.25.1' \
542
+ 'safetensors==0.3.1' \
543
+ 'huggingface_hub==0.10.1' \
544
+ 'torch==1.13.1+cpu' \
545
+ 'torchvision==0.14.1+cpu' \
546
+ -f https://download.pytorch.org/whl/cpu >/dev/null 2>&1 || true" \
547
+ 'Instalando libs Python' install
548
+ fi
549
+
550
+ if [[ "$DISTRO_DETECT" == "devuan" ]]; then
551
+ run_step "
552
+ command -v pip3 >/dev/null 2>&1 || $SUDO apt install -y python3-pip >/dev/null 2>&1
553
+ for pkg in flask sentence-transformers huggingface_hub; do
554
+ python3 -m pip show \$pkg >/dev/null 2>&1 || \
555
+ $SUDO python3 -m pip install --quiet --no-input \$pkg >/dev/null 2>&1 || true
556
+ done
557
+ " 'Verificando integridade Python' install
558
+ else
559
+ run_step "
560
+ command -v pip3 >/dev/null 2>&1 || $SUDO apt install -y python3-pip >/dev/null 2>&1
561
+ for pkg in flask sentence-transformers huggingface_hub; do
562
+ python3 -m pip show \$pkg >/dev/null 2>&1 || \
563
+ $SUDO env PIP_EXTRA_INDEX_URL='https://download.pytorch.org/whl/cpu' \
564
+ python3 -m pip install --quiet --no-input \$PIP_BREAK_OPT --target=/usr/lib/python3/dist-packages \$pkg >/dev/null 2>&1 || true
565
+ done
566
+ " 'Verificando integridade Python' install
567
+ fi
568
+
569
+
570
+
571
+
572
+
573
+ # -------------------------
574
+ # Repositório Mwsm
575
+ # -------------------------
576
+ cp "$0" "$TMP_SCRIPT" >/dev/null 2>&1 || true
577
+ run_step "rm -rf $BASE_DIR && mkdir -p $BASE_DIR && cd $BASE_DIR && \
578
+ git init && git remote add origin https://github.com/MKCodec/Mwsm.git && \
579
+ git config core.sparseCheckout true && \
580
+ echo -e 'fonts/\nicon.png\nindex.html\njquery.js\nmwsm.db\nmwsm.js\nmwsm.json\nnodemon.json\npackage.json\nscript.js\nsocket.io.js\nstyle.css\nversion.json\nmwsm.py' > .git/info/sparse-checkout && \
581
+ git pull origin main || git pull origin master" "Baixando repositório Mwsm" install
582
+
583
+ # 🧩 Se já existir instalação anterior, ativa modo silencioso
584
+ if [ -f "$BASE_DIR/mwsm.sh" ]; then
585
+ silent_menu
586
+ exit 0
587
+ fi
588
+
589
+ if [ -f "$TMP_SCRIPT" ]; then
590
+ cp "$TMP_SCRIPT" "$BASE_DIR/mwsm.sh" >/dev/null 2>&1
591
+ chmod +x "$BASE_DIR/mwsm.sh"
592
+ ln -sf "$BASE_DIR/mwsm.sh" /usr/local/bin/mwsm 2>/dev/null || $SUDO ln -sf "$BASE_DIR/mwsm.sh" /usr/local/bin/mwsm
593
+ rm -f "$TMP_SCRIPT"
594
+ fi
595
+
596
+ CURRENT_USER=$(logname 2>/dev/null || echo "$USER")
597
+ $SUDO chown -R "$CURRENT_USER":"$CURRENT_USER" "$BASE_DIR"
473
598
 
474
599
  # -------------------------
475
600
  # Dependências Node
476
601
  # -------------------------
477
- cd $BASE_DIR || return
478
- run_step "node -v >/dev/null 2>&1" "Verificando instalação do Node.js" install
479
- run_step "$SUDO npm cache clean --force" "Limpando cache NPM" install
480
- run_step "npm config set registry https://registry.npmjs.org" "Configurando registro NPM" install
602
+ cd $BASE_DIR || return
603
+ run_step "node -v >/dev/null 2>&1" "Verificando instalação do Node.js" install
604
+ run_step "$SUDO npm install -g npm@10 --quiet --no-progress" "Atualizando NPM" install
605
+ run_step "$SUDO npm cache clean --force >/dev/null 2>&1" "Limpando cache NPM" install
606
+ run_step "npm config set registry https://registry.npmjs.org >/dev/null 2>&1" "Configurando registro NPM" install
481
607
 
482
608
  if [[ "$DISTRO_DETECT" == "devuan" ]]; then
483
- run_step "$SUDO npm install -g npm@latest node-gyp@latest" "Atualizando npm e node-gyp" install
609
+ run_step "$SUDO npm install -g npm@10 node-gyp@latest" "Atualizando npm e node-gyp" install
484
610
  run_step "$SUDO npm install --silent --no-fund --no-audit" "Instalando dependências Node" install
485
611
  command -v node >/dev/null 2>&1 || $SUDO ln -sf /usr/bin/nodejs /usr/bin/node
486
612
  run_step "node -v && npm -v" "Verificando Node.js e NPM" install
@@ -512,29 +638,36 @@ install() {
512
638
  run_step "node -v && npm -v" "Verificando Node.js e NPM" install
513
639
  fi
514
640
 
641
+ run_step 'fix_wwjs' "Aplicando correções no Wwjs" install
642
+
515
643
  # -------------------------
516
644
  # Instalação e atualização do PM2
517
645
  # -------------------------
518
- if command -v pm2 >/dev/null 2>&1; then
519
- CURRENT_PM2_VERSION=$(pm2 -v | head -n1 | tr -d '[:space:]')
520
- LATEST_PM2_VERSION=$(npm view pm2 version 2>/dev/null | tr -d '[:space:]')
521
- if [[ -n "$LATEST_PM2_VERSION" && "$CURRENT_PM2_VERSION" != "$LATEST_PM2_VERSION" ]]; then
522
- echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] Atualizando PM2 de $CURRENT_PM2_VERSION para $LATEST_PM2_VERSION" >>"$LOG_FILE"
523
- run_step "$SUDO npm install -g pm2@$LATEST_PM2_VERSION --silent --no-audit --no-fund" "Atualizando PM2" install
524
- else
525
- echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] PM2 já está atualizado (v$CURRENT_PM2_VERSION)" >>"$LOG_FILE"
526
- run_step "$SUDO pm2 update >/dev/null 2>&1 || true" "Sincronizando PM2" install
527
- fi
528
- else
529
- run_step "$SUDO npm install -g pm2@latest --silent --no-audit --no-fund" "Instalando PM2" install
530
- run_step "$SUDO timeout 15s pm2 update >/dev/null 2>&1 || { $SUDO pm2 kill >/dev/null 2>&1; rm -rf ~/.pm2; $SUDO pm2 update >/dev/null 2>&1 || true; }" "Inicializando PM2" install
531
- fi
646
+ if command -v pm2 >/dev/null 2>&1; then
647
+ CURRENT_PM2_VERSION=$(pm2 -v | head -n1 | tr -d '[:space:]')
648
+ LATEST_PM2_VERSION=$(npm view pm2 version 2>/dev/null | tr -d '[:space:]')
649
+
650
+ if [[ -n "$LATEST_PM2_VERSION" && "$CURRENT_PM2_VERSION" != "$LATEST_PM2_VERSION" ]]; then
651
+ echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] Atualizando PM2 de $CURRENT_PM2_VERSION para $LATEST_PM2_VERSION" >>"$LOG_FILE"
652
+ run_step "$SUDO npm install -g pm2@$LATEST_PM2_VERSION --silent --no-audit --no-fund" \
653
+ "Atualizando PM2" install
654
+ else
655
+ echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] PM2 já está atualizado (v$CURRENT_PM2_VERSION)" >>"$LOG_FILE"
656
+ run_step "$SUDO pm2 update >/dev/null 2>&1 || true" \
657
+ "Sincronizando PM2" install
658
+ fi
659
+ else
660
+ run_step "$SUDO npm install -g pm2@latest --silent --no-audit --no-fund" \
661
+ "Instalando PM2" install
662
+ run_step "$SUDO timeout 15s pm2 update >/dev/null 2>&1 || { $SUDO pm2 kill >/dev/null 2>&1; rm -rf ~/.pm2; $SUDO pm2 update >/dev/null 2>&1 || true; }" \
663
+ "Inicializando PM2" install
664
+ fi
532
665
 
533
666
  # -------------------------
534
667
  # Inicialização dos serviços
535
668
  # -------------------------
536
669
  if [[ "$DISTRO_DETECT" == "devuan" ]]; then
537
- run_step "$SUDO sh -c 'crontab -l 2>/dev/null | grep -v \"$BASE_DIR/mwsm.js\"; echo \"@reboot cd $BASE_DIR && npm run start:mkauth\"' | crontab -" "Configurando inicialização" install
670
+ run_step "$SUDO bash -c 'CRON_JOB=\"@reboot cd $BASE_DIR && npm run start:mkauth\"; crontab -l 2>/dev/null | grep -Fxq \"\$CRON_JOB\" || { (crontab -l 2>/dev/null; echo \"\$CRON_JOB\") | crontab -; }'" "Configurando inicialização" install
538
671
  run_step "$SUDO npm run setup:mkauth" "Iniciando serviços" install
539
672
  else
540
673
  run_step "$SUDO npm run setup:mwsm" "Iniciando serviços" install
@@ -716,14 +849,27 @@ update() {
716
849
  run_step "$SUDO pm2 flush" "Limpando logs PM2" update
717
850
  run_step "$SUDO pm2 delete all && $SUDO pm2 kill" "Parando serviços" update
718
851
  fi
719
-
720
852
  run_step "backup_mwsm_db" "Exportando dados Mwsm" update
721
- run_step "git fetch origin main && git reset --hard origin/main" "Atualizando repositório Mwsm" update
722
- Setup_Mwsm
723
- if [ -f $BASE_DIR/mwsm.sh ]; then
724
- ln -sf $BASE_DIR/mwsm.sh /usr/local/bin/mwsm 2>/dev/null || $SUDO ln -sf $BASE_DIR/mwsm.sh /usr/local/bin/mwsm
725
- chmod +x /usr/local/bin/mwsm 2>/dev/null || $SUDO chmod +x /usr/local/bin/mwsm
726
- fi
853
+
854
+ cp "$0" "$TMP_SCRIPT" >/dev/null 2>&1 || true
855
+
856
+ run_step "cd $BASE_DIR && \
857
+ git fetch origin main && git reset --hard origin/main" \
858
+ "Atualizando repositório Mwsm" update
859
+
860
+ if [ -f "$TMP_SCRIPT" ]; then
861
+ cp "$TMP_SCRIPT" "$BASE_DIR/mwsm.sh" >/dev/null 2>&1
862
+ chmod +x "$BASE_DIR/mwsm.sh"
863
+ ln -sf "$BASE_DIR/mwsm.sh" /usr/local/bin/mwsm 2>/dev/null || \
864
+ $SUDO ln -sf "$BASE_DIR/mwsm.sh" /usr/local/bin/mwsm
865
+ rm -f "$TMP_SCRIPT"
866
+ fi
867
+
868
+ CURRENT_USER=$(logname 2>/dev/null || echo "$USER")
869
+ $SUDO chown -R "$CURRENT_USER":"$CURRENT_USER" "$BASE_DIR" >/dev/null 2>&1
870
+
871
+ Setup_Mwsm
872
+
727
873
  run_step "$SUDO apt-get update -y >/dev/null 2>&1" "Verificando repositórios APT" update
728
874
  run_step "$SUDO apt --fix-broken install -y >/dev/null 2>&1 || true" "Corrigindo pacotes quebrados" update
729
875
  run_step "$SUDO apt-get install -y git wget curl jq build-essential sqlite3 --no-install-recommends >/dev/null 2>&1" "Verificando dependências" update
@@ -739,31 +885,77 @@ update() {
739
885
  # Use precise detection for update branches if needed
740
886
  detect_distro
741
887
 
742
- if [[ "$DISTRO_DETECT" == "devuan" ]]; then
743
- run_step "$SUDO npm install -g npm@latest node-gyp@latest --silent --no-audit --no-fund" "Atualizando npm e node-gyp" update
888
+ if [[ "$DISTRO_DETECT" == "devuan" ]]; then
889
+ run_step "$SUDO npm install -g npm@10 node-gyp@latest --silent --no-audit --no-fund" "Atualizando npm e node-gyp" update
744
890
  else
745
- run_step "$SUDO npm install -g npm@latest --silent --no-audit --no-fund" "Atualizando npm" update
891
+ run_step "$SUDO npm install -g npm@10 --silent --no-audit --no-fund" "Atualizando npm" update
746
892
  fi
747
893
 
748
894
  run_step "$SUDO npm install --silent --no-fund --no-audit" "Atualizando dependências Node.js" update
895
+
896
+ run_step 'fix_wwjs' "Aplicando correções no Wwjs" update
897
+
898
+ # -------------------------
899
+ # 🐍 Atualização Python + Pip + Libs
900
+ # -------------------------
901
+
902
+ if python3 -m pip install --help 2>&1 | grep -q -- '--break-system-packages'; then
903
+ PIP_BREAK_OPT="--break-system-packages"
904
+ else
905
+ PIP_BREAK_OPT=""
906
+ fi
907
+
908
+ if [[ "$DISTRO_DETECT" == "devuan" ]]; then
909
+ # --- Devuan com CUDA: atualização mínima ---
749
910
  if ! command -v python3 >/dev/null 2>&1; then
750
911
  run_step "$SUDO apt install -y python3 python3-pip python3-venv --no-install-recommends >/dev/null 2>&1" "Instalando Python" update
751
912
  fi
913
+
752
914
  run_step "$SUDO python3 -m pip install --quiet --upgrade pip setuptools wheel" "Atualizando pip" update
753
915
 
754
- if [[ "$DISTRO_DETECT" == "devuan" ]]; then
755
- run_step "$SUDO python3 -m pip install --quiet --no-input \
916
+ run_step "PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
917
+ $SUDO python3 -m pip install --quiet --no-input \
756
918
  'flask==2.2.5' \
757
919
  'sentence-transformers==2.2.2' \
758
920
  'transformers==4.25.1' \
759
921
  'safetensors==0.3.1' \
760
- 'huggingface_hub==0.10.1'" "Atualizando libs Python" update
761
- else
762
- run_step "$SUDO python3 -m pip install --quiet --no-input \
922
+ 'huggingface_hub==0.10.1'" \
923
+ "Atualizando libs Python" update
924
+
925
+ else
926
+ # --- Debian/Ubuntu sem CUDA ---
927
+ if ! command -v python3 >/dev/null 2>&1; then
928
+ run_step "$SUDO apt update -y >/dev/null 2>&1 && \
929
+ $SUDO apt install -y python3 python3-pip python3-venv \
930
+ -o Dpkg::Options::='--force-confdef' \
931
+ -o Dpkg::Options::='--force-confold' >/dev/null 2>&1" \
932
+ "Instalando Python" update
933
+ fi
934
+
935
+ run_step "cd /tmp && \
936
+ PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
937
+ $SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1 && \
938
+ $SUDO python3 -m pip install --no-input --quiet --upgrade setuptools wheel >/dev/null 2>&1 || true" \
939
+ "Atualizando pip" update
940
+
941
+ run_step "cd /tmp && \
942
+ PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
943
+ $SUDO env PIP_EXTRA_INDEX_URL='https://download.pytorch.org/whl/cpu' \
944
+ python3 -m pip install --quiet --no-input $PIP_BREAK_OPT \
945
+ --target=/usr/lib/python3/dist-packages \
946
+ 'filelock<3.13.0' \
947
+ 'typing-extensions<4.6.0' \
763
948
  'flask==2.2.5' \
764
949
  'sentence-transformers==2.2.2' \
765
- 'huggingface_hub==0.10.1'" "Atualizando libs Python" update
766
- fi
950
+ 'transformers==4.25.1' \
951
+ 'safetensors==0.3.1' \
952
+ 'huggingface_hub==0.10.1' \
953
+ 'torch==1.13.1+cpu' \
954
+ 'torchvision==0.14.1+cpu' \
955
+ -f https://download.pytorch.org/whl/cpu >/dev/null 2>&1 || true" \
956
+ "Atualizando libs Python" update
957
+ fi
958
+
767
959
 
768
960
  if command -v pm2 >/dev/null 2>&1; then
769
961
  CURRENT_PM2_VERSION=$(pm2 -v | head -n1 | tr -d '[:space:]')
@@ -781,7 +973,7 @@ update() {
781
973
  run_step "migrate_mwsm" "Importando dados Mwsm" update
782
974
 
783
975
  if [[ "$DISTRO_DETECT" == "devuan" ]]; then
784
- run_step "$SUDO sh -c 'crontab -l 2>/dev/null | grep -v \"$BASE_DIR/mwsm.js\"; echo \"@reboot cd $BASE_DIR && npm run start:mkauth\"' | crontab -" "Configurando inicialização" update
976
+ run_step "$SUDO bash -c 'CRON_JOB=\"@reboot cd $BASE_DIR && npm run start:mkauth\"; crontab -l 2>/dev/null | grep -Fxq \"\$CRON_JOB\" || { (crontab -l 2>/dev/null; echo \"\$CRON_JOB\") | crontab -; }'" "Configurando inicialização" update
785
977
  run_step "$SUDO npm run setup:mkauth" "Reiniciando serviços" update
786
978
 
787
979
  else
@@ -850,7 +1042,7 @@ uninstall() {
850
1042
  detect_distro
851
1043
 
852
1044
  if [[ "$DISTRO_DETECT" == "devuan" ]]; then
853
- run_step "crontab -l 2>/dev/null | grep -v '$BASE_DIR/mwsm.js' | crontab -" "Removendo inicialização" uninstall || UNINSTALL_FAILED=true
1045
+ run_step "crontab -l 2>/dev/null | grep -Fv 'cd $BASE_DIR && npm run start:mkauth' | crontab -" "Removendo inicialização" uninstall || UNINSTALL_FAILED=true
854
1046
  else
855
1047
  run_step "$SUDO pm2 unstartup systemd" "Removendo inicialização" uninstall || UNINSTALL_FAILED=true
856
1048
  fi
@@ -882,8 +1074,11 @@ uninstall() {
882
1074
  run_step "skip" "Limpando diretórios" uninstall
883
1075
  fi
884
1076
 
1077
+ # Removendo link do comando mwsm
885
1078
  if [ -L /usr/local/bin/mwsm ] || [ -f /usr/local/bin/mwsm ]; then
886
- rm -f /usr/local/bin/mwsm 2>/dev/null || $SUDO rm -f /usr/local/bin/mwsm
1079
+ run_step "$SUDO rm -f /usr/local/bin/mwsm" "Removendo comando mwsm" uninstall || UNINSTALL_FAILED=true
1080
+ else
1081
+ run_step "skip" "Removendo comando mwsm" uninstall
887
1082
  fi
888
1083
 
889
1084
  if [ "$NO_PAUSE" = false ]; then
@@ -951,6 +1146,15 @@ reinstall() {
951
1146
  }
952
1147
 
953
1148
  view_log_hidden() {
1149
+ # sempre restaura o terminal ao sair (mesmo se der erro)
1150
+ cleanup_view() {
1151
+ stty sane >/dev/null 2>&1 || true
1152
+ tput cnorm >/dev/null 2>&1 || true
1153
+ tput sgr0 >/dev/null 2>&1 || true
1154
+ }
1155
+ trap cleanup_view EXIT
1156
+
1157
+ cleanup_view # garante início limpo
954
1158
  while true; do
955
1159
  clear
956
1160
  echo "====================================="
@@ -963,50 +1167,50 @@ view_log_hidden() {
963
1167
  echo "-------------------------------------"
964
1168
  printf "Escolha uma opção: "
965
1169
 
966
- while true; do
967
- read -rsn1 log_choice
968
- case "$log_choice" in
969
- [0-3]) break ;;
970
- *) continue ;;
971
- esac
972
- done
1170
+ read -rsn1 log_choice
973
1171
  echo "$log_choice"
974
1172
 
975
1173
  case $log_choice in
976
- 1)
977
- cutoff_epoch=$(date -d '24 hours ago' +%s)
978
- awk -v cutoff="$cutoff_epoch" '
979
- {
980
- if (match($0, /[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9] [0-9][0-9]:[0-9][0-9]:[0-9][0-9]/)) {
981
- ts = substr($0, RSTART, RLENGTH)
982
- cmd = "date -d \"" ts "\" +%s"
983
- cmd | getline t
984
- close(cmd)
985
- if (t >= cutoff) print $0
986
- }
987
- }' "$LOG_FILE" | iconv -f utf-8 -t utf-8
988
-
989
- printf "\\nPressione ENTER para voltar ao menu principal..."
990
- IFS= read -r _
991
- break
992
- ;;
993
- 2)
994
- cat "$LOG_FILE" | grep "^[0-9]\\{4\\}-" | iconv -f utf-8 -t utf-8
995
- printf "\\nPressione ENTER para voltar ao menu principal..."
996
- IFS= read -r _
997
- break
998
- ;;
999
- 3)
1000
- cat "$LOG_FILE" | grep -v "^[0-9]\\{4\\}-" | iconv -f utf-8 -t utf-8
1001
- printf "\\nPressione ENTER para voltar ao menu principal..."
1002
- IFS= read -r _
1003
- break
1004
- ;;
1005
- 0)
1006
- break
1007
- ;;
1174
+ 1)
1175
+ cleanup_view
1176
+ cutoff_date=$(date -d '24 hours ago' '+%Y-%m-%d %H:%M:%S')
1177
+ grep -E "^[0-9]{4}-[0-9]{2}-[0-9]{2}" "$LOG_FILE" | \
1178
+ awk -v cutoff="$cutoff_date" '
1179
+ {
1180
+ if ($0 >= cutoff) print $0
1181
+ }' | iconv -f utf-8 -t utf-8
1182
+ echo
1183
+ read -rp "Pressione ENTER para voltar..."
1184
+ ;;
1185
+ 2)
1186
+ cleanup_view
1187
+ grep "^[0-9]\\{4\\}-" "$LOG_FILE" | iconv -f utf-8 -t utf-8
1188
+ echo
1189
+ read -rp "Pressione ENTER para voltar..."
1190
+ ;;
1191
+ 3)
1192
+ cleanup_view
1193
+ grep -v "^[0-9]\\{4\\}-" "$LOG_FILE" | iconv -f utf-8 -t utf-8
1194
+ echo
1195
+ read -rp "Pressione ENTER para voltar..."
1196
+ ;;
1197
+ 0)
1198
+ cleanup_view
1199
+ break
1200
+ ;;
1201
+ *)
1202
+ continue
1203
+ ;;
1008
1204
  esac
1009
1205
  done
1206
+
1207
+ cleanup_view
1208
+ trap - EXIT
1209
+ sleep 0.1
1210
+ clear
1211
+ stty sane >/dev/null 2>&1 || true
1212
+ tput civis >/dev/null 2>&1 || true
1213
+
1010
1214
  }
1011
1215
 
1012
1216
  # ========================
@@ -1018,6 +1222,8 @@ clear_log_hidden() {
1018
1222
  echo "🧹 Log limpo com sucesso!"
1019
1223
  echo "-------------------------------------"
1020
1224
  sleep 2
1225
+ stty sane >/dev/null 2>&1 || true
1226
+ tput civis >/dev/null 2>&1 || true
1021
1227
  }
1022
1228
 
1023
1229
  # ========================
@@ -1027,9 +1233,10 @@ menu() {
1027
1233
  command -v tput >/dev/null 2>&1 && tput civis >/dev/null 2>&1 || true
1028
1234
  detect_distro
1029
1235
  while true; do
1030
- if [ -t 0 ]; then
1031
- stty -echo -icanon time 0 min 0 || true
1032
- fi
1236
+
1237
+ if [ -t 0 ]; then
1238
+ stty sane >/dev/null 2>&1 || true
1239
+ fi
1033
1240
 
1034
1241
  clear
1035
1242
 
@@ -1052,13 +1259,16 @@ menu() {
1052
1259
 
1053
1260
  command -v tput >/dev/null 2>&1 && tput civis >/dev/null 2>&1 || true
1054
1261
 
1055
- while true; do
1056
- read -rsn1 choice
1057
- case "$choice" in
1058
- [0-6]) break ;; # aceita apenas 0–6
1059
- *) continue ;;
1060
- esac
1061
- done
1262
+
1263
+ while true; do
1264
+ stty -echo -icanon time 0 min 0 2>/dev/null || true
1265
+ read -rsn1 choice
1266
+ stty sane 2>/dev/null || true
1267
+ case "$choice" in
1268
+ [0-6]) break ;;
1269
+ *) continue ;;
1270
+ esac
1271
+ done
1062
1272
 
1063
1273
  echo "$choice"
1064
1274