Compare commits
9 Commits
Author | SHA1 | Date |
---|---|---|
Oskar Winkels | 1982a45392 | |
Oskar Winkels | 3cfe42023b | |
Oskar Winkels | e043f475da | |
Oskar Winkels | aef2a1ae60 | |
Oskar Winkels | 215e848efd | |
Oskar Winkels | 01089aaf12 | |
Oskar Winkels | 9c0aa29bff | |
Oskar Winkels | 404a995e4f | |
Oskar Winkels | 062330bcaa |
|
@ -1,4 +1,5 @@
|
|||
import json
|
||||
import copy
|
||||
from slugify import slugify
|
||||
from threading import Thread, Event
|
||||
from datetime import datetime, timedelta
|
||||
|
@ -33,7 +34,7 @@ class Notifier(Thread):
|
|||
|
||||
ps = ps[0]
|
||||
|
||||
print("Sending notification", arrival, ps)
|
||||
print("Sending notification", arrival, ps, self.vapid_creds)
|
||||
|
||||
subscription = ps['sub']
|
||||
notification = {
|
||||
|
@ -41,13 +42,15 @@ class Notifier(Thread):
|
|||
'body': "You didn't sign out of ftracker yet",
|
||||
'arr': arrival
|
||||
}
|
||||
privkey = self.vapid_creds['private_key']
|
||||
claims = copy.copy(self.vapid_creds['claims'])
|
||||
|
||||
try:
|
||||
webpush(
|
||||
subscription,
|
||||
json.dumps(notification),
|
||||
vapid_private_key = self.vapid_creds['private_key'],
|
||||
vapid_claims = self.vapid_creds['claims']
|
||||
vapid_private_key = privkey,
|
||||
vapid_claims = claims
|
||||
)
|
||||
print("Notification sent")
|
||||
return None
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
'arrival': 'I have read and will adhere to the <a href="/guidelines" target="_blank">protection guidelines</a>',
|
||||
'departure': 'I have cleaned my workspace'
|
||||
}
|
||||
var testCheckBox = '<label class="checkbox"><input type="checkbox" name="tested" id="tested"><span>I have been tested negative for COVID in the last 24 hours</span></label>'
|
||||
var testCheckBox = '<label class="checkbox"><input type="checkbox" name="tested" id="tested"><span>I fullfill one of the <a href="https://www.bundesregierung.de/breg-de/aktuelles/bund-laender-beratung-corona-1949606">3G requirements</a></span></label>'
|
||||
var editTimeBox = '<label>Departure Date/Time:<input type="datetime-local" name="datetime" id="datetime" required></label>'
|
||||
function getParams() {
|
||||
var qparams = document.location.search.substr(1)
|
||||
|
@ -33,27 +33,26 @@
|
|||
</head>
|
||||
<body>
|
||||
<h1><script>
|
||||
document.write(qp.action ? (qp.action + "<br>Room " + qp.room) : 'FTracker<br>V1')
|
||||
document.write(qp.action ? (qp.action + "<br>Room " + qp.room) : 'FTracker<br>V1.1')
|
||||
</script></h1>
|
||||
<div id="startpage">
|
||||
This is a web app to track which people
|
||||
were in the same rooms at which times in order to backtrace
|
||||
potential viral infections.<br><br>
|
||||
If you've reached this page that either means your're
|
||||
testing things or something has gone quite wrong with the\
|
||||
URL.<br>
|
||||
This is a web app to track which people were in the same rooms at
|
||||
which times in order to backtrace potential viral infections.<br><br>
|
||||
If you've reached this page that either means your're testing
|
||||
things or something has gone quite wrong with the URL.<br>
|
||||
In the former case: Yay it works! In the latter you should
|
||||
probably contact an admin or a dev nearby :(<br><br>
|
||||
Here are a few links for testing:<br>
|
||||
<a href="/view">View Data</a>,
|
||||
<a href="/QRgen">Door Sign Generator</a>,
|
||||
<a href="/?arrival=42">Test Arrival</a>,
|
||||
<a href="/?departure=42">Test Departure</a><br><br>
|
||||
<a href="/?departure=42">Test Departure</a>,
|
||||
<a href="javascript:localStorage.removeItem('pushsub')">Reset Push Subscription</a><br><br>
|
||||
© 2020 made by <a target="_blank" href="mailto:o.winkels@fasttube.de">Oskar</a>
|
||||
for <a target="_blank" href="//fasttube.de">FaSTTUBe</a>.<br>
|
||||
For source code & licensing see <a href="//git.fasttube.de/FaSTTUBe/ftracker">git repo</a>
|
||||
</div>
|
||||
<form id="mainform" style="display: none">
|
||||
<form id="mainform" action="javascript:void(0);" style="display: none">
|
||||
<label>
|
||||
Full Name:<br>
|
||||
<input type="text" name="name" id="name" placeholder="John Doe" required>
|
||||
|
|
29
web/main.js
29
web/main.js
|
@ -6,10 +6,17 @@ if (qp.action) {
|
|||
mform.style.display = 'block'
|
||||
}
|
||||
|
||||
// Prefill the name field if it was successfully entered before
|
||||
// Get the name field if it was successfully entered before
|
||||
var savedName = localStorage.getItem('name')
|
||||
if (savedName && qp)
|
||||
if (qp && qp.name) {
|
||||
// Forced Admin checkout - prefill qp name and auto-agree
|
||||
document.getElementById('name').value = qp.name.replace(/-/g, ' ').toUpperCase();
|
||||
document.getElementById('agree').checked = true
|
||||
document.getElementById('agree').parentElement.style.display = 'none'
|
||||
} else if (savedName && qp) {
|
||||
// Prefill the client's locally saved name
|
||||
document.getElementById('name').value = savedName
|
||||
}
|
||||
|
||||
// 2nd script, server API communication
|
||||
var name, datetime, agreed, tested
|
||||
|
@ -43,7 +50,7 @@ function sendMainData() {
|
|||
'name': name,
|
||||
'arrival': datetime,
|
||||
'agreetoguidelines': agreed,
|
||||
'tested': tested
|
||||
'tested': tested // = 3G
|
||||
} :
|
||||
{
|
||||
'name': name,
|
||||
|
@ -104,7 +111,7 @@ function handleRequestSubmit(e, json) {
|
|||
var iso = new Date(input).toISOString()
|
||||
|
||||
if (e.srcElement.length > 1)
|
||||
tested = e.srcElement[1].checked
|
||||
tested = e.srcElement[1].checked // = 3G
|
||||
|
||||
// POST JSON. See docs/API.md
|
||||
var payload = (json.request == 'arrival') ?
|
||||
|
@ -113,7 +120,7 @@ function handleRequestSubmit(e, json) {
|
|||
'name': name,
|
||||
'arrival': iso,
|
||||
'agreetoguidelines': agreed,
|
||||
'tested': tested
|
||||
'tested': tested // = 3G
|
||||
} :
|
||||
{
|
||||
'name': name,
|
||||
|
@ -261,16 +268,18 @@ function registerPush(name, pushServerPublicKey) {
|
|||
}).then(function(subscription) {
|
||||
console.log("User is subscribed:", subscription);
|
||||
|
||||
var jsonSub = JSON.stringify({
|
||||
name: name,
|
||||
sub: subscription
|
||||
});
|
||||
|
||||
fetch('/pushsubscribe', {
|
||||
method: "POST",
|
||||
headers: {"Content-Type": "application/json"},
|
||||
body: JSON.stringify({
|
||||
name: name,
|
||||
sub: subscription
|
||||
})
|
||||
body: jsonSub
|
||||
}).then(function(res) {
|
||||
if (res.ok)
|
||||
localStorage.setItem('pushsub', subscription);
|
||||
localStorage.setItem('pushsub', jsonSub);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -67,9 +67,15 @@ main > section.times, #timeheader {
|
|||
font-weight: bold;
|
||||
-webkit-text-stroke: .4px #c50e1f;
|
||||
}
|
||||
.times span.tested { /* = 3G */
|
||||
background: rgb(0,136,0);
|
||||
}
|
||||
.times span.implausible {
|
||||
background: linear-gradient(to right, #c50e1f, rgba(197,14,31,0.2) 1000px);
|
||||
}
|
||||
.times span.implausible.tested { /* = 3G */
|
||||
background: linear-gradient(to right, rgb(0,136,0), rgba(0,136,0,0.2) 1000px);
|
||||
}
|
||||
.viewheader.row {
|
||||
height: 30px;
|
||||
background: #ddd !important;
|
||||
|
|
15
web/view.js
15
web/view.js
|
@ -88,6 +88,14 @@ function exportCSV() {
|
|||
|
||||
}
|
||||
|
||||
function offerUserCheckout(event) {
|
||||
|
||||
var name = event.target.getAttribute('data-name')
|
||||
var room = event.target.textContent
|
||||
window.open(`/?departure=${room}&edittime=1&name=${name}`, '_blank').focus();
|
||||
|
||||
}
|
||||
|
||||
function renderData() {
|
||||
|
||||
if (data == null) {
|
||||
|
@ -163,10 +171,13 @@ function renderData() {
|
|||
block.style.left = arr + 'px' // 1px/min
|
||||
block.style.width = Math.max(0,(dur-14)) + 'px' // 1px/min
|
||||
if (entry.tested)
|
||||
block.style.background = '#080'
|
||||
block.classList.add('tested') // = 3G
|
||||
|
||||
if (dur > 60 * 24)
|
||||
if (dur > 60 * 24) {
|
||||
block.classList.add('implausible')
|
||||
block.setAttribute('data-name', name)
|
||||
block.addEventListener('click', offerUserCheckout);
|
||||
}
|
||||
|
||||
row.appendChild(block)
|
||||
|
||||
|
|
Loading…
Reference in New Issue