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:
uvjustin 2022-08-25 20:32:30 +08:00 committed by GitHub
parent 0d6dd1ed0f
commit 8c45dab9b8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 22 additions and 18 deletions

View File

@ -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;

View File

@ -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>")

View File

@ -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>