mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-05-09 23:15:28 +03:00
Compare commits
10 Commits
7b6d0c5e42
...
573a5ede62
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
573a5ede62 | ||
|
|
a8b6ea5005 | ||
|
|
a89c7d8819 | ||
|
|
5d67ba76fd | ||
|
|
2c9a25e678 | ||
|
|
d8f599c377 | ||
|
|
5bd74666a7 | ||
|
|
c2b50af170 | ||
|
|
ca2242dac2 | ||
|
|
4cbe124b61 |
@ -1,18 +1,18 @@
|
||||
# Nvidia ONNX Runtime GPU Support
|
||||
--extra-index-url 'https://pypi.nvidia.com'
|
||||
cython==3.0.*; platform_machine == 'x86_64'
|
||||
nvidia-cuda-cupti-cu12==12.9.79; platform_machine == 'x86_64'
|
||||
nvidia-cublas-cu12==12.9.1.*; platform_machine == 'x86_64'
|
||||
nvidia-cudnn-cu12==9.19.0.*; platform_machine == 'x86_64'
|
||||
nvidia-cufft-cu12==11.4.1.*; platform_machine == 'x86_64'
|
||||
nvidia-curand-cu12==10.3.10.*; platform_machine == 'x86_64'
|
||||
nvidia-cuda-nvcc-cu12==12.9.86; platform_machine == 'x86_64'
|
||||
nvidia-cuda-nvrtc-cu12==12.9.86; platform_machine == 'x86_64'
|
||||
nvidia-cuda-runtime-cu12==12.9.79; platform_machine == 'x86_64'
|
||||
nvidia-cusolver-cu12==11.7.5.*; platform_machine == 'x86_64'
|
||||
nvidia-cusparse-cu12==12.5.10.*; platform_machine == 'x86_64'
|
||||
nvidia-nccl-cu12==2.29.7; platform_machine == 'x86_64'
|
||||
nvidia-nvjitlink-cu12==12.9.86; platform_machine == 'x86_64'
|
||||
nvidia-cuda-cupti-cu12==12.8.90; platform_machine == 'x86_64'
|
||||
nvidia-cublas-cu12==12.8.4.1; platform_machine == 'x86_64'
|
||||
nvidia-cudnn-cu12==9.8.0.87; platform_machine == 'x86_64'
|
||||
nvidia-cufft-cu12==11.3.3.83; platform_machine == 'x86_64'
|
||||
nvidia-curand-cu12==10.3.9.90; platform_machine == 'x86_64'
|
||||
nvidia-cuda-nvcc-cu12==12.8.93; platform_machine == 'x86_64'
|
||||
nvidia-cuda-nvrtc-cu12==12.8.93; platform_machine == 'x86_64'
|
||||
nvidia-cuda-runtime-cu12==12.8.90; platform_machine == 'x86_64'
|
||||
nvidia-cusolver-cu12==11.7.3.90; platform_machine == 'x86_64'
|
||||
nvidia-cusparse-cu12==12.5.8.93; platform_machine == 'x86_64'
|
||||
nvidia-nccl-cu12==2.26.2.post1; platform_machine == 'x86_64'
|
||||
nvidia-nvjitlink-cu12==12.8.93; platform_machine == 'x86_64'
|
||||
onnx==1.16.*; platform_machine == 'x86_64'
|
||||
onnxruntime-gpu==1.24.*; platform_machine == 'x86_64'
|
||||
protobuf==3.20.3; platform_machine == 'x86_64'
|
||||
|
||||
@ -162,6 +162,8 @@ Normal operation may leave small numbers of orphaned files until Frigate's sched
|
||||
|
||||
The Maintenance pane in the Frigate UI or an API endpoint `POST /api/media/sync` can be used to trigger a media sync. When using the API, a job ID is returned and the operation continues on the server. Status can be checked with the `/api/media/sync/status/{job_id}` endpoint.
|
||||
|
||||
Setting `verbose: true` writes a detailed report of every orphaned file and database entry to `/config/media_sync/<job_id>.txt`. For recordings, the report separates orphaned database entries (DB records whose files are missing from disk) from orphaned files (files on disk with no corresponding database record).
|
||||
|
||||
:::warning
|
||||
|
||||
This operation uses considerable CPU resources and includes a safety threshold that aborts if more than 50% of files would be deleted. Only run when necessary. If you set `force: true` the safety threshold will be bypassed; do not use `force` unless you are certain the deletions are intended.
|
||||
|
||||
@ -205,7 +205,7 @@ Inference is done with the `onnx` detector type. Speeds will vary greatly depend
|
||||
| GTX 1070 | s-320: 16 ms | | 320: 14 ms |
|
||||
| RTX 3050 | t-320: 8 ms s-320: 10 ms s-640: 28 ms | Nano-320: ~ 12 ms | 320: ~ 10 ms 640: ~ 16 ms |
|
||||
| RTX 3070 | t-320: 6 ms s-320: 8 ms s-640: 25 ms | Nano-320: ~ 9 ms | 320: ~ 8 ms 640: ~ 14 ms |
|
||||
| RTX 5060 Ti | t-320: 5 ms s-320: 7 ms s-640: 22 ms | Nano-320: ~ 6 ms | |
|
||||
| RTX 5060 Ti | t-320: 5 ms s-320: 7 ms s-640: 22 ms | Nano-320: ~ 4 ms | |
|
||||
| RTX A4000 | | | 320: ~ 15 ms |
|
||||
| Tesla P40 | | | 320: ~ 105 ms |
|
||||
|
||||
|
||||
6
docs/package-lock.json
generated
6
docs/package-lock.json
generated
@ -12313,9 +12313,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/immutable": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.4.tgz",
|
||||
"integrity": "sha512-p6u1bG3YSnINT5RQmx/yRZBpenIl30kVxkTLDyHLIMk0gict704Q9n+thfDI7lTRm9vXdDYutVzXhzcThxTnXA==",
|
||||
"version": "5.1.5",
|
||||
"resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.5.tgz",
|
||||
"integrity": "sha512-t7xcm2siw+hlUM68I+UEOK+z84RzmN59as9DZ7P1l0994DKUWV7UXBMQZVxaoMSRQ+PBZbHCOoBt7a2wxOMt+A==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/import-fresh": {
|
||||
|
||||
5
docs/static/frigate-api.yaml
vendored
5
docs/static/frigate-api.yaml
vendored
@ -6891,6 +6891,11 @@ components:
|
||||
title: Force
|
||||
description: "If True, bypass safety threshold checks"
|
||||
default: false
|
||||
verbose:
|
||||
type: boolean
|
||||
title: Verbose
|
||||
description: "If True, write full orphan file list to /config/media_sync/<job_id>.txt"
|
||||
default: false
|
||||
type: object
|
||||
title: MediaSyncBody
|
||||
MotionSearchMetricsResponse:
|
||||
|
||||
@ -5,6 +5,7 @@ import copy
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import platform
|
||||
import traceback
|
||||
import urllib
|
||||
from datetime import datetime, timedelta
|
||||
@ -246,19 +247,26 @@ def get_active_profile(request: Request):
|
||||
@router.get("/ffmpeg/presets", dependencies=[Depends(allow_any_authenticated())])
|
||||
def ffmpeg_presets():
|
||||
"""Return available ffmpeg preset keys for config UI usage."""
|
||||
machine = platform.machine().lower()
|
||||
is_arm64 = machine in ("aarch64", "arm64", "armv8", "armv7l")
|
||||
|
||||
if is_arm64:
|
||||
hwaccel_presets = [
|
||||
"preset-rpi-64-h264",
|
||||
"preset-rpi-64-h265",
|
||||
"preset-jetson-h264",
|
||||
"preset-jetson-h265",
|
||||
"preset-rkmpp",
|
||||
"preset-vaapi",
|
||||
]
|
||||
else:
|
||||
hwaccel_presets = [
|
||||
"preset-vaapi",
|
||||
"preset-intel-qsv-h264",
|
||||
"preset-intel-qsv-h265",
|
||||
"preset-nvidia",
|
||||
]
|
||||
|
||||
# Whitelist based on documented presets in ffmpeg_presets.md
|
||||
hwaccel_presets = [
|
||||
"preset-rpi-64-h264",
|
||||
"preset-rpi-64-h265",
|
||||
"preset-vaapi",
|
||||
"preset-intel-qsv-h264",
|
||||
"preset-intel-qsv-h265",
|
||||
"preset-nvidia",
|
||||
"preset-jetson-h264",
|
||||
"preset-jetson-h265",
|
||||
"preset-rkmpp",
|
||||
]
|
||||
input_presets = [
|
||||
"preset-http-jpeg-generic",
|
||||
"preset-http-mjpeg-generic",
|
||||
@ -864,7 +872,10 @@ def sync_media(body: MediaSyncBody = Body(...)):
|
||||
202 Accepted with job_id, or 409 Conflict if job already running.
|
||||
"""
|
||||
job_id = start_media_sync_job(
|
||||
dry_run=body.dry_run, media_types=body.media_types, force=body.force
|
||||
dry_run=body.dry_run,
|
||||
media_types=body.media_types,
|
||||
force=body.force,
|
||||
verbose=body.verbose,
|
||||
)
|
||||
|
||||
if job_id is None:
|
||||
|
||||
@ -45,3 +45,7 @@ class MediaSyncBody(BaseModel):
|
||||
force: bool = Field(
|
||||
default=False, description="If True, bypass safety threshold checks"
|
||||
)
|
||||
verbose: bool = Field(
|
||||
default=False,
|
||||
description="If True, write full orphan file list to disk",
|
||||
)
|
||||
|
||||
@ -1227,6 +1227,33 @@ async def event_clip(
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/review/{review_id}/clip.mp4",
|
||||
)
|
||||
async def review_clip(
|
||||
request: Request,
|
||||
review_id: str,
|
||||
padding: int = Query(0, description="Padding to apply to clip."),
|
||||
):
|
||||
try:
|
||||
review: ReviewSegment = ReviewSegment.get(ReviewSegment.id == review_id)
|
||||
except DoesNotExist:
|
||||
return JSONResponse(
|
||||
content={"success": False, "message": "Review not found"}, status_code=404
|
||||
)
|
||||
|
||||
await require_camera_access(review.camera, request=request)
|
||||
|
||||
end_ts = (
|
||||
datetime.now().timestamp()
|
||||
if review.end_time is None
|
||||
else review.end_time + padding
|
||||
)
|
||||
return await recording_clip(
|
||||
request, review.camera, review.start_time - padding, end_ts
|
||||
)
|
||||
|
||||
|
||||
@router.get(
|
||||
"/events/{event_id}/preview.gif",
|
||||
)
|
||||
@ -1337,9 +1364,9 @@ def preview_gif(
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
file_start = f"preview_{camera_name}"
|
||||
start_file = f"{file_start}-{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}-{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
file_start = f"preview_{camera_name}-"
|
||||
start_file = f"{file_start}{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
selected_previews = []
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
@ -1519,9 +1546,9 @@ def preview_mp4(
|
||||
status_code=404,
|
||||
)
|
||||
|
||||
file_start = f"preview_{camera_name}"
|
||||
start_file = f"{file_start}-{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}-{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
file_start = f"preview_{camera_name}-"
|
||||
start_file = f"{file_start}{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
selected_previews = []
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
|
||||
@ -145,9 +145,9 @@ def preview_hour(
|
||||
def get_preview_frames_from_cache(camera_name: str, start_ts: float, end_ts: float):
|
||||
"""Get list of cached preview frames"""
|
||||
preview_dir = os.path.join(CACHE_DIR, "preview_frames")
|
||||
file_start = f"preview_{camera_name}"
|
||||
start_file = f"{file_start}-{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}-{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
file_start = f"preview_{camera_name}-"
|
||||
start_file = f"{file_start}{start_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}{end_ts}.{PREVIEW_FRAME_TYPE}"
|
||||
selected_previews = []
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
|
||||
@ -324,9 +324,9 @@ class ReviewDescriptionProcessor(PostProcessorApi):
|
||||
end_time: float,
|
||||
) -> list[str]:
|
||||
preview_dir = os.path.join(CACHE_DIR, "preview_frames")
|
||||
file_start = f"preview_{camera}"
|
||||
start_file = f"{file_start}-{start_time}.webp"
|
||||
end_file = f"{file_start}-{end_time}.webp"
|
||||
file_start = f"preview_{camera}-"
|
||||
start_file = f"{file_start}{start_time}.webp"
|
||||
end_file = f"{file_start}{end_time}.webp"
|
||||
all_frames = []
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
|
||||
@ -54,12 +54,16 @@ class OllamaClient(GenAIClient):
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def _clean_schema_for_ollama(schema: dict) -> dict:
|
||||
def _clean_schema_for_ollama(schema: dict, *, _is_properties: bool = False) -> dict:
|
||||
"""Strip Pydantic metadata from a JSON schema for Ollama compatibility.
|
||||
|
||||
Ollama's grammar-based constrained generation works best with minimal
|
||||
schemas. Pydantic adds title/description/constraint fields that can
|
||||
cause the grammar generator to silently skip required fields.
|
||||
|
||||
Keys inside a ``properties`` dict are actual field names and must never
|
||||
be stripped, even if they collide with a metadata key name (e.g. a
|
||||
model field called ``title``).
|
||||
"""
|
||||
STRIP_KEYS = {
|
||||
"title",
|
||||
@ -71,10 +75,12 @@ class OllamaClient(GenAIClient):
|
||||
}
|
||||
result = {}
|
||||
for key, value in schema.items():
|
||||
if key in STRIP_KEYS:
|
||||
if not _is_properties and key in STRIP_KEYS:
|
||||
continue
|
||||
if isinstance(value, dict):
|
||||
result[key] = OllamaClient._clean_schema_for_ollama(value)
|
||||
result[key] = OllamaClient._clean_schema_for_ollama(
|
||||
value, _is_properties=(key == "properties")
|
||||
)
|
||||
elif isinstance(value, list):
|
||||
result[key] = [
|
||||
OllamaClient._clean_schema_for_ollama(item)
|
||||
|
||||
@ -1,13 +1,14 @@
|
||||
"""Media sync job management with background execution."""
|
||||
|
||||
import logging
|
||||
import os
|
||||
import threading
|
||||
from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Optional
|
||||
|
||||
from frigate.comms.inter_process import InterProcessRequestor
|
||||
from frigate.const import UPDATE_JOB_STATE
|
||||
from frigate.const import CONFIG_DIR, UPDATE_JOB_STATE
|
||||
from frigate.jobs.job import Job
|
||||
from frigate.jobs.manager import (
|
||||
get_current_job,
|
||||
@ -16,7 +17,7 @@ from frigate.jobs.manager import (
|
||||
set_current_job,
|
||||
)
|
||||
from frigate.types import JobStatusTypesEnum
|
||||
from frigate.util.media import sync_all_media
|
||||
from frigate.util.media import sync_all_media, write_orphan_report
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -29,6 +30,7 @@ class MediaSyncJob(Job):
|
||||
dry_run: bool = False
|
||||
media_types: list[str] = field(default_factory=lambda: ["all"])
|
||||
force: bool = False
|
||||
verbose: bool = False
|
||||
|
||||
|
||||
class MediaSyncRunner(threading.Thread):
|
||||
@ -61,6 +63,21 @@ class MediaSyncRunner(threading.Thread):
|
||||
force=self.job.force,
|
||||
)
|
||||
|
||||
# Write verbose report if requested
|
||||
if self.job.verbose:
|
||||
report_dir = os.path.join(CONFIG_DIR, "media_sync")
|
||||
os.makedirs(report_dir, exist_ok=True)
|
||||
report_path = os.path.join(report_dir, f"{self.job.id}.txt")
|
||||
write_orphan_report(
|
||||
results,
|
||||
report_path,
|
||||
job_id=self.job.id,
|
||||
dry_run=self.job.dry_run,
|
||||
)
|
||||
logger.info(
|
||||
"Media sync verbose orphan report written to %s", report_path
|
||||
)
|
||||
|
||||
# Store results and mark as complete
|
||||
self.job.results = results.to_dict()
|
||||
self.job.status = JobStatusTypesEnum.success
|
||||
@ -95,6 +112,7 @@ def start_media_sync_job(
|
||||
dry_run: bool = False,
|
||||
media_types: Optional[list[str]] = None,
|
||||
force: bool = False,
|
||||
verbose: bool = False,
|
||||
) -> Optional[str]:
|
||||
"""Start a new media sync job if none is currently running.
|
||||
|
||||
@ -113,6 +131,7 @@ def start_media_sync_job(
|
||||
dry_run=dry_run,
|
||||
media_types=media_types or ["all"],
|
||||
force=force,
|
||||
verbose=verbose,
|
||||
)
|
||||
|
||||
logger.debug(f"Creating new media sync job: {job.id}")
|
||||
|
||||
@ -266,8 +266,8 @@ class PreviewRecorder:
|
||||
.timestamp()
|
||||
)
|
||||
|
||||
file_start = f"preview_{config.name}"
|
||||
start_file = f"{file_start}-{start_ts}.webp"
|
||||
file_start = f"preview_{config.name}-"
|
||||
start_file = f"{file_start}{start_ts}.webp"
|
||||
|
||||
for file in sorted(os.listdir(os.path.join(CACHE_DIR, FOLDER_PREVIEW_FRAMES))):
|
||||
if not file.startswith(file_start):
|
||||
|
||||
@ -156,9 +156,9 @@ class RecordingExporter(threading.Thread):
|
||||
else:
|
||||
# need to generate from existing images
|
||||
preview_dir = os.path.join(CACHE_DIR, "preview_frames")
|
||||
file_start = f"preview_{self.camera}"
|
||||
start_file = f"{file_start}-{self.start_time}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}-{self.end_time}.{PREVIEW_FRAME_TYPE}"
|
||||
file_start = f"preview_{self.camera}-"
|
||||
start_file = f"{file_start}{self.start_time}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}{self.end_time}.{PREVIEW_FRAME_TYPE}"
|
||||
selected_preview = None
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
@ -264,9 +264,9 @@ class RecordingExporter(threading.Thread):
|
||||
if is_current_hour(self.start_time):
|
||||
# get list of current preview frames
|
||||
preview_dir = os.path.join(CACHE_DIR, "preview_frames")
|
||||
file_start = f"preview_{self.camera}"
|
||||
start_file = f"{file_start}-{self.start_time}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}-{self.end_time}.{PREVIEW_FRAME_TYPE}"
|
||||
file_start = f"preview_{self.camera}-"
|
||||
start_file = f"{file_start}{self.start_time}.{PREVIEW_FRAME_TYPE}"
|
||||
end_file = f"{file_start}{self.end_time}.{PREVIEW_FRAME_TYPE}"
|
||||
|
||||
for file in sorted(os.listdir(preview_dir)):
|
||||
if not file.startswith(file_start):
|
||||
|
||||
@ -49,6 +49,7 @@ class SyncResult:
|
||||
orphans_found: int = 0
|
||||
orphans_deleted: int = 0
|
||||
orphan_paths: list[str] = field(default_factory=list)
|
||||
orphan_db_paths: list[str] = field(default_factory=list)
|
||||
aborted: bool = False
|
||||
error: str | None = None
|
||||
|
||||
@ -132,7 +133,7 @@ def sync_recordings(
|
||||
)
|
||||
|
||||
result.orphans_found += len(recordings_to_delete)
|
||||
result.orphan_paths.extend(
|
||||
result.orphan_db_paths.extend(
|
||||
[
|
||||
recording["path"]
|
||||
for recording in recordings_to_delete
|
||||
@ -773,6 +774,61 @@ class MediaSyncResults:
|
||||
return results
|
||||
|
||||
|
||||
def write_orphan_report(
|
||||
results: "MediaSyncResults",
|
||||
path: str,
|
||||
job_id: str = "",
|
||||
dry_run: bool = False,
|
||||
) -> None:
|
||||
"""Write a verbose orphan report file listing all orphan paths by media type.
|
||||
|
||||
Args:
|
||||
results: The completed MediaSyncResults.
|
||||
path: File path to write the report to.
|
||||
job_id: Job ID for the report header.
|
||||
dry_run: Whether the sync was a dry run, for the report header.
|
||||
"""
|
||||
try:
|
||||
with open(path, "w") as f:
|
||||
f.write("# Media Sync Orphan Report\n")
|
||||
f.write(f"# Job: {job_id}\n")
|
||||
f.write(
|
||||
f"# Date: {datetime.datetime.now().astimezone(datetime.timezone.utc).isoformat()}\n"
|
||||
)
|
||||
f.write(f"# Mode: dry_run={dry_run}\n\n")
|
||||
|
||||
for name, result in [
|
||||
("recordings", results.recordings),
|
||||
("event_snapshots", results.event_snapshots),
|
||||
("event_thumbnails", results.event_thumbnails),
|
||||
("review_thumbnails", results.review_thumbnails),
|
||||
("previews", results.previews),
|
||||
("exports", results.exports),
|
||||
]:
|
||||
if result is None:
|
||||
continue
|
||||
|
||||
if result.orphan_db_paths:
|
||||
f.write(
|
||||
f"## {name} - orphaned db entries ({len(result.orphan_db_paths)})\n"
|
||||
)
|
||||
for orphan_path in result.orphan_db_paths:
|
||||
f.write(f"{orphan_path}\n")
|
||||
f.write("\n")
|
||||
|
||||
if result.orphan_paths:
|
||||
f.write(
|
||||
f"## {name} - orphaned files ({len(result.orphan_paths)})\n"
|
||||
)
|
||||
for orphan_path in result.orphan_paths:
|
||||
f.write(f"{orphan_path}\n")
|
||||
f.write("\n")
|
||||
|
||||
logger.debug("Wrote verbose orphan report to %s", path)
|
||||
except OSError as e:
|
||||
logger.error("Failed to write orphan report to %s: %s", path, e)
|
||||
|
||||
|
||||
def sync_all_media(
|
||||
dry_run: bool = False, media_types: list[str] = ["all"], force: bool = False
|
||||
) -> MediaSyncResults:
|
||||
|
||||
@ -117,12 +117,16 @@ def get_cpu_stats() -> dict[str, dict]:
|
||||
"mem": str(system_mem.percent),
|
||||
}
|
||||
|
||||
keywords = ["ffmpeg", "go2rtc", "frigate.", "python3"]
|
||||
for process in psutil.process_iter(["pid", "name", "cpu_percent", "cmdline"]):
|
||||
pid = str(process.info["pid"])
|
||||
try:
|
||||
cpu_percent = process.info["cpu_percent"]
|
||||
cmdline = " ".join(process.info["cmdline"]).rstrip()
|
||||
|
||||
if not any(keyword in cmdline for keyword in keywords):
|
||||
continue
|
||||
|
||||
with open(f"/proc/{pid}/stat", "r") as f:
|
||||
stats = f.readline().split()
|
||||
utime = int(stats[13])
|
||||
|
||||
319
web/package-lock.json
generated
319
web/package-lock.json
generated
@ -4776,9 +4776,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@rjsf/validator-ajv8/node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
@ -4798,9 +4798,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.9.tgz",
|
||||
"integrity": "sha512-qZdlImWXur0CFakn2BJ2znJOdqYZKiedEPEVNTBrpfPjc/YuTGcaYZcdmNFTkUj3DU0ZM/AElcM8Ybww3xVLzA==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.0.tgz",
|
||||
"integrity": "sha512-WOhNW9K8bR3kf4zLxbfg6Pxu2ybOUbB2AjMDHSQx86LIF4rH4Ft7vmMwNt0loO0eonglSNy4cpD3MKXXKQu0/A==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -4812,9 +4812,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm64": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.9.tgz",
|
||||
"integrity": "sha512-4KW7P53h6HtJf5Y608T1ISKvNIYLWRKMvfnG0c44M6In4DQVU58HZFEVhWINDZKp7FZps98G3gxwC1sb0wXUUg==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.0.tgz",
|
||||
"integrity": "sha512-u6JHLll5QKRvjciE78bQXDmqRqNs5M/3GVqZeMwvmjaNODJih/WIrJlFVEihvV0MiYFmd+ZyPr9wxOVbPAG2Iw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4826,9 +4826,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-arm64": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.9.tgz",
|
||||
"integrity": "sha512-0CY3/K54slrzLDjOA7TOjN1NuLKERBgk9nY5V34mhmuu673YNb+7ghaDUs6N0ujXR7fz5XaS5Aa6d2TNxZd0OQ==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.0.tgz",
|
||||
"integrity": "sha512-qEF7CsKKzSRc20Ciu2Zw1wRrBz4g56F7r/vRwY430UPp/nt1x21Q/fpJ9N5l47WWvJlkNCPJz3QRVw008fi7yA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4840,9 +4840,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-darwin-x64": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.9.tgz",
|
||||
"integrity": "sha512-eOojSEAi/acnsJVYRxnMkPFqcxSMFfrw7r2iD9Q32SGkb/Q9FpUY1UlAu1DH9T7j++gZ0lHjnm4OyH2vCI7l7Q==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.0.tgz",
|
||||
"integrity": "sha512-WADYozJ4QCnXCH4wPB+3FuGmDPoFseVCUrANmA5LWwGmC6FL14BWC7pcq+FstOZv3baGX65tZ378uT6WG8ynTw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -4854,9 +4854,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-arm64": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.9.tgz",
|
||||
"integrity": "sha512-2lzjQPJbN5UnHm7bHIUKFMulGTQwdvOkouJDpPysJS+QFBGDJqcfh+CxxtG23Ik/9tEvnebQiylYoazFMAgrYw==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.0.tgz",
|
||||
"integrity": "sha512-6b8wGHJlDrGeSE3aH5mGNHBjA0TTkxdoNHik5EkvPHCt351XnigA4pS7Wsj/Eo9Y8RBU6f35cjN9SYmCFBtzxw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4868,9 +4868,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-freebsd-x64": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.9.tgz",
|
||||
"integrity": "sha512-SLl0hi2Ah2H7xQYd6Qaiu01kFPzQ+hqvdYSoOtHYg/zCIFs6t8sV95kaoqjzjFwuYQLtOI0RZre/Ke0nPaQV+g==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.0.tgz",
|
||||
"integrity": "sha512-h25Ga0t4jaylMB8M/JKAyrvvfxGRjnPQIR8lnCayyzEjEOx2EJIlIiMbhpWxDRKGKF8jbNH01NnN663dH638mA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -4882,9 +4882,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-gnueabihf": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.9.tgz",
|
||||
"integrity": "sha512-88I+D3TeKItrw+Y/2ud4Tw0+3CxQ2kLgu3QvrogZ0OfkmX/DEppehus7L3TS2Q4lpB+hYyxhkQiYPJ6Mf5/dPg==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.0.tgz",
|
||||
"integrity": "sha512-RzeBwv0B3qtVBWtcuABtSuCzToo2IEAIQrcyB/b2zMvBWVbjo8bZDjACUpnaafaxhTw2W+imQbP2BD1usasK4g==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -4896,9 +4896,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm-musleabihf": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.9.tgz",
|
||||
"integrity": "sha512-3qyfWljSFHi9zH0KgtEPG4cBXHDFhwD8kwg6xLfHQ0IWuH9crp005GfoUUh/6w9/FWGBwEHg3lxK1iHRN1MFlA==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.0.tgz",
|
||||
"integrity": "sha512-Sf7zusNI2CIU1HLzuu9Tc5YGAHEZs5Lu7N1ssJG4Tkw6e0MEsN7NdjUDDfGNHy2IU+ENyWT+L2obgWiguWibWQ==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
@ -4910,9 +4910,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-6TZjPHjKZUQKmVKMUowF3ewHxctrRR09eYyvT5eFv8w/fXarEra83A2mHTVJLA5xU91aCNOUnM+DWFMSbQ0Nxw==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-DX2x7CMcrJzsE91q7/O02IJQ5/aLkVtYFryqCjduJhUfGKG6yJV8hxaw8pZa93lLEpPTP/ohdN4wFz7yp/ry9A==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4924,9 +4924,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-arm64-musl": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.9.tgz",
|
||||
"integrity": "sha512-LD2fytxZJZ6xzOKnMbIpgzFOuIKlxVOpiMAXawsAZ2mHBPEYOnLRK5TTEsID6z4eM23DuO88X0Tq1mErHMVq0A==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.0.tgz",
|
||||
"integrity": "sha512-09EL+yFVbJZlhcQfShpswwRZ0Rg+z/CsSELFCnPt3iK+iqwGsI4zht3secj5vLEs957QvFFXnzAT0FFPIxSrkQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -4937,10 +4937,10 @@
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-loongarch64-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-dRAgTfDsn0TE0HI6cmo13hemKpVHOEyeciGtvlBTkpx/F65kTvShtY/EVyZEIfxFkV5JJTuQ9tP5HGBS0hfxIg==",
|
||||
"node_modules/@rollup/rollup-linux-loong64-gnu": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-i9IcCMPr3EXm8EQg5jnja0Zyc1iFxJjZWlb4wr7U2Wx/GrddOuEafxRdMPRYVaXjgbhvqalp6np07hN1w9kAKw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
@ -4951,10 +4951,38 @@
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-PHcNOAEhkoMSQtMf+rJofwisZqaU8iQ8EaSps58f5HYll9EAY5BSErCZ8qBDMVbq88h4UxaNPlbrKqfWP8RfJA==",
|
||||
"node_modules/@rollup/rollup-linux-loong64-musl": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.0.tgz",
|
||||
"integrity": "sha512-DGzdJK9kyJ+B78MCkWeGnpXJ91tK/iKA6HwHxF4TAlPIY7GXEvMe8hBFRgdrR9Ly4qebR/7gfUs9y2IoaVEyog==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-gnu": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-RwpnLsqC8qbS8z1H1AxBA1H6qknR4YpPR9w2XX0vo2Sz10miu57PkNcnHVaZkbqyw/kUWfKMI73jhmfi9BRMUQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-ppc64-musl": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.0.tgz",
|
||||
"integrity": "sha512-Z8pPf54Ly3aqtdWC3G4rFigZgNvd+qJlOE52fmko3KST9SoGfAdSRCwyoyG05q1HrrAblLbk1/PSIV+80/pxLg==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
@ -4966,9 +4994,23 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-Z2i0Uy5G96KBYKjeQFKbbsB54xFOL5/y1P5wNBsbXB8yE+At3oh0DVMjQVzCJRJSfReiB2tX8T6HUFZ2k8iaKg==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-3a3qQustp3COCGvnP4SvrMHnPQ9d1vzCakQVRTliaz8cIp/wULGjiGpbcqrkv0WrHTEp8bQD/B3HBjzujVWLOA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-riscv64-musl": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.0.tgz",
|
||||
"integrity": "sha512-pjZDsVH/1VsghMJ2/kAaxt6dL0psT6ZexQVrijczOf+PeP2BUqTHYejk3l6TlPRydggINOeNRhvpLa0AYpCWSQ==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
@ -4980,9 +5022,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-s390x-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-U+5SwTMoeYXoDzJX5dhDTxRltSrIax8KWwfaaYcynuJw8mT33W7oOgz0a+AaXtGuvhzTr2tVKh5UO8GVANTxyQ==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-3ObQs0BhvPgiUVZrN7gqCSvmFuMWvWvsjG5ayJ3Lraqv+2KhOsp+pUbigqbeWqueGIsnn+09HBw27rJ+gYK4VQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
@ -4994,9 +5036,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-gnu": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.9.tgz",
|
||||
"integrity": "sha512-FwBHNSOjUTQLP4MG7y6rR6qbGw4MFeQnIBrMe161QGaQoBQLqSUEKlHIiVgF3g/mb3lxlxzJOpIBhaP+C+KP2A==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-EtylprDtQPdS5rXvAayrNDYoJhIz1/vzN2fEubo3yLE7tfAw+948dO0g4M0vkTVFhKojnF+n6C8bDNe+gDRdTg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -5008,9 +5050,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-linux-x64-musl": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.9.tgz",
|
||||
"integrity": "sha512-cYRpV4650z2I3/s6+5/LONkjIz8MBeqrk+vPXV10ORBnshpn8S32bPqQ2Utv39jCiDcO2eJTuSlPXpnvmaIgRA==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.0.tgz",
|
||||
"integrity": "sha512-k09oiRCi/bHU9UVFqD17r3eJR9bn03TyKraCrlz5ULFJGdJGi7VOmm9jl44vOJvRJ6P7WuBi/s2A97LxxHGIdw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -5021,10 +5063,38 @@
|
||||
"linux"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openbsd-x64": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.0.tgz",
|
||||
"integrity": "sha512-1o/0/pIhozoSaDJoDcec+IVLbnRtQmHwPV730+AOD29lHEEo4F5BEUB24H0OBdhbBBDwIOSuf7vgg0Ywxdfiiw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-openharmony-arm64": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.0.tgz",
|
||||
"integrity": "sha512-pESDkos/PDzYwtyzB5p/UoNU/8fJo68vcXM9ZW2V0kjYayj1KaaUfi1NmTUTUpMn4UhU4gTuK8gIaFO4UGuMbA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openharmony"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-arm64-msvc": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.9.tgz",
|
||||
"integrity": "sha512-z4mQK9dAN6byRA/vsSgQiPeuO63wdiDxZ9yg9iyX2QTzKuQM7T4xlBoeUP/J8uiFkqxkcWndWi+W7bXdPbt27Q==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.0.tgz",
|
||||
"integrity": "sha512-hj1wFStD7B1YBeYmvY+lWXZ7ey73YGPcViMShYikqKT1GtstIKQAtfUI6yrzPjAy/O7pO0VLXGmUVWXQMaYgTQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
@ -5036,9 +5106,9 @@
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-ia32-msvc": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.9.tgz",
|
||||
"integrity": "sha512-KB48mPtaoHy1AwDNkAJfHXvHp24H0ryZog28spEs0V48l3H1fr4i37tiyHsgKZJnCmvxsbATdZGBpbmxTE3a9w==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.0.tgz",
|
||||
"integrity": "sha512-SyaIPFoxmUPlNDq5EHkTbiKzmSEmq/gOYFI/3HHJ8iS/v1mbugVa7dXUzcJGQfoytp9DJFLhHH4U3/eTy2Bq4w==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
@ -5049,10 +5119,24 @@
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-gnu": {
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.0.tgz",
|
||||
"integrity": "sha512-RdcryEfzZr+lAr5kRm2ucN9aVlCCa2QNq4hXelZxb8GG0NJSazq44Z3PCCc8wISRuCVnGs0lQJVX5Vp6fKA+IA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
]
|
||||
},
|
||||
"node_modules/@rollup/rollup-win32-x64-msvc": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.9.tgz",
|
||||
"integrity": "sha512-AyleYRPU7+rgkMWbEh71fQlrzRfeP6SyMnRf9XX4fCdDPAJumdSBqYEcWPMzVQ4ScAl7E4oFfK0GUVn77xSwbw==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.0.tgz",
|
||||
"integrity": "sha512-PrsWNQ8BuE00O3Xsx3ALh2Df8fAj9+cvvX9AIA6o4KpATR98c9mud4XtDWVvsEuyia5U4tVSTKygawyJkjm60w==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
@ -5387,9 +5471,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree-jsx": {
|
||||
@ -5677,9 +5761,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5687,13 +5771,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
|
||||
"version": "9.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz",
|
||||
"integrity": "sha512-KqWh+VchfxcMNRAJjj2tnsSJdNbHsVgnkBhTNrW7AjVo6OvLtxw8zfT9oLw1JSohlFzJ8jCoTgaoXvJ+kHt6fw==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
@ -5928,9 +6012,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "6.12.6",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
|
||||
"integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
|
||||
"version": "6.14.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
|
||||
"integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -5962,9 +6046,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/ajv-formats/node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
"integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
|
||||
"version": "8.18.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
|
||||
"integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"fast-deep-equal": "^3.1.3",
|
||||
@ -7779,9 +7863,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.3.1",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz",
|
||||
"integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==",
|
||||
"version": "3.4.2",
|
||||
"resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
|
||||
"integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@ -10410,9 +10494,10 @@
|
||||
}
|
||||
},
|
||||
"node_modules/minimatch": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"version": "3.1.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
|
||||
"integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@ -12222,13 +12307,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "4.34.9",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.9.tgz",
|
||||
"integrity": "sha512-nF5XYqWWp9hx/LrpC8sZvvvmq0TeTjQgaZHYmAgwysT9nh8sWnZhBnM8ZyVbbJFIQBLwHDNoMqsBZBbUo4U8sQ==",
|
||||
"version": "4.60.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.0.tgz",
|
||||
"integrity": "sha512-yqjxruMGBQJ2gG4HtjZtAfXArHomazDHoFwFFmZZl0r7Pdo7qCIXKqKHZc8yeoMgzJJ+pO6pEEHa+V7uzWlrAQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "1.0.6"
|
||||
"@types/estree": "1.0.8"
|
||||
},
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
@ -12238,25 +12323,31 @@
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"@rollup/rollup-android-arm-eabi": "4.34.9",
|
||||
"@rollup/rollup-android-arm64": "4.34.9",
|
||||
"@rollup/rollup-darwin-arm64": "4.34.9",
|
||||
"@rollup/rollup-darwin-x64": "4.34.9",
|
||||
"@rollup/rollup-freebsd-arm64": "4.34.9",
|
||||
"@rollup/rollup-freebsd-x64": "4.34.9",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.34.9",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.34.9",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.34.9",
|
||||
"@rollup/rollup-linux-loongarch64-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-powerpc64le-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.34.9",
|
||||
"@rollup/rollup-linux-x64-musl": "4.34.9",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.34.9",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.34.9",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.34.9",
|
||||
"@rollup/rollup-android-arm-eabi": "4.60.0",
|
||||
"@rollup/rollup-android-arm64": "4.60.0",
|
||||
"@rollup/rollup-darwin-arm64": "4.60.0",
|
||||
"@rollup/rollup-darwin-x64": "4.60.0",
|
||||
"@rollup/rollup-freebsd-arm64": "4.60.0",
|
||||
"@rollup/rollup-freebsd-x64": "4.60.0",
|
||||
"@rollup/rollup-linux-arm-gnueabihf": "4.60.0",
|
||||
"@rollup/rollup-linux-arm-musleabihf": "4.60.0",
|
||||
"@rollup/rollup-linux-arm64-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-arm64-musl": "4.60.0",
|
||||
"@rollup/rollup-linux-loong64-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-loong64-musl": "4.60.0",
|
||||
"@rollup/rollup-linux-ppc64-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-ppc64-musl": "4.60.0",
|
||||
"@rollup/rollup-linux-riscv64-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-riscv64-musl": "4.60.0",
|
||||
"@rollup/rollup-linux-s390x-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-x64-gnu": "4.60.0",
|
||||
"@rollup/rollup-linux-x64-musl": "4.60.0",
|
||||
"@rollup/rollup-openbsd-x64": "4.60.0",
|
||||
"@rollup/rollup-openharmony-arm64": "4.60.0",
|
||||
"@rollup/rollup-win32-arm64-msvc": "4.60.0",
|
||||
"@rollup/rollup-win32-ia32-msvc": "4.60.0",
|
||||
"@rollup/rollup-win32-x64-gnu": "4.60.0",
|
||||
"@rollup/rollup-win32-x64-msvc": "4.60.0",
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
@ -13033,9 +13124,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||
"integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
@ -13064,13 +13155,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/test-exclude/node_modules/minimatch": {
|
||||
"version": "9.0.5",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
|
||||
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
|
||||
"version": "9.0.9",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
|
||||
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
"brace-expansion": "^2.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16 || 14 >=14.17"
|
||||
|
||||
@ -1253,6 +1253,8 @@
|
||||
"dryRunDisabled": "Files will be deleted",
|
||||
"force": "Force",
|
||||
"forceDesc": "Bypass safety threshold and complete sync even if more than 50% of the files would be deleted.",
|
||||
"verbose": "Verbose",
|
||||
"verboseDesc": "Write a full list of orphaned files to disk for review.",
|
||||
"running": "Sync Running...",
|
||||
"start": "Start Sync",
|
||||
"inProgress": "Sync is in progress. This page is disabled.",
|
||||
@ -1330,7 +1332,18 @@
|
||||
"none": "None",
|
||||
"useGlobalSetting": "Inherit from global setting",
|
||||
"selectPreset": "Select preset",
|
||||
"manualPlaceholder": "Enter FFmpeg arguments"
|
||||
"manualPlaceholder": "Enter FFmpeg arguments",
|
||||
"presetLabels": {
|
||||
"preset-rpi-64-h264": "Raspberry Pi (H.264)",
|
||||
"preset-rpi-64-h265": "Raspberry Pi (H.265)",
|
||||
"preset-vaapi": "VAAPI (Intel/AMD GPU)",
|
||||
"preset-intel-qsv-h264": "Intel QuickSync (H.264)",
|
||||
"preset-intel-qsv-h265": "Intel QuickSync (H.265)",
|
||||
"preset-nvidia": "NVIDIA GPU",
|
||||
"preset-jetson-h264": "NVIDIA Jetson (H.264)",
|
||||
"preset-jetson-h265": "NVIDIA Jetson (H.265)",
|
||||
"preset-rkmpp": "Rockchip RKMPP"
|
||||
}
|
||||
},
|
||||
"cameraInputs": {
|
||||
"itemTitle": "Stream {{index}}"
|
||||
|
||||
@ -405,7 +405,10 @@ export function FfmpegArgsWidget(props: WidgetProps) {
|
||||
<SelectContent>
|
||||
{presetOptions.map((preset) => (
|
||||
<SelectItem key={preset} value={preset}>
|
||||
{preset}
|
||||
{t(`configForm.ffmpegArgs.presetLabels.${preset}`, {
|
||||
ns: "views/settings",
|
||||
defaultValue: preset,
|
||||
})}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
|
||||
@ -22,6 +22,7 @@ export default function MediaSyncSettingsView() {
|
||||
]);
|
||||
const [dryRun, setDryRun] = useState(true);
|
||||
const [force, setForce] = useState(false);
|
||||
const [verbose, setVerbose] = useState(false);
|
||||
const [isSubmitting, setIsSubmitting] = useState(false);
|
||||
|
||||
const MEDIA_TYPES = [
|
||||
@ -67,6 +68,7 @@ export default function MediaSyncSettingsView() {
|
||||
dry_run: dryRun,
|
||||
media_types: selectedMediaTypes,
|
||||
force: force,
|
||||
verbose: verbose,
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
@ -94,7 +96,7 @@ export default function MediaSyncSettingsView() {
|
||||
} finally {
|
||||
setIsSubmitting(false);
|
||||
}
|
||||
}, [selectedMediaTypes, dryRun, force, t]);
|
||||
}, [selectedMediaTypes, dryRun, force, verbose, t]);
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -205,6 +207,25 @@ export default function MediaSyncSettingsView() {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col">
|
||||
<div className="flex flex-row items-center justify-between gap-4">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="verbose" className="cursor-pointer">
|
||||
{t("maintenance.sync.verbose")}
|
||||
</Label>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
{t("maintenance.sync.verboseDesc")}
|
||||
</p>
|
||||
</div>
|
||||
<Switch
|
||||
id="verbose"
|
||||
checked={verbose}
|
||||
onCheckedChange={setVerbose}
|
||||
disabled={isJobRunning}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Action Buttons */}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user