Skip to content

IFilesMetadata - #40761

Merged
ArtificialOwl merged 3 commits into
masterfrom
enh/noid/files-metadata
Nov 7, 2023
Merged

IFilesMetadata#40761
ArtificialOwl merged 3 commits into
masterfrom
enh/noid/files-metadata

Conversation

@ArtificialOwl

@ArtificialOwlArtificialOwl commented Oct 4, 2023

Copy link
Copy Markdown
Member

#40676

Introduction

This is a feature that allow any app to store files metadata.

When a file is created or modified, an event is broadcasted so that a listener can:

  • request for an identical event, but on the background job process
  • set metadata, key and value
  • define metadata index
  • help building queries to search on an indexed metadata
  • help building queries that returns metadata linked to fileid

tasks

  • model Metadata
    • store type of metadata (string, int, bool, array, float)
    • serialize/deserialize and import from database
  • store metadata,
    • update database only if new data (or truly edited) is available
    • avoid parallel update in database
    • delete metadata based on key
    • delete metadata based on prefix
  • index metadata (file id, metadata key, metadata value)
    • generate entries in metadata_index based on value type
  • queries
    • helper to left join metadata based on file_id
    • helper to search on metadata key
    • helper to search on metadata value
    • helper to get metadata key and metadata value table field
    • helper to convert row's data to metadata object
  • events
    • listener on new file
    • listener on edited file
    • on request, dispatch event on background job process
    • occ metadata:get

How to add metadata from your own app:

lib/AppInfo/Application.php


$context->registerEventListener(MetadataLiveEvent::class, UpdateFilesMetadata::class);
$context->registerEventListener(MetadataBackgroundEvent::class, UpdateFilesMetadata::class);

UpdateFilesMetadata.php

use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\FilesMetadata\Event\MetadataBackgroundEvent;
use OCP\FilesMetadata\Event\MetadataLiveEvent;
class UpdateFilesMetadata implements IEventListener {
public function __construct() {}
public function handle(Event $event): void {
if (!($event instanceof MetadataLiveEvent) &&
!($event instanceof MetadataBackgroundEvent)) {
return;
}
$node = $event->getNode();
// only few files are interesting.
if ($node->getMimetype() !== 'image/jpeg') {
return;
}
// we only work on process initiated as background job, so ask for a re-run later
if ($event instanceof MetadataLiveEvent) {
$event->requestBackgroundJob();
return;
}
$fd = $node->fopen('rb');
if (false === $fd) {
return;
}
try {
$oldBufferSize = stream_set_chunk_size($fd, 1);
$data = @exif_read_data($fd, 'ANY_TAG', true);
stream_set_chunk_size($fd, $oldBufferSize);
// we have exif data in $data, let's index the photo taken date $metadata = $event->getMetadata();
$metadata->setInt('photo-taken', strtotime($data['EXIF']['DateTimeOriginal']), true);
} catch (\Exception $e) {
}
}
}

How to use the (current) QueryHelper

 /** @var ConnectionAdapter $conn */
$conn = \OCP\Server::get(ConnectionAdapter::class);
$qb = $conn->getQueryBuilder();
$qb->select('file.fileid', 'file.path')->from('filecache', 'file');
// linking metadataQuery to existing query builder
$metadataQuery = $this->filesMetadataManager->getMetadataQuery($qb, 'file', 'fileid');
// add metadata to the request's results
$metadataQuery->retrieveMetadata();
// only returns result havin
$metadataQuery->joinIndex('another');
$expr = $qb->expr();
$qb->where(
$expr->lte(
$metadataQuery->getMetadataValueIntField(),
$qb->createNamedParameter(1, IQueryBuilder::PARAM_INT)
)
);
$qb->orderBy($metadataQuery->getMetadataValueIntField(), 'desc');

Loading
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2. developingWork in progressenhancementpending documentationThis pull request needs an associated documentation update❄️ 2023-Winter

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants

@ArtificialOwl@nickvergessen@icewind1991@artonge@github-advanced-security@come-nc@AndyScherzinger@ChristophWurst@skjnldsv