2023-10-19 22:27:43 +00:00
|
|
|
from seleniumwire import webdriver # Import from seleniumwire
|
|
|
|
from seleniumwire.utils import decode
|
|
|
|
from time import sleep
|
|
|
|
from flask import Flask as f
|
|
|
|
from flask import Response
|
2023-10-21 17:17:42 +00:00
|
|
|
from dateutil import parser
|
|
|
|
from datetime import datetime, timedelta, timezone
|
2023-10-19 22:27:43 +00:00
|
|
|
import json
|
|
|
|
import re
|
2023-10-26 13:57:20 +00:00
|
|
|
import asyncio
|
|
|
|
import logging
|
|
|
|
import threading
|
|
|
|
import os
|
|
|
|
|
2023-10-26 14:12:36 +00:00
|
|
|
log = logging.getLogger('werkzeug')
|
|
|
|
log.setLevel(logging.ERROR)
|
|
|
|
log.disabled = True
|
2023-10-26 13:57:20 +00:00
|
|
|
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Create a new instance of the Chrome driver
|
|
|
|
valuestore = {}
|
2023-10-21 17:17:42 +00:00
|
|
|
datestore = {}
|
2023-10-26 13:57:20 +00:00
|
|
|
lastUpdate = datetime.now(timezone.utc)
|
|
|
|
|
2023-10-19 22:27:43 +00:00
|
|
|
app = f("web")
|
2023-10-26 13:57:20 +00:00
|
|
|
#app.logger.disabled = True
|
2023-10-21 17:17:42 +00:00
|
|
|
h2 = timedelta(hours=2)
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
def interceptor(request, response): # A response interceptor takes two args
|
2023-10-26 14:35:30 +00:00
|
|
|
global lastUpdate
|
2023-10-19 22:27:43 +00:00
|
|
|
if 'ws-travis.dus.com/socket.io/?EIO=3&transport=polling' in request.url :
|
|
|
|
body = decode(response.body, response.headers.get('Content-Encoding', 'identity'))
|
|
|
|
x = re.split("\d\d\d:\d\d\/dus,", body.decode("utf-8"))
|
2023-10-26 14:35:30 +00:00
|
|
|
lastUpdate = datetime.now(timezone.utc)
|
2023-10-19 22:27:43 +00:00
|
|
|
for i in [i for i in x if i]:
|
|
|
|
try:
|
|
|
|
j = json.loads(i)
|
|
|
|
handleJson(j)
|
|
|
|
except ValueError:
|
|
|
|
if i.find("online-level") > 0:
|
2023-10-26 13:57:20 +00:00
|
|
|
#print ("Fixed: ", i)
|
2023-10-19 22:27:43 +00:00
|
|
|
j = json.loads(i[:i.rfind(']') + 1])
|
|
|
|
handleJson(j)
|
2023-10-26 13:57:20 +00:00
|
|
|
#else:
|
|
|
|
#print ("Err: ", i)
|
|
|
|
|
|
|
|
# StackOverflow
|
|
|
|
def killChildren(driver):
|
|
|
|
print('Quitting session: ', driver.session_id)
|
|
|
|
driver.quit()
|
|
|
|
try:
|
|
|
|
pid = True
|
|
|
|
while pid:
|
|
|
|
pid = os.waitpid(-1, os.WNOHANG)
|
|
|
|
print("Reaped child: ", str(pid))
|
|
|
|
|
|
|
|
try:
|
|
|
|
if pid[0] == 0:
|
|
|
|
pid = False
|
|
|
|
except:
|
|
|
|
pass
|
2023-10-21 17:17:42 +00:00
|
|
|
|
2023-10-26 13:57:20 +00:00
|
|
|
except ChildProcessError:
|
|
|
|
pass
|
2023-10-21 17:17:42 +00:00
|
|
|
|
|
|
|
def idIsRecent(id):
|
|
|
|
return id in valuestore and datetime.now(timezone.utc) - parser.parse(datestore[id]) < timedelta(seconds=30)
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
def handleJson(jsonObj):
|
|
|
|
if isinstance(jsonObj, list):
|
|
|
|
if 'online-level' in jsonObj:
|
|
|
|
#typ = jsonObj[1]["LevelValues"][0]["Type"]
|
2023-10-21 18:03:16 +00:00
|
|
|
value = jsonObj[1]["LevelValues"][0]["Values"][0]
|
2023-10-19 22:27:43 +00:00
|
|
|
NmtId = jsonObj[1]["NmtId"]
|
2023-10-21 17:17:42 +00:00
|
|
|
time = jsonObj[1]["Time"]
|
2023-10-19 22:27:43 +00:00
|
|
|
valuestore[NmtId] = value
|
2023-10-21 17:17:42 +00:00
|
|
|
datestore[NmtId] = time
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
# Gibt den letzten bekannten Wert fuer die NMTID zurueck
|
|
|
|
@app.route('/nmt/<int:id>')
|
|
|
|
def nmtid(id):
|
2023-10-26 13:57:20 +00:00
|
|
|
if idIsRecent(id):
|
2023-10-21 18:03:16 +00:00
|
|
|
return format( valuestore[id], '.1f')
|
2023-10-19 22:27:43 +00:00
|
|
|
else:
|
2023-10-21 18:03:16 +00:00
|
|
|
return "E_NA" # Entweder out of date oder nicht existent
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
# Gibt eine Liste mit verfuegbaren ids zurueck
|
|
|
|
@app.route('/ids')
|
|
|
|
def ids():
|
2023-10-21 17:17:42 +00:00
|
|
|
l = filter(idIsRecent,list(valuestore.keys()))
|
2023-10-26 14:12:36 +00:00
|
|
|
return ','.join(map(str,list(l)))
|
2023-10-19 22:27:43 +00:00
|
|
|
|
2023-10-26 13:57:20 +00:00
|
|
|
def createDriver():
|
|
|
|
options = webdriver.ChromeOptions()
|
|
|
|
options.add_argument('--headless')
|
|
|
|
options.add_argument("--incognito")
|
|
|
|
options.add_argument("--nogpu")
|
|
|
|
options.add_argument("--disable-gpu")
|
|
|
|
options.add_argument("--window-size=1280,1280")
|
|
|
|
options.add_argument("--no-sandbox")
|
|
|
|
options.add_argument("--enable-javascript")
|
|
|
|
options.add_argument('--disable-dev-shm-usage')
|
|
|
|
driver = webdriver.Chrome(options=options)
|
2023-10-19 22:27:43 +00:00
|
|
|
driver.response_interceptor = interceptor
|
2023-10-26 13:57:20 +00:00
|
|
|
return driver
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
|
|
|
# start flask server
|
|
|
|
threading.Thread(target=lambda: app.run(host='0.0.0.0', port=80, debug=False, use_reloader=False)).start()
|
|
|
|
|
|
|
|
# wait time to restart will be dynamically adapted,
|
|
|
|
# if unexpected things happen in chrome or the real world
|
|
|
|
restartWait = timedelta(hours=4)
|
|
|
|
|
|
|
|
# setup webdriver
|
|
|
|
d0 = createDriver()
|
|
|
|
|
|
|
|
# start initial driver
|
|
|
|
d0.get('https://dus-travis.dus.com/')
|
|
|
|
lastaccess = datetime.now(timezone.utc)
|
|
|
|
|
|
|
|
# loop and restart with restartWait Interval
|
|
|
|
while True:
|
2023-10-26 14:35:30 +00:00
|
|
|
sleep(30)
|
2023-10-26 13:57:20 +00:00
|
|
|
if datetime.now(timezone.utc) > lastaccess + restartWait:
|
|
|
|
d1 = createDriver()
|
|
|
|
d1.get('https://dus-travis.dus.com/')
|
|
|
|
print ("New Failover Driver started, waiting 10 seconds ...")
|
|
|
|
sleep(10)
|
|
|
|
killChildren(d0)
|
|
|
|
del d0
|
|
|
|
print ("Original driver deleted")
|
|
|
|
d0 = createDriver()
|
|
|
|
d0.get('https://dus-travis.dus.com/')
|
|
|
|
print ("Recreating original driver and waiting 10 seconds ...")
|
|
|
|
sleep(10)
|
|
|
|
killChildren(d1)
|
|
|
|
del d1
|
|
|
|
print ("Failover Driver deleted")
|
|
|
|
lastaccess = datetime.now(timezone.utc)
|
2023-10-26 14:12:36 +00:00
|
|
|
|
2023-10-26 13:57:20 +00:00
|
|
|
l = filter(idIsRecent,list(valuestore.keys()))
|
2023-10-26 14:35:30 +00:00
|
|
|
if len(list(l)) < 1 and lastUpdate < datetime.now(timezone.utc) - timedelta(seconds=90):
|
|
|
|
restartWait = timedelta(minutes=3)
|
|
|
|
print ("Something stupid happened, setting interval to 3m")
|
2023-10-26 14:12:36 +00:00
|
|
|
else:
|
2023-10-26 14:35:30 +00:00
|
|
|
if restartWait < timedelta(hours=1):
|
|
|
|
restartWait = timedelta(hours=4)
|
|
|
|
print ("Something stupid normalized, resetting interval to 4h")
|
|
|
|
|
2023-10-26 14:12:36 +00:00
|
|
|
|
2023-10-19 22:27:43 +00:00
|
|
|
|
|
|
|
|
2023-10-26 13:57:20 +00:00
|
|
|
|