2021-11-01 16:42:52 -06:00
|
|
|
from http import HTTPStatus
|
|
|
|
|
|
2024-04-17 11:25:26 -06:00
|
|
|
from sanic import Request, response, Blueprint
|
2022-01-13 09:29:58 -07:00
|
|
|
from sanic_ext import validate
|
|
|
|
|
from sanic_ext.extensions.openapi import openapi
|
2021-11-01 16:42:52 -06:00
|
|
|
|
2022-03-08 13:26:03 -07:00
|
|
|
from modules.map import lib, schema
|
2026-03-29 18:58:31 -06:00
|
|
|
from modules.map.pins import get_map_pins_config
|
2024-04-17 11:25:26 -06:00
|
|
|
from wrolpi.api_utils import json_response
|
2026-03-29 18:58:31 -06:00
|
|
|
from wrolpi.common import wrol_mode_check
|
|
|
|
|
from wrolpi.events import Events
|
2022-03-08 13:26:03 -07:00
|
|
|
|
2024-04-17 11:25:26 -06:00
|
|
|
map_bp = Blueprint('Map', '/api/map')
|
2022-03-08 13:26:03 -07:00
|
|
|
|
|
|
|
|
|
2026-03-29 18:58:31 -06:00
|
|
|
@map_bp.get('/files')
|
|
|
|
|
@openapi.description('List available PMTiles map files')
|
|
|
|
|
def get_files(_: Request):
|
|
|
|
|
files = lib.get_pmtiles_files()
|
|
|
|
|
return json_response(dict(files=files), HTTPStatus.OK)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.delete('/files/<filename:str>')
|
|
|
|
|
@openapi.description('Delete a PMTiles map file')
|
2022-03-08 13:26:03 -07:00
|
|
|
@wrol_mode_check
|
2026-03-29 18:58:31 -06:00
|
|
|
async def delete_file(_: Request, filename: str):
|
|
|
|
|
try:
|
|
|
|
|
deleted = lib.delete_pmtiles_file(filename)
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
return response.json({'error': str(e)}, HTTPStatus.BAD_REQUEST)
|
2022-03-08 13:26:03 -07:00
|
|
|
|
2026-03-29 18:58:31 -06:00
|
|
|
if deleted:
|
|
|
|
|
return response.empty()
|
|
|
|
|
return response.json({'error': 'File not found'}, HTTPStatus.NOT_FOUND)
|
2022-03-08 13:26:03 -07:00
|
|
|
|
|
|
|
|
|
2026-03-29 18:58:31 -06:00
|
|
|
@map_bp.get('/subscribe')
|
|
|
|
|
@openapi.description('Get map catalog and current subscriptions')
|
|
|
|
|
def get_subscriptions(request: Request):
|
|
|
|
|
catalog = lib.get_map_catalog()
|
|
|
|
|
subscriptions = lib.get_map_subscriptions(request.ctx.session)
|
|
|
|
|
return json_response(dict(catalog=catalog, subscriptions=subscriptions), HTTPStatus.OK)
|
2022-03-08 13:26:03 -07:00
|
|
|
|
2026-03-29 18:58:31 -06:00
|
|
|
|
|
|
|
|
@map_bp.post('/subscribe')
|
|
|
|
|
@openapi.description('Subscribe to a map region for automatic downloads')
|
|
|
|
|
@validate(schema.MapSubscribeRequest)
|
|
|
|
|
@wrol_mode_check
|
|
|
|
|
async def post_subscribe(request: Request, body: schema.MapSubscribeRequest):
|
|
|
|
|
try:
|
|
|
|
|
await lib.subscribe(request.ctx.session, body.name, body.region)
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
return response.json({'error': str(e)}, HTTPStatus.BAD_REQUEST)
|
|
|
|
|
|
|
|
|
|
Events.send_created(f'Map subscription created for {body.name}')
|
|
|
|
|
return response.empty(HTTPStatus.CREATED)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.delete('/subscribe/<region:str>')
|
|
|
|
|
@openapi.description('Unsubscribe from a map region')
|
|
|
|
|
@wrol_mode_check
|
|
|
|
|
async def delete_subscription(request: Request, region: str):
|
|
|
|
|
try:
|
|
|
|
|
await lib.unsubscribe(request.ctx.session, region)
|
|
|
|
|
except ValueError as e:
|
|
|
|
|
return response.json({'error': str(e)}, HTTPStatus.NOT_FOUND)
|
|
|
|
|
|
|
|
|
|
return response.empty(HTTPStatus.NO_CONTENT)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.get('/pins')
|
|
|
|
|
@openapi.description('Get all map pins')
|
|
|
|
|
def get_pins(_: Request):
|
|
|
|
|
pins = get_map_pins_config().pins
|
|
|
|
|
return json_response(dict(pins=pins), HTTPStatus.OK)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.post('/pins')
|
|
|
|
|
@openapi.description('Add a map pin')
|
|
|
|
|
@validate(schema.MapPinRequest)
|
|
|
|
|
async def add_pin(_: Request, body: schema.MapPinRequest):
|
|
|
|
|
pin = get_map_pins_config().add_pin(body.lat, body.lon, body.label, body.color)
|
|
|
|
|
return json_response(dict(pin=pin), HTTPStatus.CREATED)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.delete('/pins/<pin_id:int>')
|
|
|
|
|
@openapi.description('Delete a map pin by ID')
|
|
|
|
|
async def delete_pin(_: Request, pin_id: int):
|
|
|
|
|
if get_map_pins_config().delete_pin(pin_id):
|
|
|
|
|
return response.empty(HTTPStatus.NO_CONTENT)
|
|
|
|
|
return response.json({'error': 'Pin not found'}, HTTPStatus.NOT_FOUND)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@map_bp.put('/pins/<pin_id:int>')
|
|
|
|
|
@openapi.description('Update a map pin by ID')
|
|
|
|
|
@validate(schema.MapPinUpdateRequest)
|
|
|
|
|
async def update_pin(_: Request, pin_id: int, body: schema.MapPinUpdateRequest):
|
|
|
|
|
if get_map_pins_config().update_pin(pin_id, body.label, body.color):
|
|
|
|
|
return response.empty(HTTPStatus.NO_CONTENT)
|
|
|
|
|
return response.json({'error': 'Pin not found'}, HTTPStatus.NOT_FOUND)
|