1
0
mirror of https://github.com/linkedin/oncall.git synced 2025-11-27 23:18:38 +02:00

[oncall] optionally hide oncall contact information (#297)

Still defaults to showing the contact information.
This commit is contained in:
Xinyu (Colin) Yang
2020-02-28 14:51:08 -08:00
committed by GitHub
parent b6bd71f5ae
commit 5b9520837f
13 changed files with 116 additions and 56 deletions

View File

@@ -7,9 +7,9 @@ from icalendar import Calendar, Event, vCalAddress, vText
from pytz import utc from pytz import utc
def events_to_ical(events, identifier): def events_to_ical(events, identifier, contact=True):
connection = db.connect() connection = db.connect()
cursor = connection.cursor() cursor = connection.cursor(db.DictCursor)
ical = Calendar() ical = Calendar()
ical.add('calscale', 'GREGORIAN') ical.add('calscale', 'GREGORIAN')
@@ -22,17 +22,29 @@ def events_to_ical(events, identifier):
for event in events: for event in events:
username = event['user'] username = event['user']
if username not in users: if username not in users:
cursor.execute(''' if contact:
SELECT `user`.`full_name`, `contact_mode`.`name`, `user_contact`.`destination` cursor.execute('''
FROM `user_contact` SELECT
JOIN `contact_mode` ON `contact_mode`.`id` = `user_contact`.`mode_id` `user`.`full_name` AS full_name,
JOIN `user` ON `user`.`id` = `user_contact`.`user_id` `contact_mode`.`name` AS contact_mode,
WHERE `user`.`name` = %s `user_contact`.`destination` AS destination
''', username) FROM `user_contact`
JOIN `contact_mode` ON `contact_mode`.`id` = `user_contact`.`mode_id`
JOIN `user` ON `user`.`id` = `user_contact`.`user_id`
WHERE `user`.`name` = %s
''', username)
else:
cursor.execute('''
SELECT `user`.`full_name` AS full_name
FROM `user`
WHERE `user`.`name` = %s
''', username)
info = {'username': username, 'contacts': {}} info = {'username': username, 'contacts': {}}
for row in cursor: for row in cursor:
info['full_name'] = row[0] info['full_name'] = row['full_name']
info['contacts'][row[1]] = row[2] if contact:
info['contacts'][row['contact_mode']] = row['destination']
users[username] = info users[username] = info
user = users[username] user = users[username]
@@ -47,10 +59,10 @@ def events_to_ical(events, identifier):
'%s %s shift: %s' % (event['team'], event['role'], full_name)) '%s %s shift: %s' % (event['team'], event['role'], full_name))
cal_event.add('description', cal_event.add('description',
'%s\n' % full_name + '%s\n' % full_name +
'\n'.join(['%s: %s' % (mode, dest) for mode, dest in user['contacts'].items()])) ('\n'.join(['%s: %s' % (mode, dest) for mode, dest in user['contacts'].items()]) if contact else ''))
# Attach info about the user oncall # Attach info about the user oncall
attendee = vCalAddress('MAILTO:%s' % user['contacts'].get('email')) attendee = vCalAddress('MAILTO:%s' % (user['contacts'].get('email') if contact else ''))
attendee.params['cn'] = vText(full_name) attendee.params['cn'] = vText(full_name)
attendee.params['ROLE'] = vText('REQ-PARTICIPANT') attendee.params['ROLE'] = vText('REQ-PARTICIPANT')
cal_event.add('attendee', attendee, encode=0) cal_event.add('attendee', attendee, encode=0)

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import iris from ... import iris
from ujson import dumps as json_dumps from ujson import dumps as json_dumps

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ujson import dumps as json_dumps from ujson import dumps as json_dumps

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ujson import dumps as json_dumps from ujson import dumps as json_dumps

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ujson import dumps as json_dumps from ujson import dumps as json_dumps
from falcon import HTTPNotFound, HTTPBadRequest from falcon import HTTPNotFound, HTTPBadRequest

View File

@@ -7,25 +7,7 @@ from . import ical
from ... import db from ... import db
def on_get(req, resp, team): def get_team_events(team, start):
"""
Get ics file for a given team's on-call events. Gets all events starting
after the optional "start" parameter, which defaults to the current
time. If defined, start should be a Unix timestamp in seconds.
**Example request:**
.. sourcecode:: http
GET /api/v0/teams/test-team/ical?start=12345 HTTP/1.1
Content-Type: text/calendar
BEGIN:VCALENDAR
...
"""
start = req.get_param_as_int('start')
if start is None:
start = int(time.time())
connection = db.connect() connection = db.connect()
cursor = connection.cursor(db.DictCursor) cursor = connection.cursor(db.DictCursor)
@@ -51,5 +33,32 @@ def on_get(req, resp, team):
events = cursor.fetchall() events = cursor.fetchall()
cursor.close() cursor.close()
connection.close() connection.close()
resp.body = ical.events_to_ical(events, team) return events
def on_get(req, resp, team):
"""
Get ics file for a given team's on-call events. Gets all events starting
after the optional "start" parameter, which defaults to the current
time. If defined, start should be a Unix timestamp in seconds.
**Example request:**
.. sourcecode:: http
GET /api/v0/teams/test-team/ical?start=12345 HTTP/1.1
Content-Type: text/calendar
BEGIN:VCALENDAR
...
"""
start = req.get_param_as_int('start')
if start is None:
start = int(time.time())
contact = req.get_param_as_bool('contact')
if contact is None:
contact = True
events = get_team_events(team, start)
resp.body = ical.events_to_ical(events, team, contact)
resp.set_header('Content-Type', 'text/calendar') resp.set_header('Content-Type', 'text/calendar')

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db, iris from ... import db, iris
from ...utils import load_json_body from ...utils import load_json_body
from ...auth import login_required from ...auth import login_required

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ...auth import login_required, check_team_auth from ...auth import login_required, check_team_auth
from falcon import HTTPNotFound from falcon import HTTPNotFound

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ujson import dumps as json_dumps from ujson import dumps as json_dumps
from falcon import HTTPError, HTTPBadRequest, HTTP_201 from falcon import HTTPError, HTTPBadRequest, HTTP_201
@@ -60,4 +63,4 @@ def on_post(req, resp, team):
cursor.close() cursor.close()
connection.close() connection.close()
resp.status = HTTP_201 resp.status = HTTP_201

View File

@@ -1,6 +1,9 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ...constants import SUPPORTED_TIMEZONES from ...constants import SUPPORTED_TIMEZONES
from ujson import dumps as json_dumps from ujson import dumps as json_dumps
def on_get(req, resp): def on_get(req, resp):
resp.body = json_dumps(SUPPORTED_TIMEZONES) resp.body = json_dumps(SUPPORTED_TIMEZONES)

View File

@@ -6,26 +6,7 @@ from . import ical
from ... import db from ... import db
def on_get(req, resp, user_name): def get_user_events(user_name, start):
"""
Get ics file for a given user's on-call events. Gets all events starting
after the optional "start" parameter, which defaults to the current
time. If defined, start should be a Unix timestamp in seconds.
**Example request:**
.. sourcecode:: http
GET /api/v0/users/jdoe/ical HTTP/1.1
Content-Type: text/calendar
BEGIN:VCALENDAR
...
"""
start = req.get_param_as_int('start')
if start is None:
start = int(time.time())
connection = db.connect() connection = db.connect()
cursor = connection.cursor(db.DictCursor) cursor = connection.cursor(db.DictCursor)
@@ -51,5 +32,33 @@ def on_get(req, resp, user_name):
events = cursor.fetchall() events = cursor.fetchall()
cursor.close() cursor.close()
connection.close() connection.close()
resp.body = ical.events_to_ical(events, user_name) return events
def on_get(req, resp, user_name):
"""
Get ics file for a given user's on-call events. Gets all events starting
after the optional "start" parameter, which defaults to the current
time. If defined, start should be a Unix timestamp in seconds.
**Example request:**
.. sourcecode:: http
GET /api/v0/users/jdoe/ical HTTP/1.1
Content-Type: text/calendar
BEGIN:VCALENDAR
...
"""
start = req.get_param_as_int('start')
if start is None:
start = int(time.time())
contact = req.get_param_as_bool('contact')
if contact is None:
contact = True
events = get_user_events(user_name, start)
resp.body = ical.events_to_ical(events, user_name, contact)
resp.set_header('Content-Type', 'text/calendar') resp.set_header('Content-Type', 'text/calendar')

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ...auth import login_required, check_user_auth from ...auth import login_required, check_user_auth
from falcon import HTTPNotFound from falcon import HTTPNotFound

View File

@@ -1,3 +1,6 @@
# Copyright (c) LinkedIn Corporation. All rights reserved. Licensed under the BSD-2 Clause license.
# See LICENSE in the project root for license information.
from ... import db from ... import db
from ...utils import load_json_body from ...utils import load_json_body
from ...auth import login_required, check_user_auth from ...auth import login_required, check_user_auth