Skip to content

Commit f603db7

Browse files
committed
clarify contact import, use google contact id as NC card URI, update contacts with more recent update time
Signed-off-by: Julien Veyssier <julien-nc@posteo.net>
1 parent 3ebb66c commit f603db7

File tree

2 files changed

+61
-38
lines changed

2 files changed

+61
-38
lines changed

lib/Service/GoogleContactsAPIService.php

Lines changed: 52 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ public function getContactList(string $userId): Generator {
155155
* @return array
156156
*/
157157
public function importContacts(string $userId, ?string $uri, int $key, ?string $newAddrBookName): array {
158+
$existingAddressBook = null;
158159
if ($key === 0) {
159160
$addressBooks = $this->contactsManager->getUserAddressBooks();
160161
foreach ($addressBooks as $k => $ab) {
@@ -180,19 +181,48 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
180181
if (!$addressBook) {
181182
return ['error' => 'no such address book'];
182183
}
184+
$existingAddressBook = $addressBook;
183185
}
184186

185187
$groupsById = $this->getContactGroupsById($userId);
186188
$contacts = $this->getContactList($userId);
187189
$nbAdded = 0;
190+
$nbUpdated = 0;
188191
$totalContactNumber = 0;
189192
foreach ($contacts as $k => $c) {
190193
$totalContactNumber++;
191-
// avoid existing contacts
192-
if ($this->contactExists($c, $key)) {
193-
$this->logger->debug('Skipping contact which already exists', ['contact' => $c, 'app' => Application::APP_ID]);
194+
195+
$googleResourceName = $c['resourceName'] ?? null;
196+
if ($googleResourceName === null) {
197+
$this->logger->debug('Skipping contact with no resourceName', ['contact' => $c, 'app' => Application::APP_ID]);
194198
continue;
195199
}
200+
// contacts are not displayed in the Contacts app if there are slashes in their URI...
201+
$googleResourceName = str_replace('/', '_', $googleResourceName);
202+
203+
// check if contact exists and needs to be updated
204+
$existingContact = null;
205+
if ($existingAddressBook !== null) {
206+
$existingContact = $this->cdBackend->getCard($key, $googleResourceName);
207+
if ($existingContact) {
208+
$googleUpdateTime = $c['metadata']['sources'][0]['updateTime'] ?? null;
209+
if ($googleUpdateTime === null) {
210+
$googleUpdateTimestamp = 0;
211+
} else {
212+
try {
213+
$googleUpdateTimestamp = (new Datetime($googleUpdateTime))->getTimestamp();
214+
} catch (Exception | Throwable $e) {
215+
$googleUpdateTimestamp = 0;
216+
}
217+
}
218+
219+
if ($googleUpdateTimestamp <= $existingContact['lastmodified']) {
220+
$this->logger->debug('Skipping existing contact which is up-to-date', ['contact' => $c, 'app' => Application::APP_ID]);
221+
continue;
222+
}
223+
}
224+
}
225+
196226
$vCard = new VCard();
197227

198228
$displayName = '';
@@ -406,11 +436,20 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
406436
}
407437
}
408438

409-
try {
410-
$this->cdBackend->createCard($key, 'goog' . $k, $vCard->serialize());
411-
$nbAdded++;
412-
} catch (Throwable | Exception $e) {
413-
$this->logger->warning('Error when creating contact', ['exception' => $e, 'app' => Application::APP_ID]);
439+
if ($existingContact === null || $existingContact === false) {
440+
try {
441+
$this->cdBackend->createCard($key, $googleResourceName, $vCard->serialize());
442+
$nbAdded++;
443+
} catch (Throwable|Exception $e) {
444+
$this->logger->warning('Error when creating contact', ['exception' => $e, 'contact' => $c, 'app' => Application::APP_ID]);
445+
}
446+
} else {
447+
try {
448+
$this->cdBackend->updateCard($key, $googleResourceName, $vCard->serialize());
449+
$nbUpdated++;
450+
} catch (Throwable|Exception $e) {
451+
$this->logger->warning('Error when updating contact', ['exception' => $e, 'contact' => $c, 'app' => Application::APP_ID]);
452+
}
414453
}
415454
}
416455
$this->logger->debug($totalContactNumber . ' contacts seen', ['app' => Application::APP_ID]);
@@ -419,34 +458,10 @@ public function importContacts(string $userId, ?string $uri, int $key, ?string $
419458
if (isset($contactGeneratorReturn['error'])) {
420459
return $contactGeneratorReturn;
421460
}
422-
return ['nbAdded' => $nbAdded];
423-
}
424-
425-
/**
426-
* @param array $contact
427-
* @param int $addressBookKey
428-
* @return bool
429-
*/
430-
private function contactExists(array $contact, int $addressBookKey): bool {
431-
$displayName = null;
432-
// $familyName = null;
433-
// $firstName = null;
434-
if (isset($contact['names']) && is_array($contact['names'])) {
435-
foreach ($contact['names'] as $n) {
436-
$displayName = $n['displayName'] ?? '';
437-
// $familyName = $n['familyName'] ?? '';
438-
// $firstName = $n['givenName'] ?? '';
439-
break;
440-
}
441-
if ($displayName) {
442-
$searchResult = $this->contactsManager->search($displayName, ['FN']);
443-
foreach ($searchResult as $resContact) {
444-
if ($resContact['FN'] === $displayName && (int)$resContact['addressbook-key'] === $addressBookKey) {
445-
return true;
446-
}
447-
}
448-
}
449-
}
450-
return false;
461+
return [
462+
'nbSeen' => $totalContactNumber,
463+
'nbAdded' => $nbAdded,
464+
'nbUpdated' => $nbUpdated,
465+
];
451466
}
452467
}

src/components/PersonalSettings.vue

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -640,9 +640,17 @@ export default {
640640
const url = generateUrl('/apps/integration_google/import-contacts')
641641
axios.get(url, req)
642642
.then((response) => {
643+
const nbSeen = response.data.nbSeen
643644
const nbAdded = response.data.nbAdded
645+
const nbUpdated = response.data.nbUpdated
644646
showSuccess(
645-
this.n('integration_google', '{number} contact successfully imported in {name}', '{number} contacts successfully imported in {name}', nbAdded, { number: nbAdded, name: this.selectedAddressBookName })
647+
this.n(
648+
'integration_google',
649+
'{nbSeen} Google contact seen. {nbAdded} added, {nbUpdated} updated in {name}',
650+
'{nbSeen} Google contacts seen. {nbAdded} added, {nbUpdated} updated in {name}',
651+
nbSeen,
652+
{ nbAdded, nbSeen, nbUpdated, name: this.selectedAddressBookName }
653+
)
646654
)
647655
this.showAddressBooks = false
648656
})

0 commit comments

Comments
 (0)