- добавление скриптов для systemd
This commit is contained in:
Binary file not shown.
33
bot-news-linux-gaming.service
Normal file
33
bot-news-linux-gaming.service
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=Linux Gaming News Bot
|
||||||
|
Documentation=https://github.com/xpamych/bot-news-linux-gaming
|
||||||
|
After=network.target network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=xpamych
|
||||||
|
Group=xpamych
|
||||||
|
WorkingDirectory=/home/xpamych/Yandex.Disk/IdeaProjects/bot-news-linux-gaming
|
||||||
|
ExecStart=/usr/bin/python3 /home/xpamych/Yandex.Disk/IdeaProjects/bot-news-linux-gaming/news-bot-modular.py
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
|
||||||
|
# Переменные окружения
|
||||||
|
Environment=PYTHONPATH=/home/xpamych/Yandex.Disk/IdeaProjects/bot-news-linux-gaming
|
||||||
|
Environment=PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
# Ограничения безопасности
|
||||||
|
NoNewPrivileges=yes
|
||||||
|
PrivateTmp=yes
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=read-only
|
||||||
|
ReadWritePaths=/home/xpamych/Yandex.Disk/IdeaProjects/bot-news-linux-gaming
|
||||||
|
|
||||||
|
# Логирование
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
SyslogIdentifier=news-bot
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@@ -80,14 +80,50 @@ class DiscordClient:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
async def send_message(self, channel, content):
|
async def send_message(self, channel, content):
|
||||||
"""Отправка сообщения в Discord канал"""
|
"""Отправка сообщения в Discord канал с разбивкой длинных сообщений"""
|
||||||
if not self.is_enabled():
|
if not self.is_enabled():
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Разбиваем содержимое на части по 2000 символов (лимит Discord)
|
# Discord лимит: 2000 символов
|
||||||
for i in range(0, len(content), 2000):
|
max_length = 2000
|
||||||
await channel.send(content[i:i+2000])
|
|
||||||
|
if len(content) <= max_length:
|
||||||
|
# Короткое сообщение - отправляем как есть
|
||||||
|
await channel.send(content)
|
||||||
|
else:
|
||||||
|
# Длинное сообщение - разбиваем умно по строкам
|
||||||
|
self.logger.warning(f"Сообщение слишком длинное ({len(content)} символов), разбиваем на части")
|
||||||
|
|
||||||
|
parts = []
|
||||||
|
current_part = ""
|
||||||
|
|
||||||
|
for line in content.split('\n'):
|
||||||
|
# Если добавление этой строки превысит лимит
|
||||||
|
if len(current_part + line + '\n') > max_length:
|
||||||
|
if current_part:
|
||||||
|
parts.append(current_part.rstrip())
|
||||||
|
current_part = ""
|
||||||
|
current_part += line + '\n'
|
||||||
|
|
||||||
|
# Добавляем последнюю часть
|
||||||
|
if current_part:
|
||||||
|
parts.append(current_part.rstrip())
|
||||||
|
|
||||||
|
self.logger.info(f"Сообщение разбито на {len(parts)} частей для Discord")
|
||||||
|
|
||||||
|
# Отправляем каждую часть
|
||||||
|
for i, part in enumerate(parts, 1):
|
||||||
|
if len(parts) > 1:
|
||||||
|
part_content = f"[Часть {i}/{len(parts)}]\n\n{part}"
|
||||||
|
else:
|
||||||
|
part_content = part
|
||||||
|
await channel.send(part_content)
|
||||||
|
|
||||||
|
# Небольшая задержка между частями
|
||||||
|
if i < len(parts):
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
|
||||||
self.logger.info("Сообщение успешно отправлено в Discord")
|
self.logger.info("Сообщение успешно отправлено в Discord")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Ошибка отправки сообщения в Discord: {e}")
|
self.logger.error(f"Ошибка отправки сообщения в Discord: {e}")
|
||||||
@@ -142,7 +178,7 @@ class DiscordClient:
|
|||||||
await client.close()
|
await client.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
# Публикуем новости
|
# Публикуем новости в обратном порядке, чтобы новые оказались сверху в ленте
|
||||||
for topic_id, topic_title in reversed(list_for_public):
|
for topic_id, topic_title in reversed(list_for_public):
|
||||||
from site_api import SiteAPI
|
from site_api import SiteAPI
|
||||||
site_api = SiteAPI()
|
site_api = SiteAPI()
|
||||||
|
127
install-service.sh
Executable file
127
install-service.sh
Executable file
@@ -0,0 +1,127 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Установочный скрипт для Linux Gaming News Bot
|
||||||
|
# Создает systemd service и настраивает его для автозапуска
|
||||||
|
|
||||||
|
set -e # Выход при любой ошибке
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Функции для цветного вывода
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Проверка запуска от root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
print_error "Скрипт должен быть запущен с правами root (sudo)"
|
||||||
|
print_info "Используйте: sudo ./install-service.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Определение текущего пользователя (не root)
|
||||||
|
REAL_USER=$(who am i | awk '{print $1}')
|
||||||
|
if [ -z "$REAL_USER" ]; then
|
||||||
|
REAL_USER=$(logname 2>/dev/null || echo $SUDO_USER)
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$REAL_USER" ]; then
|
||||||
|
print_error "Не удалось определить имя пользователя"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_info "Установка сервиса для пользователя: $REAL_USER"
|
||||||
|
|
||||||
|
# Определение директории проекта
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
PROJECT_DIR="$SCRIPT_DIR"
|
||||||
|
|
||||||
|
print_info "Директория проекта: $PROJECT_DIR"
|
||||||
|
|
||||||
|
# Проверка существования файлов
|
||||||
|
if [ ! -f "$PROJECT_DIR/news-bot-modular.py" ]; then
|
||||||
|
print_error "Не найден файл news-bot-modular.py в $PROJECT_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -f "$PROJECT_DIR/bot-news-linux-gaming.service" ]; then
|
||||||
|
print_error "Не найден файл bot-news-linux-gaming.service в $PROJECT_DIR"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Проверка наличия keys.py
|
||||||
|
if [ ! -f "$PROJECT_DIR/keys.py" ]; then
|
||||||
|
print_warning "Не найден файл keys.py с настройками"
|
||||||
|
print_info "Создайте keys.py на основе keys_example.py перед запуском сервиса:"
|
||||||
|
print_info " cp keys_example.py keys.py"
|
||||||
|
print_info " nano keys.py # заполните реальными ключами"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Создание временного файла сервиса с правильными путями
|
||||||
|
TEMP_SERVICE=$(mktemp)
|
||||||
|
sed "s|/home/xpamych/Yandex.Disk/IdeaProjects/bot-news-linux-gaming|$PROJECT_DIR|g" "$PROJECT_DIR/bot-news-linux-gaming.service" > "$TEMP_SERVICE"
|
||||||
|
sed -i "s|User=xpamych|User=$REAL_USER|g" "$TEMP_SERVICE"
|
||||||
|
sed -i "s|Group=xpamych|Group=$REAL_USER|g" "$TEMP_SERVICE"
|
||||||
|
|
||||||
|
print_info "Копирование systemd unit файла..."
|
||||||
|
cp "$TEMP_SERVICE" /etc/systemd/system/bot-news-linux-gaming.service
|
||||||
|
rm "$TEMP_SERVICE"
|
||||||
|
|
||||||
|
print_info "Установка прав доступа..."
|
||||||
|
chmod 644 /etc/systemd/system/bot-news-linux-gaming.service
|
||||||
|
chown root:root /etc/systemd/system/bot-news-linux-gaming.service
|
||||||
|
|
||||||
|
print_info "Перезагрузка systemd..."
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
print_success "Сервис успешно установлен!"
|
||||||
|
print_info ""
|
||||||
|
print_info "Для управления сервисом используйте команды:"
|
||||||
|
print_info " sudo systemctl enable bot-news-linux-gaming # Включить автозапуск"
|
||||||
|
print_info " sudo systemctl start bot-news-linux-gaming # Запустить сервис"
|
||||||
|
print_info " sudo systemctl status bot-news-linux-gaming # Посмотреть статус"
|
||||||
|
print_info " sudo systemctl stop bot-news-linux-gaming # Остановить сервис"
|
||||||
|
print_info " sudo systemctl disable bot-news-linux-gaming # Отключить автозапуск"
|
||||||
|
print_info ""
|
||||||
|
print_info "Логи сервиса:"
|
||||||
|
print_info " sudo journalctl -u bot-news-linux-gaming -f # Следить за логами"
|
||||||
|
print_info " sudo journalctl -u bot-news-linux-gaming -n 50 # Последние 50 строк"
|
||||||
|
print_info ""
|
||||||
|
|
||||||
|
# Предложение сразу включить и запустить
|
||||||
|
read -p "Включить автозапуск и запустить сервис сейчас? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
print_info "Включение автозапуска..."
|
||||||
|
systemctl enable bot-news-linux-gaming
|
||||||
|
|
||||||
|
print_info "Запуск сервиса..."
|
||||||
|
systemctl start bot-news-linux-gaming
|
||||||
|
|
||||||
|
sleep 2
|
||||||
|
|
||||||
|
print_info "Статус сервиса:"
|
||||||
|
systemctl status bot-news-linux-gaming --no-pager
|
||||||
|
|
||||||
|
print_success "Сервис запущен и добавлен в автозагрузку!"
|
||||||
|
else
|
||||||
|
print_info "Сервис установлен, но не запущен. Запустите его командой:"
|
||||||
|
print_info " sudo systemctl enable --now bot-news-linux-gaming"
|
||||||
|
fi
|
155
service-control.sh
Executable file
155
service-control.sh
Executable file
@@ -0,0 +1,155 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Простой скрипт управления Linux Gaming News Bot
|
||||||
|
|
||||||
|
SERVICE_NAME="bot-news-linux-gaming"
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция показа статуса
|
||||||
|
show_status() {
|
||||||
|
print_info "Статус сервиса $SERVICE_NAME:"
|
||||||
|
systemctl status $SERVICE_NAME --no-pager -l
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция показа логов
|
||||||
|
show_logs() {
|
||||||
|
local lines=${1:-50}
|
||||||
|
print_info "Последние $lines строк логов:"
|
||||||
|
sudo journalctl -u $SERVICE_NAME -n $lines --no-pager
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция следения за логами
|
||||||
|
follow_logs() {
|
||||||
|
print_info "Следование за логами (Ctrl+C для выхода):"
|
||||||
|
sudo journalctl -u $SERVICE_NAME -f
|
||||||
|
}
|
||||||
|
|
||||||
|
# Функция показа помощи
|
||||||
|
show_help() {
|
||||||
|
echo "Управление Linux Gaming News Bot"
|
||||||
|
echo ""
|
||||||
|
echo "Использование: $0 [команда]"
|
||||||
|
echo ""
|
||||||
|
echo "Команды:"
|
||||||
|
echo " start - Запустить сервис"
|
||||||
|
echo " stop - Остановить сервис"
|
||||||
|
echo " restart - Перезапустить сервис"
|
||||||
|
echo " status - Показать статус сервиса"
|
||||||
|
echo " enable - Включить автозапуск"
|
||||||
|
echo " disable - Отключить автозапуск"
|
||||||
|
echo " logs - Показать последние логи"
|
||||||
|
echo " logs N - Показать последние N строк логов"
|
||||||
|
echo " follow - Следить за логами в реальном времени"
|
||||||
|
echo " install - Установить сервис (требует sudo)"
|
||||||
|
echo " uninstall - Удалить сервис (требует sudo)"
|
||||||
|
echo " help - Показать эту справку"
|
||||||
|
echo ""
|
||||||
|
}
|
||||||
|
|
||||||
|
# Проверка существования сервиса
|
||||||
|
check_service_exists() {
|
||||||
|
if ! systemctl list-unit-files | grep -q "^$SERVICE_NAME.service"; then
|
||||||
|
print_error "Сервис $SERVICE_NAME не установлен"
|
||||||
|
print_info "Запустите: sudo ./install-service.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Основная логика
|
||||||
|
case "${1}" in
|
||||||
|
"start")
|
||||||
|
check_service_exists
|
||||||
|
print_info "Запуск сервиса..."
|
||||||
|
sudo systemctl start $SERVICE_NAME
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
"stop")
|
||||||
|
check_service_exists
|
||||||
|
print_info "Остановка сервиса..."
|
||||||
|
sudo systemctl stop $SERVICE_NAME
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
"restart")
|
||||||
|
check_service_exists
|
||||||
|
print_info "Перезапуск сервиса..."
|
||||||
|
sudo systemctl restart $SERVICE_NAME
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
"status")
|
||||||
|
check_service_exists
|
||||||
|
show_status
|
||||||
|
;;
|
||||||
|
"enable")
|
||||||
|
check_service_exists
|
||||||
|
print_info "Включение автозапуска..."
|
||||||
|
sudo systemctl enable $SERVICE_NAME
|
||||||
|
print_success "Автозапуск включен"
|
||||||
|
;;
|
||||||
|
"disable")
|
||||||
|
check_service_exists
|
||||||
|
print_info "Отключение автозапуска..."
|
||||||
|
sudo systemctl disable $SERVICE_NAME
|
||||||
|
print_success "Автозапуск отключен"
|
||||||
|
;;
|
||||||
|
"logs")
|
||||||
|
check_service_exists
|
||||||
|
if [ -n "$2" ] && [[ "$2" =~ ^[0-9]+$ ]]; then
|
||||||
|
show_logs $2
|
||||||
|
else
|
||||||
|
show_logs
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
"follow")
|
||||||
|
check_service_exists
|
||||||
|
follow_logs
|
||||||
|
;;
|
||||||
|
"install")
|
||||||
|
if [ ! -f "./install-service.sh" ]; then
|
||||||
|
print_error "Файл install-service.sh не найден"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sudo ./install-service.sh
|
||||||
|
;;
|
||||||
|
"uninstall")
|
||||||
|
if [ ! -f "./uninstall-service.sh" ]; then
|
||||||
|
print_error "Файл uninstall-service.sh не найден"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
sudo ./uninstall-service.sh
|
||||||
|
;;
|
||||||
|
"help"|"--help"|"-h")
|
||||||
|
show_help
|
||||||
|
;;
|
||||||
|
"")
|
||||||
|
print_warning "Команда не указана"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
print_error "Неизвестная команда: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
@@ -82,11 +82,58 @@ class TelegramNewsClient:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
async def send_message(self, client, channel_username, content):
|
async def send_message(self, client, channel_username, content):
|
||||||
"""Отправка сообщения в Telegram канал/топик с обработкой flood wait"""
|
"""Отправка сообщения в Telegram канал/топик с обработкой flood wait и длинных сообщений"""
|
||||||
try:
|
try:
|
||||||
# Получаем entity канала
|
# Получаем entity канала
|
||||||
entity = await client.get_entity(channel_username)
|
entity = await client.get_entity(channel_username)
|
||||||
|
|
||||||
|
# Telegram лимит: 4096 символов
|
||||||
|
max_length = 4096
|
||||||
|
|
||||||
|
# Если сообщение слишком длинное, разбиваем его
|
||||||
|
if len(content) > max_length:
|
||||||
|
self.logger.warning(f"Сообщение слишком длинное ({len(content)} символов), разбиваем на части")
|
||||||
|
|
||||||
|
# Разбиваем по параграфам, чтобы не резать посередине слов
|
||||||
|
parts = []
|
||||||
|
current_part = ""
|
||||||
|
|
||||||
|
for line in content.split('\n'):
|
||||||
|
# Если добавление этой строки превысит лимит
|
||||||
|
if len(current_part + line + '\n') > max_length:
|
||||||
|
if current_part:
|
||||||
|
parts.append(current_part.rstrip())
|
||||||
|
current_part = ""
|
||||||
|
current_part += line + '\n'
|
||||||
|
|
||||||
|
# Добавляем последнюю часть
|
||||||
|
if current_part:
|
||||||
|
parts.append(current_part.rstrip())
|
||||||
|
|
||||||
|
self.logger.info(f"Сообщение разбито на {len(parts)} частей")
|
||||||
|
|
||||||
|
# Отправляем каждую часть
|
||||||
|
for i, part in enumerate(parts, 1):
|
||||||
|
if len(parts) > 1:
|
||||||
|
part_content = f"[Часть {i}/{len(parts)}]\n\n{part}"
|
||||||
|
else:
|
||||||
|
part_content = part
|
||||||
|
|
||||||
|
await self._send_single_message(client, entity, part_content)
|
||||||
|
|
||||||
|
# Небольшая задержка между частями
|
||||||
|
if i < len(parts):
|
||||||
|
await asyncio.sleep(1)
|
||||||
|
else:
|
||||||
|
# Обычная отправка
|
||||||
|
await self._send_single_message(client, entity, content)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.error(f"Ошибка получения entity канала '{channel_username}': {e}")
|
||||||
|
self.logger.info("Убедитесь, что имя канала указано правильно и бот имеет доступ")
|
||||||
|
|
||||||
|
async def _send_single_message(self, client, entity, content):
|
||||||
|
"""Отправка одного сообщения с обработкой flood wait"""
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
# Если указан topic_id, отправляем в топик
|
# Если указан topic_id, отправляем в топик
|
||||||
@@ -108,10 +155,7 @@ class TelegramNewsClient:
|
|||||||
await asyncio.sleep(e.seconds)
|
await asyncio.sleep(e.seconds)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Ошибка отправки сообщения в Telegram: {e}")
|
self.logger.error(f"Ошибка отправки сообщения в Telegram: {e}")
|
||||||
break
|
raise
|
||||||
except Exception as e:
|
|
||||||
self.logger.error(f"Ошибка получения entity канала '{channel_username}': {e}")
|
|
||||||
self.logger.info("Убедитесь, что имя канала указано правильно и бот имеет доступ")
|
|
||||||
|
|
||||||
async def check_and_publish_news(self, news_list):
|
async def check_and_publish_news(self, news_list):
|
||||||
"""Проверка и публикация новостей в Telegram"""
|
"""Проверка и публикация новостей в Telegram"""
|
||||||
@@ -151,7 +195,7 @@ class TelegramNewsClient:
|
|||||||
|
|
||||||
self.logger.info(f"Новости для публикации в Telegram: {list_for_public}")
|
self.logger.info(f"Новости для публикации в Telegram: {list_for_public}")
|
||||||
|
|
||||||
# Публикуем новости
|
# Публикуем новости в обратном порядке, чтобы новые оказались сверху в ленте
|
||||||
for topic_id, topic_title in reversed(list_for_public):
|
for topic_id, topic_title in reversed(list_for_public):
|
||||||
from site_api import SiteAPI
|
from site_api import SiteAPI
|
||||||
site_api = SiteAPI()
|
site_api = SiteAPI()
|
||||||
|
68
uninstall-service.sh
Executable file
68
uninstall-service.sh
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Скрипт удаления Linux Gaming News Bot systemd service
|
||||||
|
|
||||||
|
set -e # Выход при любой ошибке
|
||||||
|
|
||||||
|
# Цвета для вывода
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Функции для цветного вывода
|
||||||
|
print_info() {
|
||||||
|
echo -e "${BLUE}[INFO]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_success() {
|
||||||
|
echo -e "${GREEN}[SUCCESS]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[ERROR]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Проверка запуска от root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
print_error "Скрипт должен быть запущен с правами root (sudo)"
|
||||||
|
print_info "Используйте: sudo ./uninstall-service.sh"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
SERVICE_NAME="bot-news-linux-gaming"
|
||||||
|
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
|
||||||
|
|
||||||
|
print_info "Удаление сервиса $SERVICE_NAME..."
|
||||||
|
|
||||||
|
# Остановка сервиса если он запущен
|
||||||
|
if systemctl is-active --quiet $SERVICE_NAME; then
|
||||||
|
print_info "Остановка сервиса..."
|
||||||
|
systemctl stop $SERVICE_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Отключение автозапуска если включен
|
||||||
|
if systemctl is-enabled --quiet $SERVICE_NAME; then
|
||||||
|
print_info "Отключение автозапуска..."
|
||||||
|
systemctl disable $SERVICE_NAME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Удаление файла сервиса
|
||||||
|
if [ -f "$SERVICE_FILE" ]; then
|
||||||
|
print_info "Удаление файла сервиса..."
|
||||||
|
rm "$SERVICE_FILE"
|
||||||
|
else
|
||||||
|
print_warning "Файл сервиса не найден: $SERVICE_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Перезагрузка systemd
|
||||||
|
print_info "Перезагрузка systemd..."
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
print_success "Сервис $SERVICE_NAME успешно удален!"
|
||||||
|
print_info "Файлы проекта не затронуты и остались на месте."
|
@@ -155,7 +155,7 @@ class VKClient:
|
|||||||
|
|
||||||
self.logger.info(f"Новости для публикации в VK: {list_for_public}")
|
self.logger.info(f"Новости для публикации в VK: {list_for_public}")
|
||||||
|
|
||||||
# Публикуем новости
|
# Публикуем новости в обратном порядке, чтобы новые оказались сверху в ленте
|
||||||
for topic_id, topic_title in reversed(list_for_public):
|
for topic_id, topic_title in reversed(list_for_public):
|
||||||
from site_api import SiteAPI
|
from site_api import SiteAPI
|
||||||
site_api = SiteAPI()
|
site_api = SiteAPI()
|
||||||
|
Reference in New Issue
Block a user