Merge branch 'master' into dev-priv/master

This commit is contained in:
Jason Wen
2023-06-07 02:12:24 -04:00
11 changed files with 107 additions and 14 deletions
+5
View File
@@ -5,6 +5,7 @@
#include <string>
#include <QDebug>
#include <QFile>
#include "selfdrive/ui/qt/offroad/networking.h"
@@ -181,6 +182,10 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) {
setSpacing(50);
addItem(new LabelControl(tr("Dongle ID"), getDongleId().value_or(tr("N/A"))));
addItem(new LabelControl(tr("Serial"), params.get("HardwareSerial").c_str()));
QFile f("/data/otp/otp.conf");
f.open(QIODevice::ReadOnly | QIODevice::Text);
QString pin = f.readAll();
addItem(new LabelControl(tr("Dashcam Viewer PIN"), pin));
// offroad-only buttons
+52 -2
View File
@@ -1,18 +1,53 @@
#!/usr/bin/env python3
import os
import random
import secrets
import system.dashcamviewer.helpers as dashcam
from flask import Flask, render_template, Response, request, send_from_directory
from flask import Flask, render_template, Response, request, send_from_directory, session, redirect, url_for
from functools import wraps
from system.loggerd.config import ROOT as REALDATA
app = Flask(__name__)
def login_required(f):
@wraps(f)
def decorated_route(*args, **kwargs):
if not session.get("logged_in"):
return redirect(url_for("index_page"))
return f(*args, **kwargs)
return decorated_route
@app.route("/")
def index_page():
if session.get("logged_in"):
return redirect(url_for("home_page"))
return render_template("login.html")
@app.route("/login", methods=["POST"])
def login():
inputted_pin = request.form.get("pin")
with open(dashcam.PIN_PATH + "otp.conf", "r") as file:
correct_pin = file.read().strip()
if inputted_pin == correct_pin:
session["logged_in"] = True
return redirect(url_for("home_page"))
else:
error_message = "Incorrect PIN. Please try again."
return render_template("login.html", error=error_message)
@app.route("/index")
@login_required
def home_page():
return render_template("index.html")
@app.route("/footage/full/<cameratype>/<route>")
@login_required
def full(cameratype, route):
chunk_size = 1024 * 512 # 5KiB
file_name = cameratype + (".ts" if cameratype == "qcamera" else ".hevc")
@@ -26,6 +61,7 @@ def full(cameratype, route):
@app.route("/footage/<cameratype>/<segment>")
@login_required
def fcamera(cameratype, segment):
if not dashcam.is_valid_segment(segment):
return render_template("error.html", error="invalid segment")
@@ -34,6 +70,7 @@ def fcamera(cameratype, segment):
@app.route("/footage/<route>")
@login_required
def route(route):
if len(route) != 20:
return render_template("error.html", error="route not found")
@@ -54,11 +91,13 @@ def route(route):
@app.route("/footage")
@login_required
def footage():
return render_template("footage.html", rows=dashcam.all_routes())
@app.route("/screenrecords")
@login_required
def screenrecords():
rows = dashcam.all_screenrecords()
if not rows:
@@ -67,27 +106,38 @@ def screenrecords():
@app.route("/screenrecords/<clip>")
@login_required
def screenrecord(clip):
return render_template("screenrecords.html", rows=dashcam.all_screenrecords(), clip=clip)
@app.route("/screenrecords/play/pipe/<file>")
@login_required
def videoscreenrecord(file):
file_name = dashcam.SCREENRECORD_PATH + file
return Response(dashcam.ffplay_mp4_wrap_process_builder(file_name).stdout.read(), status=200, mimetype='video/mp4')
@app.route("/screenrecords/download/<clip>")
@login_required
def download_file(clip):
return send_from_directory(dashcam.SCREENRECORD_PATH, clip, as_attachment=True)
@app.route("/about")
@login_required
def about():
return render_template("about.html")
def main():
if not os.path.exists(dashcam.PIN_PATH):
os.makedirs(dashcam.PIN_PATH)
pin = str(random.randint(100000, 999999))
with open(dashcam.PIN_PATH + "otp.conf", "w") as file:
file.write(pin)
app.secret_key = secrets.token_hex(32)
app.run(host="0.0.0.0", port=5050)
+2 -1
View File
@@ -9,9 +9,10 @@ from tools.lib.route import SegmentName
# path to sunnypilot screen recordings
if PC:
SCREENRECORD_PATH = os.path.join(str(Path.home()), ".comma", "media", "0", "videos", "")
PIN_PATH = os.path.join(str(Path.home()), ".comma", "otp", "")
else:
SCREENRECORD_PATH = "/data/media/0/videos/"
PIN_PATH = "/data/otp/"
def all_screenrecords():
Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

+2 -2
View File
@@ -6,8 +6,8 @@
{% block main %}
<br>
<b>About</b>
<br><br>
<h1>About</h1>
<br>
<footer class="small text-center text-muted" style="word-wrap: break-word;">
Special thanks to:<br><br>
ntegan1<br>
+1 -1
View File
@@ -5,7 +5,7 @@
{% endblock %}
{% block main %}
<br> Oopss
<br> Oops
<br><br><br><br>
{{ error | safe }}
{% endblock %}
+2 -2
View File
@@ -6,8 +6,8 @@
{% block main %}
<br>
<b>Dashcam Routes</b>
<br><br>
<h1>Dashcam Routes</h1>
<br>
{% for row in rows %}
<a href="footage/{{ row }}">{{ row }}</a><br>
{% endfor %}
+2 -2
View File
@@ -6,8 +6,8 @@
{% block main %}
<br>
<b>Dashcam Viewer</b>
<br><br>
<h1>Dashcam Viewer</h1>
<br>
<a href='/footage'>View Dashcam Footage</a><br>
<br><a href='/screenrecords'>View Screen Recordings</a><br>
{% endblock %}
+37
View File
@@ -0,0 +1,37 @@
{% extends "layout.html" %}
{% block title %}
Login
{% endblock %}
{% block main %}
<div class="container">
<br>
<h1>Login</h1>
<br>
{% if error %}
<p class="error">{{ error }}</p>
{% endif %}
<form action="/login" method="POST">
<div class="form-group">
<label for="pin">Enter PIN below:</label>
<div class="input-container">
<input type="text" id="pin" name="pin" maxlength="6" minlength="6" required>
</div>
</div>
<br>
<div class="form-group submit-button">
<input type="submit" value="Submit">
</div>
<br>
<details>
<summary>Where to find the PIN?</summary>
<br>
<p>The PIN can be found on the comma device:</p>
<p><b>Settings ➡️ Device ➡️ Dashcam Viewer PIN</b></p>
<img src=" {{ url_for("static", filename="dashcam_pin.png")}}" alt="Dashcam Viewer Pin Location" style="max-width: 100%; height: auto;">
<br><br>
</details>
</form>
</div>
{% endblock %}
+2 -2
View File
@@ -8,8 +8,8 @@
{% block main %}
{% autoescape false %}
<br>
<b>Dashcam Segments (one per minute)</b>
<br><br>
<h1>Dashcam Segments (one per minute)</h1>
<br>
<video id="video" width="320" height="240" controls autoplay="autoplay" style="background:black">
</video>
<br><br>
@@ -6,8 +6,8 @@
{% block main %}
<br>
<b>Screen Recordings</b>
<br><br>
<h1>Screen Recordings</h1>
<br>
<video id="video" width="320" height="240" controls autoplay="autoplay" style="background:black">
</video>
<br><br>