Skip to content

Commit

Permalink
Create photos sidebar tab
Browse files Browse the repository at this point in the history
Signed-off-by: Louis Chemineau <[email protected]>
  • Loading branch information
artonge committed Nov 9, 2023
1 parent 0a42ed4 commit 78d92c5
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 15 deletions.
25 changes: 15 additions & 10 deletions lib/MetadataProvider/ExifMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,11 @@ public function handle(Event $event): void {
}

if ($rawExifData && array_key_exists('EXIF', $rawExifData)) {
$event->getMetadata()->setArray('photos-exif', $this->base64Encode($rawExifData['EXIF']));
$event->getMetadata()->setArray('photos-exif', $this->sanitizeEntries($rawExifData['EXIF']));
}

if ($rawExifData && array_key_exists('IFD0', $rawExifData)) {
$event->getMetadata()->setArray('photos-ifd0', $this->base64Encode($rawExifData['IFD0']));
$event->getMetadata()->setArray('photos-ifd0', $this->sanitizeEntries($rawExifData['IFD0']));
}

if (
Expand Down Expand Up @@ -144,19 +144,24 @@ private function parseGPSData(string $rawData): float {
* This method will base 64 encode any non UTF-8 string in an array.
* This will also remove control characters from UTF-8 strings.
*/
private function base64Encode(array $data): array {
private function sanitizeEntries(array $data): array {
$cleanData = [];

foreach ($data as $key => $value) {
if (!is_string($value)) {
continue;
if (is_string($value) && !mb_check_encoding($value, 'UTF-8')) {
$value = 'base64:'.base64_encode($value);
} elseif (is_string($value)) {
// TODO: Can be remove when the Sidebar use the @nextcloud/files to fetch and parse the DAV response.
$value = preg_replace('/[[:cntrl:]]/u', '', $value);
}

if (!mb_check_encoding($value, 'UTF-8')) {
$data[$key] = 'base64:'.base64_encode($value);
} else {
$data[$key] = preg_replace('/[[:cntrl:]]/u', '', $value);
if (preg_match('/[^a-zA-Z]/', $key) !== 0) {
$key = preg_replace('/[^a-zA-Z]/', '_', $key);
}

$cleanData[$key] = $value;
}

return $data;
return $cleanData;
}
}
18 changes: 18 additions & 0 deletions src/sidebar.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,22 @@ window.addEventListener('DOMContentLoaded', async function() {
const { default: PhotosTab } = await import(/* webpackPreload: true */ './views/PhotosTab.vue')
PhotosTabView = PhotosTabView ?? Vue.extend(PhotosTab)
}

/**
*
* @param metadataArray
*/
function parseMetadataArray(metadataArray) {
return metadataArray?.reduce((parsedArray, metadata) => ({ ...parsedArray, [metadata.nodeName]: metadata.textContent }), {})
}

OC.Files.getClient().addFileInfoParser(function(response) {
return {
'metadata-photos-original_date_time': response.propStat[0].properties[`{${OC.Files.Client.NS_NEXTCLOUD}}metadata-photos-original_date_time`],
'metadata-photos-exif': parseMetadataArray(response.propStat[0].properties[`{${OC.Files.Client.NS_NEXTCLOUD}}metadata-photos-exif`]),
'metadata-photos-ifd0': parseMetadataArray(response.propStat[0].properties[`{${OC.Files.Client.NS_NEXTCLOUD}}metadata-photos-ifd0`]),
'metadata-photos-gps': parseMetadataArray(response.propStat[0].properties[`{${OC.Files.Client.NS_NEXTCLOUD}}metadata-photos-gps`]),
'metadata-photos-place': response.propStat[0].properties[`{${OC.Files.Client.NS_NEXTCLOUD}}metadata-photos-place`],
}
})
})
19 changes: 14 additions & 5 deletions src/views/PhotosTab.vue
Original file line number Diff line number Diff line change
Expand Up @@ -87,31 +87,40 @@ export default {
* @return {object}
*/
exif() {
return this.fileInfo.attributes['metadata-photos-exif']
return this.fileInfo['metadata-photos-exif']
},
/**
* @return {object}
*/
ifd0() {
return this.fileInfo.attributes['metadata-photos-ifd0']
return this.fileInfo['metadata-photos-ifd0']
},
/**
* @return {object}
*/
place() {
return this.fileInfo.attributes['metadata-photos-place']
return this.fileInfo['metadata-photos-place']
},
/**
* @return {object}
*/
gps() {
return this.fileInfo.attributes['metadata-photos-gps']
const gps = this.fileInfo['metadata-photos-gps']
if (!gps) {
return undefined
}

return {
latitude: Number.parseFloat(gps.latitude || 0),
longitude: Number.parseFloat(gps.longitude || 0),
altitude: Number.parseFloat(gps.altitude || 0),
}
},
/**
* @return {object}
*/
originalDateTime() {
return this.fileInfo.attributes['metadata-photos-original_date_time'] * 1000
return this.fileInfo['metadata-photos-original_date_time'] * 1000
},
/**
* @return {string}
Expand Down

0 comments on commit 78d92c5

Please sign in to comment.