Add working directory per user with cd command support
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
This commit is contained in:
parent
c852b09148
commit
8070762310
56
bot.py
56
bot.py
|
|
@ -49,6 +49,7 @@ class UserState:
|
||||||
input_type: Optional[str] = None # "name", "description", "icon", "command"
|
input_type: Optional[str] = None # "name", "description", "icon", "command"
|
||||||
parent_menu: Optional[str] = None
|
parent_menu: Optional[str] = None
|
||||||
context: Dict[str, Any] = field(default_factory=dict)
|
context: Dict[str, Any] = field(default_factory=dict)
|
||||||
|
working_directory: Optional[str] = None # Текущая директория пользователя
|
||||||
|
|
||||||
|
|
||||||
class StateManager:
|
class StateManager:
|
||||||
|
|
@ -270,11 +271,16 @@ async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
|
||||||
state_manager.reset(user.id)
|
state_manager.reset(user.id)
|
||||||
|
|
||||||
|
# Показать текущую директорию
|
||||||
|
working_dir = config.get("working_directory", str(Path.home()))
|
||||||
|
|
||||||
await update.message.reply_text(
|
await update.message.reply_text(
|
||||||
f"👋 Привет, {user.first_name}!\n\n"
|
f"👋 Привет, {user.first_name}!\n\n"
|
||||||
f"{config.icon} *{config.name}*\n"
|
f"{config.icon} *{config.name}*\n"
|
||||||
f"_{config.description}_\n\n"
|
f"_{config.description}_\n\n"
|
||||||
f"*Просто отправьте CLI команду в чат* — я её выполню!\n\n"
|
f"*Просто отправьте CLI команду в чат* — я её выполню!\n\n"
|
||||||
|
f"📁 Рабочая директория: `{working_dir}`\n\n"
|
||||||
|
f"Используйте `cd путь` для смены директории.\n"
|
||||||
f"Или используйте кнопки меню для быстрых команд.\n"
|
f"Или используйте кнопки меню для быстрых команд.\n"
|
||||||
f"Команда /help покажет справку.",
|
f"Команда /help покажет справку.",
|
||||||
parse_mode="Markdown",
|
parse_mode="Markdown",
|
||||||
|
|
@ -296,6 +302,12 @@ async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
• `df -h` — свободное место на диске
|
• `df -h` — свободное место на диске
|
||||||
• `git status` — статус git
|
• `git status` — статус git
|
||||||
|
|
||||||
|
*Навигация по директориям:*
|
||||||
|
• `cd путь` — сменить директорию (например, `cd git/project`)
|
||||||
|
• `cd ..` — на уровень вверх
|
||||||
|
• `cd ~` — в домашнюю директорию
|
||||||
|
• `pwd` — показать текущую директорию
|
||||||
|
|
||||||
*Кнопки меню:*
|
*Кнопки меню:*
|
||||||
• 📋 Предустановленные команды — быстрые команды по категориям
|
• 📋 Предустановленные команды — быстрые команды по категориям
|
||||||
• ⚙️ Настройки бота — изменение имени, описания, иконки
|
• ⚙️ Настройки бота — изменение имени, описания, иконки
|
||||||
|
|
@ -490,10 +502,14 @@ async def menu_callback(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
|
|
||||||
|
|
||||||
async def execute_cli_command(query, command: str):
|
async def execute_cli_command(query, command: str):
|
||||||
"""Выполнение CLI команды."""
|
"""Выполнение CLI команды из кнопки меню."""
|
||||||
working_dir = config.get("working_directory", str(Path.home()))
|
user_id = query.from_user.id
|
||||||
|
state = state_manager.get(user_id)
|
||||||
|
|
||||||
logger.info(f"Выполнение команды: {command}")
|
# Определяем рабочую директорию: сначала пользовательская, потом из конфига
|
||||||
|
working_dir = state.working_directory or config.get("working_directory", str(Path.home()))
|
||||||
|
|
||||||
|
logger.info(f"Выполнение команды: {command} в директории: {working_dir}")
|
||||||
|
|
||||||
await query.edit_message_text(
|
await query.edit_message_text(
|
||||||
f"⏳ *Выполнение...*\n\n`{command}`",
|
f"⏳ *Выполнение...*\n\n`{command}`",
|
||||||
|
|
@ -631,7 +647,39 @@ async def handle_text_message(update: Update, context: ContextTypes.DEFAULT_TYPE
|
||||||
|
|
||||||
async def execute_cli_command_from_message(update: Update, command: str):
|
async def execute_cli_command_from_message(update: Update, command: str):
|
||||||
"""Выполнение CLI команды из сообщения."""
|
"""Выполнение CLI команды из сообщения."""
|
||||||
working_dir = config.get("working_directory", str(Path.home()))
|
user_id = update.effective_user.id
|
||||||
|
state = state_manager.get(user_id)
|
||||||
|
|
||||||
|
# Определяем рабочую директорию: сначала пользовательская, потом из конфига
|
||||||
|
working_dir = state.working_directory or config.get("working_directory", str(Path.home()))
|
||||||
|
|
||||||
|
# Обработка команды cd - меняем директорию пользователя
|
||||||
|
if command.strip().startswith("cd "):
|
||||||
|
parts = command.strip().split(maxsplit=1)
|
||||||
|
if len(parts) == 2:
|
||||||
|
target_dir = parts[1]
|
||||||
|
|
||||||
|
# Обработка ~ и относительных путей
|
||||||
|
if target_dir.startswith("~"):
|
||||||
|
target_dir = str(Path.home()) + target_dir[1:]
|
||||||
|
elif not target_dir.startswith("/"):
|
||||||
|
target_dir = str(Path(working_dir) / target_dir)
|
||||||
|
|
||||||
|
# Проверка существования директории
|
||||||
|
if Path(target_dir).is_dir():
|
||||||
|
state.working_directory = target_dir
|
||||||
|
await update.message.reply_text(
|
||||||
|
f"📁 *Директория изменена:*\n`{target_dir}`",
|
||||||
|
parse_mode="Markdown"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
await update.message.reply_text(
|
||||||
|
f"❌ *Директория не найдена:*\n`{target_dir}`",
|
||||||
|
parse_mode="Markdown"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
logger.info(f"Выполнение команды: {command} в директории: {working_dir}")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
process = await asyncio.create_subprocess_shell(
|
process = await asyncio.create_subprocess_shell(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue