mirror of
https://github.com/anten-ka/gotelegram_pro.git
synced 2026-05-19 15:56:04 +00:00
UI: спиннер, прогресс-бар и галочки на каждом шаге установки
Made-with: Cursor
This commit is contained in:
155
install.sh
155
install.sh
@@ -12,6 +12,53 @@ BLUE='\033[0;34m'
|
|||||||
WHITE='\033[1;37m'
|
WHITE='\033[1;37m'
|
||||||
NC='\033[0m'
|
NC='\033[0m'
|
||||||
|
|
||||||
|
# ── Спиннер и прогресс-бар ────────────────────────────────────────────────────
|
||||||
|
spin_pid=""
|
||||||
|
spinner_start() {
|
||||||
|
local msg="${1:-Подождите...}"
|
||||||
|
(
|
||||||
|
local frames=('⠋' '⠙' '⠹' '⠸' '⠼' '⠴' '⠦' '⠧' '⠇' '⠏')
|
||||||
|
local i=0
|
||||||
|
while true; do
|
||||||
|
printf "\r ${CYAN}${frames[$i]}${NC} ${msg}" >&2
|
||||||
|
i=$(( (i+1) % ${#frames[@]} ))
|
||||||
|
sleep 0.12
|
||||||
|
done
|
||||||
|
) &
|
||||||
|
spin_pid=$!
|
||||||
|
}
|
||||||
|
spinner_stop() {
|
||||||
|
[ -n "$spin_pid" ] && kill "$spin_pid" 2>/dev/null && wait "$spin_pid" 2>/dev/null
|
||||||
|
spin_pid=""
|
||||||
|
printf "\r\033[K" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
progress_bar() {
|
||||||
|
local current="$1" total="$2" label="${3:-}"
|
||||||
|
local pct=$(( current * 100 / total ))
|
||||||
|
local filled=$(( pct / 2 ))
|
||||||
|
local empty=$(( 50 - filled ))
|
||||||
|
local bar=""
|
||||||
|
for ((i=0; i<filled; i++)); do bar+="█"; done
|
||||||
|
for ((i=0; i<empty; i++)); do bar+="░"; done
|
||||||
|
printf "\r ${GREEN}[${bar}]${NC} ${pct}%% ${label}" >&2
|
||||||
|
[ "$current" -eq "$total" ] && echo "" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
run_with_progress() {
|
||||||
|
local label="$1"; shift
|
||||||
|
spinner_start "$label"
|
||||||
|
"$@" >/dev/null 2>&1
|
||||||
|
local rc=$?
|
||||||
|
spinner_stop
|
||||||
|
if [ $rc -eq 0 ]; then
|
||||||
|
echo -e " ${GREEN}✓${NC} $label"
|
||||||
|
else
|
||||||
|
echo -e " ${RED}✗${NC} $label ${RED}(ошибка)${NC}"
|
||||||
|
fi
|
||||||
|
return $rc
|
||||||
|
}
|
||||||
|
|
||||||
# ── Конфиг ───────────────────────────────────────────────────────────────────
|
# ── Конфиг ───────────────────────────────────────────────────────────────────
|
||||||
CONTAINER_NAME="mtproto-proxy"
|
CONTAINER_NAME="mtproto-proxy"
|
||||||
BOT_DIR="/opt/gotelegram-bot"
|
BOT_DIR="/opt/gotelegram-bot"
|
||||||
@@ -37,24 +84,34 @@ install_pkg() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_base_deps() {
|
install_base_deps() {
|
||||||
for cmd in curl docker; do
|
local steps=0 total=4 # curl, docker, qrencode, docker-start
|
||||||
if ! command -v $cmd &>/dev/null; then
|
|
||||||
echo -e "${YELLOW}[*] Установка $cmd...${NC}"
|
progress_bar $steps $total "Проверка зависимостей..."
|
||||||
if [ "$cmd" = "docker" ]; then
|
if ! command -v curl &>/dev/null; then
|
||||||
curl -fsSL https://get.docker.com | sh
|
run_with_progress "Установка curl" install_pkg curl
|
||||||
systemctl enable --now docker
|
|
||||||
else
|
|
||||||
install_pkg $cmd
|
|
||||||
fi
|
fi
|
||||||
|
steps=$((steps+1)); progress_bar $steps $total "curl"
|
||||||
|
|
||||||
|
if ! command -v docker &>/dev/null; then
|
||||||
|
spinner_start "Установка Docker (это может занять 1-2 минуты)..."
|
||||||
|
curl -fsSL https://get.docker.com | sh >/dev/null 2>&1
|
||||||
|
systemctl enable --now docker >/dev/null 2>&1
|
||||||
|
spinner_stop
|
||||||
|
echo -e " ${GREEN}✓${NC} Docker установлен"
|
||||||
fi
|
fi
|
||||||
done
|
steps=$((steps+1)); progress_bar $steps $total "docker"
|
||||||
|
|
||||||
if ! command -v qrencode &>/dev/null; then
|
if ! command -v qrencode &>/dev/null; then
|
||||||
install_pkg qrencode 2>/dev/null || true
|
run_with_progress "Установка qrencode" install_pkg qrencode
|
||||||
fi
|
fi
|
||||||
|
steps=$((steps+1)); progress_bar $steps $total "qrencode"
|
||||||
|
|
||||||
if ! docker info &>/dev/null 2>&1; then
|
if ! docker info &>/dev/null 2>&1; then
|
||||||
systemctl start docker 2>/dev/null || true
|
systemctl start docker 2>/dev/null || true
|
||||||
sleep 2
|
sleep 2
|
||||||
fi
|
fi
|
||||||
|
steps=$((steps+1)); progress_bar $steps $total "Готово"
|
||||||
|
echo ""
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Утилиты ──────────────────────────────────────────────────────────────────
|
# ── Утилиты ──────────────────────────────────────────────────────────────────
|
||||||
@@ -225,6 +282,7 @@ menu_install() {
|
|||||||
|
|
||||||
echo ""
|
echo ""
|
||||||
echo -e "${YELLOW}[*] Настройка прокси (домен: $DOMAIN, порт: $PORT)...${NC}"
|
echo -e "${YELLOW}[*] Настройка прокси (домен: $DOMAIN, порт: $PORT)...${NC}"
|
||||||
|
echo ""
|
||||||
|
|
||||||
# Docker проверка
|
# Docker проверка
|
||||||
if ! docker info &>/dev/null 2>&1; then
|
if ! docker info &>/dev/null 2>&1; then
|
||||||
@@ -233,43 +291,65 @@ menu_install() {
|
|||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Генерация secret
|
local SECRET install_steps=5 install_cur=0
|
||||||
echo -e "${GREEN}[*] Генерация secret...${NC}"
|
|
||||||
local SECRET
|
# Шаг 1: pull образа (если нет)
|
||||||
|
install_cur=$((install_cur+1)); progress_bar $install_cur $install_steps "Загрузка образа mtg..."
|
||||||
|
if ! docker images --format '{{.Repository}}:{{.Tag}}' | grep -q "nineseconds/mtg:2"; then
|
||||||
|
spinner_start "Загрузка Docker-образа mtg (первый раз — до 1 мин)..."
|
||||||
|
docker pull nineseconds/mtg:2 >/dev/null 2>&1
|
||||||
|
spinner_stop
|
||||||
|
fi
|
||||||
|
echo -e " ${GREEN}✓${NC} Образ mtg готов"
|
||||||
|
|
||||||
|
# Шаг 2: генерация secret
|
||||||
|
install_cur=$((install_cur+1)); progress_bar $install_cur $install_steps "Генерация secret..."
|
||||||
|
spinner_start "Генерация secret для $DOMAIN..."
|
||||||
SECRET=$(docker run --rm nineseconds/mtg:2 generate-secret --hex "$DOMAIN" 2>/dev/null)
|
SECRET=$(docker run --rm nineseconds/mtg:2 generate-secret --hex "$DOMAIN" 2>/dev/null)
|
||||||
|
spinner_stop
|
||||||
if [ -z "$SECRET" ]; then
|
if [ -z "$SECRET" ]; then
|
||||||
echo -e "${RED}Ошибка генерации secret.${NC}"
|
echo -e " ${RED}✗${NC} Ошибка генерации secret."
|
||||||
read -p "Нажмите Enter..."
|
read -p "Нажмите Enter..."
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
echo -e " ${GREEN}✓${NC} Secret сгенерирован"
|
||||||
|
|
||||||
# Остановка старого
|
# Шаг 3: остановка старого
|
||||||
|
install_cur=$((install_cur+1)); progress_bar $install_cur $install_steps "Очистка..."
|
||||||
docker stop "$CONTAINER_NAME" &>/dev/null
|
docker stop "$CONTAINER_NAME" &>/dev/null
|
||||||
docker rm "$CONTAINER_NAME" &>/dev/null
|
docker rm "$CONTAINER_NAME" &>/dev/null
|
||||||
|
echo -e " ${GREEN}✓${NC} Старый контейнер удалён"
|
||||||
|
|
||||||
# Запуск с TCP + UDP (UDP для звонков)
|
# Шаг 4: запуск нового
|
||||||
echo -e "${GREEN}[*] Запуск контейнера (TCP + UDP)...${NC}"
|
install_cur=$((install_cur+1)); progress_bar $install_cur $install_steps "Запуск контейнера..."
|
||||||
|
spinner_start "Запуск MTProxy (TCP + UDP)..."
|
||||||
docker run -d --name "$CONTAINER_NAME" --restart always \
|
docker run -d --name "$CONTAINER_NAME" --restart always \
|
||||||
-p "$PORT":"$PORT"/tcp \
|
-p "$PORT":"$PORT"/tcp \
|
||||||
-p "$PORT":"$PORT"/udp \
|
-p "$PORT":"$PORT"/udp \
|
||||||
nineseconds/mtg:2 simple-run \
|
nineseconds/mtg:2 simple-run \
|
||||||
-n 1.1.1.1 -i prefer-ipv4 \
|
-n 1.1.1.1 -i prefer-ipv4 \
|
||||||
0.0.0.0:"$PORT" "$SECRET" > /dev/null 2>&1
|
0.0.0.0:"$PORT" "$SECRET" > /dev/null 2>&1
|
||||||
|
sleep 2
|
||||||
|
spinner_stop
|
||||||
|
|
||||||
if ! proxy_is_running; then
|
if ! proxy_is_running; then
|
||||||
echo -e "${RED}Контейнер не запустился. Проверьте: docker logs $CONTAINER_NAME${NC}"
|
echo -e " ${RED}✗${NC} Контейнер не запустился. Проверьте: docker logs $CONTAINER_NAME"
|
||||||
read -p "Нажмите Enter..."
|
read -p "Нажмите Enter..."
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
echo -e " ${GREEN}✓${NC} Контейнер запущен"
|
||||||
|
|
||||||
# Сохраняем конфиг
|
# Шаг 5: сохранение
|
||||||
|
install_cur=$((install_cur+1)); progress_bar $install_cur $install_steps "Готово!"
|
||||||
mkdir -p "$BOT_DIR"
|
mkdir -p "$BOT_DIR"
|
||||||
cat > "$BOT_DIR/proxy.json" << CFGEOF
|
cat > "$BOT_DIR/proxy.json" << CFGEOF
|
||||||
{"domain": "$DOMAIN", "port": "$PORT", "secret": "$SECRET"}
|
{"domain": "$DOMAIN", "port": "$PORT", "secret": "$SECRET"}
|
||||||
CFGEOF
|
CFGEOF
|
||||||
|
|
||||||
clear
|
echo ""
|
||||||
echo -e "${GREEN}Прокси установлен! (TCP + UDP, звонки поддержаны)${NC}"
|
echo -e "${GREEN}══════════════════════════════════════════════════${NC}"
|
||||||
|
echo -e "${GREEN} Прокси установлен! (TCP + UDP, звонки поддержаны)${NC}"
|
||||||
|
echo -e "${GREEN}══════════════════════════════════════════════════${NC}"
|
||||||
show_config
|
show_config
|
||||||
read -p "Нажмите Enter для возврата в меню..."
|
read -p "Нажмите Enter для возврата в меню..."
|
||||||
}
|
}
|
||||||
@@ -817,13 +897,36 @@ BOTEOF
|
|||||||
}
|
}
|
||||||
|
|
||||||
install_bot_deps() {
|
install_bot_deps() {
|
||||||
echo -e "${GREEN}[*] Настройка Python venv...${NC}"
|
local bot_steps=3 bot_cur=0
|
||||||
|
|
||||||
|
bot_cur=$((bot_cur+1)); progress_bar $bot_cur $bot_steps "Создание venv..."
|
||||||
if [ ! -d "$BOT_DIR/venv" ]; then
|
if [ ! -d "$BOT_DIR/venv" ]; then
|
||||||
python3 -m venv "$BOT_DIR/venv" || { echo -e "${RED}Ошибка создания venv.${NC}"; return 1; }
|
spinner_start "Создание Python venv..."
|
||||||
|
python3 -m venv "$BOT_DIR/venv" 2>/dev/null
|
||||||
|
spinner_stop
|
||||||
|
if [ ! -d "$BOT_DIR/venv" ]; then
|
||||||
|
echo -e " ${RED}✗${NC} Ошибка создания venv."
|
||||||
|
return 1
|
||||||
fi
|
fi
|
||||||
echo -e "${GREEN}[*] Установка зависимостей (pip)...${NC}"
|
fi
|
||||||
"$BOT_DIR/venv/bin/pip" install --upgrade pip -q 2>/dev/null || true
|
echo -e " ${GREEN}✓${NC} Python venv готов"
|
||||||
"$BOT_DIR/venv/bin/pip" install -r "$BOT_DIR/requirements.txt" -q || { echo -e "${RED}pip install не удался.${NC}"; return 1; }
|
|
||||||
|
bot_cur=$((bot_cur+1)); progress_bar $bot_cur $bot_steps "Обновление pip..."
|
||||||
|
spinner_start "Обновление pip..."
|
||||||
|
"$BOT_DIR/venv/bin/pip" install --upgrade pip -q 2>/dev/null
|
||||||
|
spinner_stop
|
||||||
|
echo -e " ${GREEN}✓${NC} pip обновлён"
|
||||||
|
|
||||||
|
bot_cur=$((bot_cur+1)); progress_bar $bot_cur $bot_steps "Установка зависимостей..."
|
||||||
|
spinner_start "Установка python-telegram-bot (до 1 мин)..."
|
||||||
|
"$BOT_DIR/venv/bin/pip" install -r "$BOT_DIR/requirements.txt" -q 2>/dev/null
|
||||||
|
local rc=$?
|
||||||
|
spinner_stop
|
||||||
|
if [ $rc -ne 0 ]; then
|
||||||
|
echo -e " ${RED}✗${NC} pip install не удался."
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
echo -e " ${GREEN}✓${NC} Зависимости установлены"
|
||||||
}
|
}
|
||||||
|
|
||||||
# ── Выход ────────────────────────────────────────────────────────────────────
|
# ── Выход ────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
Reference in New Issue
Block a user