-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathslReadConfig.py
executable file
·217 lines (203 loc) · 10.4 KB
/
slReadConfig.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
# scheduLight - automation tool for BigBlueButton and Greenlight
# copyright Martin Thomas Schrott 2020
#
# This file is part of scheduLight
# scheduLight is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
# You should have received a copy of the GNU General Public License along with Foobar. If not, see <https://www.gnu.org/licenses/>.
#
import logging.handlers
import argparse, sys, os, logging, yaml, json
from datetime import datetime, timedelta
from scheduLight import scheduLight
def parseArgs():
parser = argparse.ArgumentParser()
parser.add_argument("-c","--configFile", help="path to config file in yaml format", default="./config.yml")
parser.add_argument("-k","--keep_redis_cache", help="keep the status and config in redis cache for n seconds", default="31536000")
parser.add_argument("-i","--importCSV", help="path to meetings csv file to import")
parser.add_argument("-d","--delete_meetings", help="delete meetings from redis if they where remove from the config file", action="store_true")
parser.add_argument("-g","--logFile", help="path to logFile in yaml format", default="./scheduLight.log")
return parser.parse_args()
def write_yaml(dataFile,config):
with open(dataFile, 'w') as outfile:
yaml.dump(config, outfile, default_flow_style=False, allow_unicode=True)
def read_yaml(dataFile, ignore_missing_file = False):
try:
with open(dataFile, 'r') as stream:
try:
return yaml.load(stream, Loader=yaml.SafeLoader)
except yaml.YAMLError as ERR:
logger.error(ERR)
sys.exit()
except FileNotFoundError as ERR:
if ignore_missing_file != True:
sys.exit()
#############
### start ###
#parse the commandline arguments
args = parseArgs()
## create logger with 'readConfig'
logger = logging.getLogger('readConfig')
logger.setLevel(logging.INFO)
## create file handler which logs even debug messages
fh = logging.handlers.RotatingFileHandler(args.logFile, maxBytes=1000000, backupCount=5)
fh.setLevel(logging.INFO)
## create console handler with a higher log level
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
## create formatter and add it to the handlers
formatter = logging.Formatter('%(asctime)s %(name)-12s %(levelname)-8s %(message)s', '%Y-%m-%d %H:%M:%S')
fh.setFormatter(formatter)
formatter2 = logging.Formatter('%(levelname)-8s %(message)s')
ch.setFormatter(formatter2)
## add the handlers to the logger
logger.addHandler(fh)
logger.addHandler(ch)
#
logger.debug("starting...")
# init sheduLight instance
sl = scheduLight(args)
# set startTime
NOW = datetime.now()
logger.debug("Date: {}".format(NOW))
# loading config
logger.debug("loading config from {}...".format(args.configFile))
meetingsConfig = read_yaml(args.configFile)
#import meetings csv to configFile
if args.importCSV:
logger.debug("import meetings csv from {} to config file...".format(args.importCSV))
if 'meetings' not in meetingsConfig:
meetingsConfig['meetings'] = {}
mDict = meetingsConfig['meetings']
with open(args.importCSV, 'r') as csv:
for line in csv:
(givenname, sn, email, password, startdate, room_url, live_url, title, server) = line.strip().split(';')
givenname = givenname.strip()
sn = sn.strip()
name = "{} {}".format(givenname, sn)
orig_email = email.strip()
email = email.lower().strip()
password = password.strip()
startdate = startdate.strip()
if startdate == '0000-00-00':
startdate = None
meetingTitle = title
meetingKey = email.replace('@', '_').replace('.', '_')
server = server.strip()
# meeting infos
mDict[meetingKey] = {}
mDict[meetingKey]['id'] = meetingKey
mDict[meetingKey]['server'] = server
mDict[meetingKey]['meetingName'] = "{}".format(name)
mDict[meetingKey]['meetingTitle'] = meetingTitle
if startdate:
mDict[meetingKey]['startDate'] = startdate
# owner info
mDict[meetingKey]['owner'] = {}
mDict[meetingKey]['useHomeRoom'] = True
mDict[meetingKey]['owner']['email'] = email
mDict[meetingKey]['owner']['password'] = password
mDict[meetingKey]['owner']['socialUid'] = "CN={},OU=USERS,OU=EXTERNAL,DC=ldap,DC=domain,DC=tld".format(orig_email)
mDict[meetingKey]['owner']['fullName'] = name
# templates
mDict[meetingKey]['meetingOwnerInfoTemplate'] = "imported-meetingOwnerInfoTemplate.j2"
mDict[meetingKey]['meetingModeratorInfoTemplate'] = "imported-meetingModeratorInfoTemplate.j2"
mDict[meetingKey]['meetingShareInfoTemplate'] = "imported-meetingShareInfoTemplate.j2"
mDict[meetingKey]['meetingInvitationInfoTemplate'] = "imported-meetingInvitationInfoTemplate.j2"
mDict[meetingKey]['meetingOwnerStartedTemplate'] = "imported-meetingOwnerStartedTemplate.j2"
mDict[meetingKey]['meetingOwnerReminderTemplate'] = "imported-meetingOwnerReminderTemplate.j2"
#settings
mDict[meetingKey]['muteOnStart'] = "true"
# mDict[meetingKey]['welcome'] = None
# mDict[meetingKey]['bannerText'] = None
mDict[meetingKey]['maxParticipants'] = 150
mDict[meetingKey]['logoutURL'] = "importet.logout.url"
# mDict[meetingKey]['record'] = None
# mDict[meetingKey]['duration'] = None
# mDict[meetingKey]['autoStartRecording'] = False
# mDict[meetingKey]['allowStartStopRecording'] = None
#mDict[meetingKey]['accessCode'] = ""
# prepare liveStreaming parameters
mDict[meetingKey]['liveStreaming'] = {}
mDict[meetingKey]['liveStreaming']['playIntro'] = "/video/5min.mp4"
mDict[meetingKey]['liveStreaming']['streamerHost'] = live_url
mDict[meetingKey]['liveStreaming']['targetUrl'] = "rtmp://{}/stream/bbb".format(live_url)
write_yaml(args.configFile, meetingsConfig)
# read config from file
else:
if 'servers' in meetingsConfig:
serversList = set(meetingsConfig['servers'])
# update servers list in redis
if sl.r.exists('servers'):
logger.debug("store last servers to compare: {}".format(sl.r.rename('servers', 'oldservers')))
# process servers in config
for server in serversList:
logger.debug("processing {}...".format(server))
errors = sl.server_schema.validate(meetingsConfig['servers'][server])
if errors:
logger.error("please provide all required fields for the server: {}".format(errors))
continue
try:
sl.r.sadd('servers', server)
sl.r.set('server:{}'.format(server), json.dumps(meetingsConfig['servers'][server]))
sl.r.expire('server:{}'.format(server), args.keep_redis_cache)
logger.info("added server {}".format(server))
except Exception as ERR:
logger.error("failed to add server {} to queue. {}".format(m, ERR))
if args.delete_meetings:
# delete servers that where removed from the configFile
logger.debug("store removed servers for deletion: {}".format(sl.r.sdiffstore('delservers', 'oldservers', 'servers')))
for server in sl.r.smembers('delservers'):
logger.info("Remove server: {}".format(server))
sl.r.delete("server:{}".format(server))
sl.r.delete("server:{}:status".format(server))
sl.r.srem('servers', server)
logger.debug("clear cache of removed servers: {}".format(sl.r.delete('oldservers')))
if 'meetings' in meetingsConfig:
# update meetings list in redis
if sl.r.exists('meetings'):
logger.debug("store last meetings to compare: {}".format(sl.r.rename('meetings', 'oldMeetings')))
meetingsList = set(meetingsConfig['meetings'])
for m in meetingsList:
logger.debug("processing {}...".format(m))
errors = sl.meeting_schema.validate(meetingsConfig['meetings'][m])
if errors:
logger.error("please provide all required fields for the meeting: {}".format(errors))
continue
try:
sl.r.sadd('meetings', m)
sl.r.set('meeting:{}'.format(m), json.dumps(meetingsConfig['meetings'][m]))
sl.r.expire('meeting:{}'.format(m), args.keep_redis_cache)
logger.info("added meeting {}".format(m))
except Exception as ERR:
logger.error("failed to add meeting {} to queue. {}".format(m, ERR))
if args.delete_meetings:
# delete meetings that where removed from the configFile
logger.debug("store removed meetings for deletion: {}".format(sl.r.sdiffstore('delMeetings', 'oldMeetings', 'meetings')))
for meeting in sl.r.smembers('delMeetings'):
logger.info("Remove meeting: {}".format(meeting))
sl.r.delete("meeting:{}".format(meeting))
sl.r.delete("meeting:{}:status".format(meeting))
sl.r.srem('meetings', meeting)
logger.debug("clear cache of removed meetings: {}".format(sl.r.delete('oldMeetings')))
if 'commands' in meetingsConfig:
# add commands to redis queue
commandsList = set(meetingsConfig['commands'])
for m in commandsList:
logger.debug("processing {}...".format(m))
errors = sl.command_schema.validate(meetingsConfig['commands'][m])
if errors:
logger.error("please provide all required fields for the command: {}".format(errors))
continue
# put command to queue
try:
res = sl.r.xadd('commandStream', { m: json.dumps(meetingsConfig['commands'][m]) })
logger.info("queued command {}".format(m))
except Exception as ERR:
logger.error("failed to queue command {} to queue. {}".format(m, ERR))
# shut down
sl.r.bgsave()
sl.r.connection_pool.disconnect()