diff --git a/lib/Controller/FaceController.php b/lib/Controller/FaceController.php index 0325c1bd..12bd2d13 100644 --- a/lib/Controller/FaceController.php +++ b/lib/Controller/FaceController.php @@ -17,11 +17,14 @@ use OCA\FaceRecognition\Db\Image; use OCA\FaceRecognition\Db\ImageMapper; +use OCA\FaceRecognition\Service\FileCache; + class FaceController extends Controller { private $rootFolder; private $faceMapper; private $imageMapper; + private $fileCache; private $userId; public function __construct($AppName, @@ -29,20 +32,35 @@ public function __construct($AppName, IRootFolder $rootFolder, FaceMapper $faceMapper, ImageMapper $imageMapper, + FileCache $fileCache, $UserId) { parent::__construct($AppName, $request); $this->rootFolder = $rootFolder; $this->faceMapper = $faceMapper; $this->imageMapper = $imageMapper; + $this->fileCache = $fileCache; $this->userId = $UserId; } /** * @NoAdminRequired * @NoCSRFRequired + * + * @return DataDisplayResponse */ - public function getThumb ($id, $size) { + public function getThumb (int $id, int $size) { + + $key = 'face-'. $this->userId . '-' .$id . '-' . $size . 'x' . $size; + if ($this->fileCache->hasKey($key)) { + $imgData = $this->fileCache->get($key); + if (!is_null($imgData)) { + $img = new OCP_Image(); + $img->loadFromData($imgData); + return new DataDisplayResponse($img->data(), Http::STATUS_OK, ['Content-Type' => $img->mimeType()]); + } + } + $face = $this->faceMapper->find($id); $image = $this->imageMapper->find($this->userId, $face->getImage()); $fileId = $image->getFile(); @@ -73,12 +91,10 @@ public function getThumb ($id, $size) { $img->crop($x, $y, $w, $h); $img->scaleDownToFit($size, $size); - $resp = new DataDisplayResponse($img->data(), Http::STATUS_OK, ['Content-Type' => $img->mimeType()]); - $resp->setETag((string)crc32($img->data())); - $resp->cacheFor(7 * 24 * 60 * 60); - $resp->setLastModified(new \DateTime('now', new \DateTimeZone('GMT'))); + $this->fileCache->set($key, $img->data()); + + return new DataDisplayResponse($img->data(), Http::STATUS_OK, ['Content-Type' => $img->mimeType()]); - return $resp; } } diff --git a/lib/Service/FileCache.php b/lib/Service/FileCache.php new file mode 100644 index 00000000..9be1d217 --- /dev/null +++ b/lib/Service/FileCache.php @@ -0,0 +1,134 @@ + + * @author Lukas Reschke + * @author Roeland Jago Douma + * @author Sebastian Wessalowski + * @author Thomas Müller + * @author Vincent Petry + * + * @license AGPL-3.0 + * + * This code is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License, version 3, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License, version 3, + * along with this program. If not, see + * + */ +namespace OCA\FaceRecognition\Service; + +use OCP\Files\IAppData; +use OCP\Files\NotFoundException; +use OCP\Files\NotPermittedException; +use OCP\ICache; + +class FileCache implements ICache { + + const TIMEOUT = 60*60*24*30*2; // two months + + protected $storage; + + public function __construct(IAppData $appData) { + try { + $this->storage = $appData->getFolder('cache'); + } catch (NotFoundException $e) { + $appData->newFolder('cache'); + $this->storage = $appData->getFolder('cache'); + } + } + + /** + * @param string $key + * @return mixed|null + * @throws NotFoundException + * @throws NotPermittedException + */ + public function get($key) { + $result = null; + if ($this->hasKey($key)) { + $result = $this->storage->getFile($key)->getContent(); + } + return $result; + } + + /** + * Returns the size of the stored/cached data + * + * @param string $key + * @return int + * @throws NotFoundException + */ + public function size($key) { + $result = 0; + if ($this->hasKey($key)) { + $result = $this->storage->getFile($key)->getSize(); + } + return $result; + } + + /** + * @param string $key + * @param mixed $value + * @param int $ttl + * @return bool|mixed + * @throws NotFoundException + * @throws NotPermittedException + */ + public function set($key, $value, $ttl = 0) { + $file = $this->storage->newFile($key); + $file->putContent($value); + return true; + } + /** + * @param string $key + * @return bool + */ + public function hasKey($key) { + if ($this->storage->fileExists($key)) { + return true; + } + return false; + } + + /** + * @param string $key + * @return bool|mixed + * @throws NotFoundException + * @throws NotPermittedException + */ + public function remove($key) { + return $this->storage->getFile($key)->delete(); + } + + /** + * @param string $prefix + * @return void + * @throws NotPermittedException + */ + public function clear($prefix = '') { + $this->storage->delete(); + } + + /** + * Runs GC + * + * @throws NotPermittedException + */ + public function gc() { + foreach ($this->storage->getDirectoryListing() as $file) { + if (time() - self::TIMEOUT > $file->getMTime()) { + $file->delete(); + } + } + } + +}