Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions lib/Helper/ExifGeoData.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,16 @@ class ExifGeoData
*/
protected static function get_exif_data_array(string $path) : array{
if( function_exists('exif_read_data') ) {
$data = @exif_read_data($path, null, true)['EXIF'];
if ($data && isset($data[self::LATITUDE]) && isset($data[self::LONGITUDE])) {
return $data;
}
$data = @exif_read_data($path, null, true);
if ($data && isset($data['EXIF']) && isset($data['EXIF'][self::LATITUDE]) && isset($data['EXIF'][self::LONGITUDE])) {
return $data['EXIF'];
} elseif ($data && isset($data['GPS']) && isset($data['GPS'][self::LATITUDE]) && isset($data['GPS'][self::LONGITUDE])) {
$d = $data['GPS'];
if (!isset($d[self::TIMESTAMP]) && isset($data['EXIF'][self::TIMESTAMP])) {
$d[self::TIMESTAMP] = $data['EXIF'][self::TIMESTAMP];
}
return $data['GPS'];
}
}
$data = new PelDataWindow(file_get_contents($path));
if (PelJpeg::isValid($data)) {
Expand Down Expand Up @@ -254,7 +260,7 @@ private function parse()
// optional
if (isset($this->exif_data[self::TIMESTAMP])) {
$t = $this->exif_data[self::TIMESTAMP];
$this->timestamp = is_string($t) ? $this->string2time($t) : is_int($t) ? $t : null;
$this->timestamp = is_string($t) ? $this->string2time($t) : ( is_int($t) ? $t : null );
}
}

Expand Down
160 changes: 103 additions & 57 deletions lib/Service/GeophotoService.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@

namespace OCA\Maps\Service;

use OC\Files\Search\SearchBinaryOperator;
use OC\Files\Search\SearchComparison;
use OC\Files\Search\SearchQuery;
use OCP\Files\FileInfo;
use OCP\Files\Search\ISearchBinaryOperator;
use OCP\Files\Search\ISearchComparison;
use OCP\IL10N;
use OCP\Files\IRootFolder;
use OCP\Files\Storage\IStorage;
Expand Down Expand Up @@ -60,17 +65,19 @@ public function __construct (ILogger $logger,

/**
* @param string $userId
* @param bool $respectNomediaAndNoimage=true
* @return array with geodatas of all photos
*/
public function getAllFromDB($userId) {
public function getAllFromDB(string $userId, bool $respectNomediaAndNoimage=true) {
$ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId) : [];
$photoEntities = $this->photoMapper->findAll($userId);
$userFolder = $this->getFolderForUser($userId);
$filesById = [];
$cache = $userFolder->getStorage()->getCache();
$previewEnableMimetypes = $this->getPreviewEnabledMimetypes();
foreach ($photoEntities as $photoEntity) {
$cacheEntry = $cache->get($photoEntity->getFileId());
if ($cacheEntry) {
if ($cacheEntry) {
// this path is relative to owner's storage
//$path = $cacheEntry->getPath();
// but we want it relative to current user's storage
Expand All @@ -83,26 +90,35 @@ public function getAllFromDB($userId) {
continue;
}
$path = $userFolder->getRelativePath( $file->getPath());
$isRoot = $file === $userFolder;
$isIgnored = false;
foreach ($ignoredPaths as $ignoredPath) {
if (str_starts_with($path, $ignoredPath)) {
$isIgnored = true;
break;
}
}
if (!$isIgnored) {
$isRoot = $file === $userFolder;

$file_object = new \stdClass();
$file_object->fileId = $photoEntity->getFileId();
$file_object->fileid = $file_object->fileId;
$file_object->lat = $photoEntity->getLat();
$file_object->lng = $photoEntity->getLng();
$file_object->dateTaken = $photoEntity->getDateTaken() ?? \time();
$file_object->basename = $isRoot ? '' : $file->getName();
$file_object->filename = $this->normalizePath($path);
$file_object->etag = $cacheEntry->getEtag();
$file_object = new \stdClass();
$file_object->fileId = $photoEntity->getFileId();
$file_object->fileid = $file_object->fileId;
$file_object->lat = $photoEntity->getLat();
$file_object->lng = $photoEntity->getLng();
$file_object->dateTaken = $photoEntity->getDateTaken() ?? \time();
$file_object->basename = $isRoot ? '' : $file->getName();
$file_object->filename = $this->normalizePath($path);
$file_object->etag = $cacheEntry->getEtag();
//Not working for NC21 as Viewer requires String representation of permissions
// $file_object->permissions = $file->getPermissions();
$file_object->type = $file->getType();
$file_object->mime = $file->getMimetype();
$file_object->lastmod = $file->getMTime();
$file_object->size = $file->getSize();
$file_object->path = $path;
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$filesById[] = $file_object;
$file_object->type = $file->getType();
$file_object->mime = $file->getMimetype();
$file_object->lastmod = $file->getMTime();
$file_object->size = $file->getSize();
$file_object->path = $path;
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$filesById[] = $file_object;
}
}
}
shuffle($filesById);
Expand All @@ -111,9 +127,11 @@ public function getAllFromDB($userId) {

/**
* @param string $userId
* @param bool $respectNomediaAndNoimage
* @return array with geodatas of all nonLocalizedPhotos
*/
public function getNonLocalizedFromDB ($userId) {
public function getNonLocalizedFromDB (string $userId, bool $respectNomediaAndNoimage=true): array {
$ignoredPaths = $respectNomediaAndNoimage ? $this->getIgnoredPaths($userId) : [];
$foo = $this->loadTimeorderedPointSets($userId);
$photoEntities = $this->photoMapper->findAllNonLocalized($userId);
$userFolder = $this->getFolderForUser($userId);
Expand All @@ -136,45 +154,79 @@ public function getNonLocalizedFromDB ($userId) {
}
$path = $userFolder->getRelativePath( $file->getPath());
$isRoot = $file === $userFolder;
$isIgnored = false;

$date = $photoEntity->getDateTaken() ?? \time();
$locations = $this->getLocationGuesses($date);
foreach ($locations as $location) {
$file_object = new \stdClass();
$file_object->fileId = $photoEntity->getFileId();
$file_object->fileid = $file_object->fileId;
$file_object->path = $this->normalizePath($path);
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$file_object->lat = $location[0];
$file_object->lng = $location[1];
$file_object->dateTaken = $date;
$file_object->basename = $isRoot ? '' : $file->getName();
$file_object->filename = $this->normalizePath($path);
$file_object->etag = $cacheEntry->getEtag();
foreach ($ignoredPaths as $ignoredPath) {
if (str_starts_with($path, $ignoredPath)) {
$isIgnored = true;
break;
}
}
if (!$isIgnored) {
$date = $photoEntity->getDateTaken() ?? \time();
$locations = $this->getLocationGuesses($date);
$isRoot = $file === $userFolder;
foreach ($locations as $location) {
$file_object = new \stdClass();
$file_object->fileId = $photoEntity->getFileId();
$file_object->fileid = $file_object->fileId;
$file_object->path = $this->normalizePath($path);
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$file_object->lat = $location[0];
$file_object->lng = $location[1];
$file_object->dateTaken = $date;
$file_object->basename = $isRoot ? '' : $file->getName();
$file_object->filename = $this->normalizePath($path);
$file_object->etag = $cacheEntry->getEtag();
//Not working for NC21 as Viewer requires String representation of permissions
// $file_object->permissions = $file->getPermissions();
$file_object->type = $file->getType();
$file_object->mime = $file->getMimetype();
$file_object->lastmod = $file->getMTime();
$file_object->size = $file->getSize();
$file_object->path = $path;
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$filesById[] = $file_object;
}

$file_object->type = $file->getType();
$file_object->mime = $file->getMimetype();
$file_object->lastmod = $file->getMTime();
$file_object->size = $file->getSize();
$file_object->path = $path;
$file_object->hasPreview = in_array($cacheEntry->getMimeType(), $previewEnableMimetypes);
$filesById[] = $file_object;
}
}
}

}
shuffle($filesById);
return $filesById;
}

/**
* @return array
*/
private function getIgnoredPaths($userId): array {
$ignoredPaths = [];
$userFolder = $this->root->getUserFolder($userId);
$excludedNodes = $userFolder->search(new SearchQuery(
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_AND, [
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'mimetype', 'application/octet-stream'),
new SearchBinaryOperator(ISearchBinaryOperator::OPERATOR_OR, [
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', '.nomedia'),
new SearchComparison(ISearchComparison::COMPARE_EQUAL, 'name', '.noimage'),
]),
]),
0,
0,
[]
));
foreach($excludedNodes as $node) {
$ignoredPaths[] = $userFolder->getRelativePath($node->getParent()->getPath());
}
return $ignoredPaths;
}

/**
* returns a array of locations for a given date
* @param $dateTaken
*
* @param $dateTaken int
* @return array
*/
private function getLocationGuesses($dateTaken) {
private function getLocationGuesses(int $dateTaken): array {
$locations = [];
foreach (($this->timeorderedPointSets ?? []) as $timeordedPointSet) {
$location = $this->getLocationFromSequenceOfPoints($dateTaken,$timeordedPointSet);
Expand Down Expand Up @@ -220,7 +272,7 @@ private function loadTimeorderedPointSets($userId) {
* @param $content
* @return array
*/
private function getTracksFromGPX($content) {
private function getTracksFromGPX($content): array {
$tracks = [];
$gpx = simplexml_load_string($content);
foreach ($gpx->trk as $trk) {
Expand All @@ -234,7 +286,7 @@ private function getTracksFromGPX($content) {
* @param $track
* @return array
*/
private function getTimeorderdPointsFromTrack($track) {
private function getTimeorderdPointsFromTrack($track): array {
$points = [];
foreach ($track->trkseg as $seg) {
foreach ($seg->trkpt as $pt) {
Expand All @@ -250,10 +302,10 @@ private function getTimeorderdPointsFromTrack($track) {
}

/**
* @param $dateTaken date of the picture
* @param $dateTaken int timestamp of the picture
* @param $points array sorted by keys timestamp => [lat, lng]
*/
private function getLocationFromSequenceOfPoints($dateTaken, $points) {
private function getLocationFromSequenceOfPoints(int $dateTaken, array $points): ?array {
$foo = end($points);
$end = key($points);
$foo = reset($points);
Expand Down Expand Up @@ -282,7 +334,7 @@ private function getLocationFromSequenceOfPoints($dateTaken, $points) {
}
}

private function getPreviewEnabledMimetypes() {
private function getPreviewEnabledMimetypes(): array {
$enabledMimeTypes = [];
foreach (PhotofilesService::PHOTO_MIME_TYPES as $mimeType) {
if ($this->preview->isMimeSupported($mimeType)) {
Expand All @@ -301,13 +353,7 @@ private function normalizePath($path) {
* @return Folder
*/
private function getFolderForUser ($userId) {
$path = '/' . $userId . '/files';
if ($this->root->nodeExists($path)) {
$folder = $this->root->get($path);
} else {
$folder = $this->root->newFolder($path);
}
return $folder;
return $this->root->getUserFolder($userId);
}

}
Loading