mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-05 17:45:40 +08:00
Merge branch 'master' into dev-priv/master
This commit is contained in:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
|
||||
@@ -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 |
@@ -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>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<br> Oopss
|
||||
<br> Oops
|
||||
<br><br><br><br>
|
||||
{{ error | safe }}
|
||||
{% endblock %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
|
||||
@@ -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 %}
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user