Уведомления

Группа в Telegram: @pythonsu

#1 Март 19, 2018 19:55:00

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

os.mkdir()

Добрый день.
Господа, есть некий скрипт, вытаскивающий из mp3 файла теги и склеивает их в строку, далее создает папку os.mkdir() с именем в виде этой строки и перемещает в нее файл, теги которого были использованы.
Все работает, все хорошо. Но по непонятным мне причинам на некоторых файлах скрипт спотыкается.
Выдавая ошибку: ValueError: mkdir: embedded null character in path
Имя папки хранится в переменной и если эту переменную передать в print(), оно (имя) распечатывается. Тип данных тоже в порядке (строка). Никаких запретных (с точки зрения создания папки) символов в строке нет.
Ошибка вылетает именно в момент выполнения команды os.mkdir().


Поясните данная ошибка - результат передачи в os.mkdir() пустой строки? Или я не прав?
Самого текста скрипта под рукой нет (другой комп, другой город). Кто-то может что посоветовать, или пока нет всего кода не понятна проблема?


Офлайн

#2 Март 19, 2018 20:51:35

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

os.mkdir()

что бы не задавать такой вопрос на форуме нужно научиться отлаживать вашу программу. Оборачиваете ваш вызов mkdir в try except и когда произойдет ошибка делаете хоть принт хоть запись в файл с отладочной информацией, которая бы помогла вам разобраться в проблеме.
Но я поделюсь с вами и более нестандартными решениями - вы можете эту переменную упаковать с помощью pickle, а затем , загрузив его, более детально в режиме реального времени разобраться с вашей переменной что же с ней не так. Ну и воспроизводить вашу проблему вы сможете многократно и очень быстро.
А задавать вопрос так как вы его задали - это практически гадание.
Более опытные люди скажут что наверняка речь идет о винде и наверняка проблема с системным вызовов которому не понравился тот набор данных который ему прислали. С вашей стороны это звучит так - в тегах могут быть записан текст в разных кодировках - когда вы их считываете, вы вероятно переводите их в байты - ок ошибки тут не возникло, а про целостность и адекватность данных мы не говорим в этом месте (она уже нарушена наверняка) но вот при попытке использовать эту строку как названия файла (то есть передать ее ОС для создания записи в файловой системе) произошла ошибка.
Меня немного смущает что текст ошибки не ожидаемый, но без кода я не ручусь ничего говорить. Хотя и он может не помочь - ведь не совсем ясно что там с данными.
Как то так



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

#3 Март 19, 2018 23:27:49

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

os.mkdir()

SomethingButNotNickName
Все работает, все хорошо. Но по непонятным мне причинам на некоторых файлах скрипт спотыкается.
Выдавая ошибку: ValueError: mkdir: embedded null character in path
Значит, из тегов попал нуль-символ в строку. Ты перед созданием имени на диске должен почистить строку от всего, что туда может попасть. Когда склеил строку из тегов, почисти её от лишних символов (отфильтруй только разрешённые).



Офлайн

#4 Март 24, 2018 21:41:21

SomethingButNotNickName
Зарегистрирован: 2017-12-19
Сообщения: 75
Репутация: +  0  -
Профиль   Отправить e-mail  

os.mkdir()

Текст скрипта такой.

 import re
import shutil
import os
from mp3_tagger import VERSION_1, VERSION_2, MP3File
def func_list_files():
    """
    Возвращает список файлов внутри папки, исключая файлы программы
    :return: None
    """
    return [f for f in os.listdir('.') if os.path.isfile('.' + '\\' + f)
            and not f.endswith('.py') and not f.endswith('.exe')]
def func_list_dirs():
    """
    Возвращает список папок внутри исходной
    :return: None
    """
    return [f for f in os.listdir('.') if os.path.isdir('.' + '\\' + f)]
def func_bad_name(name):
    exceptions = {'\\', '/', '|', '<', '>', '?', ':', '"', '*', '.'}
    return bool(set(name).intersection(exceptions))
def func_get_tags(var_file, var_version):
    """
    Получает файл и возврящает список [артист, альбом]
    :param var_file: Файл для обратотки
    :param var_version: Версия тегов для работы
    :return: список тегов
    """
    mp3 = MP3File(os.path.join('.', var_file))
    mp3.set_version(var_version)
    return [mp3.artist, mp3.album, mp3.year]
def func_main():
    """
    Читает теги mp3 файлов, создает папки с названиями исполнителя и альбома
     и перемещает файлы в соответствии с их тегами
    :return: None
    """
    for file in func_list_files():
        print(file)
        tags = func_get_tags(file, VERSION_2)
        if None in tags:
            tags = func_get_tags(file, VERSION_1)
        if None in tags:
            continue
        name = tags[0] + '-' + tags[2] + '-' + tags[1]
        exception_chars = '\\\/\|<>\?:"\*\.'
        find_exceptions = re.compile('([{}])'.format(exception_chars))
        name = re.sub('\s+', ' ', name)
        if func_bad_name(name):
            name = re.sub(find_exceptions, '', name)
        name = re.sub('\s+$', '', name)
        try:
            print(name)
            os.mkdir(name)
        except FileExistsError:
            pass
        shutil.move(file, '.\\{}\\'.format(name))
    input('press enter to exit')
def func_main_reversed():
    """
    Функция обратная main
    :return: None
    """
    path = os.getcwd()
    for folder in func_list_dirs():
        print(folder)
        os.chdir('.\\{}'.format(folder))
        for file in func_list_files():
            print(file)
            shutil.move(file, path)
        os.chdir('..')
        os.rmdir(folder)
    input('press enter to exit')
# func_main_reversed()
func_main()
py.user.next
Значит, из тегов попал нуль-символ в строку
Проверка на запретные осуществляется. Если только я упустил какой-то, но вроде нет. И скрипт спотыкается на вполне простых именах (буквы, тире плюс цифры и ничего более).
JOHN_16
что бы не задавать такой вопрос на форуме нужно научиться отлаживать вашу программу. Оборачиваете ваш вызов mkdir в try except и когда произойдет ошибка делаете хоть принт хоть запись в файл с отладочной информацией, которая бы помогла вам разобраться в проблеме.
Не совсем понял этот момент. Ну обернуть в try except понятно, а какую отладочную информацию вывести? Текст ошибки? - он и так выведется.
Строка на которой была ошибка? - она выводится и в ней все хорошо (ну по крайней мере на глаз). Что еще и как это вывести?
Можно подробнее про целостность данных и почему она нарушается при считывании тега в строку. И почему если строка print'ом выводится корректно если она “не целостна и адекватна”. если можно ссылку на инфу где можно об этом почитать.

ps: убрать что-либо внутрь спойлера на форуме можно? Какой тег?

Отредактировано SomethingButNotNickName (Март 24, 2018 21:49:22)

Офлайн

#5 Март 25, 2018 00:45:03

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

os.mkdir()

SomethingButNotNickName
Проверка на запретные осуществляется.
Надо не проверять запретные, а пропускать разрешённые из исходной строки в конечную. Сделай функцию, которая принимает входную строку, перебирает её символы и в выходную строку записывает только разрешённые символы (множество которых ты определяешь внутри функции, модуль string может пригодиться). Потом после получения исходной строки из тегов файла подавай её в эту фильтрующую функцию и на выходе она будет выдавать уже готовое имя для файла. Можно и две функции сделать: одна - фильтрует символы; другая - формирует имя файла из отфильтрованных символов, дописывая к ним что-нибудь ещё.



Отредактировано py.user.next (Март 25, 2018 00:49:04)

Офлайн

#6 Март 25, 2018 10:54:17

JOHN_16
От: Россия, Петропавловск-Камчатск
Зарегистрирован: 2010-03-22
Сообщения: 3292
Репутация: +  221  -
Профиль   Отправить e-mail  

os.mkdir()

SomethingButNotNickName
Что еще и как это вывести?
Например содержание переменной, ее repr представление. Либо любую другую информацию что поможет для конкретно этой проблемы.



_________________________________________________________________________________
полезный блог о python john16blog.blogspot.com

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version