Feature: Add additional caching support to suggestions and metadata (#5414)

* Adds ETag and Last-Modified headers to suggestions, metadata and previews

* Slight update to the suggestions etag

* Small user message for why classifier didn't train again
This commit is contained in:
Trenton H
2024-01-16 09:01:07 -08:00
committed by GitHub
parent 0068f091bb
commit e16645b146
4 changed files with 185 additions and 0 deletions

View File

@@ -0,0 +1,87 @@
import pickle
from datetime import datetime
from typing import Optional
from django.conf import settings
from documents.classifier import DocumentClassifier
from documents.models import Document
def suggestions_etag(request, pk: int) -> Optional[str]:
"""
Returns an optional string for the ETag, allowing browser caching of
suggestions if the classifier has not been changed and the suggested dates
setting is also unchanged
TODO: It would be nice to not duplicate the partial loading and the loading
between here and the actual classifier
"""
if not settings.MODEL_FILE.exists():
return None
with open(settings.MODEL_FILE, "rb") as f:
schema_version = pickle.load(f)
if schema_version != DocumentClassifier.FORMAT_VERSION:
return None
_ = pickle.load(f)
last_auto_type_hash: bytes = pickle.load(f)
return f"{last_auto_type_hash}:{settings.NUMBER_OF_SUGGESTED_DATES}"
def suggestions_last_modified(request, pk: int) -> Optional[datetime]:
"""
Returns the datetime of classifier last modification. This is slightly off,
as there is not way to track the suggested date setting modification, but it seems
unlikely that changes too often
"""
if not settings.MODEL_FILE.exists():
return None
with open(settings.MODEL_FILE, "rb") as f:
schema_version = pickle.load(f)
if schema_version != DocumentClassifier.FORMAT_VERSION:
return None
last_doc_change_time = pickle.load(f)
return last_doc_change_time
def metadata_etag(request, pk: int) -> Optional[str]:
"""
Metadata is extracted from the original file, so use its checksum as the
ETag
"""
try:
doc = Document.objects.get(pk=pk)
return doc.checksum
except Document.DoesNotExist:
return None
return None
def metadata_last_modified(request, pk: int) -> Optional[datetime]:
"""
Metadata is extracted from the original file, so use its modified. Strictly speaking, this is
not the modification of the original file, but of the database object, but might as well
error on the side of more cautious
"""
try:
doc = Document.objects.get(pk=pk)
return doc.modified
except Document.DoesNotExist:
return None
return None
def preview_etag(request, pk: int) -> Optional[str]:
"""
ETag for the document preview, using the original or archive checksum, depending on the request
"""
try:
doc = Document.objects.get(pk=pk)
use_original = (
"original" in request.query_params
and request.query_params["original"] == "true"
)
return doc.checksum if use_original else doc.archive_checksum
except Document.DoesNotExist:
return None
return None