@Drno

Почему не правильно передается название файла?

Сделал простого бота для ТГ - музыку переключать \ удалять. Сам бот запускается в линуксов, плеер работает на винде.
Почему то не правильно добавляется имя файла для удаления для некоторых "имён".
Например вот такое название обрабатывает неправильно
ихсодник - Berk & The Virtual Band - Voyage Voyage.mp3 (при этом в линуксе он нормально "прописывается" куда надо)
В винду же он добавляется судя по всему только до первого пробела, ибо команда передается вот такая
run cmd /c del "C:\Users\Professional\Downloads\1_day\1_day\Berk

Я пониаю что надо как то видимо заэкранировать, но не понимаю как конкретно... ниже кусок кода который за это отвечает, команда которая передаётся это "Event"

Данные передаются в формате XML, это требование API...

spoiler

# Удаление файла с диска
async def button_delete_file(update: Update, context: ContextTypes.DEFAULT_TYPE, full_filename: str) -> None:
    """Обработчик нажатия кнопки 'Удалить файл'."""
    user_id = update.effective_chat.id

    # Определите, к какой группе принадлежит пользователь
    user_group = None
    for group, admins in GROUP_ADMINS.items():
        if user_id in admins:
            user_group = group
            break

    if user_group is None:
        await update.effective_message.reply_text("Вы не авторизованы для использования этого бота.")
        return

    # Получите IP-адрес и ключ API для группы пользователя
    ip_address = GROUP_IPS.get(user_group)
    api_key = GROUP_API_KEYS.get(user_group)

    url_list = f"http://{ip_address}:9000/?pass={api_key}&action=schedule&type=list"
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get(url_list) as response_list:
                if response_list.status == 200:
                    xml_data = await response_list.text()
                    root = ET.fromstring(xml_data)
                    task_counter = 1
                    task_name = "del-" + full_filename
                    # Если задание не найдено, создаем новое
                    # Здесь мы добавляем XML данные в запрос на добавление нового задания
                    xml_event_data = """
                    <item EnabledEvent="False" UseDate="False" EveryYear="False" Imm="False" Above="False" FileName='run cmd /c del "{}"' MuteLev="50" DelPrev="True" DoNotRunIfStopped="False" bRepeat="True" nRepeatPer="5" DoNotMarkAsScheduled="False" nRepeat="2" RepeatLimit="True" TimeToStart="" Shuffle="False" PausePlaylist="False" UseWeeks="False" Enqueue="False" DelTaskAction="0" DelTaskUseDate="False" TaskName="{}" ClearMainPlaylist="False" UseDaysOfWeek="True" Hours="000000000000000000000000" Minutes="0" Seconds="0" TimeType="0" TaskNameAsTitle="False" IntTimeToStart="2147483647" ItemImageIndex="63" FontColor="-16777208" BackColor="-16777211" GroupName="" DTMFOn="False" DTMFString="" DTMFOnly="False" DTMFExitOn="False" DTMFExitString="" MaxTimeWaitOn="False" MaxTimeWaitSec="0" MaxTimeWaitAction="0" UseFillers="False" FillersSource="" FillersRecurse="True" FillerMaxAmount="120" Id="DKCODACFWSIKHULWXDUL" Days="1111111" Weeks="00000" Time="2018-02-17 00:00:00" DelTaskTime="2018-02-17 00:00:00" />
                    """.format(full_filename, task_name)
                    url_add = f"http://{ip_address}:9000/?pass={api_key}&action=schedule&type=add&event={xml_event_data}"
                    async with session.get(url_add) as response_add:
                        if response_add.status == 200:
                            # Получаем ID созданного задания
                            async with session.get(url_list) as response_list_after_add:
                                if response_list_after_add.status == 200:
                                    xml_data_after_add = await response_list_after_add.text()
                                    root_after_add = ET.fromstring(xml_data_after_add)
                                    for event in root_after_add.findall(".//item"):
                                        if event.get("TaskName") == task_name:
                                            id = event.get("Id")
                                            break
                            # Запускаем созданное задание
                            url_run = f"http://{ip_address}:9000/?pass={api_key}&action=schedule&type=run&id={id}"
                            async with session.get(url_run) as response_run:
                                if response_run.status == 200:
                                    await update.effective_message.reply_text(f"Задание на удаление успешно запущено! Пожалуйста подождите...")
                                    # Ждем 10 секунд перед удалением задания
                                    await asyncio.sleep(5)
                                    # Удаляем задание после его запуска
                                    url_del = f"http://{ip_address}:9000/?pass={api_key}&action=schedule&type=delete&id={id}"
                                    async with session.get(url_del) as response_del:
                                        if response_del.status == 200:
                                            await update.effective_message.reply_text(f"Задание удаление успешно выполнено.")
                                        else:
                                            await update.effective_message.reply_text("Произошла ошибка при выполнении команды 'del'.")
                                else:
                                    await update.effective_message.reply_text("Произошла ошибка при выполнении команды 'run'.")
                        else:
                            await update.effective_message.reply_text("Произошла ошибка при выполнении команды 'add'.")
                else:
                    await update.effective_message.reply_text("Произошла ошибка при выполнении команды 'schedule'.")
    except Exception as e:
        await update.effective_message.reply_text("Не удалось выполнить запрос: " + str(e))
    # Возвращаемся к основному меню
    await start(update, context)

  • Вопрос задан
  • 183 просмотра
Решения вопроса 1
shabelski89
@shabelski89
engineer
Вероятно нужно сделать url encode, попробуйте так
import urllib.parse

xml_event_data = """
                    <item EnabledEvent="False" UseDate="False" EveryYear="False" Imm="False" Above="False" FileName='run cmd /c del "{}"' MuteLev="50" DelPrev="True" DoNotRunIfStopped="False" bRepeat="True" nRepeatPer="5" DoNotMarkAsScheduled="False" nRepeat="2" RepeatLimit="True" TimeToStart="" Shuffle="False" PausePlaylist="False" UseWeeks="False" Enqueue="False" DelTaskAction="0" DelTaskUseDate="False" TaskName="{}" ClearMainPlaylist="False" UseDaysOfWeek="True" Hours="000000000000000000000000" Minutes="0" Seconds="0" TimeType="0" TaskNameAsTitle="False" IntTimeToStart="2147483647" ItemImageIndex="63" FontColor="-16777208" BackColor="-16777211" GroupName="" DTMFOn="False" DTMFString="" DTMFOnly="False" DTMFExitOn="False" DTMFExitString="" MaxTimeWaitOn="False" MaxTimeWaitSec="0" MaxTimeWaitAction="0" UseFillers="False" FillersSource="" FillersRecurse="True" FillerMaxAmount="120" Id="DKCODACFWSIKHULWXDUL" Days="1111111" Weeks="00000" Time="2018-02-17 00:00:00" DelTaskTime="2018-02-17 00:00:00" />
                    """.format(full_filename, task_name)

xml_event_data = urllib.parse.quote_plus(xml_event_data)
url_add = f"http://{ip_address}:9000/?pass={api_key}&action=schedule&type=add&event={xml_event_data}"
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
grantur5707
@grantur5707
Full Stack Web Developer
Имя файла должно быть обернуто в кавычки:

xml_event_data = """
<item EnabledEvent="False" UseDate="False" EveryYear="False" Imm="False" Above="False" FileName='run cmd /c del "{}"' ...
""".format(full_filename.replace('"', '\\"'), task_name)
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы