mirror of
https://github.com/blakeblackshear/frigate.git
synced 2024-11-21 19:07:46 +01:00
Handle spaces in labels (#3679)
* Unquote label in flask routes Encode label in Camera.jsx * Don't use preprocessor * Update nginx location for cacheable images
This commit is contained in:
parent
0d6dd1ed0f
commit
8c45dab9b8
@ -172,10 +172,11 @@ http {
|
|||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
}
|
}
|
||||||
|
|
||||||
location ~* /api/(.*\.(jpg|jpeg|png)$) {
|
location ~* /api/.*\.(jpg|jpeg|png)$ {
|
||||||
add_header 'Access-Control-Allow-Origin' '*';
|
add_header 'Access-Control-Allow-Origin' '*';
|
||||||
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
|
add_header 'Access-Control-Allow-Methods' 'GET, POST, PUT, DELETE, OPTIONS';
|
||||||
proxy_pass http://frigate_api/$1$is_args$args;
|
rewrite ^/api/(.*)$ $1 break;
|
||||||
|
proxy_pass http://frigate_api;
|
||||||
proxy_pass_request_headers on;
|
proxy_pass_request_headers on;
|
||||||
proxy_set_header Host $host;
|
proxy_set_header Host $host;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
@ -8,6 +8,7 @@ import subprocess as sp
|
|||||||
import time
|
import time
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
from urllib.parse import unquote
|
||||||
|
|
||||||
import cv2
|
import cv2
|
||||||
|
|
||||||
@ -341,6 +342,7 @@ def event_thumbnail(id, max_cache_age=2592000):
|
|||||||
@bp.route("/<camera_name>/<label>/best.jpg")
|
@bp.route("/<camera_name>/<label>/best.jpg")
|
||||||
@bp.route("/<camera_name>/<label>/thumbnail.jpg")
|
@bp.route("/<camera_name>/<label>/thumbnail.jpg")
|
||||||
def label_thumbnail(camera_name, label):
|
def label_thumbnail(camera_name, label):
|
||||||
|
label = unquote(label)
|
||||||
if label == "any":
|
if label == "any":
|
||||||
event_query = (
|
event_query = (
|
||||||
Event.select()
|
Event.select()
|
||||||
@ -424,6 +426,7 @@ def event_snapshot(id):
|
|||||||
|
|
||||||
@bp.route("/<camera_name>/<label>/snapshot.jpg")
|
@bp.route("/<camera_name>/<label>/snapshot.jpg")
|
||||||
def label_snapshot(camera_name, label):
|
def label_snapshot(camera_name, label):
|
||||||
|
label = unquote(label)
|
||||||
if label == "any":
|
if label == "any":
|
||||||
event_query = (
|
event_query = (
|
||||||
Event.select()
|
Event.select()
|
||||||
@ -491,7 +494,7 @@ def event_clip(id):
|
|||||||
def events():
|
def events():
|
||||||
limit = request.args.get("limit", 100)
|
limit = request.args.get("limit", 100)
|
||||||
camera = request.args.get("camera", "all")
|
camera = request.args.get("camera", "all")
|
||||||
label = request.args.get("label", "all")
|
label = unquote(request.args.get("label", "all"))
|
||||||
sub_label = request.args.get("sub_label", "all")
|
sub_label = request.args.get("sub_label", "all")
|
||||||
zone = request.args.get("zone", "all")
|
zone = request.args.get("zone", "all")
|
||||||
after = request.args.get("after", type=float)
|
after = request.args.get("after", type=float)
|
||||||
@ -753,9 +756,9 @@ def recordings(camera_name):
|
|||||||
return jsonify([e for e in recordings.dicts()])
|
return jsonify([e for e in recordings.dicts()])
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/<camera>/start/<int:start_ts>/end/<int:end_ts>/clip.mp4")
|
@bp.route("/<camera_name>/start/<int:start_ts>/end/<int:end_ts>/clip.mp4")
|
||||||
@bp.route("/<camera>/start/<float:start_ts>/end/<float:end_ts>/clip.mp4")
|
@bp.route("/<camera_name>/start/<float:start_ts>/end/<float:end_ts>/clip.mp4")
|
||||||
def recording_clip(camera, start_ts, end_ts):
|
def recording_clip(camera_name, start_ts, end_ts):
|
||||||
download = request.args.get("download", type=bool)
|
download = request.args.get("download", type=bool)
|
||||||
|
|
||||||
recordings = (
|
recordings = (
|
||||||
@ -765,7 +768,7 @@ def recording_clip(camera, start_ts, end_ts):
|
|||||||
| (Recordings.end_time.between(start_ts, end_ts))
|
| (Recordings.end_time.between(start_ts, end_ts))
|
||||||
| ((start_ts > Recordings.start_time) & (end_ts < Recordings.end_time))
|
| ((start_ts > Recordings.start_time) & (end_ts < Recordings.end_time))
|
||||||
)
|
)
|
||||||
.where(Recordings.camera == camera)
|
.where(Recordings.camera == camera_name)
|
||||||
.order_by(Recordings.start_time.asc())
|
.order_by(Recordings.start_time.asc())
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -780,7 +783,7 @@ def recording_clip(camera, start_ts, end_ts):
|
|||||||
if clip.end_time > end_ts:
|
if clip.end_time > end_ts:
|
||||||
playlist_lines.append(f"outpoint {int(end_ts - clip.start_time)}")
|
playlist_lines.append(f"outpoint {int(end_ts - clip.start_time)}")
|
||||||
|
|
||||||
file_name = f"clip_{camera}_{start_ts}-{end_ts}.mp4"
|
file_name = f"clip_{camera_name}_{start_ts}-{end_ts}.mp4"
|
||||||
path = f"/tmp/cache/{file_name}"
|
path = f"/tmp/cache/{file_name}"
|
||||||
|
|
||||||
ffmpeg_cmd = [
|
ffmpeg_cmd = [
|
||||||
@ -809,7 +812,7 @@ def recording_clip(camera, start_ts, end_ts):
|
|||||||
)
|
)
|
||||||
if p.returncode != 0:
|
if p.returncode != 0:
|
||||||
logger.error(p.stderr)
|
logger.error(p.stderr)
|
||||||
return f"Could not create clip from recordings for {camera}.", 500
|
return f"Could not create clip from recordings for {camera_name}.", 500
|
||||||
|
|
||||||
response = make_response()
|
response = make_response()
|
||||||
response.headers["Content-Description"] = "File Transfer"
|
response.headers["Content-Description"] = "File Transfer"
|
||||||
@ -825,9 +828,9 @@ def recording_clip(camera, start_ts, end_ts):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/vod/<camera>/start/<int:start_ts>/end/<int:end_ts>")
|
@bp.route("/vod/<camera_name>/start/<int:start_ts>/end/<int:end_ts>")
|
||||||
@bp.route("/vod/<camera>/start/<float:start_ts>/end/<float:end_ts>")
|
@bp.route("/vod/<camera_name>/start/<float:start_ts>/end/<float:end_ts>")
|
||||||
def vod_ts(camera, start_ts, end_ts):
|
def vod_ts(camera_name, start_ts, end_ts):
|
||||||
recordings = (
|
recordings = (
|
||||||
Recordings.select()
|
Recordings.select()
|
||||||
.where(
|
.where(
|
||||||
@ -835,7 +838,7 @@ def vod_ts(camera, start_ts, end_ts):
|
|||||||
| Recordings.end_time.between(start_ts, end_ts)
|
| Recordings.end_time.between(start_ts, end_ts)
|
||||||
| ((start_ts > Recordings.start_time) & (end_ts < Recordings.end_time))
|
| ((start_ts > Recordings.start_time) & (end_ts < Recordings.end_time))
|
||||||
)
|
)
|
||||||
.where(Recordings.camera == camera)
|
.where(Recordings.camera == camera_name)
|
||||||
.order_by(Recordings.start_time.asc())
|
.order_by(Recordings.start_time.asc())
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -876,14 +879,14 @@ def vod_ts(camera, start_ts, end_ts):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/vod/<year_month>/<day>/<hour>/<camera>")
|
@bp.route("/vod/<year_month>/<day>/<hour>/<camera_name>")
|
||||||
def vod_hour(year_month, day, hour, camera):
|
def vod_hour(year_month, day, hour, camera_name):
|
||||||
start_date = datetime.strptime(f"{year_month}-{day} {hour}", "%Y-%m-%d %H")
|
start_date = datetime.strptime(f"{year_month}-{day} {hour}", "%Y-%m-%d %H")
|
||||||
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
|
end_date = start_date + timedelta(hours=1) - timedelta(milliseconds=1)
|
||||||
start_ts = start_date.timestamp()
|
start_ts = start_date.timestamp()
|
||||||
end_ts = end_date.timestamp()
|
end_ts = end_date.timestamp()
|
||||||
|
|
||||||
return vod_ts(camera, start_ts, end_ts)
|
return vod_ts(camera_name, start_ts, end_ts)
|
||||||
|
|
||||||
|
|
||||||
@bp.route("/vod/event/<id>")
|
@bp.route("/vod/event/<id>")
|
||||||
|
@ -133,8 +133,8 @@ export default function Camera({ camera }) {
|
|||||||
className="mb-4 mr-4"
|
className="mb-4 mr-4"
|
||||||
key={objectType}
|
key={objectType}
|
||||||
header={objectType}
|
header={objectType}
|
||||||
href={`/events?camera=${camera}&label=${objectType}`}
|
href={`/events?camera=${camera}&label=${encodeURIComponent(objectType)}`}
|
||||||
media={<img src={`${apiHost}/api/${camera}/${objectType}/thumbnail.jpg`} />}
|
media={<img src={`${apiHost}/api/${camera}/${encodeURIComponent(objectType)}/thumbnail.jpg`} />}
|
||||||
/>
|
/>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user