Add configurable download_path depth env to control auto complete depth

This commit is contained in:
arabcoders 2025-08-02 16:32:56 +03:00
parent 48fb35329a
commit 2d82737a3a
4 changed files with 38 additions and 3 deletions

View file

@ -317,4 +317,5 @@ Certain configuration values can be set via environment variables, using the `-e
| YTP_TASKS_HANDLER_TIMER | The cron expression for the tasks handler timer | `15 */1 * * *` | | YTP_TASKS_HANDLER_TIMER | The cron expression for the tasks handler timer | `15 */1 * * *` |
| YTP_PLAYLIST_ITEMS_CONCURRENCY | The number of playlist items be to processed at same time | `1` | | YTP_PLAYLIST_ITEMS_CONCURRENCY | The number of playlist items be to processed at same time | `1` |
| YTP_TEMP_DISABLED | Disable temp files handling. | `false` | | YTP_TEMP_DISABLED | Disable temp files handling. | `false` |
| YTP_DOWNLOAD_PATH_DEPTH | How many subdirectories to show in auto complete. | `1` |

View file

@ -1405,6 +1405,32 @@ def find_unpickleable(obj, name="root", seen=None):
find_unpickleable(value, f"{name}.{attr}", seen) find_unpickleable(value, f"{name}.{attr}", seen)
except Exception as ie: except Exception as ie:
LOG.error(f"[ERROR] Accessing {name}.{attr}: {ie}") LOG.error(f"[ERROR] Accessing {name}.{attr}: {ie}")
elif isinstance(obj, (list, tuple, set)): elif isinstance(obj, list | tuple | set):
for idx, item in enumerate(obj): for idx, item in enumerate(obj):
find_unpickleable(item, f"{name}[{idx}]", seen) find_unpickleable(item, f"{name}[{idx}]", seen)
def list_folders(path: Path, base: Path, depth_limit: int) -> list[str]:
"""
List all folders relative to a base path, up to a specified depth limit.
Args:
path (Path): The path to start listing folders from.
base (Path): The base path to which the folders should be relative.
depth_limit (int): The maximum depth to traverse from the base path.
Returns:
list[str]: A list of folder paths relative to the base path, up to the specified
"""
rel_depth: int = len(path.relative_to(base).parts)
if rel_depth > depth_limit:
return []
folders: list[str] = []
for entry in path.iterdir():
if entry.is_dir():
folders.append(str(entry.relative_to(base)))
folders.extend(list_folders(entry, base, depth_limit))
return folders

View file

@ -25,6 +25,9 @@ class Config:
download_path: str = "." download_path: str = "."
"""The path to the download directory.""" """The path to the download directory."""
download_path_depth: int = 2
"""How many subdirectories to show in auto complete."""
temp_path: str = "/tmp" temp_path: str = "/tmp"
"""The path to the temporary directory.""" """The path to the temporary directory."""
@ -219,6 +222,7 @@ class Config:
"extract_info_timeout", "extract_info_timeout",
"debugpy_port", "debugpy_port",
"playlist_items_concurrency", "playlist_items_concurrency",
"download_path_depth",
) )
"The variables that are integers." "The variables that are integers."

View file

@ -10,7 +10,7 @@ from app.library.DownloadQueue import DownloadQueue
from app.library.Events import EventBus, Events from app.library.Events import EventBus, Events
from app.library.Presets import Presets from app.library.Presets import Presets
from app.library.router import RouteType, route from app.library.router import RouteType, route
from app.library.Utils import tail_log from app.library.Utils import list_folders, tail_log
LOG: logging.Logger = logging.getLogger(__name__) LOG: logging.Logger = logging.getLogger(__name__)
@ -29,7 +29,11 @@ async def connect(config: Config, queue: DownloadQueue, notify: EventBus, sid: s
"paused": queue.is_paused(), "paused": queue.is_paused(),
} }
data["folders"] = [folder.name for folder in Path(config.download_path).iterdir() if folder.is_dir()] data["folders"] = list_folders(
path=Path(config.download_path),
base=Path(config.download_path),
depth_limit=config.download_path_depth-1,
)
await notify.emit( await notify.emit(
Events.CONNECTED, Events.CONNECTED,