#!/bin/env python3 # import re import sys import threading import time from time import sleep from os.path import basename from datetime import datetime from argparse import ArgumentParser from http.server import BaseHTTPRequestHandler, HTTPServer try: from pygtail import Pygtail except ImportError as e: print('[Error] Please install pygtail via pip! {}'.format(e)) sys.exit(1) try: from sh import tail except ImportError as e: print('[Error] Please install sh via pip! {}'.format(e)) sys.exit(1) class MeetingRoom(): """ represent a Jitsi Meetingroom jid: eg room@conference.meet.leinelab.org ctime: eg 2020-06-01 12:32:02 .. """ members = [] def __init__(self, jid, ctime): self.jid = jid self.ctime = ctime def setOwner(self, name): self.owner = name def getOwner(self): if hasattr(self, 'owner'): return self.owner else: return None def addMember(self, name): self.members.append(name) def getMembers(self): return self.members def __str__(self): return '{}: {}'.format(self.jid, self.owner) class logThread(threading.Thread): def __init__(self, threadID, name, filename): threading.Thread.__init__(self) self.threadID = threadID self.name = name self.filename = filename def run(self): while True: getLogMsg(self.filename) sleep(5) class MyServer(BaseHTTPRequestHandler): def do_GET(self): self.send_response(200) self.send_header("Content-type", "text/html") self.end_headers() self.wfile.write(bytes("
Request: %s
" % self.path, "utf-8")) self.wfile.write(bytes("", "utf-8")) self.wfile.write(bytes("This is an example web server.
", "utf-8")) if basename(self.path) in roomList: self.wfile.write(bytes(""+basename(self.path)+": "+str(roomList[basename(self.path)].ctime)+"
", "utf-8")) self.wfile.write(bytes("Participants: "+str(len(roomList[basename(self.path)].members))+"
", "utf-8")) else: for key, value in roomList.items(): link = ''.format(value.jid, key) self.wfile.write(bytes(link, "utf-8")) self.wfile.write(bytes("", "utf-8")) def getRoomName(jid): return jid.split("@")[0].strip() def mkDatetime(str_date, str_time): return datetime.fromisoformat('{} {}'.format(str_date, str_time)) # active room dictionary roomList = {} testList = { 'test': 'Nichts wichtiges', 'lounge': 'lounge@meet.leinelab.de' } # @see https://regex101.com/r/R1B1OL/1 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) # disposed room disposed_regex = r"^Disposed\sconference\sfor\sroom\:\s(.*)@(.*)\sconference\scount:\s(\d+)" disposed = re.compile(disposed_regex) ## # get the room owner owner_regex = r"Granted\sowner\sto\s([a-z0-9-]+)\@(.*)\/(.*)" owner = re.compile(owner_regex) # get member for room member_regex = r"^Member\s(.*)@(.*)\/(.*)\sjoined." member = re.compile(member_regex) def process_line(line): """ process a logfile line, using global object and vars globals: prog, disposed, owner, member, roomList line: string """ 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)) print('{} {}'.format(room_date, room_name)) currentRoom = MeetingRoom(room_name, room_date) if room_name in roomList: # delete old room and recreate it del roomList[room_name] roomList[room_name] = currentRoom else: roomList[room_name] = currentRoom disposed_room = disposed.match(erg.group(7)) if disposed_room: room_name = disposed_room.group(1) print('-> room disposed: {}'.format(room_name)) if room_name in roomList: del roomList[room_name] owner_match = owner.match(erg.group(7)) if owner_match: room_name = owner_match.group(1).strip() room_owner = owner_match.group(3).strip() # print('{}: {}'.format(room_name, room_owner)) if room_name in roomList: roomList[room_name].setOwner(room_owner) member_match = member.match(erg.group(7)) if member_match: room_name = member_match.group(1).strip() room_member = member_match.group(3).strip() print('--> {}: {}'.format(room_name, room_member)) if room_name in roomList: roomList[room_name].addMember(room_member) def getLogMsg(logfile): """ get log messages and commit it to process_line used pytail module """ # for line in Pygtail(logfile, full_lines=True): # process_line(line) for line in tail("-f", logfile, _iter=True): process_line(line) if __name__ == '__main__': # start cmdline processing parser = ArgumentParser(description='Jitsi Meet Conference Stats') parser.add_argument('--log', '-l', help='full path to jicofo logfile eg. /var/log/jitsi/jicofo.log') parser.add_argument('--verbose', '-v', help='be verbose eg. for debugging', action='store_true') parser.add_argument('--logwatch', '-w', help='run as logwatch module, dont start the webserver and only run once') args = parser.parse_args() if args.log: try: loggerThread = logThread(1, "Thread-Logger", args.log) loggerThread.start() except: print('Error: unable to start threads') hostName = 'localhost' serverPort = 9999 webServer = HTTPServer((hostName, serverPort), MyServer) try: print("Server started http://%s:%s" % (hostName, serverPort)) webServer.serve_forever() except: pass # for key in roomList: # print('Room : {}'.format(roomList[key].jid)) # print(' Created: {}'.format(roomList[key].ctime)) # print(' Owner : {}'.format(roomList[key].getOwner())) # print(' Members: {}'.format(roomList[key].getMembers()))