eaf_base_api 3.3.3__tar.gz → 3.3.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/PKG-INFO +1 -1
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/static_functions.py +35 -15
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/pyproject.toml +1 -1
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/LICENSE +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/README.md +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/__init__.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/base.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/__init__.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/config.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/errors.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/logger.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/progress_bars.py +0 -0
- {eaf_base_api-3.3.3 → eaf_base_api-3.3.4}/base_api/modules/type_hints.py +0 -0
|
@@ -2,6 +2,8 @@ import os
|
|
|
2
2
|
import re
|
|
3
3
|
import math
|
|
4
4
|
import json
|
|
5
|
+
import unicodedata
|
|
6
|
+
from pathlib import PurePath
|
|
5
7
|
from .type_hints import DownloadState
|
|
6
8
|
from datetime import timezone, datetime
|
|
7
9
|
from curl_cffi.requests import Response
|
|
@@ -432,31 +434,49 @@ def log_precondition_failed(logger, response: Response, attempt: int) -> None:
|
|
|
432
434
|
)
|
|
433
435
|
|
|
434
436
|
|
|
435
|
-
def strip_title(
|
|
436
|
-
""
|
|
437
|
-
|
|
438
|
-
|
|
437
|
+
def strip_title(
|
|
438
|
+
title: str, max_length: int = 255, default_name: str = "untitled"
|
|
439
|
+
) -> str:
|
|
440
|
+
"""Sanitize a filename to be safe across Windows, macOS, Linux, and Android.
|
|
441
|
+
|
|
442
|
+
Prevents path traversal, replaces illegal characters, handles Windows reserved
|
|
443
|
+
names, and trims to a safe length.
|
|
439
444
|
"""
|
|
445
|
+
if not title:
|
|
446
|
+
return default_name
|
|
447
|
+
|
|
448
|
+
# 1. Normalize Unicode (converts full-width slashes/characters to standard ASCII where applicable)
|
|
449
|
+
sanitized = unicodedata.normalize("NFKC", title)
|
|
440
450
|
|
|
441
|
-
#
|
|
451
|
+
# 2. Extract only the filename component (strips drive letters & path prefixes)
|
|
452
|
+
sanitized = PurePath(sanitized).name
|
|
453
|
+
|
|
454
|
+
# 3. Replace illegal filename characters & explicit path separators with underscores
|
|
442
455
|
illegal_chars = r'[<>:"/\\|?*\x00-\x1F]'
|
|
443
|
-
sanitized = re.sub(illegal_chars, "_",
|
|
456
|
+
sanitized = re.sub(illegal_chars, "_", sanitized)
|
|
444
457
|
|
|
445
|
-
# Strip invisible zero-width characters
|
|
446
|
-
sanitized = re.sub(r
|
|
458
|
+
# 4. Strip invisible zero-width & non-printable Unicode control characters
|
|
459
|
+
sanitized = re.sub(r"[\u200B-\u200D\uFEFF]", "", sanitized)
|
|
447
460
|
|
|
448
|
-
# Strip
|
|
449
|
-
|
|
461
|
+
# 5. Strip LEADING and TRAILING spaces and dots
|
|
462
|
+
# (Prevents '.' and '..' traversal tokens and hidden files)
|
|
463
|
+
sanitized = sanitized.strip(" .")
|
|
450
464
|
|
|
451
|
-
# Prevent reserved
|
|
465
|
+
# 6. Prevent Windows reserved filenames (CON, PRN, AUX, NUL, COM1-9, LPT1-9)
|
|
452
466
|
reserved_names = {
|
|
453
|
-
"CON",
|
|
467
|
+
"CON",
|
|
468
|
+
"PRN",
|
|
469
|
+
"AUX",
|
|
470
|
+
"NUL",
|
|
454
471
|
*(f"COM{i}" for i in range(1, 10)),
|
|
455
472
|
*(f"LPT{i}" for i in range(1, 10)),
|
|
456
473
|
}
|
|
457
|
-
name_only = sanitized.split(
|
|
474
|
+
name_only = sanitized.split(".")[0].upper()
|
|
458
475
|
if name_only in reserved_names:
|
|
459
476
|
sanitized = f"_{sanitized}"
|
|
460
477
|
|
|
461
|
-
# Trim to max length
|
|
462
|
-
|
|
478
|
+
# 7. Trim to max length, then re-strip trailing dots/spaces in case the slice cut mid-string
|
|
479
|
+
sanitized = sanitized[:max_length].rstrip(" .")
|
|
480
|
+
|
|
481
|
+
# 8. Return default fallback if sanitization leaves an empty string
|
|
482
|
+
return sanitized if sanitized else default_name
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|