mirror of
https://github.com/Alexander-D-Karpov/akarpov
synced 2025-07-15 10:42:35 +03:00
Improve unknown link error
This commit is contained in:
parent
0505f63a9c
commit
44982a1190
|
@ -1,12 +1,12 @@
|
||||||
from typing import Annotated
|
from typing import Annotated
|
||||||
|
|
||||||
import django
|
import django
|
||||||
from fastapi import FastAPI, Depends, HTTPException, Header
|
from fastapi import FastAPI, Depends, Header
|
||||||
from fastapi.responses import RedirectResponse
|
from fastapi.responses import RedirectResponse, HTMLResponse
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
from starlette.requests import Request
|
from starlette.requests import Request
|
||||||
|
|
||||||
from redirect.db.curd import get_link_by_slug
|
from redirect.db.curd import get_link_by_slug, LinkNotFoundException
|
||||||
from redirect.db.dependency import get_db
|
from redirect.db.dependency import get_db
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,6 +17,32 @@
|
||||||
from akarpov.tools.shortener.tasks import save_view_meta # noqa: This has to be imported strictly AFTER django setup
|
from akarpov.tools.shortener.tasks import save_view_meta # noqa: This has to be imported strictly AFTER django setup
|
||||||
|
|
||||||
|
|
||||||
|
@app.exception_handler(LinkNotFoundException)
|
||||||
|
async def unicorn_exception_handler(request: Request, exc: LinkNotFoundException):
|
||||||
|
return HTMLResponse(
|
||||||
|
status_code=404,
|
||||||
|
# language=HTML
|
||||||
|
content="""
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<title>Unknown Link</title>
|
||||||
|
<style>
|
||||||
|
h1 {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", ui-system, sans-serif;
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: medium;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Such link doesn't exist or has been revoked</h1>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
""",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@app.get("/{slug}")
|
@app.get("/{slug}")
|
||||||
def redirect(slug: str, request: Request, db: Session = Depends(get_db), user_agent: Annotated[str | None, Header()] = None) -> RedirectResponse:
|
def redirect(slug: str, request: Request, db: Session = Depends(get_db), user_agent: Annotated[str | None, Header()] = None) -> RedirectResponse:
|
||||||
"""Main route that redirects to a page based on the slug."""
|
"""Main route that redirects to a page based on the slug."""
|
||||||
|
@ -24,8 +50,6 @@ def redirect(slug: str, request: Request, db: Session = Depends(get_db), user_ag
|
||||||
return RedirectResponse(url=f'/tools/shortener/p/{slug.replace("+", "")}')
|
return RedirectResponse(url=f'/tools/shortener/p/{slug.replace("+", "")}')
|
||||||
|
|
||||||
link = get_link_by_slug(db, slug)
|
link = get_link_by_slug(db, slug)
|
||||||
if link is None:
|
|
||||||
raise HTTPException(status_code=404, detail="Unknown Short Link")
|
|
||||||
|
|
||||||
save_view_meta.apply_async(
|
save_view_meta.apply_async(
|
||||||
kwargs={
|
kwargs={
|
||||||
|
|
|
@ -1,11 +1,14 @@
|
||||||
from typing import Optional
|
|
||||||
|
|
||||||
from sqlalchemy.orm import Session
|
from sqlalchemy.orm import Session
|
||||||
|
|
||||||
from redirect.db import models
|
from redirect.db import models
|
||||||
from redirect.util import slug_to_link_id
|
from redirect.util import slug_to_link_id
|
||||||
|
|
||||||
|
|
||||||
|
class LinkNotFoundException(Exception):
|
||||||
|
def __init__(self, slug: str):
|
||||||
|
self.slug = slug
|
||||||
|
|
||||||
|
|
||||||
def get_link(db: Session, link_id: int):
|
def get_link(db: Session, link_id: int):
|
||||||
"""Gets short link metdata by its id.
|
"""Gets short link metdata by its id.
|
||||||
|
|
||||||
|
@ -19,19 +22,20 @@ def get_link(db: Session, link_id: int):
|
||||||
_get_link_by_slug_cache = {}
|
_get_link_by_slug_cache = {}
|
||||||
|
|
||||||
|
|
||||||
def get_link_by_slug(db: Session, slug: str) -> Optional[tuple[int, str]]:
|
def get_link_by_slug(db: Session, slug: str) -> tuple[int, str]:
|
||||||
"""Converts slug to id and gets related link target.
|
"""Converts slug to id and gets related link target.
|
||||||
|
|
||||||
:param db Open connection to a database
|
:param db Open connection to a database
|
||||||
:param slug of the link
|
:param slug of the link
|
||||||
|
|
||||||
|
:raise LinkNotFoundException if link is not found
|
||||||
:return target link id & url"""
|
:return target link id & url"""
|
||||||
if slug in _get_link_by_slug_cache:
|
if slug in _get_link_by_slug_cache:
|
||||||
return _get_link_by_slug_cache[slug]
|
return _get_link_by_slug_cache[slug]
|
||||||
|
|
||||||
link = get_link(db, slug_to_link_id(slug))
|
link = get_link(db, slug_to_link_id(slug))
|
||||||
if link is None or not link.enabled:
|
if link is None or not link.enabled:
|
||||||
return None
|
raise LinkNotFoundException(slug)
|
||||||
|
|
||||||
_get_link_by_slug_cache[slug] = (link.id, link.source)
|
_get_link_by_slug_cache[slug] = (link.id, link.source)
|
||||||
return link.id, link.source
|
return link.id, link.source
|
||||||
|
|
Loading…
Reference in New Issue
Block a user