From 537765cc11a95624cecbd2d0b528b0604f8a9b55 Mon Sep 17 00:00:00 2001 From: Arne Hamann Date: Tue, 23 Apr 2019 12:13:51 +0200 Subject: [PATCH 1/9] Load points from devices Signed-off-by: Arne Hamann --- lib/Service/GeophotoService.php | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/Service/GeophotoService.php b/lib/Service/GeophotoService.php index e19d90be1..5d36d4c7e 100644 --- a/lib/Service/GeophotoService.php +++ b/lib/Service/GeophotoService.php @@ -25,6 +25,7 @@ use OCA\Maps\DB\Geophoto; use OCA\Maps\DB\GeophotoMapper; use OCA\Maps\Service\TracksService; +use OCA\Maps\Service\DevicesService; class GeophotoService { @@ -35,8 +36,9 @@ class GeophotoService { private $preview; private $tracksService; private $timeordedPointSets; + private $devicesService; - public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, GeophotoMapper $photoMapper, IPreview $preview, TracksService $tracksService, $userId) { + public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, GeophotoMapper $photoMapper, IPreview $preview, TracksService $tracksService, DevicesService $devicesService, $userId) { $this->root = $root; $this->l10n = $l10n; $this->photoMapper = $photoMapper; @@ -45,6 +47,7 @@ public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, Ge $this->tracksService = $tracksService; $this->timeordedPointSets = null; $this->userId = $userId; + $this->devicesService = $devicesService; } @@ -165,6 +168,15 @@ private function loadTimeordedPointSets($userId) { } } } + foreach ($this->devicesService->getDevicesFromDB($userId) as $device) { + $device_points = $this->devicesService->getDevicePointsFromDB($userId, $device); + $points = []; + foreach ($device_points as $pt) { + $points[$pt->timestamp] = [(string) $pt->lat, (string) $pt->lng]; + } + $foo = ksort($points); + $this->timeordedPointSets[] = $points; + } return null; } From c8a894cfbdcae81f847204c6fa0976771edafeaf Mon Sep 17 00:00:00 2001 From: Arne Hamann Date: Tue, 23 Apr 2019 12:24:58 +0200 Subject: [PATCH 2/9] skip point sets which does not overlap with the date Signed-off-by: Arne Hamann --- lib/Service/GeophotoService.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/lib/Service/GeophotoService.php b/lib/Service/GeophotoService.php index 5d36d4c7e..55d4bf832 100644 --- a/lib/Service/GeophotoService.php +++ b/lib/Service/GeophotoService.php @@ -219,6 +219,13 @@ private function getTimeorderdPointsFromTrack($track) { * @param $points array sorted by keys timestamp => [lat, lng] */ private function getLocationFromSequenceOfPoints($dateTaken, $points) { + $foo = end($points); + $end = key($points); + $foo = reset($points); + $start = key($points); + if ($start > $dateTaken OR $end < $dateTaken) { + return null; + } $smaller = null; $bigger = null; foreach ($points as $time => $locations) { From df336390ccdd20d39f46e912fd7a3716ee8f9ab3 Mon Sep 17 00:00:00 2001 From: Arne Hamann Date: Tue, 23 Apr 2019 17:57:21 +0200 Subject: [PATCH 3/9] Added mapsTimeOrderedPointSets cache Signed-off-by: Arne Hamann --- lib/Service/GeophotoService.php | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/Service/GeophotoService.php b/lib/Service/GeophotoService.php index 55d4bf832..7194bdc0d 100644 --- a/lib/Service/GeophotoService.php +++ b/lib/Service/GeophotoService.php @@ -19,6 +19,7 @@ use OCP\Files\Folder; use OCP\IPreview; use OCP\ILogger; +use OCP\ICache; use OCA\Maps\Service\PhotofilesService; @@ -37,8 +38,9 @@ class GeophotoService { private $tracksService; private $timeordedPointSets; private $devicesService; + private $cache; - public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, GeophotoMapper $photoMapper, IPreview $preview, TracksService $tracksService, DevicesService $devicesService, $userId) { + public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, GeophotoMapper $photoMapper, IPreview $preview, TracksService $tracksService, DevicesService $devicesService, ICache $cache, $userId) { $this->root = $root; $this->l10n = $l10n; $this->photoMapper = $photoMapper; @@ -48,7 +50,7 @@ public function __construct (ILogger $logger, IRootFolder $root, IL10N $l10n, Ge $this->timeordedPointSets = null; $this->userId = $userId; $this->devicesService = $devicesService; - + $this->cache = $cache; } /** @@ -94,7 +96,7 @@ public function getAllFromDB ($userId) { * @return array with geodatas of all nonLocalizedPhotos */ public function getNonLocalizedFromDB ($userId) { - $foo = $this->loadTimeordedPointSets($userId); + $foo = $this->loadTimeOrderedPointSets($userId); $photoEntities = $this->photoMapper->findAllNonLocalized($userId); $userFolder = $this->getFolderForUser($userId); $filesById = []; @@ -155,7 +157,11 @@ private function getLocationGuesses($dateTaken) { * Timeorderd Point sets is an Array of Arrays with time => location as key=>value pair, which are orderd by the key. * This function loads this Arrays from all Track files of the user. */ - private function loadTimeordedPointSets($userId) { + private function loadTimeOrderedPointSets($userId) { + $this->timeordedPointSets = $this->cache->get('mapsTimeOrderedPointSets'); + if (!is_null($this->timeordedPointSets)) { + return null; + } $userFolder = $this->getFolderForUser($userId); foreach ($this->tracksService->getTracksFromDB($userId) as $gpxfile) { $res = $userFolder->getById($gpxfile['file_id']); @@ -177,6 +183,7 @@ private function loadTimeordedPointSets($userId) { $foo = ksort($points); $this->timeordedPointSets[] = $points; } + $this->cache->set('mapsTimeOrderedPointSets', $this->timeordedPointSets, $ttl=120); return null; } @@ -191,6 +198,7 @@ private function getTracksFromGPX($content) { foreach ($gpx->trk as $trk) { $tracks[] = $trk; } + return $tracks; } From e6770656799fc55039411f6218de90598242f206 Mon Sep 17 00:00:00 2001 From: Arne Hamann Date: Tue, 23 Apr 2019 18:51:54 +0200 Subject: [PATCH 4/9] Added Api for lazy loading Signed-off-by: Arne Hamann --- appinfo/routes.php | 2 ++ lib/Controller/PhotosController.php | 17 +++++++++ lib/DB/GeophotoMapper.php | 12 +++++++ lib/Service/GeophotoService.php | 54 +++++++++++++++++++++++++++++ 4 files changed, 85 insertions(+) diff --git a/appinfo/routes.php b/appinfo/routes.php index e9f7b5363..d96f97e38 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -21,6 +21,8 @@ // photos ['name' => 'photos#getPhotosFromDb', 'url' => '/photos', 'verb' => 'GET'], ['name' => 'photos#getNonLocalizedPhotosFromDb', 'url' => '/photos/nonlocalized', 'verb' => 'GET'], + ['name' => 'photos#getNonLocalizedPhotoIds', 'url' => '/photos/nonlocalizedids', 'verb' => 'GET'], + ['name' => 'photos#getNonLocalizedPhotosById', 'url' => '/photos/nonlocalized/{id}', 'verb' => 'GET'], ['name' => 'photos#placePhotos', 'url' => '/photos', 'verb' => 'POST'], // contacts diff --git a/lib/Controller/PhotosController.php b/lib/Controller/PhotosController.php index 5e72faea2..7eeebaad7 100644 --- a/lib/Controller/PhotosController.php +++ b/lib/Controller/PhotosController.php @@ -53,6 +53,23 @@ public function getNonLocalizedPhotosFromDb() { return new DataResponse($result); } + /** + * @NoAdminRequired + * @NoCSRFRequired + */ + public function getNonLocalizedPhotoIds() { + $result = $this->geophotoService->getNonLocalizedIdsFromDB($this->userId); + return new DataResponse($result); + } + + /** + * @param $id + * @NoAdminRequired + * @NoCSRFRequired + */ + public function getNonLocalizedPhotosById($id) { + return new DataResponse($this->geophotoService->getNonLocalizedById($this->userId, $id)); + } /** * @NoAdminRequired diff --git a/lib/DB/GeophotoMapper.php b/lib/DB/GeophotoMapper.php index 4a4e0d6c9..2be8a16b4 100644 --- a/lib/DB/GeophotoMapper.php +++ b/lib/DB/GeophotoMapper.php @@ -27,6 +27,18 @@ public function find($id) { return $this->findEntity($sql, [$id]); } + public function findByUserAndId($userId, $id) { + try { + $sql = 'SELECT * FROM `*PREFIX*maps_photos` ' . + 'WHERE `user_id` = ? ' . + 'AND `id` = ? '; + return $this->findEntity($sql, [$userId, $id]); + } + catch (\Throwable $e) { + return null; + } + } + public function findByFileId($userId, $fileId) { try { $sql = 'SELECT * FROM `*PREFIX*maps_photos` ' . diff --git a/lib/Service/GeophotoService.php b/lib/Service/GeophotoService.php index 7194bdc0d..616ffe3e8 100644 --- a/lib/Service/GeophotoService.php +++ b/lib/Service/GeophotoService.php @@ -133,6 +133,60 @@ public function getNonLocalizedFromDB ($userId) { return $filesById; } + /** + * @param string $userId + * @return array with all id's of nonLocalizedPhotos + */ + public function getNonLocalizedIdsFromDB ($userId) { + $foo = $this->loadTimeOrderedPointSets($userId); + $photoEntities = $this->photoMapper->findAllNonLocalized($userId); + $fileIds = []; + foreach ($photoEntities as $photoEntity) { + $fileIds[] = $photoEntity->getId(); + } + return $fileIds; + } + /** + * + */ + public function getNonLocalizedById($userId, $id) { + $foo = $this->loadTimeOrderedPointSets($userId); + $photoEntity = $this->photoMapper->findByUserAndId($userId, $id); + $filesById = []; + if (is_null($photoEntity)) { + return $filesById; + } + $userFolder = $this->getFolderForUser($userId); + + $cache = $userFolder->getStorage()->getCache(); + $previewEnableMimetypes = $this->getPreviewEnabledMimetypes(); + + $cacheEntry = $cache->get($photoEntity->getFileId()); + if ($cacheEntry) { + // this path is relative to owner's storage + //$path = $cacheEntry->getPath(); + // but we want it relative to current user's storage + $file = $userFolder->getById($photoEntity->getFileId())[0]; + if (!is_null($file)) { + $path = preg_replace('/^\/'.$userId.'\//', '', $file->getPath()); + + $date = $photoEntity->getDateTaken() ?? \time(); + $locations = $this->getLocationGuesses($date); + foreach ($locations as $location) { + $file_object = new \stdClass(); + $file_object->fileId = $photoEntity->getFileId(); + $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; + $filesById[] = $file_object; + }; + } + } + + return $filesById; + } /** * returns a array of locations for a given date * @param $dateTaken From 719925e0d9009d3f8982c42000141c19b60481f7 Mon Sep 17 00:00:00 2001 From: Arne Hamann Date: Tue, 23 Apr 2019 19:11:13 +0200 Subject: [PATCH 5/9] Toggle Photos Navigation entry Signed-off-by: Arne Hamann --- js/photosController.js | 11 +++++++++++ templates/navigation/index.php | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/js/photosController.js b/js/photosController.js index 5905bf34c..51bd89211 100644 --- a/js/photosController.js +++ b/js/photosController.js @@ -51,6 +51,13 @@ PhotosController.prototype = { $(this).parent().parent().parent().find('>.app-navigation-entry-menu').addClass('open'); } }); + // expand navigation + $('body').on('click', '#navigation-photos', function(e) { + if (e.target.tagName === 'LI' && $(e.target).attr('id') === 'navigation-photos') { + that.toggleNavigation(); + that.optionsController.saveOptionValues({photosNavigationShow: $('#navigation-favorites').hasClass('open')}); + } + }); }, updateMyFirstLastDates: function() { @@ -86,6 +93,10 @@ PhotosController.prototype = { } }, + toggleNavigation: function() { + $('#navigation-photos').toggleClass('open'); + }, + getPhotoMarkerOnClickFunction: function() { var _app = this; return function(evt) { diff --git a/templates/navigation/index.php b/templates/navigation/index.php index 230032ae8..d33f38bfb 100644 --- a/templates/navigation/index.php +++ b/templates/navigation/index.php @@ -68,7 +68,7 @@ -