fix for windows

This commit is contained in:
Jesse Bannon 2023-03-10 00:00:13 -08:00
parent 842e15c4f0
commit 6133d3e243
2 changed files with 19 additions and 21 deletions

View file

@ -10,12 +10,8 @@ from ytdl_sub.validators.string_formatter_validators import OverridesStringForma
from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator from ytdl_sub.validators.string_formatter_validators import StringFormatterValidator
from ytdl_sub.validators.validators import StringValidator from ytdl_sub.validators.validators import StringValidator
_MAX_FILE_NAME_LEN: int = 0
_MAX_FILE_NAME_BYTES: int = 0
if IS_WINDOWS: if IS_WINDOWS:
from ctypes.wintypes import MAX_PATH _MAX_FILE_NAME_BYTES = 255
_MAX_FILE_NAME_LEN = MAX_PATH
else: else:
_MAX_FILE_NAME_BYTES = os.pathconf("/", "PC_NAME_MAX") _MAX_FILE_NAME_BYTES = os.pathconf("/", "PC_NAME_MAX")
@ -48,9 +44,7 @@ class StringFormatterFilePathValidator(StringFormatterValidator):
@classmethod @classmethod
def _is_file_name_too_long(cls, file_name: str) -> bool: def _is_file_name_too_long(cls, file_name: str) -> bool:
return (_MAX_FILE_NAME_LEN and len(file_name) > _MAX_FILE_NAME_LEN) or ( return len(file_name.encode("utf-8")) > _MAX_FILE_NAME_BYTES
_MAX_FILE_NAME_BYTES and len(file_name.encode("utf-8")) > _MAX_FILE_NAME_BYTES
)
@classmethod @classmethod
def _get_extension_split(cls, file_name: str) -> Tuple[str, str]: def _get_extension_split(cls, file_name: str) -> Tuple[str, str]:
@ -71,13 +65,10 @@ class StringFormatterFilePathValidator(StringFormatterValidator):
@classmethod @classmethod
def _truncate_file_name(cls, file_name: str) -> str: def _truncate_file_name(cls, file_name: str) -> str:
file_sub_name, file_ext = cls._get_extension_split(file_name) file_sub_name, file_ext = cls._get_extension_split(file_name)
if _MAX_FILE_NAME_LEN:
to_trim = len(file_name) - _MAX_FILE_NAME_LEN + 1 desired_size = _MAX_FILE_NAME_BYTES - len(file_ext.encode("utf-8")) - 1
file_sub_name = file_sub_name[:-to_trim] while len(file_sub_name.encode("utf-8")) > desired_size:
elif _MAX_FILE_NAME_BYTES: file_sub_name = file_sub_name[:-1]
desired_size = _MAX_FILE_NAME_BYTES - len(file_ext.encode("utf-8")) - 1
while len(file_sub_name.encode("utf-8")) > desired_size:
file_sub_name = file_sub_name[:-1]
return f"{file_sub_name}.{file_ext}" return f"{file_sub_name}.{file_ext}"

View file

@ -11,14 +11,17 @@ class TestStringFormatterFilePathValidator:
@pytest.mark.parametrize( @pytest.mark.parametrize(
"ext", "ext",
[ [
".mp4", "mp4",
".info.json", "info.json",
] ]
+ [f".en.{ext}" for ext in SUBTITLE_EXTENSIONS], + [f"en-US.{ext}" for ext in SUBTITLE_EXTENSIONS],
) )
def test_truncates_file_name_successfully(self, ext: str): @pytest.mark.parametrize('file_name_char', ['a', '𒃀'])
@pytest.mark.parametrize('file_name_len', [10, 10000])
def test_truncates_file_name_successfully(self, ext: str, file_name_char: str, file_name_len: int):
ext = f".{ext}" # pytest args with . in the beginning act weird
with tempfile.TemporaryDirectory() as temp_dir: with tempfile.TemporaryDirectory() as temp_dir:
file_name = ("a" * 10000) + ext file_name = (file_name_char * file_name_len) + ext
file_path = str(Path(temp_dir) / file_name) file_path = str(Path(temp_dir) / file_name)
formatter = StringFormatterFilePathValidator(name="test", value=str(file_path)) formatter = StringFormatterFilePathValidator(name="test", value=str(file_path))
@ -30,4 +33,8 @@ class TestStringFormatterFilePathValidator:
# Ensure it can actually open the file # Ensure it can actually open the file
with open(truncated_file_path, "w", encoding="utf-8"): with open(truncated_file_path, "w", encoding="utf-8"):
pass # Make sure the file is actually in the directory
dir_paths = list(Path(temp_dir).rglob("*"))
assert len(dir_paths) == 1
assert Path(truncated_file_path) == dir_paths[0]