Line too long errors
This commit is contained in:
@@ -41,7 +41,10 @@ def main() -> None:
|
|||||||
"media_folders",
|
"media_folders",
|
||||||
nargs="*",
|
nargs="*",
|
||||||
metavar="MEDIA_FOLDER",
|
metavar="MEDIA_FOLDER",
|
||||||
help="One or more media folders to index (default: none — configure via UI or API)",
|
help=(
|
||||||
|
"One or more media folders to index "
|
||||||
|
"(default: none — configure via UI or API)"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-l",
|
"-l",
|
||||||
|
|||||||
@@ -89,9 +89,7 @@ def _pattern_to_regex(pattern: str) -> re.Pattern[str]:
|
|||||||
|
|
||||||
regex_str = "".join(parts)
|
regex_str = "".join(parts)
|
||||||
|
|
||||||
regex_str = (
|
regex_str = "^" + regex_str if anchored or has_slash else "(?:^|/)" + regex_str
|
||||||
"^" + regex_str if anchored or has_slash else "(?:^|/)" + regex_str
|
|
||||||
)
|
|
||||||
|
|
||||||
# Must match the whole remaining path or be a prefix (directory match)
|
# Must match the whole remaining path or be a prefix (directory match)
|
||||||
regex_str += "(?:/.*)?$"
|
regex_str += "(?:/.*)?$"
|
||||||
|
|||||||
@@ -559,7 +559,9 @@ class RootScanner:
|
|||||||
id=task_id,
|
id=task_id,
|
||||||
status="completed",
|
status="completed",
|
||||||
progress=1,
|
progress=1,
|
||||||
detail=f"Showreel: {title} ({len(generated)} reels)",
|
detail=(
|
||||||
|
f"Showreel: {title} ({len(generated)} reels)"
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -46,7 +46,8 @@ def _log_ffmpeg_not_found_once(cmd: list[str]) -> None:
|
|||||||
return
|
return
|
||||||
_ffmpeg_not_found_logged = True
|
_ffmpeg_not_found_logged = True
|
||||||
logger.error(
|
logger.error(
|
||||||
"ffmpeg executable was not found on PATH. Install ffmpeg and restart MediaHive. Command: %s",
|
"ffmpeg executable was not found on PATH. "
|
||||||
|
"Install ffmpeg and restart MediaHive. Command: %s",
|
||||||
shlex.join(cmd),
|
shlex.join(cmd),
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ async def _run_ffmpeg(
|
|||||||
await _kill_proc(proc)
|
await _kill_proc(proc)
|
||||||
try:
|
try:
|
||||||
stdout, stderr = await proc.communicate()
|
stdout, stderr = await proc.communicate()
|
||||||
except (OSError, asyncio.SubprocessError):
|
except OSError, asyncio.SubprocessError:
|
||||||
stdout, stderr = b"", b""
|
stdout, stderr = b"", b""
|
||||||
logger.exception(
|
logger.exception(
|
||||||
"ffmpeg command timed out. cmd=%s stderr=%s",
|
"ffmpeg command timed out. cmd=%s stderr=%s",
|
||||||
@@ -89,7 +90,8 @@ async def _run_ffmpeg(
|
|||||||
if proc.returncode != 0:
|
if proc.returncode != 0:
|
||||||
if allow_nonzero_exit:
|
if allow_nonzero_exit:
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"ffmpeg command exited non-zero as expected for probe. cmd=%s returncode=%s",
|
"ffmpeg command exited non-zero as expected for probe. "
|
||||||
|
"cmd=%s returncode=%s",
|
||||||
shlex.join(cmd),
|
shlex.join(cmd),
|
||||||
proc.returncode,
|
proc.returncode,
|
||||||
)
|
)
|
||||||
@@ -108,7 +110,7 @@ async def _run_ffmpeg(
|
|||||||
except asyncio.CancelledError:
|
except asyncio.CancelledError:
|
||||||
await _kill_proc(proc)
|
await _kill_proc(proc)
|
||||||
raise
|
raise
|
||||||
except (OSError, asyncio.SubprocessError):
|
except OSError, asyncio.SubprocessError:
|
||||||
logger.exception("Unexpected error running ffmpeg command: %s", shlex.join(cmd))
|
logger.exception("Unexpected error running ffmpeg command: %s", shlex.join(cmd))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@@ -134,7 +136,7 @@ def get_reel_source_extensions() -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
def _to_media_path(path: Path, media_root: Path | None = None) -> str:
|
def _to_media_path(path: Path, media_root: Path | None = None) -> str:
|
||||||
"""Convert an absolute reel file path to a media-root-relative path when possible."""
|
"""Convert an absolute reel path to media-root-relative when possible."""
|
||||||
if media_root:
|
if media_root:
|
||||||
try:
|
try:
|
||||||
return path.relative_to(media_root).as_posix()
|
return path.relative_to(media_root).as_posix()
|
||||||
@@ -241,7 +243,7 @@ def get_existing_showreel_paths(
|
|||||||
timestamps: list[int] = SHOWREEL_TIMESTAMPS,
|
timestamps: list[int] = SHOWREEL_TIMESTAMPS,
|
||||||
media_root: Path | None = None,
|
media_root: Path | None = None,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
"""Return preferred existing showreel paths, one per reel slot, in AV1-first order."""
|
"""Return preferred showreel paths, one per reel slot, in AV1-first order."""
|
||||||
source_sets = get_existing_showreel_source_sets(
|
source_sets = get_existing_showreel_source_sets(
|
||||||
media_folder,
|
media_folder,
|
||||||
timestamps=timestamps,
|
timestamps=timestamps,
|
||||||
@@ -255,7 +257,7 @@ def get_existing_showreel_source_sets(
|
|||||||
timestamps: list[int] = SHOWREEL_TIMESTAMPS,
|
timestamps: list[int] = SHOWREEL_TIMESTAMPS,
|
||||||
media_root: Path | None = None,
|
media_root: Path | None = None,
|
||||||
) -> list[list[str]]:
|
) -> list[list[str]]:
|
||||||
"""Return all existing showreel source files for each reel slot in AV1-first order."""
|
"""Return all showreel source files per reel slot in AV1-first order."""
|
||||||
source_sets: list[list[str]] = []
|
source_sets: list[list[str]] = []
|
||||||
for reel_num in range(1, len(timestamps) + 1):
|
for reel_num in range(1, len(timestamps) + 1):
|
||||||
sources = [
|
sources = [
|
||||||
@@ -446,9 +448,7 @@ async def probe_media_info(video_path: str) -> MediaProbeInfo:
|
|||||||
|
|
||||||
info = MediaProbeInfo()
|
info = MediaProbeInfo()
|
||||||
cmd = ["ffmpeg", "-hide_banner", "-i", video_path]
|
cmd = ["ffmpeg", "-hide_banner", "-i", video_path]
|
||||||
ffmpeg_result = await _run_ffmpeg(
|
ffmpeg_result = await _run_ffmpeg(cmd, timeout_seconds=30, allow_nonzero_exit=True)
|
||||||
cmd, timeout_seconds=30, allow_nonzero_exit=True
|
|
||||||
)
|
|
||||||
if ffmpeg_result is None:
|
if ffmpeg_result is None:
|
||||||
_media_probe_cache[video_path] = info
|
_media_probe_cache[video_path] = info
|
||||||
return info
|
return info
|
||||||
@@ -695,7 +695,8 @@ async def generate_showreel_images(
|
|||||||
"""Generate showreel video clips from a video file at specified timestamps.
|
"""Generate showreel video clips from a video file at specified timestamps.
|
||||||
|
|
||||||
Saves 10-second clips in a platform-native format, downscaled to max 720px width,
|
Saves 10-second clips in a platform-native format, downscaled to max 720px width,
|
||||||
preserving original color metadata. macOS emits MP4/H.265; other platforms emit WebM/AV1.
|
preserving original color metadata.
|
||||||
|
macOS emits MP4/H.265; other platforms emit WebM/AV1.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
video_path: Path to the video file (or index.bdmv for Blu-ray discs)
|
video_path: Path to the video file (or index.bdmv for Blu-ray discs)
|
||||||
@@ -842,7 +843,8 @@ async def generate_showreel_images(
|
|||||||
on_progress(reel_num)
|
on_progress(reel_num)
|
||||||
else:
|
else:
|
||||||
logger.error(
|
logger.error(
|
||||||
" Showreel reel%d failed for %s: output file was not created. cmd=%s",
|
" Showreel reel%d failed for %s: "
|
||||||
|
"output file was not created. cmd=%s",
|
||||||
reel_num,
|
reel_num,
|
||||||
title or "unknown",
|
title or "unknown",
|
||||||
shlex.join(cmd),
|
shlex.join(cmd),
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ async def tmdb_api_request(
|
|||||||
|
|
||||||
|
|
||||||
async def fetch_movie_details(movie_id: int) -> dict | None:
|
async def fetch_movie_details(movie_id: int) -> dict | None:
|
||||||
"""Fetch detailed movie info including credits, similar, keywords, and alternative titles."""
|
"""Fetch movie info including credits, similar, keywords, and alt titles."""
|
||||||
# Use append_to_response to get multiple data in one request
|
# Use append_to_response to get multiple data in one request
|
||||||
return await tmdb_api_request(
|
return await tmdb_api_request(
|
||||||
f"/movie/{movie_id}",
|
f"/movie/{movie_id}",
|
||||||
|
|||||||
@@ -578,7 +578,8 @@ def _start_gamepad_remote(
|
|||||||
|
|
||||||
|
|
||||||
def _setup_logging() -> Path:
|
def _setup_logging() -> Path:
|
||||||
"""Redirect stdout/stderr and configure logging to a log file in %APPDATA%/mediahive/.
|
"""Redirect stdout/stderr and configure logging to a file in
|
||||||
|
%APPDATA%/mediahive/.
|
||||||
|
|
||||||
In a PyInstaller --windowed build there is no console, so any print() or
|
In a PyInstaller --windowed build there is no console, so any print() or
|
||||||
unhandled exception traceback would be lost. This ensures everything ends
|
unhandled exception traceback would be lost. This ensures everything ends
|
||||||
|
|||||||
@@ -143,7 +143,9 @@ def find_dev_tool() -> list[str]:
|
|||||||
|
|
||||||
if name == "bun":
|
if name == "bun":
|
||||||
logger.warning(
|
logger.warning(
|
||||||
"Bun has a bug in WS proxying (https://github.com/oven-sh/bun/issues/9882). Consider using npm instead."
|
"Bun has a bug in WS proxying "
|
||||||
|
"(https://github.com/oven-sh/bun/issues/9882). "
|
||||||
|
"Consider using npm instead."
|
||||||
)
|
)
|
||||||
|
|
||||||
return [tool, *dev_args[name]]
|
return [tool, *dev_args[name]]
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
"""Utilities meant for devserver script, used only in source repository with dev deps."""
|
"""Utilities for the devserver script in the source repository.
|
||||||
|
|
||||||
|
Used only with development dependencies.
|
||||||
|
"""
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
import subprocess
|
import subprocess
|
||||||
@@ -14,7 +17,10 @@ from fastapi_vue.hostutil import parse_endpoint
|
|||||||
|
|
||||||
|
|
||||||
class ProcessGroup:
|
class ProcessGroup:
|
||||||
"""Manage async subprocesses with automatic cleanup, like TaskGroup for processes."""
|
"""Manage async subprocesses with automatic cleanup.
|
||||||
|
|
||||||
|
Acts like TaskGroup for processes.
|
||||||
|
"""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self._procs: list[asyncio.subprocess.Process] = []
|
self._procs: list[asyncio.subprocess.Process] = []
|
||||||
@@ -98,7 +104,10 @@ class ProcessGroup:
|
|||||||
|
|
||||||
|
|
||||||
async def check_ports_free(*urls: str) -> None:
|
async def check_ports_free(*urls: str) -> None:
|
||||||
"""Verify URLs are not responding (ports are free). Raise SystemExit if any respond."""
|
"""Verify URLs are not responding (ports are free).
|
||||||
|
|
||||||
|
Raise SystemExit if any endpoint responds.
|
||||||
|
"""
|
||||||
|
|
||||||
async def check(client: httpx.AsyncClient, url: str) -> None:
|
async def check(client: httpx.AsyncClient, url: str) -> None:
|
||||||
with suppress(httpx.RequestError):
|
with suppress(httpx.RequestError):
|
||||||
|
|||||||
+4
-2
@@ -3,7 +3,8 @@
|
|||||||
Usage:
|
Usage:
|
||||||
uv run scripts/winbuild.py
|
uv run scripts/winbuild.py
|
||||||
|
|
||||||
This runs in the project environment where dependencies are available via pyproject.toml.
|
This runs in the project environment where dependencies
|
||||||
|
are available via pyproject.toml.
|
||||||
|
|
||||||
This script:
|
This script:
|
||||||
1. Reads the version from pyproject.toml
|
1. Reads the version from pyproject.toml
|
||||||
@@ -248,7 +249,8 @@ def main() -> None:
|
|||||||
ensure_macos_icon()
|
ensure_macos_icon()
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
"Skipping ffmpeg bundling on this platform (uses system ffmpeg if available)."
|
"Skipping ffmpeg bundling on this platform "
|
||||||
|
"(uses system ffmpeg if available)."
|
||||||
)
|
)
|
||||||
build_wheel()
|
build_wheel()
|
||||||
build_executable()
|
build_executable()
|
||||||
|
|||||||
@@ -338,7 +338,8 @@ Examples:
|
|||||||
print(f"\nDry run: {added} would be added, {skipped} already loaded")
|
print(f"\nDry run: {added} would be added, {skipped} already loaded")
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"\nRtorrent results: {added} added, {skipped} skipped, {failed} failed"
|
f"\nRtorrent results: {added} added, "
|
||||||
|
f"{skipped} skipped, {failed} failed"
|
||||||
)
|
)
|
||||||
|
|
||||||
# Clean up unregistered torrents from rtorrent
|
# Clean up unregistered torrents from rtorrent
|
||||||
@@ -402,11 +403,13 @@ Examples:
|
|||||||
print()
|
print()
|
||||||
if dry_run:
|
if dry_run:
|
||||||
print(
|
print(
|
||||||
f"Dry run: {len(unregistered)} would be removed (rtorrent + .torrent + downloads)"
|
f"Dry run: {len(unregistered)} would be removed "
|
||||||
|
"(rtorrent + .torrent + downloads)"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print(
|
print(
|
||||||
f"Cleanup: {removed_from_rtorrent} from rtorrent, {removed_torrent_files} .torrents, {removed_downloads} downloads"
|
f"Cleanup: {removed_from_rtorrent} from rtorrent, "
|
||||||
|
f"{removed_torrent_files} .torrents, {removed_downloads} downloads"
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
print("No unregistered torrents found.")
|
print("No unregistered torrents found.")
|
||||||
|
|||||||
Reference in New Issue
Block a user