elstat/elstat/blueprints/incidents.py

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)