Moved config to yml file

This commit is contained in:
Filip Znachor 2022-12-08 20:59:11 +01:00
parent 1067333518
commit 883bb30fea
5 changed files with 90 additions and 84 deletions

2
.gitignore vendored
View file

@ -1,3 +1,3 @@
config.py config.yml
*.pyc *.pyc
assets assets

View file

@ -1,12 +1,12 @@
from bottle import route, template, error, run, get, ServerAdapter, static_file
from departures import Departure
from operator import itemgetter
import threading import threading
from operator import itemgetter
from wsgiref.simple_server import make_server, WSGIRequestHandler
from departures import Departure
from bottle import route, error, run, get, ServerAdapter, static_file
class Server(ServerAdapter): class Server(ServerAdapter):
server = None server = None
def run(self, handler): def run(self, handler):
from wsgiref.simple_server import make_server, WSGIRequestHandler
if self.quiet: if self.quiet:
class QuietHandler(WSGIRequestHandler): class QuietHandler(WSGIRequestHandler):
def log_request(self, *args, **kw): def log_request(self, *args, **kw):
@ -17,8 +17,6 @@ class Server(ServerAdapter):
def stop(self): def stop(self):
self.server.shutdown() self.server.shutdown()
server = Server(host="0.0.0.0", port=8080)
@route('/departures') @route('/departures')
def index(): def index():
resp = [] resp = []
@ -29,14 +27,18 @@ def index():
@get("/") @get("/")
def static(): def static():
return static_file("index.html", root="static") return static_file("index.html", root="static")
@error(404) @error(404)
def error404(error): def error404(err):
return '' return ''
def start(): class API:
run(quiet=True, server=server)
thread = threading.Thread(target=start) def __init__(self, main):
thread.start() self.server = Server(host=main.config["http"]["host"], port=main.config["http"]["port"])
self.thread = threading.Thread(target=self.start)
self.thread.start()
def start(self):
run(quiet=True, server=self.server)

View file

@ -1,13 +1,6 @@
from requests.structures import CaseInsensitiveDict
import json
import requests
from dateutil import parser
from datetime import datetime
from lora import lora_controller
from math import floor from math import floor
from datetime import datetime
from dateutil import parser
class Departure: class Departure:
@ -33,43 +26,8 @@ class Departure:
remove.append(did) remove.append(did)
for did in remove: for did in remove:
Departure.storage.pop(did) Departure.storage.pop(did)
@staticmethod
def fetch(stop_id, limit):
url = "https://jizdnirady.pmdp.cz/odjezdy/vyhledat" def __init__(self, did, type, line, last_stop, departure, delay, lora_controller):
headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json"
data = {
"Stop": {
"StopId": stop_id
},
"DateAndTime": None,
"MaxResults": limit,
"FullResults": False
}
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=100).json()
for c in resp:
did = f"{stop_id}|{abs(c['ConnectionId']['ConnectionId'])}"
if did not in Departure.storage:
Departure(
did,
c["Line"]["TractionType"],
c["Line"]["Name"],
c["LastStopName"],
c["DepartureTime"],
0 if not c["DelayMin"] else c["DelayMin"]
)
else:
Departure.storage[did].update(
0 if not c["DelayMin"] else c["DelayMin"]
)
def __init__(self, did, type, line, last_stop, departure, delay):
departure = (parser.parse(departure)).timestamp() departure = (parser.parse(departure)).timestamp()
if -(datetime.now().timestamp() - (departure + delay*60))/60 <= -1: if -(datetime.now().timestamp() - (departure + delay*60))/60 <= -1:
return return
@ -83,11 +41,12 @@ class Departure:
self.last_stop = last_stop self.last_stop = last_stop
self.departure = departure self.departure = departure
self.delay = delay self.delay = delay
lora_controller.data(self) self.controller = lora_controller
self.controller.data(self)
def update(self, delay): def update(self, delay):
if delay != self.delay: if delay != self.delay:
lora_controller.data(self) self.controller.data(self)
self.delay = delay self.delay = delay
def get_departure(self): def get_departure(self):

View file

@ -1,6 +1,5 @@
import requests import requests
from requests.structures import CaseInsensitiveDict from requests.structures import CaseInsensitiveDict
import config
import json import json
import threading import threading
from time import sleep from time import sleep
@ -12,27 +11,29 @@ urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class LoraController: class LoraController:
def __init__(self): def __init__(self, main):
self.main = main
self.storage = dict() self.storage = dict()
self.devices = [] self.devices = []
# TODO: create separated message pool for each device # TODO: create separated message pool for each device
self.message_pool = [] self.message_pool = []
self.thread = None self.thread = None
self.token = ""
def generate_token(self): def generate_token(self):
url = f"https://lora.plzen.eu/api/v2/login" url = "https://lora.plzen.eu/api/v2/login"
headers = CaseInsensitiveDict() headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json" headers["Content-Type"] = "application/json"
data = { data = {
"email": config.lora_api_username, "email": self.main.config["lora_api"]["username"],
"password": config.lora_api_password "password": self.main.config["lora_api"]["password"]
} }
data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json() data = requests.post(url, verify=False, headers=headers, data=json.dumps(data)).json()
config.lora_api_token = data["token"] self.token = data["token"]
def new(self, id): def new(self, id):
self.devices.append(LoraDevice(self, id)) self.devices.append(LoraDevice(self, id))
@ -55,14 +56,14 @@ class LoraController:
def thread_sending(self): def thread_sending(self):
while True: while True:
if not len(self.message_pool): if len(self.message_pool) == 0:
break break
data = self.message_pool.pop(0) data = self.message_pool.pop(0)
url = f"https://lora.plzen.eu/api/v2/nodes/{data[0]:0>16x}/queue" url = f"https://lora.plzen.eu/api/v2/nodes/{data[0]:0>16x}/queue"
string = data[2]() string = data[2]()
headers = CaseInsensitiveDict() headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json" headers["Content-Type"] = "application/json"
headers["Authorization"] = f"Bearer {config.lora_api_token}" headers["Authorization"] = f"Bearer {self.token}"
payload = { payload = {
"confirmed": True, "confirmed": True,
"data": b64encode(string.encode("utf-8")).decode("ascii"), "data": b64encode(string.encode("utf-8")).decode("ascii"),
@ -81,9 +82,4 @@ class LoraDevice:
def send(self, msg): def send(self, msg):
self.controller.send(self.id, self.port+1, msg) self.controller.send(self.id, self.port+1, msg)
self.port = (self.port + 1) % 15 self.port = (self.port + 1) % 15
lora_controller = LoraController()
lora_controller.new(0xbdea85badeedf1)

View file

@ -1,18 +1,67 @@
from departures import Departure from departures import Departure
from requests.structures import CaseInsensitiveDict
import json
import requests
from time import sleep from time import sleep
from lora import lora_controller from lora import LoraController
import threading import threading
from api import server from api import API
from pathlib import Path
import yaml
import sys import sys
class MainLoop: class Main:
def __init__(self, stop_id, controller): def __init__(self, stop_id):
config = Path("config.yml")
try:
self.config = yaml.safe_load(config.read_text(encoding="utf-8-sig"))
except:
print("Invalid config file!")
sys.exit(-1)
self.ended = False self.ended = False
self.stop_id = stop_id self.stop_id = stop_id
self.controller = controller lora_controller = LoraController(self)
lora_controller.new(0xbdea85badeedf1)
self.controller = lora_controller
self.thread = threading.Thread(target=self.update_loop) self.thread = threading.Thread(target=self.update_loop)
self.thread.start() self.thread.start()
self.api = API(self)
def fetch(self, stop_id, limit):
url = "https://jizdnirady.pmdp.cz/odjezdy/vyhledat"
headers = CaseInsensitiveDict()
headers["Content-Type"] = "application/json"
data = {
"Stop": {
"StopId": stop_id
},
"DateAndTime": None,
"MaxResults": limit,
"FullResults": False
}
resp = requests.post(url, headers=headers, data=json.dumps(data), timeout=100).json()
for c in resp:
did = f"{stop_id}|{abs(c['ConnectionId']['ConnectionId'])}"
if did not in Departure.storage:
Departure(
did,
c["Line"]["TractionType"],
c["Line"]["Name"],
c["LastStopName"],
c["DepartureTime"],
0 if not c["DelayMin"] else c["DelayMin"],
self.controller
)
else:
Departure.storage[did].update(
0 if not c["DelayMin"] else c["DelayMin"]
)
def update_loop(self): def update_loop(self):
refetch = 0 refetch = 0
@ -27,7 +76,7 @@ class MainLoop:
if refetch == 0: if refetch == 0:
self.controller.time() self.controller.time()
Departure.fetch(self.stop_id, 20) self.fetch(self.stop_id, 20)
refetch = (refetch + 1) % 3 refetch = (refetch + 1) % 3
regenerate = (regenerate + 1) % (6*30) regenerate = (regenerate + 1) % (6*30)
@ -36,14 +85,14 @@ class MainLoop:
Departure.clear() Departure.clear()
for i in range(10): for _ in range(10):
sleep(1) sleep(1)
if self.ended: if self.ended:
break break
def stop(self): def stop(self):
print("Stopping...") print("Stopping...")
server.stop() self.api.server.stop()
self.ended = True self.ended = True
self.controller.message_pool = [] self.controller.message_pool = []
@ -70,5 +119,5 @@ class MainLoop:
except KeyboardInterrupt: except KeyboardInterrupt:
self.stop() self.stop()
main_loop = MainLoop("40", lora_controller) main = Main("40")
main_loop.input_loop() main.input_loop()