Files
Link-Log/backend/app/api/links.py
T
2026-08-25 08:39:46 +02:00

75 lines
2.4 KiB
Python

## Copyright © 2026 Olaf Kolkman
## SPDX-License-Identifier: GPL-3.0-or-later
from fastapi import APIRouter, Header, HTTPException, status
from pydantic import BaseModel
from backend.app.services.link_service import create_link, list_public_links, list_tags, update_link
from backend.app.services.plugin_manager import plugin_manager
from backend.app.services.token_service import validate_token
router = APIRouter()
class LinkCreate(BaseModel):
title: str
url: str
comment: str = ''
timestamp: str | None = None
tags: list[str] = []
class LinkUpdate(BaseModel):
title: str
url: str
comment: str = ''
tags: list[str] = []
@router.get('/tags')
def available_tags():
return list_tags()
@router.post('/links', status_code=status.HTTP_201_CREATED)
def create_link_endpoint(payload: LinkCreate, authorization: str | None = Header(default=None)):
if not authorization or not authorization.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Missing or invalid Authorization header')
token = authorization.replace('Bearer ', '', 1)
info = validate_token(token)
if info is None:
raise HTTPException(status_code=401, detail='Token expired or invalid')
try:
record = create_link(info['user_id'], payload.title, payload.url, payload.comment, payload.timestamp, payload.tags)
except ValueError as error:
raise HTTPException(status_code=422, detail=str(error)) from error
plugin_manager.dispatch({'type': 'link_created', **record})
return record
@router.put('/links/{link_id}')
def update_link_endpoint(
link_id: str,
payload: LinkUpdate,
authorization: str | None = Header(default=None),
):
if not authorization or not authorization.startswith('Bearer '):
raise HTTPException(status_code=401, detail='Missing or invalid Authorization header')
info = validate_token(authorization.replace('Bearer ', '', 1))
if info is None:
raise HTTPException(status_code=401, detail='Token expired or invalid')
try:
record = update_link(link_id, info['user_id'], payload.title, payload.url, payload.comment, payload.tags)
except ValueError as error:
raise HTTPException(status_code=422, detail=str(error)) from error
if record is None:
raise HTTPException(status_code=404, detail='Link not found or not owned by user')
return record
@router.get('/links')
def list_links():
return list_public_links()