Skip to content

Commit

Permalink
refactor(RecommendationController): Migrate to OCS
Browse files Browse the repository at this point in the history
Signed-off-by: provokateurin <kate@provokateurin.de>
  • Loading branch information
provokateurin committed Jan 7, 2025
1 parent e353055 commit 3ee463a
Show file tree
Hide file tree
Showing 7 changed files with 308 additions and 17 deletions.
2 changes: 1 addition & 1 deletion REUSE.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ SPDX-FileCopyrightText = "2019 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"

[[annotations]]
path = ["psalm.xml", "psalm-baseline.xml"]
path = ["psalm.xml", "psalm-baseline.xml", "openapi.json"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2024 Nextcloud GmbH and Nextcloud contributors"
SPDX-License-Identifier = "AGPL-3.0-or-later"
6 changes: 4 additions & 2 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
'routes' => [
['name' => 'settings#getSettings', 'url' => '/settings', 'verb' => 'GET'],
['name' => 'settings#setSetting', 'url' => '/settings/{key}', 'verb' => 'PUT'],
['name' => 'recommendation#index', 'url' => '/api/recommendations', 'verb' => 'GET'],
['name' => 'recommendation#always', 'url' => '/api/recommendations/always', 'verb' => 'GET'],
],
'ocs' => [
['name' => 'recommendation#always', 'url' => '/api/v1/recommendations/always', 'verb' => 'GET'],
['name' => 'recommendation#index', 'url' => '/api/v1/recommendations', 'verb' => 'GET'],
],
];
36 changes: 25 additions & 11 deletions lib/Controller/RecommendationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,20 @@

use Exception;
use OCA\Recommendations\AppInfo\Application;
use OCA\Recommendations\Service\IRecommendation;
use OCA\Recommendations\Service\RecommendationService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\OCSController;
use OCP\IConfig;
use OCP\IRequest;
use OCP\IUserSession;
use ResponseDefinitions;

class RecommendationController extends Controller {
/**
* @psalm-import-type RecommendationsRecommendedFile from ResponseDefinitions
*/
class RecommendationController extends OCSController {
private IUserSession $userSession;
private RecommendationService $recommendationService;
private IConfig $config;
Expand All @@ -34,38 +40,46 @@ public function __construct(IRequest $request,
}

/**
* Get recommendations, but only if enabled
*
* @NoAdminRequired
* @return JSONResponse
* @return DataResponse<Http::STATUS_OK, array{enabled: bool, recommendations?: list<RecommendationsRecommendedFile>}, array{}>
*
* 200: Recommendations returned
*/
public function index(): JSONResponse {
public function index(): DataResponse {
$user = $this->userSession->getUser();
if (is_null($user)) {
throw new Exception("Not logged in");
}
$response = [];
$response['enabled'] = $this->config->getUserValue($user->getUID(), Application::APP_ID, 'enabled', 'true') === 'true';
if ($response['enabled']) {
$response['recommendations'] = $this->recommendationService->getRecommendations($user);
$response['recommendations'] = array_map(static fn (IRecommendation $recommendation) => $recommendation->jsonSerialize(), $this->recommendationService->getRecommendations($user));
}
return new JSONResponse(
return new DataResponse(
$response
);
}

/**
* Get recommendations
*
* @NoAdminRequired
* @return JSONResponse
* @return DataResponse<Http::STATUS_OK, array{enabled: bool, recommendations: list<RecommendationsRecommendedFile>}, array{}>
*
* 200: Recommendations returned
*/
public function always(): JSONResponse {
public function always(): DataResponse {
$user = $this->userSession->getUser();
if (is_null($user)) {
throw new Exception("Not logged in");
}
$response = [
'enabled' => $this->config->getUserValue($user->getUID(), Application::APP_ID, 'enabled', 'true') === 'true',
'recommendations' => $this->recommendationService->getRecommendations($user),
'recommendations' => array_map(static fn (IRecommendation $recommendation) => $recommendation->jsonSerialize(), $this->recommendationService->getRecommendations($user)),
];
return new JSONResponse(
return new DataResponse(
$response
);
}
Expand Down
25 changes: 25 additions & 0 deletions lib/ResponseDefinitions.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

/**
* @psalm-type RecommendationsRecommendedFile = array{
* id: string,
* timestamp: int,
* name: string,
* directory: string,
* extension: string,
* mimeType: string,
* hasPreview: bool,
* reason: string,
* }
*
* @psalm-suppress UnusedClass
*/
class ResponseDefinitions {
}
7 changes: 7 additions & 0 deletions lib/Service/RecommendedFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@
namespace OCA\Recommendations\Service;

use OCP\Files\Node;
use ResponseDefinitions;

/**
* @psalm-import-type RecommendationsRecommendedFile from ResponseDefinitions
*/
class RecommendedFile implements IRecommendation {
private string $directory;
private Node $node;
Expand Down Expand Up @@ -57,6 +61,9 @@ public function setHasPreview(bool $state) {
$this->hasPreview = $state;
}

/**
* @return RecommendationsRecommendedFile
*/
#[\ReturnTypeWillChange]
public function jsonSerialize() {
return [
Expand Down
243 changes: 243 additions & 0 deletions openapi.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,243 @@
{
"openapi": "3.0.3",
"info": {
"title": "recommendations",
"version": "0.0.1",
"description": "Shows recommended files",
"license": {
"name": "agpl"
}
},
"components": {
"securitySchemes": {
"basic_auth": {
"type": "http",
"scheme": "basic"
},
"bearer_auth": {
"type": "http",
"scheme": "bearer"
}
},
"schemas": {
"OCSMeta": {
"type": "object",
"required": [
"status",
"statuscode"
],
"properties": {
"status": {
"type": "string"
},
"statuscode": {
"type": "integer"
},
"message": {
"type": "string"
},
"totalitems": {
"type": "string"
},
"itemsperpage": {
"type": "string"
}
}
},
"RecommendedFile": {
"type": "object",
"required": [
"id",
"timestamp",
"name",
"directory",
"extension",
"mimeType",
"hasPreview",
"reason"
],
"properties": {
"id": {
"type": "string"
},
"timestamp": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
},
"directory": {
"type": "string"
},
"extension": {
"type": "string"
},
"mimeType": {
"type": "string"
},
"hasPreview": {
"type": "boolean"
},
"reason": {
"type": "string"
}
}
}
}
},
"paths": {
"/ocs/v2.php/apps/recommendations/api/v1/recommendations/always": {
"get": {
"operationId": "recommendation-always",
"summary": "Get recommendations",
"tags": [
"recommendation"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Recommendations returned",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"enabled",
"recommendations"
],
"properties": {
"enabled": {
"type": "boolean"
},
"recommendations": {
"type": "array",
"items": {
"$ref": "#/components/schemas/RecommendedFile"
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"/ocs/v2.php/apps/recommendations/api/v1/recommendations": {
"get": {
"operationId": "recommendation-index",
"summary": "Get recommendations, but only if enabled",
"tags": [
"recommendation"
],
"security": [
{
"bearer_auth": []
},
{
"basic_auth": []
}
],
"parameters": [
{
"name": "OCS-APIRequest",
"in": "header",
"description": "Required to be true for the API request to pass",
"required": true,
"schema": {
"type": "boolean",
"default": true
}
}
],
"responses": {
"200": {
"description": "Recommendations returned",
"content": {
"application/json": {
"schema": {
"type": "object",
"required": [
"ocs"
],
"properties": {
"ocs": {
"type": "object",
"required": [
"meta",
"data"
],
"properties": {
"meta": {
"$ref": "#/components/schemas/OCSMeta"
},
"data": {
"type": "object",
"required": [
"enabled"
],
"properties": {
"enabled": {
"type": "boolean"
},
"recommendations": {
"type": "array",
"items": {
"$ref": "#/components/schemas/RecommendedFile"
}
}
}
}
}
}
}
}
}
}
}
}
}
}
},
"tags": []
}
Loading

0 comments on commit 3ee463a

Please sign in to comment.