bot-mwsm 3.0.1
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/.github/FUNDING.yml +2 -0
- package/.github/workflows/Mwsm.yml +188 -0
- package/.github/workflows/publish.yml +62 -0
- package/LICENSE +21 -0
- package/README.md +204 -0
- package/bash/mwsm.sh +1060 -0
- package/bash/setup.sh +173 -0
- package/docs/pix.html +146 -0
- package/fonts/OpenSans-Regular-webfont.html +0 -0
- package/fonts/css/font-awesome.min.css +4 -0
- package/fonts/fontawesome-webfont (1).eot +0 -0
- package/fonts/fontawesome-webfont.eot +0 -0
- package/fonts/fontawesome-webfont.ttf +0 -0
- package/fonts/fontawesome-webfont.woff +0 -0
- package/fonts/fontawesome-webfont.woff2 +0 -0
- package/fonts/fonts/fontawesome-webfont3e6e-2.html +0 -0
- package/fonts/fonts/fontawesome-webfont3e6e.eot +0 -0
- package/fonts/fonts/fontawesome-webfont3e6e.html +0 -0
- package/fonts/fonts/fontawesome-webfont3e6e.svg +2671 -0
- package/fonts/fonts/fontawesome-webfont3e6e.woff +0 -0
- package/fonts/fonts/fontawesome-webfontd41d.eot +0 -0
- package/fonts/glyphicons-halflings-regular.eot +0 -0
- package/fonts/glyphicons-halflings-regular.html +0 -0
- package/fonts/glyphicons-halflings-regular.svg +288 -0
- package/fonts/glyphicons-halflings-regular.woff +0 -0
- package/fonts/glyphicons-halflings-regulard41d.eot +0 -0
- package/fonts/texgyreadventor-regular-webfont.html +0 -0
- package/icon.png +0 -0
- package/img/Mwsm.png +0 -0
- package/img/auth.png +0 -0
- package/img/autobot.png +0 -0
- package/img/autupdate.png +0 -0
- package/img/cli.png +0 -0
- package/img/cronshed.png +0 -0
- package/img/debug.log +0 -0
- package/img/debug.png +0 -0
- package/img/delay.png +0 -0
- package/img/dev.png +0 -0
- package/img/endpoint.png +0 -0
- package/img/find.png +0 -0
- package/img/log.png +0 -0
- package/img/mkauth.png +0 -0
- package/img/msn.png +0 -0
- package/img/paycon.png +0 -0
- package/img/prevent.png +0 -0
- package/img/resent.png +0 -0
- package/img/reset.png +0 -0
- package/img/resync.png +0 -0
- package/img/settings.png +0 -0
- package/img/shifts.png +0 -0
- package/img/spam.png +0 -0
- package/img/spam2.png +0 -0
- package/img/status.png +0 -0
- package/img/status2.png +0 -0
- package/img/stop.png +0 -0
- package/img/success.png +0 -0
- package/img/sync.png +0 -0
- package/img/terminal.png +0 -0
- package/img/timers.png +0 -0
- package/img/uid.png +0 -0
- package/img/update.png +0 -0
- package/img/whatsapp.png +0 -0
- package/index.html +1543 -0
- package/jquery.js +2 -0
- package/mwsm.db +0 -0
- package/mwsm.js +4979 -0
- package/mwsm.json +25 -0
- package/mwsm.py +91 -0
- package/nodemon.json +3 -0
- package/package.json +62 -0
- package/script.js +24815 -0
- package/socket.io.js +9 -0
- package/style.css +8744 -0
- package/version.json +8 -0
package/bash/mwsm.sh
ADDED
|
@@ -0,0 +1,1060 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# =====================================
|
|
4
|
+
# 📦 Gerenciador do Bot-Mwsm
|
|
5
|
+
# =====================================
|
|
6
|
+
tput civis
|
|
7
|
+
|
|
8
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
9
|
+
SUDO=""
|
|
10
|
+
else
|
|
11
|
+
SUDO="sudo"
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
cleanup_terminal() {
|
|
15
|
+
if [ -t 1 ]; then
|
|
16
|
+
stty sane >/dev/null 2>&1 || true
|
|
17
|
+
fi
|
|
18
|
+
command -v tput >/dev/null 2>&1 && tput cnorm >/dev/null 2>&1 || true
|
|
19
|
+
}
|
|
20
|
+
trap cleanup_terminal EXIT INT TERM
|
|
21
|
+
|
|
22
|
+
pause_and_restore() {
|
|
23
|
+
tput cnorm >/dev/null 2>&1 || true
|
|
24
|
+
stty sane >/dev/null 2>&1 || true
|
|
25
|
+
sleep 0.2
|
|
26
|
+
echo
|
|
27
|
+
read -rp "Pressione ENTER para voltar ao menu..."
|
|
28
|
+
tput civis >/dev/null 2>&1 || true
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
uninstall_concluido() {
|
|
32
|
+
local dirs=(
|
|
33
|
+
"/var/api/Mwsm"
|
|
34
|
+
"/var/log/Mwsm"
|
|
35
|
+
"/root/.pm2/logs/Ask-Mwsm-out.log"
|
|
36
|
+
"/root/.pm2/logs/Ask-Mwsm-error.log"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
for d in "${dirs[@]}"; do
|
|
40
|
+
if [ -e "$d" ]; then
|
|
41
|
+
return 1 # ainda tem algo, desinstalação incompleta
|
|
42
|
+
fi
|
|
43
|
+
done
|
|
44
|
+
|
|
45
|
+
return 0 # tudo removido → pode pular pro install
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
Setup_Mwsm() {
|
|
49
|
+
local SCRIPT_PATH="/var/api/Mwsm/mwsm.sh"
|
|
50
|
+
local SRC=""
|
|
51
|
+
local LOG_PREFIX
|
|
52
|
+
LOG_PREFIX="$(date '+%Y-%m-%d %H:%M:%S') - [SETUP]"
|
|
53
|
+
if [ -n "${BASH_SOURCE[0]:-}" ]; then
|
|
54
|
+
SRC="${BASH_SOURCE[0]}"
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ -n "$SRC" ] && realpath "$SRC" >/dev/null 2>&1; then
|
|
58
|
+
SRC="$(realpath "$SRC")"
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
if [ ! -f "$SRC" ] || [ -z "$SRC" ]; then
|
|
62
|
+
if [ -r "/proc/$$/fd/0" ]; then
|
|
63
|
+
SRC="/proc/$$/fd/0"
|
|
64
|
+
elif [ -r "/proc/self/fd/0" ]; then
|
|
65
|
+
SRC="/proc/self/fd/0"
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
if [ -z "$SRC" ]; then
|
|
70
|
+
echo "$LOG_PREFIX ⚠️ Não foi possível localizar o script em execução para restaurar mwsm.sh" >>"$LOG_FILE"
|
|
71
|
+
return 1
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
if [[ -d /var/api/Mwsm && ! -f "$SCRIPT_PATH" ]]; then
|
|
75
|
+
echo "$LOG_PREFIX 🔁 Restaurando mwsm.sh a partir de $SRC" >>"$LOG_FILE"
|
|
76
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
77
|
+
cp -- "$SRC" "$SCRIPT_PATH" 2>>"$LOG_FILE" || {
|
|
78
|
+
echo "$LOG_PREFIX ❌ Falha ao copiar $SRC -> $SCRIPT_PATH" >>"$LOG_FILE"
|
|
79
|
+
return 1
|
|
80
|
+
}
|
|
81
|
+
chmod +x "$SCRIPT_PATH" 2>>"$LOG_FILE" || true
|
|
82
|
+
else
|
|
83
|
+
$SUDO bash -c "cp -- '$SRC' '$SCRIPT_PATH' && chmod +x '$SCRIPT_PATH'" 2>>"$LOG_FILE" || {
|
|
84
|
+
echo "$LOG_PREFIX ❌ Falha ao copiar (sudo) $SRC -> $SCRIPT_PATH" >>"$LOG_FILE"
|
|
85
|
+
return 1
|
|
86
|
+
}
|
|
87
|
+
fi
|
|
88
|
+
|
|
89
|
+
if [ -f "$SCRIPT_PATH" ]; then
|
|
90
|
+
echo "$LOG_PREFIX ✅ mwsm.sh restaurado em $SCRIPT_PATH" >>"$LOG_FILE"
|
|
91
|
+
return 0
|
|
92
|
+
else
|
|
93
|
+
echo "$LOG_PREFIX ❌ Após copiar, $SCRIPT_PATH ainda não existe." >>"$LOG_FILE"
|
|
94
|
+
return 1
|
|
95
|
+
fi
|
|
96
|
+
fi
|
|
97
|
+
return 0
|
|
98
|
+
}
|
|
99
|
+
silent_menu() {
|
|
100
|
+
local local_file="/var/api/Mwsm/mwsm.sh"
|
|
101
|
+
local remote_url="https://raw.githubusercontent.com/MKCodec/Mwsm/refs/heads/main/bash/mwsm.sh"
|
|
102
|
+
if curl -sL "$remote_url" -o "$local_file"; then
|
|
103
|
+
$SUDO chmod +x "$local_file" >/dev/null 2>&1
|
|
104
|
+
exec "$SUDO" "$local_file" >/dev/null 2>&1 &
|
|
105
|
+
exit 0
|
|
106
|
+
fi
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
LOG_FILE="/var/log/mwsm.log"
|
|
110
|
+
mkdir -p "$(dirname "$LOG_FILE")"
|
|
111
|
+
touch "$LOG_FILE"
|
|
112
|
+
chmod 644 "$LOG_FILE"
|
|
113
|
+
export PATH="$PATH:/usr/local/bin:/usr/bin:/bin"
|
|
114
|
+
if [ -f /etc/os-release ]; then
|
|
115
|
+
. /etc/os-release
|
|
116
|
+
DISTRO=$(echo "${ID:-}" | tr '[:upper:]' '[:lower:]' | tr -d '"')
|
|
117
|
+
else
|
|
118
|
+
DISTRO=""
|
|
119
|
+
fi
|
|
120
|
+
DISTRO=${DISTRO:-$(lsb_release -si 2>/dev/null | tr '[:upper:]' '[:lower:]')}
|
|
121
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] Detectado sistema: $DISTRO" >>"$LOG_FILE"
|
|
122
|
+
|
|
123
|
+
# Detecta Devuan (usa eudev, sem systemd)
|
|
124
|
+
if grep -qi "devuan" /etc/os-release 2>/dev/null; then
|
|
125
|
+
IS_DEVUAN=true
|
|
126
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] Detectado sistema Devuan (sem systemd)" >>"$LOG_FILE"
|
|
127
|
+
else
|
|
128
|
+
IS_DEVUAN=false
|
|
129
|
+
fi
|
|
130
|
+
|
|
131
|
+
ACTION_DONE=false
|
|
132
|
+
INSTALL_FAILED=false
|
|
133
|
+
IS_REINSTALL=false
|
|
134
|
+
NODE_REPO_FAILED=false
|
|
135
|
+
NODE_INSTALL_FAILED=false
|
|
136
|
+
NPM_INSTALL_FAILED=false
|
|
137
|
+
LAST_SUCCESS=""
|
|
138
|
+
|
|
139
|
+
# =================================
|
|
140
|
+
# Função de execução
|
|
141
|
+
# =================================
|
|
142
|
+
run_step() {
|
|
143
|
+
local CMD="$1"
|
|
144
|
+
local MSG="$2"
|
|
145
|
+
local CONTEXT="$3"
|
|
146
|
+
local spin='-\|/'
|
|
147
|
+
local i=0
|
|
148
|
+
tput civis 2>/dev/null
|
|
149
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [STEP] Iniciando: $MSG" >>"$LOG_FILE"
|
|
150
|
+
|
|
151
|
+
# Skip manual explícito
|
|
152
|
+
if [ "$CMD" = "skip" ] || [ "$CMD" = "true" ]; then
|
|
153
|
+
for _ in $(seq 30); do
|
|
154
|
+
i=$(((i + 1) % 4))
|
|
155
|
+
printf "\r${spin:$i:1} %s" "$MSG"
|
|
156
|
+
sleep 0.1
|
|
157
|
+
done
|
|
158
|
+
printf "\r✔ %s\n" "$MSG"
|
|
159
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [STEP] Finalizado: $MSG (SKIP)" >>"$LOG_FILE"
|
|
160
|
+
return 0
|
|
161
|
+
fi
|
|
162
|
+
|
|
163
|
+
# Executa o comando real
|
|
164
|
+
(
|
|
165
|
+
set +e
|
|
166
|
+
if declare -f "${CMD%% *}" >/dev/null 2>&1; then
|
|
167
|
+
${CMD}
|
|
168
|
+
else
|
|
169
|
+
bash -c "$CMD"
|
|
170
|
+
fi
|
|
171
|
+
) &>>"$LOG_FILE" &
|
|
172
|
+
local PID=$!
|
|
173
|
+
|
|
174
|
+
# Spinner visual
|
|
175
|
+
while kill -0 $PID 2>/dev/null; do
|
|
176
|
+
i=$(((i + 1) % 4))
|
|
177
|
+
printf "\r${spin:$i:1} %s" "$MSG"
|
|
178
|
+
sleep 0.1
|
|
179
|
+
done
|
|
180
|
+
wait $PID
|
|
181
|
+
local STATUS=$?
|
|
182
|
+
|
|
183
|
+
# Falso positivo
|
|
184
|
+
if [ $STATUS -ne 0 ]; then
|
|
185
|
+
local LAST_LOG
|
|
186
|
+
LAST_LOG=$(tail -n 15 "$LOG_FILE")
|
|
187
|
+
|
|
188
|
+
if echo "$LAST_LOG" | grep -qE "No process found|not a git repository|nothing to commit|already up to date"; then
|
|
189
|
+
for _ in $(seq 30); do
|
|
190
|
+
i=$(((i + 1) % 4))
|
|
191
|
+
printf "\r${spin:$i:1} %s" "$MSG"
|
|
192
|
+
sleep 0.1
|
|
193
|
+
done
|
|
194
|
+
printf "\r✔ %s\n" "$MSG"
|
|
195
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [STEP] Finalizado: $MSG (SKIP)" >>"$LOG_FILE"
|
|
196
|
+
return 0
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Erro real
|
|
200
|
+
printf "\r❌ %s\n" "$MSG"
|
|
201
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [STEP] Finalizado: $MSG (FAIL)" >>"$LOG_FILE"
|
|
202
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [ERROR] Falha ao executar: $CMD" >>"$LOG_FILE"
|
|
203
|
+
INSTALL_FAILED=true
|
|
204
|
+
return 1
|
|
205
|
+
fi
|
|
206
|
+
|
|
207
|
+
# Sucesso real
|
|
208
|
+
printf "\r✔ %s\n" "$MSG"
|
|
209
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [STEP] Finalizado: $MSG (OK)" >>"$LOG_FILE"
|
|
210
|
+
return 0
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
# ========================
|
|
214
|
+
# Instalar
|
|
215
|
+
# ========================
|
|
216
|
+
install() {
|
|
217
|
+
local NO_CLEAR=false
|
|
218
|
+
local NO_PAUSE=false
|
|
219
|
+
|
|
220
|
+
if [ "$1" = "no_clear" ]; then
|
|
221
|
+
NO_CLEAR=true
|
|
222
|
+
fi
|
|
223
|
+
if [ "$2" = "no_pause" ]; then
|
|
224
|
+
NO_PAUSE=true
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
if [[ -d /var/api/Mwsm && -f /var/api/Mwsm/package.json ]]; then
|
|
228
|
+
echo "-------------------------------------"
|
|
229
|
+
echo "⚠️ O Mwsm já está instalado!"
|
|
230
|
+
echo "-------------------------------------"
|
|
231
|
+
sleep 2
|
|
232
|
+
return
|
|
233
|
+
fi
|
|
234
|
+
|
|
235
|
+
INSTALL_FAILED=false
|
|
236
|
+
NODE_REPO_FAILED=false
|
|
237
|
+
NODE_INSTALL_FAILED=false
|
|
238
|
+
NPM_INSTALL_FAILED=false
|
|
239
|
+
CUSTOM_API_URL="https://raw.githubusercontent.com/MKCodec/MkAuth-API/main/titulo.api"
|
|
240
|
+
API_PATH="/opt/mk-auth/api/titulo.api"
|
|
241
|
+
|
|
242
|
+
if [ "$IS_REINSTALL" = false ]; then
|
|
243
|
+
if [ "$NO_CLEAR" = false ]; then
|
|
244
|
+
clear
|
|
245
|
+
echo "====================================="
|
|
246
|
+
echo " 🚀 Instalando Mwsm"
|
|
247
|
+
echo "====================================="
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
# -------------------------
|
|
252
|
+
# Pacotes básicos
|
|
253
|
+
# -------------------------
|
|
254
|
+
|
|
255
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
256
|
+
$SUDO rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock
|
|
257
|
+
run_step "$SUDO dpkg --configure -a || true" "Corrigindo pendências..." install
|
|
258
|
+
run_step '[[ $(df /opt --output=avail | tail -1) -gt 102400 ]]' "Validando partição..." install
|
|
259
|
+
|
|
260
|
+
if [[ "$DISTRO" == "debian" ]]; then
|
|
261
|
+
|
|
262
|
+
run_step "$SUDO bash -c '
|
|
263
|
+
if [ -f /etc/os-release ]; then
|
|
264
|
+
. /etc/os-release
|
|
265
|
+
DISTRO=$(echo ${ID:-} | tr [:upper:] [:lower:])
|
|
266
|
+
DEBIAN_VERSION=$(grep VERSION_CODENAME /etc/os-release 2>/dev/null | cut -d= -f2)
|
|
267
|
+
if [ -z \"$DEBIAN_VERSION\" ]; then
|
|
268
|
+
DEBIAN_VERSION=$(grep VERSION_ID /etc/os-release 2>/dev/null | cut -d= -f2 | tr -d \\\" )
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
if [ \"$DISTRO\" = debian ] || [ \"$DISTRO\" = devuan ]; then
|
|
272
|
+
if [ -z \"$DEBIAN_VERSION\" ] || [ \"$DEBIAN_VERSION\" = buster ] || [ \"$DEBIAN_VERSION\" = stretch ]; then
|
|
273
|
+
if [ -f /etc/apt/sources.list ]; then
|
|
274
|
+
sed -i \"s|deb\\.debian\\.org|archive\\.debian\\.org|g\" /etc/apt/sources.list
|
|
275
|
+
sed -i \"s|security\\.debian\\.org|archive\\.debian\\.org/debian-security|g\" /etc/apt/sources.list
|
|
276
|
+
fi
|
|
277
|
+
echo \"Acquire::Check-Valid-Until false;\" > /etc/apt/apt.conf.d/99archive
|
|
278
|
+
apt-get clean -qq >/dev/null 2>&1
|
|
279
|
+
rm -rf /var/lib/apt/lists/* >/dev/null 2>&1
|
|
280
|
+
apt-get update --allow-releaseinfo-change -o Acquire::Check-Valid-Until=false -y -qq >/dev/null 2>&1
|
|
281
|
+
fi
|
|
282
|
+
fi
|
|
283
|
+
fi
|
|
284
|
+
'" "Ajustando repositórios Debian antigos" install
|
|
285
|
+
|
|
286
|
+
run_step "$SUDO bash -c 'apt-get clean && rm -rf /var/lib/apt/lists/* && apt-get update --allow-releaseinfo-change -o Acquire::Check-Valid-Until=false -y'" "Recarregando cache APT" install
|
|
287
|
+
run_step "$SUDO bash -c '
|
|
288
|
+
apt --fix-broken install -y || true
|
|
289
|
+
apt-get clean
|
|
290
|
+
apt-get update --allow-releaseinfo-change -y || true
|
|
291
|
+
'" "Reparando dependências quebradas..." install
|
|
292
|
+
fi
|
|
293
|
+
if [[ "$DISTRO" == "ubuntu" ]]; then
|
|
294
|
+
run_step "$SUDO apt update -y; $SUDO apt upgrade -y \
|
|
295
|
+
-o Dpkg::Options::='--force-confdef' \
|
|
296
|
+
-o Dpkg::Options::='--force-confold'" "Atualizando pacotes..." install
|
|
297
|
+
run_step "$SUDO apt-get install -y git wget curl jq build-essential libnss3-dev \
|
|
298
|
+
libgdk-pixbuf2.0-dev libgtk-3-dev libxss-dev libasound2 \
|
|
299
|
+
-o Dpkg::Options::='--force-confdef' \
|
|
300
|
+
-o Dpkg::Options::='--force-confold'" "Instalando dependências..." install
|
|
301
|
+
else
|
|
302
|
+
run_step "$SUDO apt update -y" "Atualizando pacotes..." install
|
|
303
|
+
run_step "$SUDO apt install -y curl git wget jq build-essential \
|
|
304
|
+
-o Dpkg::Options::='--force-confdef' \
|
|
305
|
+
-o Dpkg::Options::='--force-confold'" "Instalando pacotes base..." install
|
|
306
|
+
run_step "$SUDO apt install -y ca-certificates fonts-liberation libappindicator3-1 \
|
|
307
|
+
libasound2 libatk-bridge2.0-0 libatk1.0-0 libc6 libcairo2 libcups2 \
|
|
308
|
+
libdbus-1-3 libexpat1 libfontconfig1 libgbm1 libgcc1 libglib2.0-0 \
|
|
309
|
+
libgtk-3-0 libnspr4 libnss3 libpango-1.0-0 libpangocairo-1.0-0 \
|
|
310
|
+
libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 \
|
|
311
|
+
libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 \
|
|
312
|
+
libxss1 libxtst6 lsb-release xdg-utils \
|
|
313
|
+
-o Dpkg::Options::='--force-confdef' \
|
|
314
|
+
-o Dpkg::Options::='--force-confold'" "Instalando pacotes extras..." install
|
|
315
|
+
fi
|
|
316
|
+
run_step "command -v sqlite3 >/dev/null 2>&1 || $SUDO apt-get install -y sqlite3 --no-install-recommends" "Instalando SQLite3" install
|
|
317
|
+
# -------------------------
|
|
318
|
+
# Node.js
|
|
319
|
+
# -------------------------
|
|
320
|
+
run_step "$SUDO bash -c '
|
|
321
|
+
cd /root || exit 1
|
|
322
|
+
apt-get update -y
|
|
323
|
+
apt-get install -y curl gnupg ca-certificates --no-install-recommends
|
|
324
|
+
curl -fsSL https://deb.nodesource.com/setup_20.x | bash - || exit 1
|
|
325
|
+
'" "Configurando repositório Node.js" install
|
|
326
|
+
|
|
327
|
+
if [ "$NODE_REPO_FAILED" = true ]; then
|
|
328
|
+
printf "❌ Instalando Node.js\n"
|
|
329
|
+
printf "❌ Instalando dependências Node\n"
|
|
330
|
+
printf "❌ Iniciando serviços\n"
|
|
331
|
+
INSTALL_FAILED=true
|
|
332
|
+
else
|
|
333
|
+
run_step "$SUDO bash -c '
|
|
334
|
+
cd /root || exit 1
|
|
335
|
+
apt-get update -y
|
|
336
|
+
apt-get install -y nodejs \
|
|
337
|
+
-o Dpkg::Options::=\"--force-confdef\" \
|
|
338
|
+
-o Dpkg::Options::=\"--force-confold\" --no-install-recommends
|
|
339
|
+
node -v && npm -v
|
|
340
|
+
'" "Instalando Node.js" install
|
|
341
|
+
|
|
342
|
+
if [ "$NODE_INSTALL_FAILED" = true ]; then
|
|
343
|
+
printf "❌ Instalando dependências Node\n"
|
|
344
|
+
printf "❌ Iniciando serviços\n"
|
|
345
|
+
INSTALL_FAILED=true
|
|
346
|
+
else
|
|
347
|
+
# -------------------------
|
|
348
|
+
# 🐍 Python + Pip + Libs
|
|
349
|
+
# -------------------------
|
|
350
|
+
run_step "$SUDO apt update -y >/dev/null 2>&1 && \
|
|
351
|
+
$SUDO apt install -y python3 python3-pip python3-venv \
|
|
352
|
+
-o Dpkg::Options::='--force-confdef' \
|
|
353
|
+
-o Dpkg::Options::='--force-confold' >/dev/null 2>&1" \
|
|
354
|
+
'Instalando Python' install
|
|
355
|
+
|
|
356
|
+
if ! command -v pip3 >/dev/null 2>&1; then
|
|
357
|
+
run_step "$SUDO python3 -m ensurepip --upgrade >/dev/null 2>&1" \
|
|
358
|
+
'Restaurando pip' install
|
|
359
|
+
fi
|
|
360
|
+
|
|
361
|
+
run_step "cd /tmp && \
|
|
362
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
|
|
363
|
+
$SUDO python3 -m pip install --quiet --no-input --upgrade pip setuptools wheel" \
|
|
364
|
+
'Atualizando Python' install
|
|
365
|
+
|
|
366
|
+
if grep -qiE 'debian|devuan' /etc/os-release; then
|
|
367
|
+
run_step "cd /tmp && \
|
|
368
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
|
|
369
|
+
$SUDO python3 -m pip install --quiet --no-input \
|
|
370
|
+
'flask==2.2.5' \
|
|
371
|
+
'sentence-transformers==2.2.2' \
|
|
372
|
+
'transformers==4.25.1' \
|
|
373
|
+
'safetensors==0.3.1' \
|
|
374
|
+
'huggingface_hub==0.10.1'" \
|
|
375
|
+
'Instalando libs Python' install
|
|
376
|
+
elif grep -qi 'ubuntu' /etc/os-release; then
|
|
377
|
+
run_step "cd /tmp && \
|
|
378
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
|
|
379
|
+
$SUDO python3 -m pip install --quiet --no-input \
|
|
380
|
+
'flask==2.2.5' \
|
|
381
|
+
'sentence-transformers==2.2.2' \
|
|
382
|
+
'huggingface_hub==0.10.1'" \
|
|
383
|
+
'Instalando libs Python' install
|
|
384
|
+
else
|
|
385
|
+
run_step "cd /tmp && \
|
|
386
|
+
PIP_DISABLE_PIP_VERSION_CHECK=1 PIP_ROOT_USER_ACTION=ignore \
|
|
387
|
+
$SUDO python3 -m pip install --quiet --no-input \
|
|
388
|
+
flask sentence-transformers 'huggingface_hub==0.10.1'" \
|
|
389
|
+
'Instalando libs Python' install
|
|
390
|
+
fi
|
|
391
|
+
|
|
392
|
+
run_step "python3 -m pip show flask >/dev/null 2>&1 && \
|
|
393
|
+
python3 -m pip show sentence-transformers >/dev/null 2>&1 && \
|
|
394
|
+
python3 -m pip show huggingface_hub >/dev/null 2>&1" \
|
|
395
|
+
'Verificando integridade Python' install
|
|
396
|
+
|
|
397
|
+
# -------------------------
|
|
398
|
+
# Repositório Mwsm
|
|
399
|
+
# -------------------------
|
|
400
|
+
run_step "rm -rf /var/api/Mwsm && mkdir -p /var/api/Mwsm && cd /var/api/Mwsm && \
|
|
401
|
+
git init && git remote add origin https://github.com/MKCodec/Mwsm.git && \
|
|
402
|
+
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 && \
|
|
403
|
+
git pull origin main || git pull origin master" "Baixando repositório Mwsm" install
|
|
404
|
+
CURRENT_USER=$(logname 2>/dev/null || echo "$USER")
|
|
405
|
+
$SUDO chown -R "$CURRENT_USER":"$CURRENT_USER" /var/api/Mwsm
|
|
406
|
+
Setup_Mwsm
|
|
407
|
+
if [ -f /var/api/Mwsm/mwsm.sh ]; then
|
|
408
|
+
ln -sf /var/api/Mwsm/mwsm.sh /usr/local/bin/mwsm 2>/dev/null || $SUDO ln -sf /var/api/Mwsm/mwsm.sh /usr/local/bin/mwsm
|
|
409
|
+
chmod +x /usr/local/bin/mwsm 2>/dev/null || $SUDO chmod +x /usr/local/bin/mwsm
|
|
410
|
+
fi
|
|
411
|
+
# -------------------------
|
|
412
|
+
# Dependências Node
|
|
413
|
+
# -------------------------
|
|
414
|
+
cd /var/api/Mwsm || return
|
|
415
|
+
run_step "node -v >/dev/null 2>&1" "Verificando instalação do Node.js" install
|
|
416
|
+
run_step "$SUDO npm cache clean --force" "Limpando cache NPM" install
|
|
417
|
+
run_step "npm config set registry https://registry.npmjs.org" "Configurando registro NPM" install
|
|
418
|
+
|
|
419
|
+
if [[ "$DISTRO" == "debian" ]]; then
|
|
420
|
+
run_step "$SUDO npm install -g npm@latest node-gyp@latest" "Atualizando npm e node-gyp" install
|
|
421
|
+
run_step "$SUDO npm install --silent --no-fund --no-audit" "Instalando dependências Node" install
|
|
422
|
+
command -v node >/dev/null 2>&1 || $SUDO ln -sf /usr/bin/nodejs /usr/bin/node
|
|
423
|
+
run_step "node -v && npm -v" "Verificando Node.js e NPM" install
|
|
424
|
+
|
|
425
|
+
$SUDO mkdir -p /opt/mk-auth/api
|
|
426
|
+
$SUDO chmod 755 /opt/mk-auth/api
|
|
427
|
+
|
|
428
|
+
if ! ping -c1 raw.githubusercontent.com &>/dev/null; then
|
|
429
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [WARN] Falha de conexão com raw.githubusercontent.com" >>"$LOG_FILE"
|
|
430
|
+
fi
|
|
431
|
+
|
|
432
|
+
if ping -c1 raw.githubusercontent.com &>/dev/null; then
|
|
433
|
+
EXPECTED_HASH=$($SUDO wget -qO- "$CUSTOM_API_URL" | sha256sum | awk '{print $1}')
|
|
434
|
+
if [[ ! -f "$API_PATH" ]]; then
|
|
435
|
+
run_step "$SUDO wget -q \"$CUSTOM_API_URL\" -O \"$API_PATH\"" "Instalando integração MkAuth" install
|
|
436
|
+
else
|
|
437
|
+
LOCAL_HASH=$(sha256sum "$API_PATH" | awk '{print $1}')
|
|
438
|
+
if [[ "$LOCAL_HASH" != "$EXPECTED_HASH" ]]; then
|
|
439
|
+
run_step "$SUDO wget -q \"$CUSTOM_API_URL\" -O \"$API_PATH\"" "Atualizando integração MkAuth" install
|
|
440
|
+
fi
|
|
441
|
+
fi
|
|
442
|
+
else
|
|
443
|
+
run_step "false" "Instalando integração MkAuth" install
|
|
444
|
+
fi
|
|
445
|
+
else
|
|
446
|
+
run_step "$SUDO npm install --silent --no-fund --no-audit" "Instalando dependências Node" install
|
|
447
|
+
command -v node >/dev/null 2>&1 || $SUDO ln -sf /usr/bin/nodejs /usr/bin/node
|
|
448
|
+
run_step "node -v && npm -v" "Verificando Node.js e NPM" install
|
|
449
|
+
fi
|
|
450
|
+
|
|
451
|
+
# -------------------------
|
|
452
|
+
# Instalação e atualização do PM2
|
|
453
|
+
# -------------------------
|
|
454
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
455
|
+
CURRENT_PM2_VERSION=$(pm2 -v | head -n1 | tr -d '[:space:]')
|
|
456
|
+
LATEST_PM2_VERSION=$(npm view pm2 version 2>/dev/null | tr -d '[:space:]')
|
|
457
|
+
if [[ -n "$LATEST_PM2_VERSION" && "$CURRENT_PM2_VERSION" != "$LATEST_PM2_VERSION" ]]; then
|
|
458
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] Atualizando PM2 de $CURRENT_PM2_VERSION para $LATEST_PM2_VERSION" >>"$LOG_FILE"
|
|
459
|
+
run_step "$SUDO npm install -g pm2@$LATEST_PM2_VERSION --silent --no-audit --no-fund" "Atualizando PM2" install
|
|
460
|
+
else
|
|
461
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [INFO] PM2 já está atualizado (v$CURRENT_PM2_VERSION)" >>"$LOG_FILE"
|
|
462
|
+
run_step "$SUDO pm2 update >/dev/null 2>&1 || true" "Sincronizando PM2" install
|
|
463
|
+
fi
|
|
464
|
+
else
|
|
465
|
+
run_step "$SUDO npm install -g pm2@latest --silent --no-audit --no-fund" "Instalando PM2" install
|
|
466
|
+
run_step "$SUDO pm2 update >/dev/null 2>&1 || true" "Inicializando PM2" install
|
|
467
|
+
fi
|
|
468
|
+
|
|
469
|
+
# -------------------------
|
|
470
|
+
# Inicialização dos serviços
|
|
471
|
+
# -------------------------
|
|
472
|
+
if [[ "$DISTRO" == "ubuntu" ]]; then
|
|
473
|
+
run_step "$SUDO npm run setup:mwsm" "Iniciando serviços" install
|
|
474
|
+
else
|
|
475
|
+
run_step "$SUDO sh -c 'crontab -l 2>/dev/null | grep -v \"/var/api/Mwsm/mwsm.js\"; echo \"@reboot cd /var/api/Mwsm && npm run start:mkauth\"' | crontab -" "Configurando inicialização" install
|
|
476
|
+
run_step "$SUDO npm run setup:mkauth" "Iniciando serviços" install
|
|
477
|
+
fi
|
|
478
|
+
fi
|
|
479
|
+
fi
|
|
480
|
+
# -------------------------
|
|
481
|
+
# Resultado final
|
|
482
|
+
# -------------------------
|
|
483
|
+
if [ "$IS_REINSTALL" = false ]; then
|
|
484
|
+
if [ "$INSTALL_FAILED" = false ]; then
|
|
485
|
+
echo "-------------------------------------"
|
|
486
|
+
echo "✅ Instalação concluída!"
|
|
487
|
+
echo "-------------------------------------"
|
|
488
|
+
LAST_SUCCESS="install"
|
|
489
|
+
else
|
|
490
|
+
echo "-------------------------------------"
|
|
491
|
+
echo "❌ Falha na instalação."
|
|
492
|
+
echo "-------------------------------------"
|
|
493
|
+
if [ -d "/var/api/Mwsm" ]; then
|
|
494
|
+
rm -rf /var/api/Mwsm
|
|
495
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [ROLLBACK] Diretório /var/api/Mwsm removido por falha." >>"$LOG_FILE"
|
|
496
|
+
fi
|
|
497
|
+
fi
|
|
498
|
+
fi
|
|
499
|
+
|
|
500
|
+
# Log
|
|
501
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [INSTALL] Fim da instalação (status: $([ "$INSTALL_FAILED" = true ] && echo FAIL || echo OK))" >>"$LOG_FILE"
|
|
502
|
+
|
|
503
|
+
# Se for chamado pelo reinstall, não pausa
|
|
504
|
+
if [ "$NO_PAUSE" = true ]; then
|
|
505
|
+
return
|
|
506
|
+
fi
|
|
507
|
+
|
|
508
|
+
echo
|
|
509
|
+
pause_and_restore
|
|
510
|
+
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
backup_mwsm_db() {
|
|
516
|
+
local DB_PATH="/var/api/Mwsm/mwsm.db"
|
|
517
|
+
local BACKUP_DIR="/tmp/Mwsm"
|
|
518
|
+
local BACKUP_FILE="$BACKUP_DIR/mwsm.db"
|
|
519
|
+
|
|
520
|
+
mkdir -p "$BACKUP_DIR"
|
|
521
|
+
|
|
522
|
+
if [ -f "$DB_PATH" ]; then
|
|
523
|
+
cp "$DB_PATH" "$BACKUP_FILE"
|
|
524
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [BACKUP] Backup criado em $BACKUP_FILE" >>"$LOG_FILE"
|
|
525
|
+
else
|
|
526
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [BACKUP] ⚠️ Banco original não encontrado em $DB_PATH" >>"$LOG_FILE"
|
|
527
|
+
return 1
|
|
528
|
+
fi
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
|
|
532
|
+
|
|
533
|
+
migrate_mwsm() {
|
|
534
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [MIGRATION] Iniciando migração de banco Mwsm" >>"$LOG_FILE"
|
|
535
|
+
|
|
536
|
+
local SRC_DB="/tmp/Mwsm/mwsm.db"
|
|
537
|
+
local DEST_DB="/var/api/Mwsm/mwsm.db"
|
|
538
|
+
local SQLITE_BIN
|
|
539
|
+
SQLITE_BIN=$(command -v sqlite3)
|
|
540
|
+
local SYSTEM_TABLES=("attachments" "resources" "emotions" "console" "engine")
|
|
541
|
+
|
|
542
|
+
# Verificações iniciais
|
|
543
|
+
if [ ! -f "$SRC_DB" ]; then
|
|
544
|
+
echo "[MIGRATION] ERRO: Backup não encontrado em $SRC_DB" >>"$LOG_FILE"
|
|
545
|
+
return 1
|
|
546
|
+
fi
|
|
547
|
+
|
|
548
|
+
if [ ! -f "$DEST_DB" ]; then
|
|
549
|
+
echo "[MIGRATION] ERRO: Banco de destino não encontrado em $DEST_DB" >>"$LOG_FILE"
|
|
550
|
+
return 1
|
|
551
|
+
fi
|
|
552
|
+
|
|
553
|
+
echo "[MIGRATION] Copiando dados personalizados do backup para o novo banco..." >>"$LOG_FILE"
|
|
554
|
+
|
|
555
|
+
# Percorre todas as tabelas do backup
|
|
556
|
+
for table in $($SQLITE_BIN "$SRC_DB" ".tables"); do
|
|
557
|
+
[[ -z "$table" ]] && continue
|
|
558
|
+
|
|
559
|
+
# Ignorar tabelas de sistema
|
|
560
|
+
for sys in "${SYSTEM_TABLES[@]}"; do
|
|
561
|
+
[[ "$table" == "$sys" ]] && {
|
|
562
|
+
echo "[MIGRATION] Ignorando tabela de sistema: $table" >>"$LOG_FILE"
|
|
563
|
+
continue 2
|
|
564
|
+
}
|
|
565
|
+
done
|
|
566
|
+
|
|
567
|
+
# Verifica se a tabela também existe no novo banco
|
|
568
|
+
if ! $SQLITE_BIN "$DEST_DB" "SELECT name FROM sqlite_master WHERE type='table' AND name='$table';" | grep -q "$table"; then
|
|
569
|
+
echo "[MIGRATION] ⚠️ Tabela $table não existe no novo DB — ignorando." >>"$LOG_FILE"
|
|
570
|
+
continue
|
|
571
|
+
fi
|
|
572
|
+
|
|
573
|
+
# Conta registros
|
|
574
|
+
local src_count dest_count
|
|
575
|
+
src_count=$($SQLITE_BIN "$SRC_DB" "SELECT COUNT(*) FROM '$table';")
|
|
576
|
+
dest_count=$($SQLITE_BIN "$DEST_DB" "SELECT COUNT(*) FROM '$table';")
|
|
577
|
+
|
|
578
|
+
# Se backup não tiver dados, pula
|
|
579
|
+
if [ "$src_count" -eq 0 ]; then
|
|
580
|
+
echo "[MIGRATION] ⚠️ Nenhum dado em $table no backup — pulando." >>"$LOG_FILE"
|
|
581
|
+
continue
|
|
582
|
+
fi
|
|
583
|
+
|
|
584
|
+
echo "[MIGRATION] 🔄 Migrando dados da tabela: $table" >>"$LOG_FILE"
|
|
585
|
+
|
|
586
|
+
# Recupera nomes de colunas
|
|
587
|
+
local columns
|
|
588
|
+
columns=$($SQLITE_BIN "$SRC_DB" "PRAGMA table_info('$table');" | awk -F'|' '{print $2}' | xargs | tr ' ' ',')
|
|
589
|
+
|
|
590
|
+
# Loop por ID — assume que há uma coluna "id"
|
|
591
|
+
for id in $($SQLITE_BIN "$SRC_DB" "SELECT id FROM '$table';"); do
|
|
592
|
+
# Se registro não existe no novo, insere
|
|
593
|
+
if ! $SQLITE_BIN "$DEST_DB" "SELECT id FROM '$table' WHERE id=$id;" | grep -q "$id"; then
|
|
594
|
+
$SQLITE_BIN "$DEST_DB" "INSERT INTO '$table' SELECT * FROM '$SRC_DB'.'$table' WHERE id=$id;" 2>>"$LOG_FILE" \
|
|
595
|
+
&& echo "[MIGRATION] ➕ Inserido registro id=$id em $table" >>"$LOG_FILE"
|
|
596
|
+
continue
|
|
597
|
+
fi
|
|
598
|
+
|
|
599
|
+
# Se existe, faz update seletivo
|
|
600
|
+
local updates=()
|
|
601
|
+
while IFS='|' read -r col val; do
|
|
602
|
+
# Pula colunas nulas ou id
|
|
603
|
+
[[ "$col" == "id" ]] && continue
|
|
604
|
+
[[ -z "$val" ]] && continue
|
|
605
|
+
local current
|
|
606
|
+
current=$($SQLITE_BIN "$DEST_DB" "SELECT $col FROM '$table' WHERE id=$id;")
|
|
607
|
+
if [ -z "$current" ] || [ "$current" = "NULL" ] || [ "$current" != "$val" ]; then
|
|
608
|
+
updates+=("$col='$(echo "$val" | sed "s/'/''/g")'")
|
|
609
|
+
fi
|
|
610
|
+
done < <($SQLITE_BIN "$SRC_DB" "SELECT * FROM '$table' WHERE id=$id;" -separator '|' -header | tail -n +2 | awk -F'|' '{ for(i=1;i<=NF;i++) print i"|"$i }' | while read -r line; do
|
|
611
|
+
idx=$(echo "$line" | cut -d'|' -f1)
|
|
612
|
+
val=$(echo "$line" | cut -d'|' -f2-)
|
|
613
|
+
col=$($SQLITE_BIN "$SRC_DB" "PRAGMA table_info('$table');" | awk -F'|' -v i="$idx" '$1==i-1 {print $2}')
|
|
614
|
+
echo "$col|$val"
|
|
615
|
+
done)
|
|
616
|
+
|
|
617
|
+
# Aplica atualização, se houver colunas a atualizar
|
|
618
|
+
if [ "${#updates[@]}" -gt 0 ]; then
|
|
619
|
+
local set_clause
|
|
620
|
+
set_clause=$(IFS=,; echo "${updates[*]}")
|
|
621
|
+
$SQLITE_BIN "$DEST_DB" "UPDATE '$table' SET $set_clause WHERE id=$id;" 2>>"$LOG_FILE" \
|
|
622
|
+
&& echo "[MIGRATION] 🔁 Atualizado registro id=$id em $table" >>"$LOG_FILE"
|
|
623
|
+
fi
|
|
624
|
+
done
|
|
625
|
+
done
|
|
626
|
+
|
|
627
|
+
echo "[MIGRATION] Migração concluída com sucesso." >>"$LOG_FILE"
|
|
628
|
+
|
|
629
|
+
# Remove backup após migração
|
|
630
|
+
rm -f "$SRC_DB"
|
|
631
|
+
echo "[MIGRATION] Backup removido: $SRC_DB" >>"$LOG_FILE"
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
# ========================
|
|
635
|
+
# Atualiza
|
|
636
|
+
# ========================
|
|
637
|
+
update() {
|
|
638
|
+
INSTALL_FAILED=false
|
|
639
|
+
|
|
640
|
+
if [[ ! -d /var/api/Mwsm || ! -f /var/api/Mwsm/package.json ]]; then
|
|
641
|
+
echo "-------------------------------------"
|
|
642
|
+
echo "⚠️ O Mwsm não está instalado!"
|
|
643
|
+
echo "-------------------------------------"
|
|
644
|
+
sleep 2
|
|
645
|
+
return
|
|
646
|
+
fi
|
|
647
|
+
cd /var/api/Mwsm || return
|
|
648
|
+
clear
|
|
649
|
+
echo "====================================="
|
|
650
|
+
echo " 🔄 Atualizando Mwsm"
|
|
651
|
+
echo "====================================="
|
|
652
|
+
|
|
653
|
+
if [ -f /etc/os-release ]; then
|
|
654
|
+
. /etc/os-release
|
|
655
|
+
DISTRO=$(echo "${ID:-}" | tr '[:upper:]' '[:lower:]')
|
|
656
|
+
else
|
|
657
|
+
DISTRO="unknown"
|
|
658
|
+
fi
|
|
659
|
+
|
|
660
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
661
|
+
run_step "$SUDO pm2 flush" "Limpando logs PM2" update
|
|
662
|
+
run_step "$SUDO pm2 delete all && $SUDO pm2 kill" "Parando serviços" update
|
|
663
|
+
fi
|
|
664
|
+
|
|
665
|
+
run_step "backup_mwsm_db" "Exportando dados Mwsm" update
|
|
666
|
+
run_step "git fetch origin main && git reset --hard origin/main" "Atualizando repositório Mwsm" update
|
|
667
|
+
Setup_Mwsm
|
|
668
|
+
if [ -f /var/api/Mwsm/mwsm.sh ]; then
|
|
669
|
+
ln -sf /var/api/Mwsm/mwsm.sh /usr/local/bin/mwsm 2>/dev/null || $SUDO ln -sf /var/api/Mwsm/mwsm.sh /usr/local/bin/mwsm
|
|
670
|
+
chmod +x /usr/local/bin/mwsm 2>/dev/null || $SUDO chmod +x /usr/local/bin/mwsm
|
|
671
|
+
fi
|
|
672
|
+
run_step "$SUDO apt-get update -y >/dev/null 2>&1" "Verificando repositórios APT" update
|
|
673
|
+
run_step "$SUDO apt --fix-broken install -y >/dev/null 2>&1 || true" "Corrigindo pacotes quebrados" update
|
|
674
|
+
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
|
|
675
|
+
|
|
676
|
+
if ! command -v node >/dev/null 2>&1; then
|
|
677
|
+
run_step "$SUDO bash -c 'curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && apt-get install -y nodejs'" "Reinstalando Node.js" update
|
|
678
|
+
fi
|
|
679
|
+
|
|
680
|
+
run_step "node -v && npm -v" "Verificando Node.js e NPM" update
|
|
681
|
+
run_step "$SUDO npm cache clean --force" "Limpando cache NPM" update
|
|
682
|
+
run_step "npm config set registry https://registry.npmjs.org" "Configurando repositório NPM" update
|
|
683
|
+
if grep -qi 'ubuntu' /etc/os-release; then
|
|
684
|
+
run_step "$SUDO npm install -g npm@latest --silent --no-audit --no-fund" "Atualizando npm" update
|
|
685
|
+
else
|
|
686
|
+
run_step "$SUDO npm install -g npm@latest node-gyp@latest --silent --no-audit --no-fund" "Atualizando npm e node-gyp" update
|
|
687
|
+
fi
|
|
688
|
+
run_step "$SUDO npm install --silent --no-fund --no-audit" "Atualizando dependências Node.js" update
|
|
689
|
+
|
|
690
|
+
if ! command -v python3 >/dev/null 2>&1; then
|
|
691
|
+
run_step "$SUDO apt install -y python3 python3-pip python3-venv --no-install-recommends >/dev/null 2>&1" "Instalando Python" update
|
|
692
|
+
fi
|
|
693
|
+
|
|
694
|
+
run_step "$SUDO python3 -m pip install --quiet --upgrade pip setuptools wheel" "Atualizando pip" update
|
|
695
|
+
|
|
696
|
+
if grep -qi 'ubuntu' /etc/os-release; then
|
|
697
|
+
run_step "$SUDO python3 -m pip install --quiet --no-input \
|
|
698
|
+
'flask==2.2.5' \
|
|
699
|
+
'sentence-transformers==2.2.2' \
|
|
700
|
+
'huggingface_hub==0.10.1'" "Atualizando libs Python" update
|
|
701
|
+
else
|
|
702
|
+
run_step "$SUDO python3 -m pip install --quiet --no-input \
|
|
703
|
+
'flask==2.2.5' \
|
|
704
|
+
'sentence-transformers==2.2.2' \
|
|
705
|
+
'transformers==4.25.1' \
|
|
706
|
+
'safetensors==0.3.1' \
|
|
707
|
+
'huggingface_hub==0.10.1'" "Atualizando libs Python" update
|
|
708
|
+
fi
|
|
709
|
+
|
|
710
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
711
|
+
CURRENT_PM2_VERSION=$(pm2 -v | head -n1 | tr -d '[:space:]')
|
|
712
|
+
LATEST_PM2_VERSION=$(npm view pm2 version 2>/dev/null | tr -d '[:space:]')
|
|
713
|
+
if [[ -n "$LATEST_PM2_VERSION" && "$CURRENT_PM2_VERSION" != "$LATEST_PM2_VERSION" ]]; then
|
|
714
|
+
run_step "$SUDO npm install -g pm2@$LATEST_PM2_VERSION --silent --no-audit --no-fund" "Atualizando PM2" update
|
|
715
|
+
else
|
|
716
|
+
run_step "$SUDO pm2 update >/dev/null 2>&1 || true" "Sincronizando PM2" update
|
|
717
|
+
fi
|
|
718
|
+
else
|
|
719
|
+
run_step "$SUDO npm install -g pm2@latest --silent --no-audit --no-fund" "Instalando PM2" update
|
|
720
|
+
run_step "$SUDO pm2 update >/dev/null 2>&1 || true" "Inicializando PM2" update
|
|
721
|
+
fi
|
|
722
|
+
|
|
723
|
+
run_step "migrate_mwsm" "Importando dados Mwsm" update
|
|
724
|
+
|
|
725
|
+
if [[ "$DISTRO" == "ubuntu" ]]; then
|
|
726
|
+
run_step "$SUDO npm run setup:mwsm" "Reiniciando serviços" update
|
|
727
|
+
else
|
|
728
|
+
run_step "$SUDO sh -c 'crontab -l 2>/dev/null | grep -v \"/var/api/Mwsm/mwsm.js\"; echo \"@reboot cd /var/api/Mwsm && npm run start:mkauth\"' | crontab -" "Configurando inicialização" update
|
|
729
|
+
run_step "$SUDO npm run setup:mkauth" "Reiniciando serviços" update
|
|
730
|
+
fi
|
|
731
|
+
|
|
732
|
+
# -------------------------
|
|
733
|
+
# Resultado final
|
|
734
|
+
# -------------------------
|
|
735
|
+
if [ "$INSTALL_FAILED" = false ]; then
|
|
736
|
+
echo "-------------------------------------"
|
|
737
|
+
echo "✅ Atualização concluída com sucesso!"
|
|
738
|
+
echo "-------------------------------------"
|
|
739
|
+
LAST_SUCCESS="install"
|
|
740
|
+
else
|
|
741
|
+
echo "-------------------------------------"
|
|
742
|
+
echo "❌ Falha na atualização."
|
|
743
|
+
echo "-------------------------------------"
|
|
744
|
+
fi
|
|
745
|
+
|
|
746
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [UPDATE] Fim da atualização (status: $([ "$INSTALL_FAILED" = true ] && echo FAIL || echo OK))" >>"$LOG_FILE"
|
|
747
|
+
echo
|
|
748
|
+
pause_and_restore
|
|
749
|
+
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
# ========================
|
|
753
|
+
# Desinstalar
|
|
754
|
+
# ========================
|
|
755
|
+
uninstall() {
|
|
756
|
+
local NO_CLEAR=false
|
|
757
|
+
local NO_PAUSE=false
|
|
758
|
+
|
|
759
|
+
if [ "$IS_REINSTALL" = false ]; then
|
|
760
|
+
if [[ ! -d /var/api/Mwsm || ! -f /var/api/Mwsm/package.json ]]; then
|
|
761
|
+
echo "-------------------------------------"
|
|
762
|
+
echo "⚠️ O Mwsm não está instalado!"
|
|
763
|
+
echo "-------------------------------------"
|
|
764
|
+
sleep 2
|
|
765
|
+
return
|
|
766
|
+
fi
|
|
767
|
+
fi
|
|
768
|
+
|
|
769
|
+
|
|
770
|
+
if [ "$1" = "no_clear" ]; then
|
|
771
|
+
NO_CLEAR=true
|
|
772
|
+
fi
|
|
773
|
+
if [ "$2" = "no_pause" ]; then
|
|
774
|
+
NO_PAUSE=true
|
|
775
|
+
fi
|
|
776
|
+
|
|
777
|
+
# Cabeçalho
|
|
778
|
+
if [ "$NO_CLEAR" = false ]; then
|
|
779
|
+
clear
|
|
780
|
+
echo "====================================="
|
|
781
|
+
echo " 🗑️ Removendo Mwsm"
|
|
782
|
+
echo "====================================="
|
|
783
|
+
fi
|
|
784
|
+
|
|
785
|
+
UNINSTALL_FAILED=false
|
|
786
|
+
|
|
787
|
+
# Parando serviços PM2
|
|
788
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
789
|
+
run_step "$SUDO pm2 stop all && $SUDO pm2 delete all" "Removendo serviços" uninstall || UNINSTALL_FAILED=true
|
|
790
|
+
else
|
|
791
|
+
run_step "skip" "Removendo serviços" uninstall
|
|
792
|
+
fi
|
|
793
|
+
|
|
794
|
+
# Removendo inicialização
|
|
795
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
796
|
+
if [[ "$DISTRO" == "ubuntu" ]]; then
|
|
797
|
+
run_step "$SUDO pm2 unstartup systemd" "Removendo inicialização" uninstall || UNINSTALL_FAILED=true
|
|
798
|
+
else
|
|
799
|
+
run_step "crontab -l 2>/dev/null | grep -v '/var/api/Mwsm/mwsm.js' | crontab -" "Removendo inicialização" uninstall || UNINSTALL_FAILED=true
|
|
800
|
+
fi
|
|
801
|
+
else
|
|
802
|
+
run_step "skip" "Removendo inicialização" uninstall
|
|
803
|
+
fi
|
|
804
|
+
|
|
805
|
+
# Removendo PM2 global
|
|
806
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
807
|
+
run_step "$SUDO npm remove -g pm2" "Removendo PM2" uninstall || UNINSTALL_FAILED=true
|
|
808
|
+
else
|
|
809
|
+
run_step "skip" "Removendo PM2" uninstall
|
|
810
|
+
fi
|
|
811
|
+
|
|
812
|
+
# Limpando cache do NPM
|
|
813
|
+
if command -v npm >/dev/null 2>&1; then
|
|
814
|
+
if [ -d "$HOME/.npm" ]; then
|
|
815
|
+
run_step "cd /tmp && $SUDO npm cache clean --force" "Limpando cache NPM" uninstall || UNINSTALL_FAILED=true
|
|
816
|
+
else
|
|
817
|
+
run_step "skip" "Limpando cache NPM" uninstall
|
|
818
|
+
fi
|
|
819
|
+
else
|
|
820
|
+
run_step "skip" "Limpando cache NPM" uninstall
|
|
821
|
+
fi
|
|
822
|
+
|
|
823
|
+
|
|
824
|
+
# Limpando diretórios
|
|
825
|
+
if [[ -d /var/api/Mwsm ]]; then
|
|
826
|
+
[[ "$PWD" =~ /var/api/Mwsm ]] && cd /root 2>/dev/null || cd /tmp
|
|
827
|
+
run_step "rm -rf /var/api/Mwsm" "Limpando diretórios" uninstall || UNINSTALL_FAILED=true
|
|
828
|
+
else
|
|
829
|
+
run_step "skip" "Limpando diretórios" uninstall
|
|
830
|
+
fi
|
|
831
|
+
|
|
832
|
+
if [ -L /usr/local/bin/mwsm ] || [ -f /usr/local/bin/mwsm ]; then
|
|
833
|
+
rm -f /usr/local/bin/mwsm 2>/dev/null || $SUDO rm -f /usr/local/bin/mwsm
|
|
834
|
+
fi
|
|
835
|
+
|
|
836
|
+
# Exibe resultado final
|
|
837
|
+
if [ "$NO_PAUSE" = false ]; then
|
|
838
|
+
if [ "$UNINSTALL_FAILED" = false ]; then
|
|
839
|
+
echo "-------------------------------------"
|
|
840
|
+
echo "✅ Remoção concluída!"
|
|
841
|
+
echo "-------------------------------------"
|
|
842
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [UNINSTALL] Fim da remoção (OK)" >>"$LOG_FILE"
|
|
843
|
+
else
|
|
844
|
+
echo "-------------------------------------"
|
|
845
|
+
echo "❌ Falha na remoção."
|
|
846
|
+
echo "-------------------------------------"
|
|
847
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [UNINSTALL] Fim da remoção (FAIL)" >>"$LOG_FILE"
|
|
848
|
+
fi
|
|
849
|
+
else
|
|
850
|
+
if [ "$UNINSTALL_FAILED" = false ]; then
|
|
851
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [UNINSTALL] Fim da remoção (OK - modo silencioso)" >>"$LOG_FILE"
|
|
852
|
+
else
|
|
853
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [UNINSTALL] Fim da remoção (FAIL - modo silencioso)" >>"$LOG_FILE"
|
|
854
|
+
fi
|
|
855
|
+
fi
|
|
856
|
+
|
|
857
|
+
if [ "$NO_PAUSE" = true ]; then
|
|
858
|
+
return
|
|
859
|
+
fi
|
|
860
|
+
|
|
861
|
+
echo
|
|
862
|
+
if [ "$NO_PAUSE" = false ]; then
|
|
863
|
+
pause_and_restore
|
|
864
|
+
fi
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
# ========================
|
|
868
|
+
# Reinstalar
|
|
869
|
+
# ========================
|
|
870
|
+
reinstall() {
|
|
871
|
+
INSTALL_FAILED=false
|
|
872
|
+
IS_REINSTALL=true
|
|
873
|
+
|
|
874
|
+
clear
|
|
875
|
+
echo "====================================="
|
|
876
|
+
echo " ♻️ Reinstalando Mwsm"
|
|
877
|
+
echo "====================================="
|
|
878
|
+
|
|
879
|
+
if ! uninstall_concluido; then
|
|
880
|
+
uninstall no_clear no_pause
|
|
881
|
+
fi
|
|
882
|
+
|
|
883
|
+
install no_clear no_pause
|
|
884
|
+
|
|
885
|
+
echo
|
|
886
|
+
echo "-------------------------------------"
|
|
887
|
+
if [ "$INSTALL_FAILED" = false ]; then
|
|
888
|
+
echo "✅ Reinstalação concluída!"
|
|
889
|
+
echo "-------------------------------------"
|
|
890
|
+
LAST_SUCCESS="install"
|
|
891
|
+
else
|
|
892
|
+
echo "❌ Reinstalação concluída com falhas."
|
|
893
|
+
echo "-------------------------------------"
|
|
894
|
+
fi
|
|
895
|
+
|
|
896
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [REINSTALL] Fim da reinstalação (status: $([ "$INSTALL_FAILED" = true ] && echo FAIL || echo OK))" >>"$LOG_FILE"
|
|
897
|
+
echo
|
|
898
|
+
pause_and_restore
|
|
899
|
+
}
|
|
900
|
+
|
|
901
|
+
view_log_hidden() {
|
|
902
|
+
while true; do
|
|
903
|
+
clear
|
|
904
|
+
echo "====================================="
|
|
905
|
+
echo " 📜 Logs do Mwsm"
|
|
906
|
+
echo "====================================="
|
|
907
|
+
echo "1) Últimas 24h"
|
|
908
|
+
echo "2) Completo"
|
|
909
|
+
echo "3) Bruto"
|
|
910
|
+
echo "0) Voltar"
|
|
911
|
+
echo "-------------------------------------"
|
|
912
|
+
printf "Escolha uma opção: "
|
|
913
|
+
|
|
914
|
+
# Lê uma única tecla (sem Enter) e só aceita 0–3
|
|
915
|
+
while true; do
|
|
916
|
+
read -rsn1 log_choice
|
|
917
|
+
case "$log_choice" in
|
|
918
|
+
[0-3]) break ;;
|
|
919
|
+
*) continue ;;
|
|
920
|
+
esac
|
|
921
|
+
done
|
|
922
|
+
echo "$log_choice"
|
|
923
|
+
|
|
924
|
+
case $log_choice in
|
|
925
|
+
1)
|
|
926
|
+
cutoff_epoch=$(date -d '24 hours ago' +%s)
|
|
927
|
+
# awk: encontra a primeira timestamp válida em cada linha, converte e compara
|
|
928
|
+
awk -v cutoff="$cutoff_epoch" '
|
|
929
|
+
{
|
|
930
|
+
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]/)) {
|
|
931
|
+
ts = substr($0, RSTART, RLENGTH)
|
|
932
|
+
cmd = "date -d \"" ts "\" +%s"
|
|
933
|
+
cmd | getline t
|
|
934
|
+
close(cmd)
|
|
935
|
+
if (t >= cutoff) print $0
|
|
936
|
+
}
|
|
937
|
+
}' "$LOG_FILE" | iconv -f utf-8 -t utf-8
|
|
938
|
+
|
|
939
|
+
printf "\\nPressione ENTER para voltar ao menu principal..."
|
|
940
|
+
IFS= read -r _
|
|
941
|
+
break
|
|
942
|
+
;;
|
|
943
|
+
2)
|
|
944
|
+
cat "$LOG_FILE" | grep "^[0-9]\\{4\\}-" | iconv -f utf-8 -t utf-8
|
|
945
|
+
printf "\\nPressione ENTER para voltar ao menu principal..."
|
|
946
|
+
IFS= read -r _
|
|
947
|
+
break
|
|
948
|
+
;;
|
|
949
|
+
3)
|
|
950
|
+
cat "$LOG_FILE" | grep -v "^[0-9]\\{4\\}-" | iconv -f utf-8 -t utf-8
|
|
951
|
+
printf "\\nPressione ENTER para voltar ao menu principal..."
|
|
952
|
+
IFS= read -r _
|
|
953
|
+
break
|
|
954
|
+
;;
|
|
955
|
+
0)
|
|
956
|
+
break
|
|
957
|
+
;;
|
|
958
|
+
esac
|
|
959
|
+
done
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
# ========================
|
|
963
|
+
# Limpar logs oculto
|
|
964
|
+
# ========================
|
|
965
|
+
clear_log_hidden() {
|
|
966
|
+
: >"$LOG_FILE"
|
|
967
|
+
echo "-------------------------------------"
|
|
968
|
+
echo "🧹 Log limpo com sucesso!"
|
|
969
|
+
echo "-------------------------------------"
|
|
970
|
+
sleep 2
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
# ========================
|
|
974
|
+
# Menu principal
|
|
975
|
+
# ========================
|
|
976
|
+
menu() {
|
|
977
|
+
# Desativa o cursor logo no início, antes de qualquer saída
|
|
978
|
+
command -v tput >/dev/null 2>&1 && tput civis >/dev/null 2>&1 || true
|
|
979
|
+
|
|
980
|
+
while true; do
|
|
981
|
+
if [ -t 0 ]; then
|
|
982
|
+
stty -echo -icanon time 0 min 0 || true
|
|
983
|
+
fi
|
|
984
|
+
|
|
985
|
+
clear
|
|
986
|
+
|
|
987
|
+
echo "====================================="
|
|
988
|
+
echo " 📦 Gerenciador do Bot-Mwsm"
|
|
989
|
+
echo "====================================="
|
|
990
|
+
echo "1) Instalar"
|
|
991
|
+
echo "2) Atualizar"
|
|
992
|
+
echo "3) Reinstalar"
|
|
993
|
+
echo "4) Desinstalar"
|
|
994
|
+
echo "0) Sair"
|
|
995
|
+
echo "-------------------------------------"
|
|
996
|
+
printf "Escolha uma opção: "
|
|
997
|
+
|
|
998
|
+
# Mantém o cursor oculto o tempo todo
|
|
999
|
+
command -v tput >/dev/null 2>&1 && tput civis >/dev/null 2>&1 || true
|
|
1000
|
+
|
|
1001
|
+
# Lê uma única tecla (sem Enter)
|
|
1002
|
+
while true; do
|
|
1003
|
+
read -rsn1 choice
|
|
1004
|
+
case "$choice" in
|
|
1005
|
+
[0-6]) break ;; # aceita apenas 0–6
|
|
1006
|
+
*) continue ;; # ignora qualquer outra tecla
|
|
1007
|
+
esac
|
|
1008
|
+
done
|
|
1009
|
+
|
|
1010
|
+
echo "$choice"
|
|
1011
|
+
|
|
1012
|
+
echo "$(date '+%Y-%m-%d %H:%M:%S') - [MENU] Opção $choice selecionada" >>"$LOG_FILE"
|
|
1013
|
+
|
|
1014
|
+
case $choice in
|
|
1015
|
+
1) install ;;
|
|
1016
|
+
2) update ;;
|
|
1017
|
+
3) reinstall ;;
|
|
1018
|
+
4) uninstall ;;
|
|
1019
|
+
5) view_log_hidden ;; # oculto
|
|
1020
|
+
6) clear_log_hidden ;; # oculto
|
|
1021
|
+
0)
|
|
1022
|
+
# Reativa o cursor antes de sair
|
|
1023
|
+
command -v tput >/dev/null 2>&1 && tput cnorm >/dev/null 2>&1 || true
|
|
1024
|
+
if [[ "$LAST_SUCCESS" == "install" ]]; then
|
|
1025
|
+
if command -v pm2 >/dev/null 2>&1; then
|
|
1026
|
+
NAME=$(jq -r .name /var/api/Mwsm/package.json 2>/dev/null)
|
|
1027
|
+
MATCHED=""
|
|
1028
|
+
|
|
1029
|
+
if [[ -n "$NAME" && -f /var/api/Mwsm/mwsm.json ]]; then
|
|
1030
|
+
if jq -r 'tostring' /var/api/Mwsm/mwsm.json 2>/dev/null | grep -q "$NAME"; then
|
|
1031
|
+
MATCHED="$NAME"
|
|
1032
|
+
fi
|
|
1033
|
+
fi
|
|
1034
|
+
|
|
1035
|
+
if [[ -z "$MATCHED" ]]; then
|
|
1036
|
+
if $SUDO pm2 list | grep -q "Bot-Mwsm"; then
|
|
1037
|
+
MATCHED="Bot-Mwsm"
|
|
1038
|
+
fi
|
|
1039
|
+
fi
|
|
1040
|
+
|
|
1041
|
+
if [[ -n "$MATCHED" ]]; then
|
|
1042
|
+
$SUDO pm2 update >/dev/null 2>&1
|
|
1043
|
+
$SUDO pm2 flush >/dev/null 2>&1
|
|
1044
|
+
clear
|
|
1045
|
+
exec $SUDO pm2 logs "$MATCHED"
|
|
1046
|
+
fi
|
|
1047
|
+
fi
|
|
1048
|
+
fi
|
|
1049
|
+
unset DEBIAN_FRONTEND
|
|
1050
|
+
clear
|
|
1051
|
+
silent_menu
|
|
1052
|
+
exit 0
|
|
1053
|
+
;;
|
|
1054
|
+
esac
|
|
1055
|
+
done
|
|
1056
|
+
|
|
1057
|
+
command -v tput >/dev/null 2>&1 && tput cnorm >/dev/null 2>&1 || true
|
|
1058
|
+
}
|
|
1059
|
+
|
|
1060
|
+
menu
|