Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update track.py (fix "bad escape \M") #52

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ray2301
Copy link

@ray2301 ray2301 commented Dec 5, 2023

  • added a sanitize_string function to sanitize strings for filenames or directories
  • used this function to sanitize strings before constructing file paths
  • modify the regular expression to correctly match filenames that start with the sanitized filename
  • changed the file renaming process to use shutil.move instead of Path(filename_temp).rename(filename) to handle potential issues when the source and destination are in the same directory (files being renamed to "._1")

needs to be tested more, but it fixes the problem from the title.

- added a sanitize_string function to sanitize strings for filenames or directories
- used this function to sanitize strings before constructing file paths
- modify the regular expression to correctly match filenames that start with the sanitized filename
- changed the file renaming process to use shutil.move instead of Path(filename_temp).rename(filename) to handle potential issues when the source and destination are in the same directory (files being renamed to "._1")

needs to be tested more, but it fixes the problem.
@shinji257
Copy link

I know you said it still needs testing but I hit an album where I can consistently reproduce and I get the error with this one even with your patch.

###   SKIPPING SONG - FAILED TO QUERY METADATA   ###
Track_ID: 7aA5ODlMMfksbG1v4rXzmS
album_num: 01
artist: AmaLee
album: STYX HELIX (From _Re_Zero_)
album_id: 4vkdPM6LjXRpLw9rMaGM6v


bad escape \M at position 3

Traceback (most recent call last):
  File "C:\Users\shinj\AppData\Local\pipx\pipx\venvs\zotify\Lib\site-packages\zotify\track.py", line 201, in download_track
    c = len([file for file in Path(filedir).iterdir() if re.search(f'^{filename}_', str(file))]) + 1
                                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\__init__.py", line 177, in search
    return _compile(pattern, flags).search(string)
           ^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\__init__.py", line 307, in _compile
    p = _compiler.compile(pattern, flags)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\_compiler.py", line 745, in compile
    p = _parser.parse(p, flags)
        ^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\_parser.py", line 979, in parse
    p = _parse_sub(source, state, flags & SRE_FLAG_VERBOSE, 0)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\_parser.py", line 460, in _parse_sub
    itemsappend(_parse(source, state, verbose, nested + 1,
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\_parser.py", line 544, in _parse
    code = _escape(source, this, state)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\shinj\scoop\apps\python\3.12.1\Lib\re\_parser.py", line 443, in _escape
    raise source.error("bad escape %s" % escape, len(escape))
re.error: bad escape \M at position 3

@jteijema
Copy link

jteijema commented Feb 27, 2024

if not check_id and check_name:
    # Convert filename to a string before escaping
    filename_str = str(PurePath(filename))
    pattern = re.escape(filename_str) + '_'
    
    c = len([file for file in Path(filedir).iterdir() if re.search(f'^{pattern}', str(file))]) + 1

    fname = PurePath(filename).stem
    ext = PurePath(filename).suffix

    # Use the filename_str for pattern matching and then construct the new filename with the original Path object
    filename = PurePath(filedir).joinpath(f'{fname}_{c}{ext}')

Won't this be enough to fix it? It works for me hahaha

@Googolplexed0
Copy link

This was my fix, got the line count down and haven't had any naming issues since. Didn't do any sanitization though.

if not check_id and check_name:
    c = len([file for file in Path(filedir).iterdir() if file.match(filename.stem + "*")])
    filename = PurePath(filedir).joinpath(f'{filename.stem}_{c}{filename.suffix}')

Got around having to use shutil when renaming temps this way.

if filename_temp != filename:
    if Path(filename).exists():
        Path(filename).unlink()
    Path(filename_temp).rename(filename)

Both implemented on my fork and works well enough for me. I have not tested it extensively, though. I will probably come back to this.

@booth-w
Copy link
Contributor

booth-w commented Jul 1, 2024

There is already a function for sanitising strings for file names.

zotify/zotify/utils.py

Lines 245 to 266 in fa2156b

def fix_filename(name):
"""
Replace invalid characters on Linux/Windows/MacOS with underscores.
List from https://stackoverflow.com/a/31976060/819417
Trailing spaces & periods are ignored on Windows.
>>> fix_filename(" COM1 ")
'_ COM1 _'
>>> fix_filename("COM10")
'COM10'
>>> fix_filename("COM1,")
'COM1,'
>>> fix_filename("COM1.txt")
'_.txt'
>>> all('_' == fix_filename(chr(i)) for i in list(range(32)))
True
"""
if platform.system() == WINDOWS_SYSTEM:
return re.sub(r'[/\\:|<>"?*\0-\x1f]|^(AUX|COM[1-9]|CON|LPT[1-9]|NUL|PRN)(?![^.])|^\s|[\s.]$', "_", str(name), flags=re.IGNORECASE)
elif platform.system() == LINUX_SYSTEM:
return re.sub(r'[/\0]', "_", str(name))
else: # MacOS
return re.sub(r'[/:\0]', "_", str(name))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants