Merge pull request #127 from maxdorninger/remove-special-chars-from-media-file-names

Remove certain special chars from file names
This commit is contained in:
Maximilian Dorninger
2025-08-01 14:31:01 +02:00
committed by GitHub
3 changed files with 43 additions and 15 deletions

View File

@@ -32,7 +32,11 @@ from media_manager.movies.repository import MovieRepository
from media_manager.exceptions import NotFoundError
import pprint
from media_manager.torrent.repository import TorrentRepository
from media_manager.torrent.utils import import_file, import_torrent
from media_manager.torrent.utils import (
import_file,
import_torrent,
remove_special_characters,
)
from media_manager.indexer.service import IndexerService
from media_manager.metadataProvider.abstractMetaDataProvider import (
AbstractMetadataProvider,
@@ -473,7 +477,10 @@ class MovieService:
movie_file_path = (
misc_config.movie_directory
/ f"{movie.name} ({movie.year}) [{movie.metadata_provider}id-{movie.external_id}]"
/ f"{remove_special_characters(movie.name)} ({movie.year}) [{movie.metadata_provider}id-{movie.external_id}]"
)
log.debug(
f"Movie {movie.name} without special characters: {remove_special_characters(movie.name)}"
)
if movie.library != "Default":
for library in misc_config.movie_libraries:
@@ -481,7 +488,7 @@ class MovieService:
log.debug(f"Using library {library.name} for movie {movie.name}")
movie_file_path = (
Path(library.path)
/ f"{movie.name} ({movie.year}) [{movie.metadata_provider}id-{movie.external_id}]"
/ f"{remove_special_characters(movie.name)} ({movie.year}) [{movie.metadata_provider}id-{movie.external_id}]"
)
break
else:
@@ -502,7 +509,7 @@ class MovieService:
except Exception as e:
log.warning(f"Could not create path {movie_file_path}: {e}")
movie_file_name = f"{movie.name} ({movie.year})"
movie_file_name = f"{remove_special_characters(movie.name)} ({movie.year})"
if movie_file.file_path_suffix != "":
movie_file_name += f" - {movie_file.file_path_suffix}"

View File

@@ -1,6 +1,7 @@
import hashlib
import logging
import mimetypes
import re
from pathlib import Path
import shutil
@@ -152,3 +153,19 @@ def get_torrent_hash(torrent: IndexerQueryResult) -> str:
log.error(f"Failed to decode torrent file: {e}")
raise
return torrent_hash
def remove_special_characters(filename: str) -> str:
"""
Removes special characters from the filename to ensure it works with Jellyfin.
:param filename: The original filename.
:return: A sanitized version of the filename.
"""
# Remove invalid characters
sanitized = re.sub(r"([<>:\"/\\|?*])", "", filename)
# Remove leading and trailing dots or spaces
sanitized = sanitized.strip(" .")
return sanitized

View File

@@ -37,7 +37,11 @@ from media_manager.exceptions import NotFoundError
import pprint
from pathlib import Path
from media_manager.torrent.repository import TorrentRepository
from media_manager.torrent.utils import import_file, import_torrent
from media_manager.torrent.utils import (
import_file,
import_torrent,
remove_special_characters,
)
from media_manager.indexer.service import IndexerService
from media_manager.metadataProvider.abstractMetaDataProvider import (
AbstractMetadataProvider,
@@ -510,25 +514,27 @@ class TvService:
f"Importing these {len(video_files)} files:\n" + pprint.pformat(video_files)
)
misc_config = AllEncompassingConfig().misc
show_file_path = (
misc_config.tv_directory
/ f"{show.name} ({show.year}) [{show.metadata_provider}id-{show.external_id}]"
show_directory_name = f"{remove_special_characters(show.name)} ({show.year}) [{show.metadata_provider}id-{show.external_id}]"
show_file_path = None
log.debug(
f"Show {show.name} without special characters: {remove_special_characters(show.name)}"
)
if show.library != "Default":
for library in misc_config.tv_libraries:
if library.name == show.library:
log.info(
f"Using library {library.name} for show {show.name} ({show.year})"
)
show_file_path = (
Path(library.path)
/ f"{show.name} ({show.year}) [{show.metadata_provider}id-{show.external_id}]"
)
show_file_path = Path(library.path) / show_directory_name
break
else:
log.warning(
f"Library {show.library} not defined in config, using default TV directory."
)
show_file_path = misc_config.tv_directory / show_directory_name
else:
show_file_path = misc_config.tv_directory / show_directory_name
season_files = self.torrent_service.get_season_files_of_torrent(torrent=torrent)
log.info(
@@ -543,9 +549,7 @@ class TvService:
except Exception as e:
log.warning(f"Could not create path {season_path}: {e}")
for episode in season.episodes:
episode_file_name = (
f"{show.name} S{season.number:02d}E{episode.number:02d}"
)
episode_file_name = f"{remove_special_characters(show.name)} S{season.number:02d}E{episode.number:02d}"
if season_file.file_path_suffix != "":
episode_file_name += f" - {season_file.file_path_suffix}"
pattern = (