diff --git a/README.md b/README.md index e0434e05..dce1c057 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,8 @@ While there are many things that could be done to further improve this app, the We would be more than excited if you would like to collaborate with us. We will merge pull requests for new features and fixes. We also would love to welcome co-maintainers. If there is a strong business case for any development of this app, we will consider your wishes for our roadmap. Please [contact your account manager](https://nextcloud.com/enterprise/) to talk about the possibilities. + +## Limitations + +This app can not migrate Google photos files due to limitations in the Google Photos API making it too complex for end users. +For more information please visit [the Google Photos Documentation.](https://developers.google.com/photos/support/updates#affected-scopes-methods) diff --git a/appinfo/info.xml b/appinfo/info.xml index d5b07388..452522f4 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -3,7 +3,7 @@ integration_google Google integration Import Google data into Nextcloud - + 4.0.0-dev agpl Julien Veyssier diff --git a/appinfo/routes.php b/appinfo/routes.php index a291847e..ec357a78 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -20,11 +20,8 @@ ['name' => 'googleAPI#getDriveSize', 'url' => '/drive-size', 'verb' => 'GET'], ['name' => 'googleAPI#getCalendarList', 'url' => '/calendars', 'verb' => 'GET'], ['name' => 'googleAPI#getContactNumber', 'url' => '/contact-number', 'verb' => 'GET'], - ['name' => 'googleAPI#getPhotoNumber', 'url' => '/photo-number', 'verb' => 'GET'], ['name' => 'googleAPI#importCalendar', 'url' => '/import-calendar', 'verb' => 'GET'], ['name' => 'googleAPI#importContacts', 'url' => '/import-contacts', 'verb' => 'GET'], - ['name' => 'googleAPI#importPhotos', 'url' => '/import-photos', 'verb' => 'GET'], - ['name' => 'googleAPI#getImportPhotosInformation', 'url' => '/import-photos-info', 'verb' => 'GET'], ['name' => 'googleAPI#importDrive', 'url' => '/import-files', 'verb' => 'GET'], ['name' => 'googleAPI#getImportDriveInformation', 'url' => '/import-files-info', 'verb' => 'GET'], ] diff --git a/lib/BackgroundJob/ImportPhotosJob.php b/lib/BackgroundJob/ImportPhotosJob.php deleted file mode 100644 index f8c6730b..00000000 --- a/lib/BackgroundJob/ImportPhotosJob.php +++ /dev/null @@ -1,39 +0,0 @@ -service->importPhotosJob($userId); - } -} diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index 75c31604..0ea0f0f8 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -39,7 +39,6 @@ class ConfigController extends Controller { public const CONTACTS_OTHER_SCOPE = 'https://www.googleapis.com/auth/contacts.other.readonly'; public const CALENDAR_SCOPE = 'https://www.googleapis.com/auth/calendar.readonly'; public const CALENDAR_EVENTS_SCOPE = 'https://www.googleapis.com/auth/calendar.events.readonly'; - public const PHOTOS_SCOPE = 'https://www.googleapis.com/auth/photoslibrary.readonly'; public function __construct( string $appName, @@ -179,7 +178,6 @@ public function oauthRedirect(string $code = '', string $state = '', string $sco 'can_access_drive' => in_array(self::DRIVE_SCOPE, $scopes) ? 1 : 0, 'can_access_contacts' => in_array(self::CONTACTS_SCOPE, $scopes) ? 1 : 0, 'can_access_other_contacts' => in_array(self::CONTACTS_OTHER_SCOPE, $scopes) ? 1 : 0, - 'can_access_photos' => in_array(self::PHOTOS_SCOPE, $scopes) ? 1 : 0, 'can_access_calendar' => (in_array(self::CALENDAR_SCOPE, $scopes) && in_array(self::CALENDAR_EVENTS_SCOPE, $scopes)) ? 1 : 0, ]; diff --git a/lib/Controller/GoogleAPIController.php b/lib/Controller/GoogleAPIController.php index 5d089eb0..b99bb785 100644 --- a/lib/Controller/GoogleAPIController.php +++ b/lib/Controller/GoogleAPIController.php @@ -16,7 +16,6 @@ use OCA\Google\Service\GoogleCalendarAPIService; use OCA\Google\Service\GoogleContactsAPIService; use OCA\Google\Service\GoogleDriveAPIService; -use OCA\Google\Service\GooglePhotosAPIService; use OCA\Google\Service\SecretService; use OCP\AppFramework\Controller; use OCP\AppFramework\Http\DataResponse; @@ -31,7 +30,6 @@ public function __construct( string $appName, IRequest $request, private IConfig $config, - private GooglePhotosAPIService $googlePhotosAPIService, private GoogleContactsAPIService $googleContactsAPIService, private GoogleDriveAPIService $googleDriveAPIService, private GoogleCalendarAPIService $googleCalendarAPIService, @@ -42,22 +40,6 @@ public function __construct( $this->accessToken = $this->userId !== null ? $this->secretService->getEncryptedUserValue($this->userId, 'token') : ''; } - /** - * @NoAdminRequired - * - * @return DataResponse - */ - public function getImportPhotosInformation(): DataResponse { - if ($this->accessToken === '') { - return new DataResponse([], 400); - } - return new DataResponse([ - 'importing_photos' => $this->config->getUserValue($this->userId, Application::APP_ID, 'importing_photos') === '1', - 'last_import_timestamp' => (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'last_import_timestamp', '0'), - 'nb_imported_photos' => (int)$this->config->getUserValue($this->userId, Application::APP_ID, 'nb_imported_photos', '0'), - ]); - } - /** * @NoAdminRequired * @@ -75,25 +57,6 @@ public function getImportDriveInformation(): DataResponse { ]); } - /** - * @NoAdminRequired - * - * @return DataResponse - */ - public function getPhotoNumber(): DataResponse { - if ($this->accessToken === '' || $this->userId === null) { - return new DataResponse([], 400); - } - /** @var array{error?:string} $result */ - $result = $this->googlePhotosAPIService->getPhotoNumber($this->userId); - if (isset($result['error'])) { - $response = new DataResponse($result['error'], 401); - } else { - $response = new DataResponse($result); - } - return $response; - } - /** * @NoAdminRequired * @@ -151,25 +114,6 @@ public function getDriveSize(): DataResponse { return $response; } - /** - * @NoAdminRequired - * - * @return DataResponse - */ - public function importPhotos(): DataResponse { - if ($this->accessToken === '' || $this->userId === null) { - return new DataResponse([], 400); - } - /** @var array{error?:string} $result */ - $result = $this->googlePhotosAPIService->startImportPhotos($this->userId); - if (isset($result['error'])) { - $response = new DataResponse($result['error'], 401); - } else { - $response = new DataResponse($result); - } - return $response; - } - /** * @NoAdminRequired * diff --git a/lib/Notification/Notifier.php b/lib/Notification/Notifier.php index 4740787d..8c06fc95 100644 --- a/lib/Notification/Notifier.php +++ b/lib/Notification/Notifier.php @@ -62,18 +62,6 @@ public function prepare(INotification $notification, string $languageCode): INot $l = $this->factory->get('integration_google', $languageCode); switch ($notification->getSubject()) { - case 'import_photos_finished': - /** @var array{nbImported?:string, targetPath: string} $p */ - $p = $notification->getSubjectParameters(); - $nbImported = (int)($p['nbImported'] ?? 0); - $targetPath = $p['targetPath']; - $content = $l->n('%n photo was imported from Google.', '%n photos were imported from Google.', $nbImported); - - $notification->setParsedSubject($content) - ->setIcon($this->url->getAbsoluteURL($this->url->imagePath(Application::APP_ID, 'app-dark.svg'))) - ->setLink($this->url->linkToRouteAbsolute('files.view.index', ['dir' => $targetPath])); - return $notification; - case 'import_drive_finished': /** @var array{nbImported?:string, targetPath: string} $p */ $p = $notification->getSubjectParameters(); diff --git a/lib/Service/GooglePhotosAPIService.php b/lib/Service/GooglePhotosAPIService.php deleted file mode 100644 index 692409dc..00000000 --- a/lib/Service/GooglePhotosAPIService.php +++ /dev/null @@ -1,424 +0,0 @@ - 50, - ]; - do { - $this->logger->debug( - 'Photos service::getPhotoNumber LAUNCHING ALBUM LIST REQUEST, userid: "' . $userId . '"', - ['app' => Application::APP_ID] - ); - $result = $this->googleApiService->request($userId, 'v1/albums', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['albums']) && is_array($result['albums'])) { - foreach ($result['albums'] as $album) { - $nbPhotos += $album['mediaItemsCount'] ?? 0; - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - - // shared albums - $considerSharedAlbums = $this->config->getUserValue($userId, Application::APP_ID, 'consider_shared_albums', '0') === '1'; - if ($considerSharedAlbums) { - $params = [ - 'pageSize' => 50, - ]; - do { - $result = $this->googleApiService->request($userId, 'v1/sharedAlbums', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['sharedAlbums']) && is_array($result['sharedAlbums'])) { - foreach ($result['sharedAlbums'] as $album) { - $nbPhotos += $album['mediaItemsCount'] ?? 0; - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - } - - // check if there is any photo outside albums - // (number is not relevant here as we just make one paginated request to avoid reaching request limit) - if ($nbPhotos === 0) { - $params = [ - 'pageSize' => 50, - ]; - - $result = $this->googleApiService->request($userId, 'v1/mediaItems', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - - if (isset($result['mediaItems']) && is_array($result['mediaItems'])) { - $nbPhotos += count($result['mediaItems']); - } else { - $this->logger->warning( - 'Google API error getting media items list to get photo number, no "mediaItems" key in ' - . json_encode($result), - ['app' => Application::APP_ID] - ); - } - } - - return [ - 'nbPhotos' => $nbPhotos, - ]; - } - - /** - * @param string $userId - * @return array - */ - public function startImportPhotos(string $userId): array { - $targetPath = $this->config->getUserValue($userId, Application::APP_ID, 'photo_output_dir', '/Google Photos'); - $targetPath = $targetPath ?: '/Google Photos'; - // create root folder - $userFolder = $this->root->getUserFolder($userId); - if (!$userFolder->nodeExists($targetPath)) { - $userFolder->newFolder($targetPath); - } else { - $folder = $userFolder->get($targetPath); - if ($folder->getType() !== FileInfo::TYPE_FOLDER) { - return ['error' => 'Impossible to create Google folder']; - } - } - $this->config->setUserValue($userId, Application::APP_ID, 'importing_photos', '1'); - $this->config->setUserValue($userId, Application::APP_ID, 'nb_imported_photos', '0'); - $this->config->setUserValue($userId, Application::APP_ID, 'last_import_timestamp', '0'); - - $this->jobList->add(ImportPhotosJob::class, ['user_id' => $userId]); - return ['targetPath' => $targetPath]; - } - - /** - * @param string $userId - * @return void - */ - public function importPhotosJob(string $userId): void { - $this->logger->debug('Importing photos for ' . $userId); - - // Set the user to register the change under his name - $this->userScopeService->setUserScope($userId); - $this->userScopeService->setFilesystemScope($userId); - - $importingPhotos = $this->config->getUserValue($userId, Application::APP_ID, 'importing_photos', '0') === '1'; - if (!$importingPhotos) { - return; - } - $jobRunning = $this->config->getUserValue($userId, Application::APP_ID, 'photo_import_running', '0') === '1'; - $nowTs = (new DateTime())->getTimestamp(); - if ($jobRunning) { - $lastJobStart = $this->config->getUserValue($userId, Application::APP_ID, 'photo_import_job_last_start'); - if ($lastJobStart !== '' && ($nowTs - intval($lastJobStart) < Application::IMPORT_JOB_TIMEOUT)) { - // last job has started less than an hour ago => we consider it can still be running - $this->jobList->add(ImportPhotosJob::class, ['user_id' => $userId]); - return; - } - } - $this->config->setUserValue($userId, Application::APP_ID, 'photo_import_running', '1'); - $this->config->setUserValue($userId, Application::APP_ID, 'photo_import_job_last_start', strval($nowTs)); - - $targetPath = $this->config->getUserValue($userId, Application::APP_ID, 'photo_output_dir', '/Google Photos'); - $targetPath = $targetPath ?: '/Google Photos'; - // import photos by batch of 500 Mo - $alreadyImported = $this->config->getUserValue($userId, Application::APP_ID, 'nb_imported_photos', '0'); - $alreadyImported = (int)$alreadyImported; - try { - $result = $this->importPhotos($userId, $targetPath, 500000000, $alreadyImported); - } catch (Exception|Throwable $e) { - $result = [ - 'error' => 'Unknown job failure. ' . $e->getMessage(), - ]; - } - if (isset($result['error']) || (isset($result['finished']) && $result['finished'])) { - $this->config->setUserValue($userId, Application::APP_ID, 'importing_photos', '0'); - $this->config->setUserValue($userId, Application::APP_ID, 'nb_imported_photos', '0'); - $this->config->setUserValue($userId, Application::APP_ID, 'last_import_timestamp', '0'); - if (isset($result['finished']) && $result['finished']) { - $this->googleApiService->sendNCNotification($userId, 'import_photos_finished', [ - 'nbImported' => $result['totalSeen'], - 'targetPath' => $targetPath, - ]); - } - if (isset($result['error'])) { - $this->logger->error('Google Photo import error: ' . $result['error'], ['app' => Application::APP_ID]); - } - } else { - $ts = (new DateTime())->getTimestamp(); - $this->config->setUserValue($userId, Application::APP_ID, 'last_import_timestamp', $ts); - $this->jobList->add(ImportPhotosJob::class, ['user_id' => $userId]); - } - $this->config->setUserValue($userId, Application::APP_ID, 'photo_import_running', '0'); - } - - /** - * @param string $userId - * @param string $targetPath - * @param ?int $maxDownloadSize - * @param int $alreadyImported - * @return array - */ - public function importPhotos( - string $userId, string $targetPath, - ?int $maxDownloadSize = null, int $alreadyImported = 0, - ): array { - // create root folder - $userFolder = $this->root->getUserFolder($userId); - if (!$userFolder->nodeExists($targetPath)) { - $folder = $userFolder->newFolder($targetPath); - } else { - $folder = $userFolder->get($targetPath); - if (!$folder instanceof Folder) { - return ['error' => 'Impossible to create Google folder']; - } - } - - $albums = []; - $params = [ - 'pageSize' => 50, - ]; - do { - $this->logger->debug( - 'Photos service::importPhotos LAUNCHING ALBUM LIST REQUEST, userid: "' . $userId . '"', - ['app' => Application::APP_ID] - ); - $result = $this->googleApiService->request($userId, 'v1/albums', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['albums']) && is_array($result['albums'])) { - foreach ($result['albums'] as $album) { - $albums[] = $album; - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - - // shared albums - $considerSharedAlbums = $this->config->getUserValue($userId, Application::APP_ID, 'consider_shared_albums', '0') === '1'; - if ($considerSharedAlbums) { - $params = [ - 'pageSize' => 50, - ]; - do { - $result = $this->googleApiService->request($userId, 'v1/sharedAlbums', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['sharedAlbums']) && is_array($result['sharedAlbums'])) { - foreach ($result['sharedAlbums'] as $album) { - $albums[] = $album; - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - } - - // get the photos - $this->logger->debug( - 'Photos service::importPhotos GETTING PHOTOS, nb albums: "' . count($albums) . '"', - ['app' => Application::APP_ID] - ); - $downloadedSize = 0; - $nbDownloaded = 0; - $totalSeenNumber = 0; - $seenIds = []; - foreach ($albums as $album) { - $albumId = $album['id']; - $albumName = $this->fileUtils->sanitizeFilename((string)($album['title']), (string)$album['id']); - if (!$folder->nodeExists($albumName)) { - $albumFolder = $folder->newFolder($albumName); - } else { - $albumFolder = $folder->get($albumName); - if ($albumFolder->getType() !== FileInfo::TYPE_FOLDER) { - return ['error' => 'Impossible to create album folder']; - } - } - - $params = [ - 'pageSize' => 100, - 'albumId' => $albumId, - ]; - do { - $result = $this->googleApiService->request($userId, 'v1/mediaItems:search', $params, 'POST', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['mediaItems']) && is_array($result['mediaItems'])) { - foreach ($result['mediaItems'] as $photo) { - $seenIds[] = $photo['id']; - $totalSeenNumber++; - $size = $this->getPhoto($userId, $photo, $albumFolder); - if (!is_null($size)) { - $nbDownloaded++; - $this->config->setUserValue($userId, Application::APP_ID, 'nb_imported_photos', $alreadyImported + $nbDownloaded); - $downloadedSize += $size; - if ($maxDownloadSize !== null && $downloadedSize > $maxDownloadSize) { - return [ - 'nbDownloaded' => $nbDownloaded, - 'targetPath' => $targetPath, - 'finished' => false, - 'totalSeen' => $totalSeenNumber, - ]; - } - } - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - } - - // get photos that don't belong to an album - $params = [ - 'pageSize' => 100, - ]; - do { - $result = $this->googleApiService->request($userId, 'v1/mediaItems', $params, 'GET', 'https://photoslibrary.googleapis.com/'); - if (isset($result['error'])) { - return $result; - } - if (isset($result['mediaItems']) && is_array($result['mediaItems'])) { - foreach ($result['mediaItems'] as $photo) { - if (!in_array($photo['id'], $seenIds)) { - $seenIds[] = $photo['id']; - $totalSeenNumber++; - $size = $this->getPhoto($userId, $photo, $folder); - if (!is_null($size)) { - $nbDownloaded++; - $this->config->setUserValue($userId, Application::APP_ID, 'nb_imported_photos', $alreadyImported + $nbDownloaded); - $downloadedSize += $size; - if ($maxDownloadSize !== null && $downloadedSize > $maxDownloadSize) { - return [ - 'nbDownloaded' => $nbDownloaded, - 'targetPath' => $targetPath, - 'finished' => false, - 'totalSeen' => $totalSeenNumber, - ]; - } - } - } - } - } - $params['pageToken'] = $result['nextPageToken'] ?? ''; - } while (isset($result['nextPageToken'])); - - return [ - 'nbDownloaded' => $nbDownloaded, - 'targetPath' => $targetPath, - 'finished' => true, - 'totalSeen' => $totalSeenNumber, - ]; - } - - /** - * @param string $userId - * @param array{baseUrl: string, id: string, filename: string, mediaMetadata: array} $photo - * @param Folder $albumFolder - * @return int|null downloaded size, null if already existing - * @throws \OCP\Files\InvalidPathException - * @throws \OCP\Files\NotFoundException - * @throws \OCP\Files\NotPermittedException - */ - private function getPhoto(string $userId, array $photo, Folder $albumFolder): ?int { - $photoName = $this->fileUtils->sanitizeFilename($photo['filename'], (string)$photo['id']); - if ($albumFolder->nodeExists($photoName)) { - $photoName = $photo['id'] . '_' . $photoName; - } - if (!$albumFolder->nodeExists($photoName)) { - if (isset($photo['mediaMetadata']['photo'])) { - $photoUrl = $photo['baseUrl'] . '=d'; - } elseif (isset($photo['mediaMetadata']['video'])) { - $photoUrl = $photo['baseUrl'] . '=dv'; - } else { - return null; - } - $savedFile = $albumFolder->newFile($photoName); - try { - $resource = $savedFile->fopen('w'); - } catch (LockedException $e) { - $this->logger->warning('Google Photo, error opening target file ' . '' . ' : file is locked', ['app' => Application::APP_ID]); - return null; - } - if ($resource === false) { - $this->logger->warning('Google Photo, error opening target file ' . '', ['app' => Application::APP_ID]); - return null; - } - $res = $this->googleApiService->simpleDownload($userId, $photoUrl, $resource); - if (!isset($res['error'])) { - if (is_resource($resource)) { - fclose($resource); - } - if (isset($photo['mediaMetadata']['creationTime'])) { - $d = new DateTime($photo['mediaMetadata']['creationTime']); - $ts = $d->getTimestamp(); - $savedFile->touch($ts); - } else { - $savedFile->touch(); - } - $stat = $savedFile->stat(); - return (int)($stat['size'] ?? 0); - } else { - $this->logger->warning('Google API error downloading photo ' . '' . ' : ' . $res['error'], ['app' => Application::APP_ID]); - if ($savedFile->isDeletable()) { - $savedFile->unlock(ILockingProvider::LOCK_EXCLUSIVE); - $savedFile->delete(); - } - } - } - return null; - } -} diff --git a/lib/Settings/Personal.php b/lib/Settings/Personal.php index ab462124..4eb03df8 100644 --- a/lib/Settings/Personal.php +++ b/lib/Settings/Personal.php @@ -43,8 +43,6 @@ public function getForm(): TemplateResponse { $userName = $this->config->getUserValue($this->userId, Application::APP_ID, 'user_name'); $driveOutputDir = $this->config->getUserValue($this->userId, Application::APP_ID, 'drive_output_dir', '/Google Drive'); $driveOutputDir = $driveOutputDir ?: '/Google Drive'; - $photoOutputDir = $this->config->getUserValue($this->userId, Application::APP_ID, 'photo_output_dir', '/Google Photos'); - $photoOutputDir = $photoOutputDir ?: '/Google Photos'; $considerSharedFiles = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_files', '0') === '1'; $considerSharedAlbums = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_shared_albums', '0') === '1'; $considerOtherContacts = $this->config->getUserValue($this->userId, Application::APP_ID, 'consider_other_contacts', '0') === '1'; @@ -89,7 +87,6 @@ public function getForm(): TemplateResponse { 'consider_other_contacts' => $considerOtherContacts, 'document_format' => $documentFormat, 'drive_output_dir' => $driveOutputDir, - 'photo_output_dir' => $photoOutputDir, 'user_scopes' => $userScopes, ]; $this->initialStateService->provideInitialState('user-config', $userConfig); diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 7b9067a8..2b7f586d 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -11,11 +11,6 @@ - - - - - @@ -163,16 +158,6 @@ - - - - - - - - - - diff --git a/src/components/AdminSettings.vue b/src/components/AdminSettings.vue index 76b7c458..7217c462 100644 --- a/src/components/AdminSettings.vue +++ b/src/components/AdminSettings.vue @@ -25,7 +25,7 @@

{{ t('integration_google', 'Put the "Client ID" and "Client secret" below.') }}
- {{ t('integration_google', 'Finally, go to "APIs & Services" => "Library" and add the following APIs: "Google Drive API", "Google Calendar API", "People API" and "Photos Library API".') }} + {{ t('integration_google', 'Finally, go to "APIs & Services" => "Library" and add the following APIs: "Google Drive API", "Google Calendar API", and "People API".') }}
{{ t('integration_google', 'Your Nextcloud users will then see a "Connect to Google" button in their personal settings.') }}

diff --git a/src/components/PersonalSettings.vue b/src/components/PersonalSettings.vue index 647ed64c..8f4ff1b4 100644 --- a/src/components/PersonalSettings.vue +++ b/src/components/PersonalSettings.vue @@ -100,74 +100,6 @@
-
-

{{ t('integration_google', 'Photos') }}

- - {{ t('integration_google', 'Ignore shared albums') }} - -
-

- - {{ t('integration_google', 'Warning: Google does not provide location data in imported photos.') }} -

-
- - - - - -

-
-
- - - - {{ t('integration_google', 'Import Google photos') }} - - - {{ t('integration_google', 'Your Google photo collection size is estimated to be bigger than your remaining space left ({formSpace})', { formSpace: myHumanFileSize(state.free_space) }) }} - -
-
-
- {{ n('integration_google', '{amount} photo imported', '{amount} photos imported', nbImportedPhotos, { amount: nbImportedPhotos }) }} -
- {{ lastPhotoImportDate }} -
- - - {{ t('integration_google', 'Cancel photo import') }} - -
-

-

{{ t('integration_google', 'Drive') }}

@@ -258,14 +190,11 @@ @@ -917,11 +710,8 @@ export default { } #google-drive button, - #google-drive select, - #google-photos button { + #google-drive select { width: 300px; - - &#google-import-photos, &#google-import-files { height: 34px; }