mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-02-19 01:17:06 +03:00
Fix build error and add delete func
This commit is contained in:
parent
b650721c38
commit
6295b4d810
@ -243,3 +243,45 @@ def get_lpr_debug(request: Request):
|
|||||||
lpr_images[image] = image
|
lpr_images[image] = image
|
||||||
|
|
||||||
return lpr_images
|
return lpr_images
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/lpr/debug/delete")
|
||||||
|
def delete_lpr_debug(request: Request, body: dict = None):
|
||||||
|
"""Delete LPR debug images."""
|
||||||
|
if not request.app.frigate_config.lpr.enabled:
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=400,
|
||||||
|
content={"message": "LPR is not enabled.", "success": False},
|
||||||
|
)
|
||||||
|
|
||||||
|
json: dict[str, any] = body or {}
|
||||||
|
list_of_ids = json.get("ids", [])
|
||||||
|
|
||||||
|
if not list_of_ids:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"success": False, "message": "Not a valid list of ids"},
|
||||||
|
status_code=404,
|
||||||
|
)
|
||||||
|
|
||||||
|
lpr_dir = os.path.join(CLIPS_DIR, "lpr")
|
||||||
|
if not os.path.exists(lpr_dir):
|
||||||
|
return JSONResponse(
|
||||||
|
status_code=404,
|
||||||
|
content={"message": "LPR debug directory not found", "success": False},
|
||||||
|
)
|
||||||
|
|
||||||
|
try:
|
||||||
|
for image_id in list_of_ids:
|
||||||
|
image_path = os.path.join(lpr_dir, sanitize_filename(image_id))
|
||||||
|
if os.path.exists(image_path):
|
||||||
|
os.remove(image_path)
|
||||||
|
|
||||||
|
return JSONResponse(
|
||||||
|
content={"success": True, "message": "Successfully deleted LPR debug images."},
|
||||||
|
status_code=200,
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
return JSONResponse(
|
||||||
|
content={"success": False, "message": f"Failed to delete LPR debug images: {str(e)}"},
|
||||||
|
status_code=500,
|
||||||
|
)
|
||||||
|
|||||||
@ -3,11 +3,15 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
|
|||||||
import LPRDetailDialog from "@/components/overlay/dialog/LPRDetailDialog";
|
import LPRDetailDialog from "@/components/overlay/dialog/LPRDetailDialog";
|
||||||
import { ScrollArea } from "@/components/ui/scroll-area";
|
import { ScrollArea } from "@/components/ui/scroll-area";
|
||||||
import { Toaster } from "@/components/ui/sonner";
|
import { Toaster } from "@/components/ui/sonner";
|
||||||
|
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||||
import { FrigateConfig } from "@/types/frigateConfig";
|
import { FrigateConfig } from "@/types/frigateConfig";
|
||||||
import { Event } from "@/types/event";
|
import { Event } from "@/types/event";
|
||||||
import { useEffect, useMemo, useState } from "react";
|
import { useCallback, useEffect, useMemo, useState } from "react";
|
||||||
import useSWR from "swr";
|
import useSWR from "swr";
|
||||||
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
import { useFormattedTimestamp } from "@/hooks/use-date-utils";
|
||||||
|
import { LuTrash2 } from "react-icons/lu";
|
||||||
|
import axios from "axios";
|
||||||
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export default function LPRDebug() {
|
export default function LPRDebug() {
|
||||||
const { data: config } = useSWR<FrigateConfig>("config");
|
const { data: config } = useSWR<FrigateConfig>("config");
|
||||||
@ -41,7 +45,7 @@ export default function LPRDebug() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="scrollbar-container flex flex-wrap gap-2 overflow-y-scroll">
|
<div className="scrollbar-container flex flex-wrap gap-2 overflow-y-scroll">
|
||||||
{lprAttempts.map((attempt: string) => (
|
{lprAttempts.map((attempt: string) => (
|
||||||
<LPRAttempt key={attempt} attempt={attempt} config={config} />
|
<LPRAttempt key={attempt} attempt={attempt} config={config} onRefresh={refreshLPR} />
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -51,9 +55,10 @@ export default function LPRDebug() {
|
|||||||
type LPRAttemptProps = {
|
type LPRAttemptProps = {
|
||||||
attempt: string;
|
attempt: string;
|
||||||
config: FrigateConfig;
|
config: FrigateConfig;
|
||||||
|
onRefresh: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
function LPRAttempt({ attempt, config }: LPRAttemptProps) {
|
function LPRAttempt({ attempt, config, onRefresh }: LPRAttemptProps) {
|
||||||
const [showDialog, setShowDialog] = useState(false);
|
const [showDialog, setShowDialog] = useState(false);
|
||||||
const data = useMemo(() => {
|
const data = useMemo(() => {
|
||||||
const parts = attempt.split("-");
|
const parts = attempt.split("-");
|
||||||
@ -74,6 +79,30 @@ function LPRAttempt({ attempt, config }: LPRAttemptProps) {
|
|||||||
config?.ui.timezone,
|
config?.ui.timezone,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const onDelete = useCallback(() => {
|
||||||
|
axios
|
||||||
|
.post(`/lpr/debug/delete`, { ids: [attempt] })
|
||||||
|
.then((resp) => {
|
||||||
|
if (resp.status == 200) {
|
||||||
|
toast.success(`Successfully deleted LPR debug image.`, {
|
||||||
|
position: "top-center",
|
||||||
|
});
|
||||||
|
onRefresh();
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
if (error.response?.data?.message) {
|
||||||
|
toast.error(`Failed to delete: ${error.response.data.message}`, {
|
||||||
|
position: "top-center",
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
toast.error(`Failed to delete: ${error.message}`, {
|
||||||
|
position: "top-center",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [attempt, onRefresh]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<LPRDetailDialog
|
<LPRDetailDialog
|
||||||
@ -84,26 +113,37 @@ function LPRAttempt({ attempt, config }: LPRAttemptProps) {
|
|||||||
lprImage={attempt}
|
lprImage={attempt}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div className="relative flex flex-col rounded-lg">
|
||||||
className="relative flex cursor-pointer flex-col rounded-lg hover:opacity-90"
|
<div
|
||||||
onClick={() => setShowDialog(true)}
|
className="w-full cursor-pointer overflow-hidden rounded-t-lg border border-t-0 *:text-card-foreground hover:opacity-90"
|
||||||
>
|
onClick={() => setShowDialog(true)}
|
||||||
<div className="w-full overflow-hidden rounded-t-lg border border-t-0 *:text-card-foreground">
|
>
|
||||||
<img className="h-40" src={`${baseUrl}clips/lpr/${attempt}`} />
|
<img className="h-40" src={`${baseUrl}clips/lpr/${attempt}`} />
|
||||||
</div>
|
</div>
|
||||||
<div className="rounded-b-lg bg-card p-2">
|
<div className="rounded-b-lg bg-card p-2">
|
||||||
<div className="flex w-full flex-col gap-2">
|
<div className="flex w-full flex-row items-center justify-between gap-2">
|
||||||
<div className="flex flex-col items-start text-xs text-primary-variant">
|
<div className="flex flex-col items-start text-xs text-primary-variant">
|
||||||
<div className="capitalize">{data.plate}</div>
|
<div className="capitalize">{data.plate}</div>
|
||||||
<div className="text-success">
|
<div className="text-success">
|
||||||
{Number.parseFloat(data.score) * 100}%
|
{Number.parseFloat(data.score) * 100}%
|
||||||
</div>
|
</div>
|
||||||
|
{event && (
|
||||||
|
<div className="text-xs text-muted-foreground">
|
||||||
|
{timestamp}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row items-start justify-end gap-5 md:gap-4">
|
||||||
|
<Tooltip>
|
||||||
|
<TooltipTrigger>
|
||||||
|
<LuTrash2
|
||||||
|
className="size-5 cursor-pointer text-primary-variant hover:text-primary"
|
||||||
|
onClick={onDelete}
|
||||||
|
/>
|
||||||
|
</TooltipTrigger>
|
||||||
|
<TooltipContent>Delete Image</TooltipContent>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
{event && (
|
|
||||||
<div className="text-xs text-muted-foreground">
|
|
||||||
{timestamp}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -469,4 +469,9 @@ export interface FrigateConfig {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ui: UiConfig;
|
ui: UiConfig;
|
||||||
|
|
||||||
|
lpr: {
|
||||||
|
enabled: boolean;
|
||||||
|
threshold: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user