1
0
mirror of https://github.com/enpaul/kodak.git synced 2024-11-23 15:07:13 +00:00

Update manip endpoint to fix path problem

One of the goals is to make the generated content directory directly hostable
via a web browser for performance. This means that the application needs to be
able to generate a file tree identical to the URL structure so that clients can
fetch a single URL and either use the cached image or trigger a manipulation
depending on whether it already exists.

With a url structure of /key and /key/manip for the source and manips respectively,
it becomes impossible to create a file tree matching it since 'key' must be both
the source file and a directory containing the manipulated images.

This updates it to use 'original' as a special manip name so the URL structure of
/key/original and /key/manip can match the directory structure
This commit is contained in:
Ethan Paul 2021-11-13 22:08:26 -05:00
parent 69171ebb93
commit a87ca3bc80
No known key found for this signature in database
GPG Key ID: D0E2CBF1245E92BF
8 changed files with 39 additions and 27 deletions

View File

@ -213,8 +213,15 @@ class ManipConfig:
@classmethod @classmethod
def from_env(cls, key: str): def from_env(cls, key: str):
"""Build dataclass from environment""" """Build dataclass from environment"""
name = os.getenv(f"KODAK_MANIP_{key}_NAME", key.lower())
if name == "original":
raise exceptions.ConfigurationError(
"Manipulation name 'original' is reserved for application usage"
)
return cls( return cls(
name=os.getenv(f"KODAK_MANIP_{key}_NAME", key.lower()), name=name,
crop=ManipCropConfig.from_env(key), crop=ManipCropConfig.from_env(key),
scale=ManipScaleConfig.from_env(key), scale=ManipScaleConfig.from_env(key),
formats=set( formats=set(

View File

@ -11,11 +11,11 @@ from kodak.configuration import KodakConfig
from kodak.database._shared import INTERFACE as interface from kodak.database._shared import INTERFACE as interface
from kodak.database._shared import KodakModel from kodak.database._shared import KodakModel
from kodak.database.access import AccessRecord from kodak.database.access import AccessRecord
from kodak.database.alias import AliasRecord
from kodak.database.image import ImageRecord from kodak.database.image import ImageRecord
from kodak.database.manip import ManipRecord
MODELS: Tuple[Type[KodakModel], ...] = (ImageRecord, AliasRecord, AccessRecord) MODELS: Tuple[Type[KodakModel], ...] = (ImageRecord, ManipRecord, AccessRecord)
def calc_batch_size( def calc_batch_size(

View File

@ -1,13 +1,18 @@
import peewee import peewee
from kodak import constants
from kodak.database._shared import ChecksumField from kodak.database._shared import ChecksumField
from kodak.database._shared import EnumField
from kodak.database._shared import KodakModel from kodak.database._shared import KodakModel
from kodak.database._shared import PathField
from kodak.database.image import ImageRecord from kodak.database.image import ImageRecord
class AliasRecord(KodakModel): class ManipRecord(KodakModel):
"""Model for manipulated image records""" """Model for manipulated image records"""
parent = peewee.ForeignKeyField(ImageRecord, null=False) parent = peewee.ForeignKeyField(ImageRecord, null=False)
name = peewee.CharField(null=False) manip = peewee.CharField(null=False)
file = PathField(null=False)
format_ = EnumField(constants.ImageFormat, null=False)
checksum = ChecksumField(null=False) checksum = ChecksumField(null=False)

View File

@ -2,15 +2,15 @@ from typing import Tuple
from typing import Type from typing import Type
from kodak.resources._shared import KodakResource from kodak.resources._shared import KodakResource
from kodak.resources.alias import ImageAlias
from kodak.resources.heartbeat import Heartbeat from kodak.resources.heartbeat import Heartbeat
from kodak.resources.image import Image from kodak.resources.image import Image
from kodak.resources.manip import ImageManip
from kodak.resources.openapi import OpenAPI from kodak.resources.openapi import OpenAPI
RESOURCES: Tuple[Type[KodakResource], ...] = ( RESOURCES: Tuple[Type[KodakResource], ...] = (
Heartbeat, Heartbeat,
Image, Image,
ImageAlias, ImageManip,
OpenAPI, OpenAPI,
) )

View File

@ -1,18 +0,0 @@
from kodak.resources._shared import authenticated
from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple
class ImageAlias(KodakResource):
"""Handle generating and returning a processed image alias"""
routes = ("/image/<string:image_name>/<string:alias>",)
@authenticated
def get(self, image_name: str, alias: str) -> ResponseTuple:
"""Retrieve an image variation"""
raise NotImplementedError
def head(self, image_name: str, alias: str) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.get(image_name, alias))

View File

@ -11,7 +11,7 @@ from kodak.resources._shared import ResponseTuple
class Image(KodakResource): class Image(KodakResource):
"""Handle requests for original source images""" """Handle requests for original source images"""
routes = ("/image/<string:image_name>",) routes = ("/image/<string:image_name>/original",)
@authenticated @authenticated
def get(self, image_name: str) -> flask.Response: # pylint: disable=no-self-use def get(self, image_name: str) -> flask.Response: # pylint: disable=no-self-use

18
kodak/resources/manip.py Normal file
View File

@ -0,0 +1,18 @@
from kodak.resources._shared import authenticated
from kodak.resources._shared import KodakResource
from kodak.resources._shared import ResponseTuple
class ImageManip(KodakResource):
"""Handle generating and returning a processed image manip"""
routes = ("/image/<string:image_name>/<string:manip>",)
@authenticated
def get(self, image_name: str, manip: str) -> ResponseTuple:
"""Retrieve an image variation"""
raise NotImplementedError
def head(self, image_name: str, manip: str) -> ResponseTuple:
"""Alias HEAD to GET"""
return self._head(self.get(image_name, manip))

View File

@ -67,7 +67,7 @@ paths:
'500': '500':
description: Server is not operating correctly description: Server is not operating correctly
headers: *headers-default headers: *headers-default
/image/{image_name}: /image/{image_name}/original:
head: head:
summary: Returns metadata about the image request summary: Returns metadata about the image request
operationId: ImageHead operationId: ImageHead