Skip to content

Commit

Permalink
Implement an basic cache for faces.. Issue #193
Browse files Browse the repository at this point in the history
  • Loading branch information
matiasdelellis committed Nov 30, 2019
1 parent 74a9db5 commit 419543e
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 6 deletions.
28 changes: 22 additions & 6 deletions lib/Controller/FaceController.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,50 @@
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,
IRequest $request,
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();
Expand Down Expand Up @@ -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;
}

}
134 changes: 134 additions & 0 deletions lib/Service/FileCache.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
<?php
/**
* @copyright Copyright (c) 2016, ownCloud, Inc.
*
* @author Joas Schilling <coding@schilljs.com>
* @author Lukas Reschke <lukas@statuscode.ch>
* @author Roeland Jago Douma <roeland@famdouma.nl>
* @author Sebastian Wessalowski <sebastian@wessalowski.org>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
*
* @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 <http://www.gnu.org/licenses/>
*
*/
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();
}
}
}

}

0 comments on commit 419543e

Please sign in to comment.