feat: add option to perform a full addressbook sync instead of a delta sync

Signed-off-by: Robin Appelman <robin@icewind.nl>
This commit is contained in:
Robin Appelman 2026-03-30 17:32:14 +02:00
parent ea92bded98
commit be81390ee3
No known key found for this signature in database
GPG key ID: 42B69D8A64526EFB
3 changed files with 17 additions and 4 deletions

View file

@ -66,6 +66,7 @@ class SyncService {
throw $ex;
}
$received = [];
// 3. apply changes
// TODO: use multi-get for download
foreach ($response['response'] as $resource => $status) {
@ -85,6 +86,15 @@ class SyncService {
}
}
// when doing a full sync, remove any items in the local address book that aren't in the remote one
if (!$syncToken) {
$existingCards = $this->backend->getCards($addressBookId);
$removedCards = array_filter($existingCards, fn (array $card) => !in_array($card['uri'], $received));
foreach ($removedCards as $removedCard) {
$this->backend->deleteCard($addressBookId, $removedCard['uri']);
}
}
return [
$response['token'],
$response['truncated'],

View file

@ -11,6 +11,7 @@ use OCA\Federation\SyncFederationAddressBooks as SyncService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class SyncFederationAddressBooks extends Command {
@ -23,19 +24,21 @@ class SyncFederationAddressBooks extends Command {
protected function configure() {
$this
->setName('federation:sync-addressbooks')
->setDescription('Synchronizes addressbooks of all federated clouds');
->setDescription('Synchronizes addressbooks of all federated clouds')
->addOption('full', null, InputOption::VALUE_NONE, 'Perform a full sync instead of a delta sync');
}
protected function execute(InputInterface $input, OutputInterface $output): int {
$progress = new ProgressBar($output);
$progress->start();
$full = (bool)$input->getOption('full');
$this->syncService->syncThemAll(function ($url, $ex) use ($progress, $output): void {
if ($ex instanceof \Exception) {
$output->writeln("Error while syncing $url : " . $ex->getMessage());
} else {
$progress->advance();
}
});
}, $full);
$progress->finish();
$output->writeln('');

View file

@ -28,7 +28,7 @@ class SyncFederationAddressBooks {
/**
* @param \Closure $callback
*/
public function syncThemAll(\Closure $callback) {
public function syncThemAll(\Closure $callback, bool $full = false) {
$trustedServers = $this->dbHandler->getAllServer();
foreach ($trustedServers as $trustedServer) {
$url = $trustedServer['url'];
@ -59,7 +59,7 @@ class SyncFederationAddressBooks {
$cardDavUser,
$addressBookUrl,
$sharedSecret,
$syncToken,
$full ? null : $syncToken,
$targetBookId,
$targetPrincipal,
$targetBookProperties