Skip to content

Commit

Permalink
Use oc_metadata to store location
Browse files Browse the repository at this point in the history
Signed-off-by: Louis Chemineau <louis@chmn.me>
  • Loading branch information
artonge committed Feb 13, 2023
1 parent ea7e786 commit 42dc0a5
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 185 deletions.
2 changes: 1 addition & 1 deletion lib/Command/MapMediaToLocationCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private function scanFolder(Folder $folder): int {
continue;
}

$this->mediaLocationManager->addLocationForFileAndUser($node->getId(), $node->getOwner()->getUID());
$this->mediaLocationManager->addLocationForFileAndUser($node->getId());
$count++;
}

Expand Down
6 changes: 3 additions & 3 deletions lib/DB/Location/LocationFile.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public function __construct(
int $size,
int $mtime,
string $etag,
private int $locationId,
private string $location,
) {
parent::__construct(
$fileId,
Expand All @@ -47,7 +47,7 @@ public function __construct(
);
}

public function getLocationId(): int {
return $this->locationId;
public function getLocation(): string {
return $this->location;
}
}
13 changes: 4 additions & 9 deletions lib/DB/Location/LocationInfo.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,17 @@
namespace OCA\Photos\DB\Location;

class LocationInfo {
private string $userId;
private int $locationId;

public function __construct(
string $userId,
int $locationId
private string $userId,
private string $location
) {
$this->userId = $userId;
$this->locationId = $locationId;
}

public function getUserId(): string {
return $this->userId;
}

public function getLocationId(): int {
return $this->locationId;
public function getLocation(): string {
return $this->location;
}
}
89 changes: 39 additions & 50 deletions lib/DB/Location/LocationMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@
use OCP\IDBConnection;

class LocationMapper {
public const TABLE_NAME = 'photos_metadata';
public const METADATA_TYPE = 'location';
public const METADATA_TYPE = 'photos_location';

public function __construct(
private IDBConnection $connection,
Expand All @@ -42,29 +41,41 @@ public function __construct(

/** @return LocationInfo[] */
public function findLocationsForUser(string $userId): array {
$mimepart = $this->mimeTypeLoader->getId('image');

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

$rows = $qb->selectDistinct('value')
->from(self::TABLE_NAME)
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
->andWhere($qb->expr()->eq('type', $qb->createNamedParameter(self::METADATA_TYPE)))
$rows = $qb->selectDistinct('meta.metadata')
->from('mounts', 'mount')
->join('mount', 'filecache', 'file', $qb->expr()->eq('file.storage', 'mount.storage_id', IQueryBuilder::PARAM_INT))
->join('mount', 'file_metadata', 'meta', $qb->expr()->eq('file.fileid', 'meta.id', IQueryBuilder::PARAM_INT))
->andWhere($qb->expr()->eq('mount.user_id', $qb->createNamedParameter($userId)))
// TODO: change 5 to the actual mimepart
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_TYPE)))
->executeQuery()
->fetchAll();

return array_map(fn ($row) => new LocationInfo($userId, (int)$row['value']), $rows);
return array_map(fn ($row) => new LocationInfo($userId, $row['metadata']), $rows);
}

/** @return LocationFile[] */
public function findFilesForUserAndLocation(string $userId, int $locationId) {
public function findFilesForUserAndLocation(string $userId, string $location) {
$mimepart = $this->mimeTypeLoader->getId('image');

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

$rows = $qb->select("fileid", "mimetype", "size", "mtime", "etag", "m.value")
->from(self::TABLE_NAME, 'm')
->leftJoin("m", "filecache", "f", $qb->expr()->eq("m.file_id", "f.fileid"))
->where($qb->expr()->eq('user_id', $qb->createNamedParameter($userId)))
->andWhere($qb->expr()->eq('m.type', $qb->createNamedParameter(self::METADATA_TYPE)))
->andWhere($qb->expr()->eq('m.value', $qb->createNamedParameter($locationId)))
->executeQuery();
$rows = $qb->select('file.fileid', 'file.name', 'file.mimetype', 'file.size', 'file.mtime', 'file.etag', 'meta.metadata')
->from('mounts', 'mount')
->join('mount', 'filecache', 'file', $qb->expr()->eq('file.storage', 'mount.storage_id'))
->join('file', 'file_metadata', 'meta', $qb->expr()->eq('file.fileid', 'meta.id'))
->andWhere($qb->expr()->eq('mount.user_id', $qb->createNamedParameter($userId)))
// TODO: change 5 to the actual mimepart
->andWhere($qb->expr()->eq('file.mimepart', $qb->createNamedParameter($mimepart, IQueryBuilder::PARAM_INT)))
->andWhere($qb->expr()->eq('meta.group_name', $qb->createNamedParameter(self::METADATA_TYPE)))
->andWhere($qb->expr()->eq('meta.metadata', $qb->createNamedParameter($location)))
->executeQuery()
->fetchAll();

return array_map(
fn ($row) => new LocationFile(
Expand All @@ -74,57 +85,35 @@ public function findFilesForUserAndLocation(string $userId, int $locationId) {
(int)$row['size'],
(int)$row['mtime'],
$row['etag'],
(int)$row['value']
$row['metadata']
),
$rows->fetchAll(),
$rows,
);
}

public function addLocationForFileAndUser(int $locationId, int $fileId, string $userId): void {
public function addLocationForFileAndUser(string $location, int $fileId): void {
try {
$query = $this->connection->getQueryBuilder();
$query->insert(self::TABLE_NAME)
$query->insert('file_metadata')
->values([
"user_id" => $query->createNamedParameter($userId),
"type" => $query->createNamedParameter(self::METADATA_TYPE),
"value" => $query->createNamedParameter($locationId),
"file_id" => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT),
"id" => $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT),
"group_name" => $query->createNamedParameter(self::METADATA_TYPE),
"metadata" => $query->createNamedParameter($location),
])
->executeStatement();
} catch (\Exception $ex) {
if ($ex->getPrevious() instanceof UniqueConstraintViolationException) {
$this->updateLocationForFile($locationId, $fileId);
$this->updateLocationForFile($location, $fileId);
}
}
}

public function updateLocationForFile(int $locationId, int $fileId): void {
$query = $this->connection->getQueryBuilder();
$query->update(self::TABLE_NAME)
->set("value", $query->createNamedParameter($locationId))
->where($query->expr()->eq('file_id', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('type', $query->createNamedParameter(self::METADATA_TYPE)))
->executeStatement();
}

public function removeLocationForFile(int $fileId, ?string $userId = null): void {
$query = $this->connection->getQueryBuilder();
$query->delete(self::TABLE_NAME)
->where($query->expr()->eq('file_id', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('type', $query->createNamedParameter(self::METADATA_TYPE)));

if ($userId !== null) {
$query->andWhere($query->expr()->eq('user_id', $query->createNamedParameter($userId)));
}

$query->executeStatement();
}

public function removeLocationForUser(string $userId): void {
public function updateLocationForFile(string $location, int $fileId): void {
$query = $this->connection->getQueryBuilder();
$query->delete(self::TABLE_NAME)
->where($query->expr()->eq('user_id', $query->createNamedParameter($userId)))
->andWhere($query->expr()->eq('type', $query->createNamedParameter(self::METADATA_TYPE)))
$query->update('file_metadata')
->set("metadata", $query->createNamedParameter($location))
->where($query->expr()->eq('id', $query->createNamedParameter($fileId, IQueryBuilder::PARAM_INT)))
->andWhere($query->expr()->eq('group_name', $query->createNamedParameter(self::METADATA_TYPE)))
->executeStatement();
}
}
7 changes: 2 additions & 5 deletions lib/Jobs/MapMediaToLocationJob.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,8 @@ public function __construct(
}

protected function run($argument) {
[$fileId, $ownerId] = $argument;
[$fileId] = $argument;

$this->mediaLocationManager->addLocationForFileAndUser(
$fileId,
$ownerId,
);
$this->mediaLocationManager->addLocationForFileAndUser($fileId);
}
}
13 changes: 1 addition & 12 deletions lib/Listener/LocationManagerEventListener.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,6 @@ public function handle(Event $event): void {
return;
}

if ($event instanceof NodeDeletedEvent) {
if ($this->isCorrectPath($event->getNode()->getPath())) {
$this->mediaLocationManager->clearLocationForFile($event->getNode()->getId());
}
}

if ($event instanceof NodeWrittenEvent) {
if (!$this->isCorrectPath($event->getNode()->getPath())) {
return;
Expand All @@ -67,13 +61,8 @@ public function handle(Event $event): void {
}

$fileId = $event->getNode()->getId();
$ownerId = $event->getNode()->getOwner()->getUID();

$this->jobList->add(MapMediaToLocationJob::class, [$fileId, $ownerId]);
}

if ($event instanceof UserDeletedEvent) {
$this->mediaLocationManager->clearLocationForUser($event->getUser()->getUID());
$this->jobList->add(MapMediaToLocationJob::class, [$fileId]);
}
}

Expand Down
84 changes: 0 additions & 84 deletions lib/Migration/Version20002Date20221012131022.php

This file was deleted.

30 changes: 11 additions & 19 deletions lib/Service/MediaLocationManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,49 +36,41 @@ public function __construct(
) {
}

public function addLocationForFileAndUser(int $fileId, string $userId): void {
$locationId = $this->getLocationIdForFile($fileId);
public function addLocationForFileAndUser(int $fileId): void {
$location = $this->getLocationForFile($fileId);

if ($locationId === -1) {
if ($location === null) {
return;
}

$this->locationMapper->addLocationForFileAndUser($locationId, $fileId, $userId);
$this->locationMapper->addLocationForFileAndUser($location, $fileId);
}

public function updateLocationForFile(int $fileId): void {
$locationId = $this->getLocationIdForFile($fileId);
$location = $this->getLocationForFile($fileId);

if ($locationId === -1) {
if ($location === null) {
return;
}

$this->locationMapper->updateLocationForFile($locationId, $fileId);
$this->locationMapper->updateLocationForFile($location, $fileId);
}

public function clearLocationForFile(int $fileId, ?string $userId = null): void {
$this->locationMapper->removeLocationForFile($fileId, $userId);
}

public function clearLocationForUser(string $userId): void {
$this->locationMapper->removeLocationForUser($userId);
}

private function getLocationIdForFile(int $fileId): int {
private function getLocationForFile(int $fileId): ?string {
$gpsMetadata = $this->metadataManager->fetchMetadataFor('gps', [$fileId])[$fileId];
$metadata = $gpsMetadata->getMetadata();

if (count($metadata) === 0) {
return -1;
return null;
}

$latitude = $metadata['latitude'];
$longitude = $metadata['longitude'];

if ($latitude === null || $longitude === null) {
return -1;
return null;
}

return $this->rgcService->getLocationIdForCoordinates($latitude, $longitude);
return $this->rgcService->getLocationForCoordinates($latitude, $longitude);
}
}
Loading

0 comments on commit 42dc0a5

Please sign in to comment.