Skip to content

Commit

Permalink
Use new metadata API
Browse files Browse the repository at this point in the history
Signed-off-by: Louis Chemineau <louis@chmn.me>
  • Loading branch information
artonge committed Oct 26, 2023
1 parent e7243b2 commit f1832b5
Show file tree
Hide file tree
Showing 19 changed files with 472 additions and 468 deletions.
3 changes: 1 addition & 2 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

<commands>
<command>OCA\Photos\Command\UpdateReverseGeocodingFilesCommand</command>
<command>OCA\Photos\Command\MapMediaToPlaceCommand</command>
</commands>

<sabre>
Expand All @@ -48,4 +47,4 @@
<background-jobs>
<job>OCA\Photos\Jobs\AutomaticPlaceMapperJob</job>
</background-jobs>
</info>
</info>
16 changes: 12 additions & 4 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,19 @@
use OCA\DAV\Connector\Sabre\Principal;
use OCA\DAV\Events\SabrePluginAuthInitEvent;
use OCA\Photos\Listener\AlbumsManagementEventListener;
use OCA\Photos\Listener\PlaceManagerEventListener;
use OCA\Photos\Listener\SabrePluginAuthInitListener;
use OCA\Photos\Listener\TagListener;
use OCA\Photos\MetadataProvider\ExifMetadataProvider;
use OCA\Photos\MetadataProvider\OriginalDateTimeMetadataProvider;
use OCA\Photos\MetadataProvider\PlaceMetadataProvider;
use OCA\Photos\MetadataProvider\SizeMetadataProvider;
use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Files\Events\Node\NodeDeletedEvent;
use OCP\Files\Events\Node\NodeWrittenEvent;
use OCP\FilesMetadata\Event\MetadataBackgroundEvent;
use OCP\FilesMetadata\Event\MetadataLiveEvent;
use OCP\Group\Events\GroupDeletedEvent;
use OCP\Group\Events\UserRemovedEvent;
use OCP\Share\Events\ShareDeletedEvent;
Expand Down Expand Up @@ -75,8 +79,12 @@ public function register(IRegistrationContext $context): void {
/** Register $principalBackend for the DAV collection */
$context->registerServiceAlias('principalBackend', Principal::class);

// Priority of -1 to be triggered after event listeners populating metadata.
$context->registerEventListener(NodeWrittenEvent::class, PlaceManagerEventListener::class, -1);
// Metadata
$context->registerEventListener(MetadataLiveEvent::class, ExifMetadataProvider::class);
$context->registerEventListener(MetadataLiveEvent::class, SizeMetadataProvider::class);
$context->registerEventListener(MetadataLiveEvent::class, OriginalDateTimeMetadataProvider::class);
$context->registerEventListener(MetadataLiveEvent::class, PlaceMetadataProvider::class);
$context->registerEventListener(MetadataBackgroundEvent::class, PlaceMetadataProvider::class);

$context->registerEventListener(NodeDeletedEvent::class, AlbumsManagementEventListener::class);
$context->registerEventListener(UserRemovedEvent::class, AlbumsManagementEventListener::class);
Expand Down
116 changes: 0 additions & 116 deletions lib/Command/MapMediaToPlaceCommand.php

This file was deleted.

17 changes: 0 additions & 17 deletions lib/DB/PhotosFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,7 @@

namespace OCA\Photos\DB;

use OC\Metadata\FileMetadata;

class PhotosFile {
/** @var array<string, FileMetadata> */
private array $metaData = [];

public function __construct(
private int $fileId,
private string $name,
Expand Down Expand Up @@ -64,16 +59,4 @@ public function getMTime(): int {
public function getEtag(): string {
return $this->etag;
}

public function setMetadata(string $key, FileMetadata $value): void {
$this->metaData[$key] = $value;
}

public function hasMetadata(string $key): bool {
return isset($this->metaData[$key]);
}

public function getMetadata(string $key): FileMetadata {
return $this->metaData[$key];
}
}
104 changes: 42 additions & 62 deletions lib/DB/Place/PlaceMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,22 @@

namespace OCA\Photos\DB\Place;

use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
use OCA\Photos\AppInfo\Application;
use OCP\DB\QueryBuilder\IQueryBuilder;
use OCP\Files\IMimeTypeLoader;
use OCP\Files\IRootFolder;
use OCP\Files\NotFoundException;
use OCP\FilesMetadata\IFilesMetadataManager;
use OCP\IDBConnection;

class PlaceMapper {
public const METADATA_GROUP = 'photos_place';
public const METADATA_KEY = 'photos-place';

public function __construct(
private IDBConnection $connection,
private IMimeTypeLoader $mimeTypeLoader,
private IRootFolder $rootFolder,
private IFilesMetadataManager $filesMetadataManager,
) {
}

Expand All @@ -49,20 +51,21 @@ public function findPlacesForUser(string $userId): array {
->getMountPoint()
->getNumericStorageId();

$mimepart = $this->mimeTypeLoader->getId('image');

$mimetypes = array_map(fn ($mimetype) => $this->mimeTypeLoader->getId($mimetype), Application::IMAGE_MIMES);

$qb = $this->connection->getQueryBuilder();

$rows = $qb->selectDistinct('meta.value')
->from('file_metadata', 'meta')
->join('meta', 'filecache', 'file', $qb->expr()->eq('file.fileid', 'meta.id', IQueryBuilder::PARAM_INT))
->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_GROUP)))
$qb->selectDistinct('meta_value')
->from('filecache', 'file');
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($qb, 'file', 'fileid');
$metadataQuery->joinIndex(self::METADATA_KEY, true);
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->executeQuery()
->fetchAll();

return array_map(fn ($row) => new PlaceInfo($userId, $row['value']), $rows);
return array_map(fn ($row) => new PlaceInfo($userId, $row['meta_value']), $rows);
}

/** @return PlaceInfo */
Expand All @@ -72,25 +75,25 @@ public function findPlaceForUser(string $userId, string $place): PlaceInfo {
->getMountPoint()
->getNumericStorageId();

$mimepart = $this->mimeTypeLoader->getId('image');
$mimetypes = array_map(fn ($mimetype) => $this->mimeTypeLoader->getId($mimetype), Application::IMAGE_MIMES);

$qb = $this->connection->getQueryBuilder();

$rows = $qb->selectDistinct('meta.value')
->from('file_metadata', 'meta')
->join('meta', 'filecache', 'file', $qb->expr()->eq('file.fileid', 'meta.id', IQueryBuilder::PARAM_INT))
->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_GROUP)))
->andWhere($qb->expr()->eq('meta.value', $qb->createNamedParameter($place)))
$qb->selectDistinct('meta_value')
->from('filecache', 'file');
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($qb, 'file', 'fileid');
$metadataQuery->joinIndex(self::METADATA_KEY, true);
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value', $qb->createNamedParameter($place)))
->executeQuery()
->fetchAll();

if (count($rows) !== 1) {
throw new NotFoundException();
}

return new PlaceInfo($userId, $rows[0]['value']);
return new PlaceInfo($userId, $rows[0]['meta_value']);
}

/** @return PlaceFile[] */
Expand All @@ -100,17 +103,17 @@ public function findFilesForUserAndPlace(string $userId, string $place) {
->getMountPoint()
->getNumericStorageId();

$mimepart = $this->mimeTypeLoader->getId('image');
$mimetypes = array_map(fn ($mimetype) => $this->mimeTypeLoader->getId($mimetype), Application::IMAGE_MIMES);

$qb = $this->connection->getQueryBuilder();

$rows = $qb->select('file.fileid', 'file.name', 'file.mimetype', 'file.size', 'file.mtime', 'file.etag', 'meta.value')
->from('file_metadata', 'meta')
->join('meta', 'filecache', 'file', $qb->expr()->eq('file.fileid', 'meta.id', IQueryBuilder::PARAM_INT))
->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_GROUP)))
->andWhere($qb->expr()->eq('meta.value', $qb->createNamedParameter($place)))
$rows = $qb->select('file.fileid', 'file.name', 'file.mimetype', 'file.size', 'file.mtime', 'file.etag', 'meta_value')
->from('filecache', 'file');
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($qb, 'file', 'fileid');
$metadataQuery->joinIndex(self::METADATA_KEY, true);
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value', $qb->createNamedParameter($place)))
->executeQuery()
->fetchAll();

Expand All @@ -122,7 +125,7 @@ public function findFilesForUserAndPlace(string $userId, string $place) {
(int)$row['size'],
(int)$row['mtime'],
$row['etag'],
$row['value']
$row['meta_value']
),
$rows,
);
Expand All @@ -134,19 +137,19 @@ public function findFileForUserAndPlace(string $userId, string $place, string $f
->getMountPoint()
->getNumericStorageId();

$mimepart = $this->mimeTypeLoader->getId('image');
$mimetypes = array_map(fn ($mimetype) => $this->mimeTypeLoader->getId($mimetype), Application::IMAGE_MIMES);

$qb = $this->connection->getQueryBuilder();

$rows = $qb->select('file.fileid', 'file.name', 'file.mimetype', 'file.size', 'file.mtime', 'file.etag', 'meta.value')
->from('file_metadata', 'meta')
->join('meta', 'filecache', 'file', $qb->expr()->eq('file.fileid', 'meta.id', IQueryBuilder::PARAM_INT))
->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
$rows = $qb->select('file.fileid', 'file.name', 'file.mimetype', 'file.size', 'file.mtime', 'file.etag', 'meta_value')
->from('filecache', 'file');
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($qb, 'file', 'fileid');
$metadataQuery->joinIndex(self::METADATA_KEY, true);
$rows = $qb->where($qb->expr()->eq('file.storage', $qb->createNamedParameter($storageId, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('file.fileid', $qb->createNamedParameter($fileId)))
->andWhere($qb->expr()->eq('file.name', $qb->createNamedParameter($fileName)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_GROUP)))
->andWhere($qb->expr()->eq('meta.value', $qb->createNamedParameter($place)))
->andWhere($qb->expr()->in('file.mimetype', $qb->createNamedParameter($mimetypes, IQueryBuilder::PARAM_INT_ARRAY)))
->andWhere($qb->expr()->eq('meta_value', $qb->createNamedParameter($place)))
->executeQuery()
->fetchAll();

Expand All @@ -161,35 +164,12 @@ public function findFileForUserAndPlace(string $userId, string $place, string $f
(int)$rows[0]['size'],
(int)$rows[0]['mtime'],
$rows[0]['etag'],
$rows[0]['value']
$rows[0]['meta_value']
);
}

public function setPlaceForFile(string $place, int $fileId): void {
try {
$query = $this->connection->getQueryBuilder();
$query->insert('file_metadata')
->values([
"id" => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT),
"group_name" => $query->createNamedParameter(self::METADATA_GROUP),
"value" => $query->createNamedParameter($place),
])
->executeStatement();
} catch (\Exception $ex) {
if ($ex->getPrevious() instanceof UniqueConstraintViolationException) {
$this->updatePlaceForFile($place, $fileId);
} else {
throw $ex;
}
}
}

public function updatePlaceForFile(string $place, int $fileId): void {
$query = $this->connection->getQueryBuilder();
$query->update('file_metadata')
->set("value", $query->createNamedParameter($place))
->where($query->expr()->eq('id', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('group_name', $query->createNamedParameter(self::METADATA_GROUP)))
->executeStatement();
$metadata = $this->filesMetadataManager->getMetadata($fileId, true);
$metadata->set('gps', $place, true);
}
}
Loading

0 comments on commit f1832b5

Please sign in to comment.