Skip to content

Commit

Permalink
Merge pull request #726 from nextcloud/repectNoMediaAndNoImage
Browse files Browse the repository at this point in the history
Respect .nomedia and .noimage files
  • Loading branch information
tacruc authored May 19, 2022
2 parents 15ef345 + 9bea343 commit c05af30
Show file tree
Hide file tree
Showing 4 changed files with 183 additions and 77 deletions.
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

0 comments on commit c05af30

Please sign in to comment.