Commit c47a2d1c authored by Martin Mareš's avatar Martin Mareš
Browse files

Hooks: New data model should make everything simpler

And as a side effect, correct :)
parent 4a57aec0
......@@ -40,8 +40,6 @@ def db_query(query, args=()):
### Utilities ###
# FIXME: Move to shared code?
def parse_time(iso_time):
return dateutil.parser.isoparse(iso_time)
......@@ -53,57 +51,32 @@ class HookApp:
self.env = env
self.wsgi_start = start_response
def log(self, msg):
print(msg, file=self.env['wsgi.errors'], flush=True)
def http_error(self, code, msg, extra_headers=[]):
self.wsgi_start("{} {}".format(code, msg), extra_headers + [
('Content-Type', 'text/plain')
])
return ["{} {}".format(code, msg)]
def create_regular_meeting(self, uid, meeting):
meeting_id = meeting["id"]
self.log(f"Meeting {meeting_id}: Planning")
def create_schedule(self, mid, meeting_id, occurrence_id, occ):
self.log("Meeting {meeting_id}.{occurrence_id}: Scheduling")
db_query("""
INSERT INTO zoom_meetings
(meeting_id, uuid, host_id, topic, type, start_time, duration)
VALUES (%s, %s, %s, %s, %s, %s, %s)
INSERT INTO zoom_schedule
(mid, occurrence_id, start_time, duration)
VALUES (%s, %s, %s, %s)
""", (
meeting_id,
meeting['uuid'],
uid,
meeting['topic'],
meeting['type'],
parse_time(meeting['start_time']),
meeting['duration'],
mid,
occurrence_id,,
parse_time(occ['start_time']),
occ['duration'],
))
def create_recurring_meeting(self, uid, meeting):
meeting_id = meeting["id"]
for occ in meeting["occurrences"]:
occ_id = occ["occurrence_id"]
self.log(f"Meeting {meeting_id}: Planning occurrence {occ_id}")
db_query("""
INSERT INTO zoom_meetings
(meeting_id, uuid, occurrence_id, host_id, topic, type, start_time, duration)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
""", (
meeting_id,
meeting['uuid'],
occ_id,
uid,
meeting['topic'],
meeting['type'],
parse_time(occ['start_time']),
occ['duration'],
))
def create_meeting(self, js):
payload = js["payload"]
meeting = payload["object"]
......@@ -116,42 +89,39 @@ class HookApp:
self.log(f"Meeting {meeting_id}: Host {host_user_id} not found in zoom_users")
return
type = meeting["type"]
if type == 2:
self.create_regular_meeting(user.id, meeting)
elif type == 8:
self.create_recurring_meeting(user.id, meeting)
else:
self.log(f"Meeting {meeting_id}: Unknown type {type}")
return
def delete_regular_meeting(self, meeting):
meeting_id = meeting["id"]
self.log(f"Meeting {meeting_id}: Deleting")
db_query("""
DELETE FROM zoom_meetings
WHERE meeting_id=%s
INSERT INTO zoom_meetings
(meeting_id, uuid, host_uid, topic, type)
VALUES (%s, %s, %s, %s, %s)
RETURNING mid
""", (
meeting_id,
meeting['uuid'],
user.uid,
meeting['topic'],
meeting['type'],
))
meeting_row = db.fetchone()
mid = meeting_row.mid
mtype = meeting["type"]
self.log(f"Meeting {meeting_id}: Creating with mid={mid}, type={mtype}")
if mtype == 8:
for occ in meeting["occurrences"]:
self.create_schedule(mid, meeting_id, occ["occurrence_id"], meeting)
elif 'start_time' in meeting:
self.create_schedule(mid, meeting_id, 0, meeting)
def delete_recurring_meeting(self, meeting):
meeting_id = meeting["id"]
if "occurrences" not in meeting:
return self.delete_regular_meeting(meeting)
def delete_recurring_schedule(self, mid, meeting_id, meeting):
for occ in meeting["occurrences"]:
occ_id = occ["occurrence_id"]
self.log(f"Meeting {meeting_id}: Deleting occurrence {occ_id}")
self.log(f"Meeting {meeting_id}.{occ_id}: Descheduling")
db_query("""
DELETE FROM zoom_meetings
WHERE meeting_id=%s AND occurrence_id=%s
DELETE FROM zoom_schedule
WHERE mid=%s AND occurrence_id=%s
""", (
meeting_id,
mid,
occ_id,
))
......@@ -161,32 +131,27 @@ class HookApp:
meeting = payload["object"]
meeting_id = meeting["id"]
type = meeting["type"]
if type == 2:
self.delete_regular_meeting(meeting)
elif type == 8:
self.delete_recurring_meeting(meeting)
else:
self.log(f"Meeting {meeting_id}: Unknown type {type}")
db_query("SELECT * FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
meeting_row = db.fetchone()
if meeting_row is None:
self.log(f"Meeting {meeting_id}: Unknown on delete")
return
mid = meeting_row.mid
mtype = meeting_row.type
def update_common_attrs(self, meeting_id, occurrence_id, new):
if "topic" in new:
self.log(f"Meeting {meeting_id}.{occurrence_id}: Updating topic")
db_query("UPDATE zoom_meetings SET topic=%s WHERE meeting_id=%s AND (occurrence_id=%s OR %s = '0')",
(new["topic"], meeting_id, occurrence_id, occurrence_id))
for a in ['uuid', 'host_id']:
if a in new:
self.log(f"Meeting {meeting_id}.{occurrence_id}: Change of {a} not supported")
if mtype == 8 and "occurrences" in meeting:
delete_recurring_schedule(mid, meeting_id, meeting)
else:
self.log(f"Meeting {meeting_id}: Deleting")
db_query("DELETE FROM zoom_schedule WHERE mid=%s", (mid,))
db_query("DELETE FROM zoom_meetings WHERE mid=%s", (mid,))
def update_schedule(self, meeting_id, occurrence_id, new):
def update_schedule(self, mid, meeting_id, occurrence_id, new):
if "start_time" in new:
self.log(f"Meeting {meeting_id}.{occurrence_id}: Updating start time")
db_query("UPDATE zoom_meetings SET start_time=%s WHERE meeting_id=%s AND (occurrence_id=%s OR %s = '0')",
(parse_time(new['start_time']), meeting_id, occurrence_id, occurrence_id))
db_query("UPDATE zoom_schedule SET start_time=%s WHERE mid=%s AND occurrence_id=%s",
(parse_time(new['start_time']), mid, occurrence_id))
if "duration" in new:
self.log(f"Meeting {meeting_id}.{occurrence_id}: Updating duration")
......@@ -194,85 +159,43 @@ class HookApp:
(new['duration'], meeting_id, occurrence_id, occurrence_id))
def update_regular_meeting(self, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Updating regular meeting")
self.update_common_attrs(meeting_id, 0, new)
self.update_schedule(meeting_id, 0, new)
def update_recurring_meeting_single(self, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Updating single occurrence")
def update_meeting_single(self, mid, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Updating single occurrences")
for occ in new["occurrences"]:
self.update_common_attrs(meeting_id, occ["occurrence_id"], new)
self.update_schedule(meeting_id, occ["occurrence_id"], new) # e.g., duration can be set here
self.update_schedule(meeting_id, occ["occurrence_id"], occ)
self.update_schedule(mid, meeting_id, occ["occurrence_id"], new) # e.g., duration can be set here
self.update_schedule(mid, meeting_id, occ["occurrence_id"], occ)
def update_recurring_meeting_all(self, meeting_id, old, new):
meeting_id = new["id"]
def update_meeting_all(self, mid, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Updating all occurrences")
if "occurrences" not in new:
self.update_common_attrs(meeting_id, 0, new)
return
db_query("SELECT * FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
orig = db.fetchone()
if orig is None:
self.log(f"Meeting {meeting_id}: Update did not find previous version")
return
db_query("DELETE FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
for occ in new["occurrences"]:
occurrence_id = occ["occurrence_id"]
self.log(f"Meeting {meeting_id}.{occurrence_id}: Re-creating")
db_query("""
INSERT INTO zoom_meetings
(meeting_id, uuid, occurrence_id, host_id, topic, type, start_time, duration)
VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
""", (
meeting_id,
new.get('uuid', orig.uuid),
occurrence_id,
orig.host_id,
new.get('topic', orig.topic),
new.get('type', orig.type),
parse_time(occ['start_time']),
occ['duration'],
))
def update_regular_to_recurring(self, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Type change to recurring")
self.update_recurring_meeting_all(meeting_id, old, new)
def update_recurring_to_regular(self, meeting_id, old, new):
self.log(f"Meeting {meeting_id}: Type change to regular")
db_query("SELECT * FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
orig = db.fetchone()
if orig is None:
self.log(f"Meeting {meeting_id}: Update did not find previous version")
return
db_query("DELETE FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
if "occurrences" in new:
# So this will be a recurrent meeting, replace all occurrences
db_query("DELETE FROM zoom_schedule WHERE mid=%s", (mid,))
for occ in meeting["occurrences"]:
self.create_schedule(mid, meeting_id, occ["occurrence_id"], new)
elif "start_time" in new:
if new["start_time"] == "":
# Descheduling (this can happen in type 3 meetings)
self.log(f"Meeting {meeting_id}: Descheduling")
db_query("DELETE FROM zoom_schedule WHERE mid=%s", (mid,))
elif "duration" in new:
# Both start time and duration are set => can safely replacing schedule
self.log(f"Meeting {meeting_id}.0: Replacing schedule")
db_query("DELETE FROM zoom_schedule WHERE mid=%s", (mid,))
self.create_schedule(mid, meeting_id, 0, new)
else:
# This is just a schedule change
self.log(f"Meeting {meeting_id}.0: Rescheduling with new start_time")
db_query("UPDATE zoom_schedule SET start_time=%s WHERE mid=%s",
(parse_time(new["start_time"]), mid))
db_query("""
INSERT INTO zoom_meetings
(meeting_id, uuid, host_id, topic, type, start_time, duration)
VALUES (%s, %s, %s, %s, %s, %s, %s)
""", (
meeting_id,
new.get('uuid', orig.uuid),
orig.host_id,
new.get('topic', orig.topic),
new['type'],
parse_time(new['start_time']),
new['duration'],
))
elif "duration" in new:
# This is just a schedule change
self.log(f"Meeting {meeting_id}.0: Rescheduling with new duration")
db_query("UPDATE zoom_schedule SET duration=%s WHERE mid=%s",
(new["duration"], mid))
def update_meeting(self, js):
......@@ -281,24 +204,32 @@ class HookApp:
old = payload["old_object"]
meeting_id = new["id"]
db_query("SELECT * FROM zoom_meetings WHERE meeting_id=%s", (meeting_id,))
meeting_row = db.fetchone()
if meeting_row is None:
self.log(f"Meeting {meeting_id}: Unknown on update")
return
mid = meeting_row.mid
old_type = meeting_row.type
new_type = new.get("type", -1)
old_type = old.get("type", -1)
if old_type != new_type:
if old_type == 2 and new_type == 8:
self.update_regular_to_recurring(meeting_id, old, new)
elif old_type == 8 and new_type == 2:
self.update_recurring_to_regular(meeting_id, old, new)
else:
self.log(f"Meeting {meeting_id}: Unsupported type change from {old_type} to {new_type}")
return
self.log(f"Meeting {meeting_id}: Transmuting from from type {old_type} to {new_type}")
db_query("UPDATE zoom_meetings SET type=%s WHERE mid=%s", (new_type, mid))
if "topic" in new:
self.log(f"Meeting {meeting_id}: Updating topic")
db_query("UPDATE zoom_meetings SET topic=%s WHERE mid=%s", (new['topic'], mid))
for a in ['uuid', 'host_id']:
if a in new:
self.log(f"Meeting {meeting_id}: Change of {a} not supported")
scope = payload.get("scope", "")
if scope == "":
self.update_regular_meeting(meeting_id, old, new)
elif scope == "all":
self.update_recurring_meeting_all(meeting_id, old, new)
elif scope == "single":
self.update_recurring_meeting_single(meeting_id, old, new)
scope = payload.get("scope", "all")
if scope == "single":
self.update_meeting_single(mid, meeting_id, old, new)
elif scope == all":
self.update_meeting_all(mid, meeting_id, old, new)
else:
self.log(f"Meeting {meeting_id}: Unsupported update scope {scope}")
......
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