153 lines
3.4 KiB
Python
153 lines
3.4 KiB
Python
import time
|
|
import datetime
|
|
|
|
from sanic import Blueprint, response
|
|
|
|
from .decorators import auth_route
|
|
from .streaming import OP
|
|
from ..snowflake import get_snowflake
|
|
|
|
|
|
bp = Blueprint(__name__)
|
|
|
|
|
|
def fetch_stages(conn, incident_id: int) -> list:
|
|
"""Fetch all the stages for an incident"""
|
|
cur = conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT title, content, timestamp
|
|
FROM incident_stages
|
|
WHERE parent_id = ?
|
|
ORDER BY timestamp ASC
|
|
""", (incident_id,))
|
|
|
|
stage_rows = cur.fetchall()
|
|
|
|
def stage_obj(stage_row) -> dict:
|
|
"""give a stage dict, given the stage row."""
|
|
return {
|
|
'title': stage_row[0],
|
|
'content': stage_row[1],
|
|
'created_at': datetime.datetime.fromtimestamp(
|
|
stage_row[3]).isoformat(),
|
|
}
|
|
|
|
return list(map(stage_obj, stage_rows))
|
|
|
|
|
|
def incident_dict(conn, row) -> dict:
|
|
"""make an incident dict, given incident row."""
|
|
start_timestamp = datetime.datetime.fromtimestamp(row[5]).isoformat()
|
|
|
|
if row[6]:
|
|
end_timestamp = datetime.datetime.fromtimestamp(row[6]).isoformat()
|
|
else:
|
|
end_timestamp = None
|
|
|
|
return {
|
|
'id': str(row[0]),
|
|
'type': row[1],
|
|
'title': row[2],
|
|
'content': row[3],
|
|
'ongoing': row[4],
|
|
|
|
'start_date': start_timestamp,
|
|
'end_date': end_timestamp,
|
|
|
|
'stages': fetch_stages(conn, row[0])
|
|
}
|
|
|
|
|
|
@bp.get('/api/incidents/current')
|
|
async def get_current_incident(request):
|
|
"""Get the current incident, if any."""
|
|
manager = request.app.manager
|
|
cur = manager.conn.cursor()
|
|
|
|
cur.execute("""
|
|
SELECT id, incident_type, title, content, ongoing,
|
|
start_timestamp, end_timestamp
|
|
FROM incidents
|
|
ORDER BY id ASC
|
|
LIMIT 1
|
|
""")
|
|
|
|
rows = cur.fetchall()
|
|
|
|
try:
|
|
row = next(iter(rows))
|
|
drow = incident_dict(manager.conn, row)
|
|
except StopIteration:
|
|
row = None
|
|
drow = {}
|
|
|
|
return response.json({
|
|
'all_good': not drow.get('ongoing'),
|
|
'current_incident': None if drow == {} else drow
|
|
})
|
|
|
|
|
|
@bp.get('/api/incidents/<page:int>')
|
|
async def get_incidents(request, page: int):
|
|
"""Get a list of incidents."""
|
|
manager = request.app.manager
|
|
cur = manager.conn.cursor()
|
|
|
|
cur.execute(f"""
|
|
SELECT id, incident_type, title, content, ongoing,
|
|
start_timestamp, end_timestamp
|
|
FROM incidents
|
|
ORDER BY id DESC
|
|
|
|
LIMIT 10
|
|
OFFSET ({page} * 10)
|
|
""")
|
|
|
|
rows = cur.fetchall()
|
|
|
|
res = []
|
|
|
|
for row in rows:
|
|
res.append(incident_dict(manager.conn, row))
|
|
|
|
return response.json({
|
|
'incidents': res,
|
|
})
|
|
|
|
|
|
@bp.put('/api/incidents')
|
|
@auth_route
|
|
async def create_incident(request):
|
|
incident = request.json
|
|
manager = request.app.manager
|
|
|
|
incident_id = get_snowflake()
|
|
start_timestamp = time.time()
|
|
|
|
manager.conn.execute("""
|
|
INSERT INTO incidents (id, incident_type, title, content,
|
|
ongoing, start_timestamp, end_timestamp)
|
|
VALUES (?, ?, ?, ?, true, ?, NULL)
|
|
""", (
|
|
incident_id,
|
|
incident['type'],
|
|
incident['title'],
|
|
incident['content'],
|
|
start_timestamp,
|
|
))
|
|
manager.conn.commit()
|
|
|
|
d_incident = incident_dict(manager.conn, (
|
|
incident_id,
|
|
incident['type'],
|
|
incident['title'],
|
|
incident['content'],
|
|
True,
|
|
start_timestamp,
|
|
None
|
|
))
|
|
|
|
manager.publish_incident(OP.INCIDENT_NEW, d_incident)
|
|
return response.json(d_incident)
|