feat: add /api/image and make the action accept image/* header

This commit is contained in:
b1ek 2024-08-20 19:23:11 +10:00
parent 4201519e1c
commit 1839181887
Signed by: blek
GPG Key ID: 14546221E3595D0C
2 changed files with 54 additions and 13 deletions

View File

@ -3,8 +3,7 @@
namespace app\controllers;
use app\models\Parameter;
use app\models\Image;
use yii\data\ActiveDataProvider;
use yii\rest\IndexAction;
use yii\filters\ContentNegotiator;
use yii\web\NotFoundHttpException;
use yii\web\Request;
use yii\web\Response;
@ -16,16 +15,15 @@ class ApiController extends \yii\rest\Controller
return Parameter::find()->with(['icon', 'iconGray'])->all();
}
public function actionImage(Request $request)
public function actionImage(Request $request, Response $response)
{
$img = Image::find()->where([ 'sha256' => $request->getQueryParam('sha256') ])->one();
if (!$img) {
throw new NotFoundHttpException();
}
\Yii::$app->response->format = Response::FORMAT_RAW;
\Yii::$app->response->headers->set('Content-Type', $img->mime);
return file_get_contents(env('UPLOADS_PATH') . '/' . $img->sha256);
$response->headers->set('X-Image-Data', json_encode($img->getAttributes()));
return $response->sendFile(env('UPLOADS_PATH') . '/' . $img->sha256, $img->original_name);
}
public function verbs()
@ -34,4 +32,17 @@ class ApiController extends \yii\rest\Controller
'index' => [ 'GET' ],
];
}
public function behaviors()
{
return [
[
'class' => ContentNegotiator::class,
'formats' => [
'image/*' => Response::FORMAT_RAW,
'application/json' => Response::FORMAT_JSON
]
]
];
}
}

View File

@ -5,12 +5,42 @@ openapi: '3.1.0'
tags:
- name: Routes
paths:
/api/image:
get:
tags:
- Routes
summary: Get image
description: |-
Get image by SHA256.
This method is designed to be referenced via `<img>`'s `src` attribute, so it returns the image with it's content type in the header.
The image data, such as original name is available in JSON in header `X-Image-Data`
parameters:
- name: sha256
schema:
type: string
in: query
responses:
200:
description: |-
# Important: application/json body is the `X-Image-Data` header value, not the actual body!
The actual body is the raw image. Its content type is in the `Content-Type` header.
content:
image/*:
type:
application/json:
schema:
$ref: '#/components/schemas/Image'
/api:
get:
tags:
- Routes
summary: Get all parameters
description: Get all parameters
description: |-
This route will get all parameters.
To get the image itself, use /api/
responses:
200:
description: OK
@ -22,7 +52,7 @@ paths:
$ref: '#/components/schemas/Parameter'
example: [
{
"id": 0,
"id": 1,
"title": "A thing happening somewhere",
"type": 1,
"icon": null,
@ -33,13 +63,13 @@ paths:
"title": "The fox jumping over a cat",
"type": 1,
"icon": {
"id": 1,
"original_name": "fox_jump.jpeg",
"url": "/images/SHA256_HASH.jpeg",
"sha256": "SHA256"
},
"icon_gray": {
"id": 2,
"original_name": "fox_jump.gray.jpeg",
"url": "/images/SHA256_HASH.jpeg",
"sha256": "SHA256"
}
}
@ -49,12 +79,12 @@ components:
Image:
type: object
properties:
id:
type: number
example: 1
source_name:
type: string
example: "source_file.jpeg"
url:
type: string
example: "/images/SHA256_HASH.jpeg"
sha256:
type: string
required: