You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
104 lines
2.2 KiB
104 lines
2.2 KiB
#!/usr/bin/env python3
|
|
|
|
#
|
|
# bbb.py
|
|
#
|
|
# Utilities to parse BBB recording components
|
|
#
|
|
# Copyright (c) 2023 Sylvain Munaut <tnt@246tNt.com>
|
|
# SPDX-License-Identifier: MIT
|
|
#
|
|
|
|
__all__ = [
|
|
'CursorEvent',
|
|
'parse_cursor_xml',
|
|
'PresentEvent',
|
|
'SlideRef',
|
|
'parse_deskshare_xml',
|
|
'parse_shapes_svg',
|
|
'PanZoomEvent',
|
|
'parse_panzooms_xml',
|
|
]
|
|
|
|
|
|
import re
|
|
from collections import namedtuple
|
|
|
|
import lxml.etree
|
|
|
|
|
|
CursorEvent = namedtuple('CursorEvent', 'ts x y')
|
|
|
|
def parse_cursor_xml(filename):
|
|
rv = []
|
|
xml_doc = lxml.etree.parse(filename)
|
|
for element in xml_doc.xpath("//recording/event"):
|
|
px, py = [float(x) for x in element.getchildren()[0].text.split()]
|
|
rv.append(CursorEvent(
|
|
float(element.get("timestamp")),
|
|
px,
|
|
py,
|
|
))
|
|
return rv
|
|
|
|
|
|
PresentEvent = namedtuple('CursorEvent', 'ts_in ts_out slide')
|
|
SlideRef = namedtuple('SlideRef', 'deck_id page')
|
|
|
|
def parse_deskshare_xml(filename):
|
|
rv = []
|
|
xml_doc = lxml.etree.parse(filename)
|
|
for element in xml_doc.xpath("//recording/event"):
|
|
st = float(element.get("start_timestamp"))
|
|
et = float(element.get("stop_timestamp"))
|
|
rv.append( PresentEvent(st, et, None) )
|
|
return rv
|
|
|
|
|
|
def parse_shapes_svg(filename):
|
|
|
|
rv = []
|
|
xml_doc = lxml.etree.parse(filename)
|
|
ns = {
|
|
'svg': 'http://www.w3.org/2000/svg',
|
|
'xlink': 'http://www.w3.org/1999/xlink',
|
|
}
|
|
|
|
for element in xml_doc.xpath("//svg:svg/svg:image", namespaces=ns):
|
|
# Parse/Validate href
|
|
href = element.get('{http://www.w3.org/1999/xlink}href')
|
|
|
|
if href == "presentation/deskshare.png":
|
|
slide = None
|
|
else:
|
|
m = re.match('^presentation/([0-9a-fA-F]{40,64}-[0-9]+)/slide-([0-9]+).png$', href)
|
|
if not m:
|
|
raise RuntimeError('Invalid presentation page link')
|
|
slide = SlideRef(m.group(1), int(m.group(2)))
|
|
|
|
# Append
|
|
rv.append(PresentEvent(
|
|
float(element.get('in')),
|
|
float(element.get('out')),
|
|
slide
|
|
))
|
|
|
|
return rv
|
|
|
|
|
|
PanZoomEvent = namedtuple('PanZoomEvent', 'ts x y w h')
|
|
|
|
def parse_panzooms_xml(filename):
|
|
rv = []
|
|
xml_doc = lxml.etree.parse(filename)
|
|
for element in xml_doc.xpath("//recording/event"):
|
|
x, y, w, h = [float(x) for x in element.getchildren()[0].text.split()]
|
|
rv.append(PanZoomEvent(
|
|
float(element.get("timestamp")),
|
|
x,
|
|
y,
|
|
w,
|
|
h,
|
|
))
|
|
return rv
|