Added departure filter
This commit is contained in:
parent
3fce82e971
commit
ee7bf407b2
|
@ -79,6 +79,15 @@ class API:
|
|||
d.set_stop(request.forms.get('stop_id'))
|
||||
return {'success': True}
|
||||
|
||||
@route('/admin/devices/change_filter', method='POST')
|
||||
def admin_devices_change_filter():
|
||||
if main.config["admin"]["secret"] != request.forms.get('secret'):
|
||||
return {'error': "unauthorized"}
|
||||
for i, d in enumerate(main.controller.devices):
|
||||
if str(i) == request.forms.get('index'):
|
||||
d.set_filter(request.forms.get('filter'))
|
||||
return {'success': True}
|
||||
|
||||
@route('/admin/devices/toggle', method='POST')
|
||||
def admin_devices_toggle():
|
||||
if main.config["admin"]["secret"] != request.forms.get('secret'):
|
||||
|
|
|
@ -2,6 +2,38 @@ from math import floor
|
|||
from datetime import datetime
|
||||
from dateutil import parser
|
||||
|
||||
class Filter:
|
||||
|
||||
storage = dict()
|
||||
|
||||
@staticmethod
|
||||
def get(name: str):
|
||||
if name in Filter.storage:
|
||||
return Filter.storage[name]
|
||||
return None
|
||||
|
||||
def __init__(self, name: str, filters):
|
||||
if "lines" not in filters:
|
||||
filters["lines"] = None
|
||||
if "types" not in filters:
|
||||
filters["types"] = None
|
||||
if "destinations" not in filters:
|
||||
filters["destinations"] = None
|
||||
self.name = name
|
||||
self.lines = filters["lines"]
|
||||
self.types = filters["types"]
|
||||
self.destinations = filters["destinations"]
|
||||
Filter.storage[name] = self
|
||||
|
||||
def filter(self, departures):
|
||||
results = []
|
||||
for d in departures:
|
||||
if not self.types or d.type in self.types:
|
||||
if not self.lines or d.line in self.lines:
|
||||
if not self.destinations or d.last_stop in self.destinations:
|
||||
results.append(d)
|
||||
return results
|
||||
|
||||
class Departure:
|
||||
|
||||
id_pool = {}
|
||||
|
|
|
@ -7,7 +7,7 @@ from base64 import b64encode
|
|||
from datetime import datetime
|
||||
from random import randint, shuffle
|
||||
from time import sleep
|
||||
from departures import Departure
|
||||
from departures import Departure, Filter
|
||||
|
||||
import urllib3
|
||||
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
|
||||
|
@ -34,22 +34,23 @@ class LoraController:
|
|||
data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json()
|
||||
self.token = data["token"]
|
||||
|
||||
def new(self, id: int, stop_id: str, enabled: bool):
|
||||
self.devices.append(LoraDevice(self, id, stop_id, enabled))
|
||||
def new(self, id: int, stop_id: str, enabled: bool, filter: Filter):
|
||||
self.devices.append(LoraDevice(self, id, stop_id, enabled, filter))
|
||||
|
||||
def json(self):
|
||||
resp = []
|
||||
for d in self.devices:
|
||||
resp.append({'id': f"{d.id:0>16x}", 'stop_id': d.stop_id, 'enabled': d.enabled})
|
||||
resp.append({'id': f"{d.id:0>16x}", 'stop_id': d.stop_id, 'enabled': d.enabled, 'filter': d.filter.name if d.filter else None})
|
||||
return resp
|
||||
|
||||
class LoraDevice:
|
||||
|
||||
def __init__(self, controller: LoraController, deveui: int, stop_id: str, enabled: bool):
|
||||
def __init__(self, controller: LoraController, deveui: int, stop_id: str, enabled: bool, filter: Filter):
|
||||
self.controller = controller
|
||||
self.id = deveui
|
||||
self.stop_id = stop_id
|
||||
self.enabled = enabled
|
||||
self.filter = filter
|
||||
self.message_pool = []
|
||||
self.thread = None
|
||||
self.port = 1
|
||||
|
@ -59,11 +60,17 @@ class LoraDevice:
|
|||
self.clear()
|
||||
self.stop_id = stop_id
|
||||
|
||||
def set_filter(self, name: str):
|
||||
self.filter = Filter.get(name)
|
||||
|
||||
def get_updated_departures(self):
|
||||
if not self.enabled:
|
||||
return
|
||||
self.send_time()
|
||||
for d in Departure.get(self.stop_id):
|
||||
departures = Departure.get(self.stop_id)
|
||||
if self.filter:
|
||||
departures = self.filter.filter(departures)
|
||||
for d in departures:
|
||||
if self.id not in d.updated or d.updated[self.id] > 0:
|
||||
self.send(d.data)
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from departures import Departure
|
||||
from departures import Departure, Filter
|
||||
from requests.structures import CaseInsensitiveDict
|
||||
import json
|
||||
import requests
|
||||
|
@ -24,11 +24,15 @@ class Main:
|
|||
self.controller = lora_controller
|
||||
self.api = API(self)
|
||||
lora_controller.generate_token()
|
||||
for name in self.config["filters"]:
|
||||
Filter(name, self.config["filters"][name])
|
||||
for d in self.config["devices"]:
|
||||
if "stop_id" in d:
|
||||
if "enabled" not in d:
|
||||
d["enabled"] = True
|
||||
lora_controller.new(d["id"], str(d["stop_id"]), d["enabled"])
|
||||
if "filter" not in d:
|
||||
d["filter"] = None
|
||||
lora_controller.new(d["id"], str(d["stop_id"]), d["enabled"], Filter.get(d["filter"]))
|
||||
self.thread = threading.Thread(target=self.update_loop)
|
||||
self.thread.start()
|
||||
|
||||
|
|
|
@ -3,11 +3,13 @@
|
|||
|
||||
.cards .header {padding: 15px; display: grid; grid-template-columns: 1fr max-content; user-select: none;}
|
||||
.cards .first {font-weight: 700;}
|
||||
.cards .settings {padding: 15px; border-top: 1px solid var(--border-color2); background: var(--alt-bg2); display: none;}
|
||||
.cards .settings.visible {display: block;}
|
||||
.cards .settings {padding: 15px; border-top: 1px solid var(--border-color2); background: var(--alt-bg2); display: none; flex-direction: column; gap: 13px;}
|
||||
.cards .settings.visible {display: flex;}
|
||||
|
||||
.cards .actions {display: flex; gap: 10px; flex-wrap: wrap; align-items: center;}
|
||||
.cards .actions::before {content: "Akce:"; font-weight: 500; font-size: 90%; opacity: .5; text-transform: uppercase;}
|
||||
.cards .actions::before, .cards .filter::before {content: "Akce:"; font-weight: 500; font-size: 90%; opacity: .5; text-transform: uppercase;}
|
||||
.cards .filter::before {content: "Aktivní filtr:"; margin-right: 10px;}
|
||||
|
||||
@media screen and (max-width: 500px) {
|
||||
.cards .actions::before {display: none;}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,14 @@
|
|||
<div class="second">{{ stops[d.stop_id] ? stops[d.stop_id].name : "Nenastaveno" }}</div>
|
||||
</div>
|
||||
<div class="settings" :class="{ visible: d.visible }">
|
||||
<div class="filter">{{ d.filter ? d.filter : "žádný" }}</div>
|
||||
<div class="actions">
|
||||
<button @click="device_clear(i)">Vymazat</button>
|
||||
<button @click="device_resend(i)" v-if="d.enabled">Přeposlat</button>
|
||||
<button @click="device_change_stop(i)">Změnit zastávku</button>
|
||||
<button @click="device_toggle(i, false)" v-if="d.enabled">Deaktivovat</button>
|
||||
<button @click="device_toggle(i, true)" v-else>Aktivovat</button>
|
||||
<button @click="device_resend(i)" v-if="d.enabled">Přeposlat</button>
|
||||
<button @click="device_change_stop(i)">Zastávka</button>
|
||||
<button @click="device_change_filter(i)">Filtr</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,10 +3,8 @@ const { createApp } = Vue;
|
|||
let app = createApp({
|
||||
data() {
|
||||
return {
|
||||
// logged: false,
|
||||
// secret: "",
|
||||
logged: true,
|
||||
secret: "TajneHeslo",
|
||||
logged: false,
|
||||
secret: "",
|
||||
stops: {},
|
||||
devices: []
|
||||
}
|
||||
|
@ -14,11 +12,11 @@ let app = createApp({
|
|||
methods: {
|
||||
async update() {
|
||||
let devices = await api("/admin/devices", {secret: this.secret});
|
||||
let stops = await api("/stops");
|
||||
if(devices.error) {
|
||||
alert("Neplatné heslo!");
|
||||
return;
|
||||
}
|
||||
let stops = await api("/stops");
|
||||
this.devices = devices.devices;
|
||||
this.stops = stops.stops;
|
||||
this.logged = true;
|
||||
|
@ -38,6 +36,12 @@ let app = createApp({
|
|||
if(!stop_id || stop_id.trim() == "") return;
|
||||
this.devices[index].stop_id = stop_id;
|
||||
await api("/admin/devices/change_stop", {index, stop_id, secret: this.secret});
|
||||
},
|
||||
async device_change_filter(index) {
|
||||
let filter = prompt("Zadejte jméno filtru:");
|
||||
if(!filter || filter.trim() == "") return;
|
||||
this.devices[index].filter = filter;
|
||||
await api("/admin/devices/change_filter", {index, filter, secret: this.secret});
|
||||
}
|
||||
}
|
||||
}).mount('#app');
|
||||
|
@ -64,4 +68,3 @@ async function api(url, data) {
|
|||
xhr.send(str.join("&"));
|
||||
});
|
||||
}
|
||||
app.update();
|
Loading…
Reference in a new issue