initial code
This commit is contained in:
parent
6e3d9c5dea
commit
8238810a12
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
__pycache__/
|
||||
*.pyc
|
||||
base.json
|
27
app.py
Normal file
27
app.py
Normal file
@ -0,0 +1,27 @@
|
||||
from flask import Flask, request, render_template
|
||||
import json
|
||||
|
||||
from appendbase import Appendbase
|
||||
|
||||
submit_secret = "test"
|
||||
app = Flask(__name__)
|
||||
base = Appendbase.from_file("base.json")
|
||||
|
||||
@app.route('/<secret>/submit', methods=[ "POST"])
|
||||
def handle_new_data(secret):
|
||||
if secret != submit_secret:
|
||||
return ''
|
||||
print(request.form)
|
||||
base.append(request.form.to_dict())
|
||||
base.to_file("base.json")
|
||||
|
||||
return "accepted"
|
||||
|
||||
@app.route('/<secret>/view')
|
||||
def return_monitor_page(secret):
|
||||
if secret != submit_secret:
|
||||
return ''
|
||||
|
||||
data_js = "let location_data = " + json.dumps(base.stuff) + ";"
|
||||
|
||||
return render_template("base.html", data_js=data_js)
|
28
appendbase.py
Normal file
28
appendbase.py
Normal file
@ -0,0 +1,28 @@
|
||||
# an append-only database made with json
|
||||
# is this google hyper-scaleable? no
|
||||
# do i care? no
|
||||
|
||||
import json
|
||||
from typing import Any
|
||||
|
||||
class Appendbase:
|
||||
stuff: list[Any]
|
||||
|
||||
def __init__(self, stuff: list[Any]):
|
||||
self.stuff = stuff
|
||||
|
||||
def append(self, thing: Any):
|
||||
self.stuff.append(thing)
|
||||
|
||||
@classmethod
|
||||
def from_file(cls, filename: str):
|
||||
try:
|
||||
with open(filename, "r") as file:
|
||||
stuff = json.loads(file.read())
|
||||
except FileNotFoundError:
|
||||
return cls([])
|
||||
return cls(stuff)
|
||||
|
||||
def to_file(self, filename: str):
|
||||
with open(filename, "w+") as file:
|
||||
file.write(json.dumps(self.stuff))
|
8
shell.nix
Normal file
8
shell.nix
Normal file
@ -0,0 +1,8 @@
|
||||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
pkgs.python3
|
||||
pkgs.python311Packages.flask
|
||||
];
|
||||
}
|
||||
|
107
templates/base.html
Normal file
107
templates/base.html
Normal file
@ -0,0 +1,107 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
|
||||
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY="
|
||||
crossorigin=""/>
|
||||
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
|
||||
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo="
|
||||
crossorigin=""></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
</head>
|
||||
<body>
|
||||
<div id="container">
|
||||
<div id="map"></div>
|
||||
<div id="bottomcontent">
|
||||
<p>
|
||||
Latest point uploaded <span id="latest_upload"></span> seconds ago at battery level <span id="battery_level"></span>.
|
||||
This page was last updated <span id="seconds">0</span> <span id="second_pluralization">seconds</span> ago.
|
||||
<a href="#" id="update">Click here to update it.</a>
|
||||
<span id="autoupdate">(<a href="./view?autoupdate=true">Or, update automatically.</a>)</span>
|
||||
<details>
|
||||
<summary>How do uploads work?</summary>
|
||||
|
||||
The phone uploads a point when both conditions are satisifed:
|
||||
|
||||
<ul>
|
||||
<li>The phone moves a meaningful distance, and</li>
|
||||
<li>The phone is able to reach this server (i.e. has a working Internet connection)</li>
|
||||
</ul>
|
||||
</details>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
display: block;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
#container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
#bottomcontent {
|
||||
flex: 0 0 auto;
|
||||
padding: 0.5rem;
|
||||
border-top: 10px dotted black;
|
||||
}
|
||||
#map {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<script>
|
||||
{{ data_js|safe }}
|
||||
|
||||
var map = L.map('map');
|
||||
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
||||
maxZoom: 19,
|
||||
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
||||
}).addTo(map);
|
||||
|
||||
var points = [];
|
||||
location_data.forEach((item) => {
|
||||
points.push([item.latitude, item.longitude]);
|
||||
});
|
||||
var polyline = L.polyline(points, {color: 'red'}).addTo(map);
|
||||
|
||||
var seconds_location = document.getElementById("latest_upload");
|
||||
var battery_level = document.getElementById("battery_level");
|
||||
var autoupdate = document.getElementById("autoupdate");
|
||||
var update_seconds = document.getElementById("seconds");
|
||||
var update_seconds_plural = document.getElementById("second_pluralization");
|
||||
var update_page = document.getElementById("update");
|
||||
|
||||
let latest = location_data[location_data.length - 1];
|
||||
var now = Math.floor(Date.now() / 1000);
|
||||
var diff = now - Number(latest.timestamp);
|
||||
|
||||
L.marker([latest.latitude, latest.longitude]).addTo(map);
|
||||
map.setView([latest.latitude, latest.longitude], 17)
|
||||
|
||||
seconds_location.innerHTML = diff;
|
||||
setInterval(function () {
|
||||
seconds_location.innerHTML = Number(seconds_location.innerHTML) + 1;
|
||||
update_seconds.innerHTML = Number(update_seconds.innerHTML) + 1;
|
||||
if(update_seconds.innerHTML == "1") {
|
||||
update_seconds_plural.innerHTML = "second";
|
||||
} else {
|
||||
update_seconds_plural.innerHTML = "seconds";
|
||||
}
|
||||
if(Number(update_seconds.innerHTML) > 15) {
|
||||
if(window.location.href.endsWith("autoupdate=true")) window.location.reload();
|
||||
}
|
||||
}, 1000);
|
||||
if(window.location.href.endsWith("autoupdate=true")) autoupdate.style.display = "none";
|
||||
battery_level.innerHTML = latest.batterylevel;
|
||||
update_page.onclick = (e) => {
|
||||
window.location.reload();
|
||||
};
|
||||
</script>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user