Commit aaafe135 authored by Johannes Barthel's avatar Johannes Barthel
Browse files

refactor into single file, no more copy/paste code

parent 314a4647
#!/usr/bin/env python3
import greenswitch
from xml.dom.minidom import parse
import pymongo
import json
import logging
logging.basicConfig(level=logging.DEBUG)
# find out password for esl socket
dom = parse("/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml")
password = None
for param in dom.getElementsByTagName("param"):
if param.attributes.get("name").nodeValue == "password":
password = param.attributes.get("value").nodeValue
if password is None:
raise ValueError("no password found in config")
# connect to mongo
mongo = pymongo.MongoClient("127.0.1.1")
db = mongo.meteor
# connect to freeswitch
fs = greenswitch.InboundESL(host='127.0.0.1', port=8021, password=password)
fs.connect()
def get_fs_member_id(caller_num, conference_id):
fs_conference = json.loads(fs.send("api conference {} json_list".format(conference_id)).data)[0]
fs_member_id = [m["id"] for m in fs_conference["members"] if m["caller_id_number"] == caller_num][0]
return fs_member_id
# wait until participant's right to use the mic gets restricted
for change in db.meetings.watch([{ "$match" : {"operationType" : "update" }}]):
print("meeting is now disableMic?")
mics_disabled = change['updateDescription']['updatedFields']['lockSettingsProps']['disableMic']
if not mics_disabled:
print("no")
continue
print("yes")
meeting_mongo_id = change['documentKey']['_id']
meeting = db.meetings.find_one({"_id": meeting_mongo_id})
#print("meeting",meeting)
conference_id = meeting["voiceProp"]["voiceConf"]
for user in db.voiceUsers.find({"joined":True, "meetingId": meeting["meetingId"]}):
#print("user")
#print(user)
if user["callerNum"].startswith("w_"):
#print("is a web user")
continue # this is a web user, phone users have their number as callerNum
fs_member_id = get_fs_member_id(user["callerNum"], conference_id)
print("muting phone user {} in meeting \"{}\" due to meeting-wide mic permission restriction by moderator".format(user["callerNum"], meeting["meetingProp"]["name"]))
#print(fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
#!/usr/bin/env python3
import greenswitch
from xml.dom.minidom import parse
import pymongo
import json
import logging
logging.basicConfig(level=logging.DEBUG)
# find out password for esl socket
dom = parse("/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml")
password = None
for param in dom.getElementsByTagName("param"):
if param.attributes.get("name").nodeValue == "password":
password = param.attributes.get("value").nodeValue
if password is None:
raise ValueError("no password found in config")
# connect to mongo
mongo = pymongo.MongoClient("127.0.1.1")
db = mongo.meteor
# connect to freeswitch
fs = greenswitch.InboundESL(host='127.0.0.1', port=8021, password=password)
fs.connect()
def get_fs_member_id(caller_num, conference_id):
fs_conference = json.loads(fs.send("api conference {} json_list".format(conference_id)).data)[0]
fs_member_id = [m["id"] for m in fs_conference["members"] if m["caller_id_number"] == caller_num][0]
return fs_member_id
def show_event(evt):
#print(evt.headers)
digit = int(evt.headers["DTMF-Digit"])
if digit != 0:
return
caller_num = evt.headers["Caller-Username"]
# SECURITY: this assumes there is only one voiceUser per call. What happens
# if there are multiple concurrent calls from the same number in
# different meetings?
voice_user = db.voiceUsers.find_one({"callerNum":caller_num, "joined": True})
if voice_user is None:
return
meeting_id = voice_user["meetingId"]
meeting = db.meetings.find_one({"meetingId": meeting_id})
locked = meeting["lockSettingsProps"]["disableMic"]
conference_id = meeting["voiceProp"]["voiceConf"]
fs_member_id = get_fs_member_id(caller_num, conference_id)
print("caller {} pressed {}, they are in a {} meeting.".format(caller_num, digit, "locked" if locked else "unlocked"))
try:
if not locked:
print(fs.send("api conference {} tmute {}".format(conference_id, fs_member_id)).data)
else:
print(fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
except KeyError as e:
print("Error when sending (t)mute:")
print(e)
# register handler
print(fs.send('EVENTS PLAIN DTMF').data)
# fs.register_handle("DTMF", lambda event: print(event.__dict__))
fs.register_handle("DTMF", show_event)
fs.process_events()
#!/usr/bin/env python3
import greenswitch
from xml.dom.minidom import parse
import pymongo
import json
import logging
import subprocess
import sys, os
logging.basicConfig(level=logging.DEBUG)
class ModeratedMic:
def __init__(self):
# find out password for esl socket
dom = parse("/opt/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml")
password = None
for param in dom.getElementsByTagName("param"):
if param.attributes.get("name").nodeValue == "password":
password = param.attributes.get("value").nodeValue
if password is None:
raise ValueError("no password found in config")
# connect to mongo
mongo = pymongo.MongoClient("127.0.1.1")
self.db = mongo.meteor
# connect to freeswitch
self.fs = greenswitch.InboundESL(host='127.0.0.1', port=8021, password=password)
self.fs.connect()
def _get_fs_member_id(self, caller_num, conference_id):
fs_conference = json.loads(self.fs.send("api conference {} json_list".format(conference_id)).data)[0]
fs_member_id = [m["id"] for m in fs_conference["members"] if m["caller_id_number"] == caller_num][0]
return fs_member_id
def _handle_dtmf_key(self, evt):
#print(evt.headers)
digit = int(evt.headers["DTMF-Digit"])
if digit != 0:
return
caller_num = evt.headers["Caller-Username"]
# SECURITY: this assumes there is only one voiceUser per call. What happens
# if there are multiple concurrent calls from the same number in
# different meetings?
voice_user = self.db.voiceUsers.find_one({"callerNum": caller_num, "joined": True})
if voice_user is None:
return
meeting_id = voice_user["meetingId"]
meeting = self.db.meetings.find_one({"meetingId": meeting_id})
locked = meeting["lockSettingsProps"]["disableMic"]
conference_id = meeting["voiceProp"]["voiceConf"]
fs_member_id = self._get_fs_member_id(caller_num, conference_id)
print("caller {} pressed {}, they are in a {} meeting.".format(caller_num, digit, "locked" if locked else "unlocked"))
try:
if not locked:
print(self.fs.send("api conference {} tmute {}".format(conference_id, fs_member_id)).data)
else:
print(self.fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
except KeyError as e:
# TODO investigate what actually happens here
print("Error when sending (t)mute:")
print(e)
def run_as_zero_key_handler(self):
# register handler
print(self.fs.send('EVENTS PLAIN DTMF').data)
self.fs.register_handle("DTMF", self._handle_dtmf_key)
# start main loop
self.fs.process_events()
def run_as_permissions_change_handler(self):
# main loop iterates over mongodb events
for change in self.db.meetings.watch([{ "$match" : {"operationType" : "update" }}]):
print("got meeting update event")
try:
mics_disabled = change['updateDescription']['updatedFields']['lockSettingsProps']['disableMic']
except KeyError as _:
print("the meeting update did not concern permissions")
continue
if not mics_disabled:
print("mics not disabled")
continue
print("mics are disabled")
# note: this will mute mics "again" if they were already muted
# and some other permission change caused the event to fire.
meeting_mongo_id = change['documentKey']['_id']
meeting = self.db.meetings.find_one({"_id": meeting_mongo_id})
#print("meeting",meeting)
conference_id = meeting["voiceProp"]["voiceConf"]
for user in self.db.voiceUsers.find({"joined":True, "meetingId": meeting["meetingId"]}):
#print("user")
#print(user)
if user["callerNum"].startswith("w_"):
#print("is a web user")
continue # this is a web user, phone users have their number as callerNum
fs_member_id = self._get_fs_member_id(user["callerNum"], conference_id)
print("muting phone user {} in meeting \"{}\" due to meeting-wide mic permission restriction by moderator".format(user["callerNum"], meeting["meetingProp"]["name"]))
print(self.fs.send("api conference {} mute {}".format(conference_id, fs_member_id)).data)
if __name__ == "__main__":
if len(sys.argv) == 1:
os.chdir(os.path.dirname(sys.argv[0]))
zero_key_handler = subprocess.Popen(["./events.py", "zero_key_handler"])
permissions_change_handler = subprocess.Popen(["./events.py", "permissions_change_handler"])
zero_key_handler.wait()
permissions_change_handler.wait()
exit(0)
moderated_mic = ModeratedMic()
if sys.argv[1] == "zero_key_handler":
moderated_mic.run_as_zero_key_handler()
elif sys.argv[1] == "permissions_change_handler":
moderated_mic.run_as_permissions_change_handler()
else:
print("invalid first argument")
exit(0)
#!/bin/bash
cd "$(dirname "$0")"
trap 'kill %1' SIGINT
./events-observe-lockmic.py & ./events-observe-zerokey.py
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment