Files
django-signposting/django_signposting/middleware.py
Daniel Bauer 6b1ea1403c Create Signposting from RO-Crate (#2)
* improvate jsonld parsing to be compatible with ro-crate

* refactoring

* example with RO-Crate

* bump version

---------

Co-authored-by: Daniel Bauer <daniel.bauer@senckenberg.de>
2024-11-21 15:40:46 +01:00

66 lines
2.1 KiB
Python

from typing import Callable
from django.http import HttpRequest, HttpResponse
from signposting import Signpost
from bs4 import BeautifulSoup
import json
from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from .utils import jsonld_to_signposts
class SignpostingMiddleware:
def __init__(self, get_response: Callable[[HttpRequest], HttpResponse]):
self.get_response = get_response
def __call__(self, request: HttpRequest) -> HttpResponse:
response = self.get_response(request)
# no signposts on errors
if response.status_code >= 400:
return response
if not hasattr(response, "_signposts"):
return response
self._add_signposts(response, response._signposts)
return response
def _add_signposts(self, response: HttpResponse, signposts: list[Signpost]):
"""Adds signposting headers to the respones.
params:
response - the response object
signposts - a list of Signposts
"""
link_snippets = []
for signpost in signposts:
link_snippets.append(f'<{signpost.target}> ; rel="{signpost.rel}"')
if signpost.type:
link_snippets[-1] += f' ; type="{signpost.type}"'
response["Link"] = " , ".join(link_snippets)
class JsonLdSignpostingParserMiddleware(MiddlewareMixin):
def process_response(
self, request: HttpRequest, response: HttpResponse
) -> HttpResponse:
if not getattr(settings, "SIGNPOSTING_PARSE_JSONLD", True):
return response
if response.get("Content-Type", "").startswith("text/html"):
soup = BeautifulSoup(response.content, "html.parser")
for script in soup.find_all("script", type="application/ld+json"):
try:
jsonld = json.loads(script.string)
signposts = jsonld_to_signposts(jsonld)
response._signposts = signposts
except json.JSONDecodeError as e:
print(e)
continue
return response