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