added excel->json recorder source generation script

This commit is contained in:
Tobias Kurze
2019-11-12 12:32:49 +01:00
parent 5d731c9fba
commit 8b05bb694f
8 changed files with 485 additions and 6 deletions

View File

@@ -12,11 +12,25 @@ from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from flask_cors import CORS
class LrcException(Exception):
def __init__(self, message: str, html_code: int = None):
super().__init__(message)
self.html_code = html_code
def __repr__(self):
if self.html_code is not None:
return "LRC Exception: \"{}\" (HTML Code: {})".format(', '.join(super().args), self.html_code)
return ', '.join(super().args)
def __str__(self):
return self.__repr__()
app = Flask(__name__)
app.config.from_object('backend.config.Config')
db = SQLAlchemy(app)
login_manager = LoginManager()
login_manager.init_app(app)
@@ -42,6 +56,7 @@ def verify_token(token):
app.logger.info(decoded)
return True
basic_auth = HTTPBasicAuth()
multi_auth = MultiAuth(basic_auth, jwt_auth)
@@ -67,4 +82,3 @@ CORS(api_bp)
# Fix flask-restplus by duck typing error handlers
jwt_extended._set_error_handler_callbacks(api_v1)

View File

@@ -0,0 +1,204 @@
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

View File

@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
"""
Models for lecture recorder
"""

View File

@@ -100,6 +100,10 @@ class RecorderAdapter:
def _get_version(self):
pass
@abstractmethod
def is_recording(self) -> bool:
pass
def get_defined_recorder_adapters():
models = []

View File

@@ -0,0 +1,142 @@
# Copyright (c) 2019. Tobias Kurze
import shutil
import time
from datetime import datetime
from pprint import pprint
import requests
from requests.auth import HTTPBasicAuth
from backend import LrcException
from backend.recorder_adapters import RecorderAdapter
# HOST = "localhost"
BASE_URL = "http://172.23.8.102" # Audimax SMP 351
USER = "admin"
PW = "lrgrashof+-"
class EpiphanV1(RecorderAdapter):
def __init__(self, admin_user: str, admin_pw: str):
self.user = admin_user
self.password = admin_pw
self.session = requests.Session()
self.session.auth = HTTPBasicAuth(self.user, self.password)
def _get_name(self):
pass
def _get_version(self):
pass
def get_status(self) -> dict:
res = self.session.get(BASE_URL + "/admin/ajax/recorder_status.cgi")
if res.ok:
return res.json()
raise LrcException(res.text, res.status_code)
def get_sysinfo(self) -> dict:
res = self.session.get(BASE_URL + "/ajax/sysinfo.cgi")
if res.ok:
return res.json()
raise LrcException(res.text, res.status_code)
def is_recording(self) -> bool:
state = self.get_status().get('state', None)
return state == "up"
def get_recording_time(self):
"""
Returns recording time in seconds. Also returns 0 if not recording.
:return:
"""
return self.get_status().get('seconds', None)
def start_recording(self):
res = self.session.get(BASE_URL + "/admin/ajax/start_recorder.cgi")
if not res.ok:
raise LrcException(res.text, res.status_code)
time.sleep(2) # just a little bit of waiting time -> it takes a bit for the Epiphan to update its state
def stop_recording(self):
res = self.session.get(BASE_URL + "/admin/ajax/stop_recorder.cgi")
if not res.ok:
raise LrcException(res.text, res.status_code)
time.sleep(4) # just a little bit of waiting time -> it takes a bit for the Epiphan to update its state
def get_ip_address(self):
try:
return self.get_sysinfo().get("system").get("network").get("interfaces")[0].get('ipaddr', None)
except Exception as err:
raise LrcException(str(err))
def get_disk_space(self):
try:
data = self.get_sysinfo().get("system").get("data")
return {'available': data.get("available", None), 'free': data.get("free", None),
'total': data.get("total", None), 'used': data.get("total", 0) - data.get("available", 0)}
except Exception as err:
raise LrcException(str(err))
def get_video_inputs(self) -> list:
ret = []
try:
video = self.get_sysinfo().get("inputs").get("video")
for v in video:
ret.append(
{'id': v.get('id', None), 'name': v.get('name', None), 'resolution': v.get('resolution', None)})
return ret
except Exception as err:
raise LrcException(str(err))
def get_hardware_revision(self):
try:
return self.get_sysinfo().get("system").get("firmware")
except Exception as err:
raise LrcException(str(err))
def get_system_time(self):
try:
time_stamp = self.get_sysinfo().get("time")
return {'unix_time_stamp': time_stamp,
'date_time_utc': datetime.utcfromtimestamp(time_stamp).strftime('%Y-%m-%dT%H:%M:%SZ')}
except Exception as err:
raise LrcException(str(err))
def get_screenshot(self):
ret = self.session.get(BASE_URL + "/admin/grab_frame.cgi?size=256x192&device=DAV93133.vga&_t=1573471990578",
stream=True)
print(ret)
pprint(ret.headers)
with open('out.jpg', 'wb') as out_file:
shutil.copyfileobj(ret.raw, out_file)
del ret
if __name__ == '__main__':
e = EpiphanV1(USER, PW)
try:
# print(e.is_recording())
"""
if e.is_recording():
e.stop_recording()
else:
e.start_recording()
print(e.is_recording())
"""
"""
print(e.get_ip_address())
print(e.get_disk_space())
print(e.get_video_inputs())
print(e.get_hardware_revision())
print(e.get_system_time())
"""
e.get_screenshot()
except LrcException as e:
print(e)

View File

@@ -6,13 +6,13 @@ REQUIRES_USER = False
REQUIRES_PW = True
# HOST = "localhost"
HOST = "129.13.51.102" # Audimax SMP 351
# HOST = "129.13.51.102" # Audimax SMP 351
# HOST = "129.13.51.106" # Tulla SMP 351
# HOST = "172.22.246.207" # Test SMP MZ
HOST = "172.22.246.207" # Test SMP MZ
USER = "admin"
PW = "123mzsmp"
PW = "audimaxsmp"
#PW = "audimaxsmp"
class SMP(TelnetAdapter, RecorderAdapter):
@@ -701,6 +701,9 @@ class SMP(TelnetAdapter, RecorderAdapter):
some advanced options skipped
"""
def is_recording(self) -> bool:
pass
def get_input_hdcp_status(self, input_number: int):
"""
returns:

View File

@@ -0,0 +1,55 @@
import json
from pprint import pprint
import xlrd
MAX_CONSECUTIVE_EMPTY_ROWS_BEFORE_CANCEL = 5
file_location = "/home/tobias/tmp/Hoersaal-Rec-Liste.xlsx"
wb = xlrd.open_workbook(file_location)
sheet = wb.sheet_by_index(0)
headers = None
recorders = []
a_lot_of_empty_rows = False
consecutive_empty_rows = 0
ix = 0
while not a_lot_of_empty_rows:
try:
vals = sheet.row_values(ix)
except IndexError:
break
if len(set(vals)) == 1 and set(vals).pop() == '':
consecutive_empty_rows += 1
if consecutive_empty_rows > MAX_CONSECUTIVE_EMPTY_ROWS_BEFORE_CANCEL:
a_lot_of_empty_rows = True
else:
consecutive_empty_rows = 0
if len(set(vals)) > 5 and headers is None: # get table header
headers = {ix: vals[ix] for ix in range(0, len(vals))}
elif len(set(vals)) > 5: # regular rows
recorders.append({headers[ix]: vals[ix] for ix in range(0, len(vals))})
ix += 1
if ix >= 100:
a_lot_of_empty_rows = True
#pprint(recorders)
print(len(recorders))
nicely_formatted_recorders = []
for r in recorders:
rec = {'name': r['Opencast / CM'],
'building': r['Gebäude'],
'room': r['Hörsaal'],
'username': r['Benutzer'],
'password': r['PW'],
'ip': r['IP'],
'mac': r['MAC'],
'type': 'SMP 351' if 'SMP 351' in r['Rekorder-Typ'] else r['Rekorder-Typ'],
'additional_camera': r['Zus. Kamera'] == 'Ja',
'firmware_version': r['FW Vers.'],
'description': json.dumps(
{'comment': r['Bemerkung'], 'network_port': r['Dosennummer'], 'rsync_name': r['Rsync-Name']})}
nicely_formatted_recorders.append(rec)
print(json.dumps(nicely_formatted_recorders))

View File

@@ -0,0 +1,57 @@
from pprint import pprint
import requests
from requests.auth import HTTPBasicAuth
from ics import Calendar
base_url = "https://opencast.bibliothek.kit.edu/recordings/calendars?agentid=CS+30.46+Chemie+Neuer+Hoersaal"
base_url = "https://opencast.bibliothek.kit.edu"
session = requests.session()
session.auth = HTTPBasicAuth("admin", "mz.paziuw!")
config = {'service_urls': {}}
def get_service_url(service_type: str):
if service_type in config['service_urls']:
return config['service_urls'][service_type]
params = {'serviceType': service_type}
url = base_url + "/services/available.json"
res = session.get(url, params=params)
if res.ok:
service = res.json()["services"]["service"]
config["service_urls"][service_type] = service["host"] + \
service["path"]
return service["host"] +service["path"]
return None
def get_calender(rec_id):
params = {'agentid': rec_id}
url = get_service_url('org.opencastproject.scheduler') + "/calendars"
print(url)
res = session.get(url, params=params)
if res.ok:
return Calendar(res.text)
def get_capture_agents():
url = get_service_url("org.opencastproject.capture.admin") + "/agents.json"
res = session.get(url)
if res.ok:
return res.json()["agents"]["agent"]
agents = get_capture_agents()
for a in agents:
print(a['name'])
print(a['state'])
if a['state'] == "capturing":
c = get_calender(a['name'])
print(list(c.timeline.now()))
exit()
c = get_calender('CS 30.46 Chemie Neuer Hoersaal')
print(c.events)
print(list(c.timeline)) # chronological order
print(list(c.timeline.now()))