First public release candidate
This commit is contained in:
parent
be43f3c761
commit
b94f27d8cd
81
jitsi-log.py
81
jitsi-log.py
|
@ -2,12 +2,12 @@
|
||||||
#
|
#
|
||||||
# simple log parser and status server for the jitsi meet video conference tool
|
# simple log parser and status server for the jitsi meet video conference tool
|
||||||
#
|
#
|
||||||
# Reik Kaps <r31k@k4p5.de> 2020
|
# Reik Kaps <r31k@k4p5.de> 2020 for Leinelab Hannover
|
||||||
|
|
||||||
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
from time import sleep
|
|
||||||
from os.path import basename
|
from os.path import basename
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
@ -27,11 +27,13 @@ except ImportError as e:
|
||||||
roomList = {}
|
roomList = {}
|
||||||
|
|
||||||
# @see https://regex101.com/r/R1B1OL/1
|
# @see https://regex101.com/r/R1B1OL/1
|
||||||
|
# general regex for a jicofo log line
|
||||||
regex = r"(Jicofo)\s(\d+-\d+-\d+)\s(\d+\:\d+\:\d+\.\d+)\s(\w+):\s\[(\d+)\]\s(.*)\(\)\s(.*)"
|
regex = r"(Jicofo)\s(\d+-\d+-\d+)\s(\d+\:\d+\:\d+\.\d+)\s(\w+):\s\[(\d+)\]\s(.*)\(\)\s(.*)"
|
||||||
prog = re.compile(regex)
|
prog = re.compile(regex)
|
||||||
|
|
||||||
##
|
##
|
||||||
# new jitsi room
|
# new jitsi room
|
||||||
|
#
|
||||||
room_regex = r"(^Joining\sthe\sroom):(.*)"
|
room_regex = r"(^Joining\sthe\sroom):(.*)"
|
||||||
room = re.compile(room_regex)
|
room = re.compile(room_regex)
|
||||||
|
|
||||||
|
@ -56,6 +58,7 @@ leaving = re.compile(leaving_regex)
|
||||||
class MeetingRoom():
|
class MeetingRoom():
|
||||||
"""
|
"""
|
||||||
represent a Jitsi Meetingroom
|
represent a Jitsi Meetingroom
|
||||||
|
|
||||||
jid: eg room@conference.meet.leinelab.org
|
jid: eg room@conference.meet.leinelab.org
|
||||||
ctime: eg 2020-06-01 12:32:02 ..
|
ctime: eg 2020-06-01 12:32:02 ..
|
||||||
"""
|
"""
|
||||||
|
@ -81,13 +84,13 @@ class MeetingRoom():
|
||||||
try:
|
try:
|
||||||
self.members.remove(name)
|
self.members.remove(name)
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
pass
|
raise
|
||||||
|
|
||||||
def getMembers(self):
|
def getMembers(self):
|
||||||
return self.members
|
return self.members
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return '{}: {}'.format(self.jid, self.owner)
|
return '{}: {}'.format(self.jid, len(self.members))
|
||||||
|
|
||||||
|
|
||||||
class logThread(threading.Thread):
|
class logThread(threading.Thread):
|
||||||
|
@ -103,15 +106,10 @@ class logThread(threading.Thread):
|
||||||
|
|
||||||
|
|
||||||
class MyServer(BaseHTTPRequestHandler):
|
class MyServer(BaseHTTPRequestHandler):
|
||||||
def badge_respones(self, response_string):
|
|
||||||
self.send_response(200)
|
|
||||||
self.send_header("Content-type", "image/svg+xml")
|
|
||||||
self.end_headers()
|
|
||||||
self.wfile.write(response_string)
|
|
||||||
|
|
||||||
def text_response(self, response_string):
|
def do_response(self, response_string, ctype="text/plain"):
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header("Content-type", "text/plain")
|
self.send_header("Content-type", ctype)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(response_string)
|
self.wfile.write(response_string)
|
||||||
|
|
||||||
|
@ -128,13 +126,18 @@ class MyServer(BaseHTTPRequestHandler):
|
||||||
if respones_format == 'json':
|
if respones_format == 'json':
|
||||||
pass
|
pass
|
||||||
elif respones_format == 'svg':
|
elif respones_format == 'svg':
|
||||||
|
participants = len(roomList[room_name].members)
|
||||||
|
if participants > 1:
|
||||||
|
rtext = '{} participants'.format(str(participants))
|
||||||
|
else:
|
||||||
|
rtext = '{} participant'.format(str(participants))
|
||||||
|
|
||||||
s = badge(left_text='{}: {}'.format('Room', room_name),
|
s = badge(left_text='{}: {}'.format('Room', room_name),
|
||||||
right_text=str(len(roomList[room_name].members)),
|
right_text=rtext,
|
||||||
left_color='blue',
|
left_color='blue',
|
||||||
right_color='green')
|
right_color='green')
|
||||||
response_string = bytes(s, "utf-8")
|
response_string = bytes(s, "utf-8")
|
||||||
self.badge_respones(response_string)
|
self.do_response(response_string, "image/svg+xml")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# default text response
|
# default text response
|
||||||
response_string = bytes(room_name
|
response_string = bytes(room_name
|
||||||
|
@ -143,7 +146,8 @@ class MyServer(BaseHTTPRequestHandler):
|
||||||
+ '|'
|
+ '|'
|
||||||
+ str(len(roomList[room_name].members))
|
+ str(len(roomList[room_name].members))
|
||||||
+ '|', "utf-8")
|
+ '|', "utf-8")
|
||||||
self.text_response(response_string)
|
self.do_response(response_string)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if respones_format == 'svg':
|
if respones_format == 'svg':
|
||||||
s = badge(left_text='{}: {}'.format('Room', room_name),
|
s = badge(left_text='{}: {}'.format('Room', room_name),
|
||||||
|
@ -151,34 +155,35 @@ class MyServer(BaseHTTPRequestHandler):
|
||||||
left_color='red',
|
left_color='red',
|
||||||
right_color='darkgray')
|
right_color='darkgray')
|
||||||
response_string = bytes(s, "utf-8")
|
response_string = bytes(s, "utf-8")
|
||||||
self.badge_respones(response_string)
|
self.text_response(response_string, "image/svg+xml")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
# text or other formats
|
||||||
|
# return http code 404 (room) not found
|
||||||
self.send_response(404)
|
self.send_response(404)
|
||||||
# self.send_header("Content-type", "text/plain")
|
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
|
|
||||||
|
|
||||||
def getRoomName(jid):
|
def process_line(line: str):
|
||||||
return jid.split("@")[0].strip()
|
|
||||||
|
|
||||||
|
|
||||||
def mkDatetime(str_date, str_time):
|
|
||||||
return datetime.fromisoformat('{} {}'.format(str_date, str_time))
|
|
||||||
|
|
||||||
|
|
||||||
def process_line(line):
|
|
||||||
"""
|
"""
|
||||||
process a logfile line, using global object and vars
|
process a logfile line, using global object and vars
|
||||||
globals: prog, disposed, owner, member, roomList
|
globals: prog, disposed, owner, member, roomList
|
||||||
line: string
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
line: str
|
||||||
|
a line form the logfile
|
||||||
|
|
||||||
"""
|
"""
|
||||||
erg = prog.match(line)
|
erg = prog.match(line)
|
||||||
if erg:
|
if erg:
|
||||||
# detect room creation
|
# detect room creation
|
||||||
new_room = room.match(erg.group(7))
|
new_room = room.match(erg.group(7))
|
||||||
if new_room:
|
if new_room:
|
||||||
room_name = getRoomName(new_room.group(2))
|
room_name = new_room.group(2).split("@")[0].strip()
|
||||||
room_date = mkDatetime(erg.group(2), erg.group(3))
|
room_date = datetime.fromisoformat('{} {}'.
|
||||||
|
format(erg.group(2),
|
||||||
|
erg.group(3)))
|
||||||
print('{} {} created'.format(room_date, room_name))
|
print('{} {} created'.format(room_date, room_name))
|
||||||
currentRoom = MeetingRoom(room_name, room_date)
|
currentRoom = MeetingRoom(room_name, room_date)
|
||||||
if room_name in roomList:
|
if room_name in roomList:
|
||||||
|
@ -213,26 +218,24 @@ def process_line(line):
|
||||||
# participant is leaving a the room
|
# participant is leaving a the room
|
||||||
leaving_match = leaving.match(erg.group(7))
|
leaving_match = leaving.match(erg.group(7))
|
||||||
if leaving_match:
|
if leaving_match:
|
||||||
try:
|
|
||||||
room_name = leaving_match.group(1).strip()
|
room_name = leaving_match.group(1).strip()
|
||||||
room_member = leaving_match.group(3).strip()
|
room_member = leaving_match.group(3).strip()
|
||||||
except:
|
|
||||||
room_name = 'undefined'
|
|
||||||
room_member = 'undefined'
|
|
||||||
|
|
||||||
print('{} leaves {}'.format(room_member, room_name))
|
print('{} leaves {}'.format(room_member, room_name))
|
||||||
if room_name in roomList:
|
if room_name in roomList:
|
||||||
roomList[room_name].delMember(room_member)
|
roomList[room_name].delMember(room_member)
|
||||||
|
|
||||||
|
|
||||||
def getLogMsg(logfile):
|
def getLogMsg(logfile: str):
|
||||||
"""
|
"""
|
||||||
get log messages and commit it to process_line
|
get log messages and commit it to process_line
|
||||||
used pytail module
|
used tail from sh module
|
||||||
"""
|
|
||||||
# for line in Pygtail(logfile, full_lines=True):
|
|
||||||
# process_line(line)
|
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
-----------
|
||||||
|
logfile: str
|
||||||
|
path as string to logfile
|
||||||
|
|
||||||
|
"""
|
||||||
for line in tail("-f", logfile, _iter=True):
|
for line in tail("-f", logfile, _iter=True):
|
||||||
process_line(line)
|
process_line(line)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue