Skip to content

Commit

Permalink
updates
Browse files Browse the repository at this point in the history
  • Loading branch information
asbiin committed Aug 1, 2023
1 parent 88678ca commit 4efd85d
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,6 @@ public function handle()
{
$subscription = AddressBookSubscription::findOrFail($this->option('subscriptionId'));

SynchronizeAddressBooks::dispatch($subscription, $this->option('force'));
SynchronizeAddressBooks::dispatch($subscription, $this->option('force'))->onQueue('high');
}
}
26 changes: 22 additions & 4 deletions app/Console/Commands/NewAddressBookSubscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use App\Domains\Contact\DavClient\Jobs\SynchronizeAddressBooks;
use App\Domains\Contact\DavClient\Services\CreateAddressBookSubscription;
use App\Models\AddressBookSubscription;
use App\Models\User;
use App\Models\Vault;
use Illuminate\Console\Command;
Expand All @@ -21,7 +22,9 @@ class NewAddressBookSubscription extends Command
{--vaultId= : Id of the vault to add subscription to}
{--url= : CardDAV url of the address book}
{--login= : Login}
{--password= : Password of the account}';
{--password= : Password of the account}
{--pushonly : Set only push way}
{--getonly : Set only get way}';

/**
* The console command description.
Expand All @@ -48,28 +51,43 @@ public function handle(): int
return 3;
}

$pushonly = $this->option('pushonly');
$getonly = $this->option('getonly');
if ($pushonly && $getonly) {
$this->error('Cannot set both pushonly and getonly');

return 4;
}

$url = $this->option('url') ?? $this->ask('CardDAV url of the address book');
$login = $this->option('login') ?? $this->ask('Login name');
$password = $this->option('password') ?? $this->secret('User password');

try {
$addressBookSubscription = app(CreateAddressBookSubscription::class)->execute([
$subscription = app(CreateAddressBookSubscription::class)->execute([
'account_id' => $user->account_id,
'vault_id' => $vault->id,
'author_id' => $user->id,
'base_uri' => $url,
'username' => $login,
'password' => $password,
]);

if ($pushonly) {
$subscription->sync_way = AddressBookSubscription::WAY_PUSH;
} elseif ($getonly) {
$subscription->sync_way = AddressBookSubscription::WAY_GET;
}
$subscription->save();
} catch (\Exception $e) {
$this->error('Could not add subscription');
$this->error($e->getMessage());

return -1;
}

$this->info('Subscription added');
SynchronizeAddressBooks::dispatch($addressBookSubscription, true);
$this->info("Subscription added: {$subscription->id}");
SynchronizeAddressBooks::dispatch($subscription, true)->onQueue('high');

return 0;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,11 +234,11 @@ public function getObjectUuid(?string $collectionId, string $uuid): ?Contact
}

return Contact::firstWhere([
'distant_uuid' => $uuid,
'vault_id' => $vault->id,
'distant_uuid' => $uuid,
]) ?? Contact::firstWhere([
'id' => $uuid,
'vault_id' => $vault->id,
'id' => $uuid,
]);
}

Expand Down Expand Up @@ -404,6 +404,7 @@ public function updateCard($addressBookId, $cardUri, $cardData): ?string

Bus::batch([$job])
->allowFailures()
->onQueue('high')
->dispatch();

return null;
Expand All @@ -425,7 +426,7 @@ public function deleteCard($addressBookId, $cardUri): bool
'author_id' => $this->user->id,
'vault_id' => $contact->vault_id,
'contact_id' => $contact->id,
]);
])->onQueue('high');

return true;
}
Expand Down
2 changes: 1 addition & 1 deletion app/Domains/Contact/DavClient/Jobs/UpdateAddressBooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private function manageSubscriptions(Collection $subscriptions, Carbon $now): vo
{
$subscriptions
->filter(fn (AddressBookSubscription $subscription): bool => $this->isTimeToRunSync($subscription, $now))
->each(fn (AddressBookSubscription $subscription) => SynchronizeAddressBooks::dispatch($subscription));
->each(fn (AddressBookSubscription $subscription) => SynchronizeAddressBooks::dispatch($subscription)->onQueue('high'));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,21 @@ public function execute(bool $force = false): string
{
$this->client = $this->subscription->getClient();

// Get changes to sync
$localChanges = $this->getLocalChanges();

$updateSyncToken = new UpdateSubscriptionLocalSyncToken([
'addressbook_subscription_id' => $this->subscription->id,
]);

$jobs = $force
? $this->forcesync($localChanges)
: $this->sync($localChanges);
? $this->forcesync()
: $this->sync();

$batch = Bus::batch($jobs);

if ($this->subscription->isWayPush) {

Check failure on line 41 in app/Domains/Contact/DavClient/Services/Utils/AddressBookSynchronizer.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property App\Models\AddressBookSubscription::$isWayPush.
$batch = $batch->then(fn () => $updateSyncToken->handle());
}

$batch = Bus::batch($jobs)
->then(fn () => $updateSyncToken->handle())
->allowFailures()
$batch = $batch->allowFailures()
->onQueue('high')
->dispatch();

Expand All @@ -59,17 +60,25 @@ private function getLocalChanges(): Collection
/**
* Sync the address book.
*/
private function sync(?Collection $localChanges): Collection
private function sync(): Collection
{
// Get distant changes to sync
$changes = $this->getDistantChanges();

// Get distant contacts
$jobs = app(PrepareJobsContactUpdater::class)
->withSubscription($this->subscription)
->execute($changes);
$jobs = collect();
if ($this->subscription->isWayGet) {

Check failure on line 70 in app/Domains/Contact/DavClient/Services/Utils/AddressBookSynchronizer.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property App\Models\AddressBookSubscription::$isWayGet.
$jobs = $jobs->union(
app(PrepareJobsContactUpdater::class)
->withSubscription($this->subscription)
->execute($changes)
);
}

if ($this->subscription->isWayPush) {

Check failure on line 78 in app/Domains/Contact/DavClient/Services/Utils/AddressBookSynchronizer.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property App\Models\AddressBookSubscription::$isWayPush.
// Get changes to sync
$localChanges = $this->getLocalChanges();

if (! $this->subscription->readonly) {
$jobs = $jobs->union(
app(PrepareJobsContactPush::class)
->withSubscription($this->subscription)
Expand All @@ -83,7 +92,7 @@ private function sync(?Collection $localChanges): Collection
/**
* Sync the address book.
*/
private function forcesync(?Collection $localChanges): Collection
private function forcesync(): Collection
{
// Get current list of contacts
$localContacts = $this->backend()->getObjects($this->subscription->vault_id);
Expand All @@ -94,11 +103,20 @@ private function forcesync(?Collection $localChanges): Collection

// Get missed contacts
$missed = $distContacts->reject(fn (ContactDto $contact): bool => $localUuids->contains($this->backend()->getUuid($contact->uri)));
$jobs = app(PrepareJobsContactUpdater::class)
->withSubscription($this->subscription)
->execute($missed);

if (! $this->subscription->readonly) {
$jobs = collect();
if ($this->subscription->isWayGet) {

Check failure on line 108 in app/Domains/Contact/DavClient/Services/Utils/AddressBookSynchronizer.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property App\Models\AddressBookSubscription::$isWayGet.
$jobs = $jobs->union(
app(PrepareJobsContactUpdater::class)
->withSubscription($this->subscription)
->execute($missed)
);
}

if ($this->subscription->isWayPush) {

Check failure on line 116 in app/Domains/Contact/DavClient/Services/Utils/AddressBookSynchronizer.php

View workflow job for this annotation

GitHub Actions / phpstan

Access to an undefined property App\Models\AddressBookSubscription::$isWayPush.
// Get changes to sync
$localChanges = $this->getLocalChanges();

$jobs = $jobs->union(
app(PrepareJobsContactPushMissed::class)
->withSubscription($this->subscription)
Expand Down Expand Up @@ -186,9 +204,9 @@ private function getDistantEtags(): array
private function callSyncCollectionWhenNeeded(): array
{
// get the current distant syncToken
$distantSyncToken = $this->client->getProperty('{DAV:}sync-token');
$currentSyncToken = $this->client->getProperty('{DAV:}sync-token');

if (($this->subscription->syncToken ?? '') === $distantSyncToken) {
if (($this->subscription->distant_sync_token ?? '') === $currentSyncToken) {
// no change at all
return [];
}
Expand All @@ -201,7 +219,7 @@ private function callSyncCollectionWhenNeeded(): array
*/
private function callSyncCollection(): array
{
$syncToken = $this->subscription->syncToken ?? '';
$syncToken = $this->subscription->distant_sync_token ?? '';

// get sync
try {
Expand All @@ -212,13 +230,13 @@ private function callSyncCollection(): array

// save the new syncToken as current one
if ($newSyncToken = Arr::get($collection, 'synctoken')) {
$this->subscription->syncToken = $newSyncToken;
$this->subscription->distant_sync_token = $newSyncToken;
$this->subscription->save();
}
} catch (RequestException $e) {
Log::error(__CLASS__.' '.__FUNCTION__.':'.$e->getMessage(), [$e]);
$collection = [];
$this->subscription->syncToken = null;
$this->subscription->distant_sync_token = null;
$this->subscription->save();
}

Expand Down
6 changes: 3 additions & 3 deletions app/Domains/Contact/ManageContact/Dav/ImportContact.php
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ private function importNameFromFN(array $contactData, VCard $entry): array
*/
private function importUid(array $contactData, VCard $entry): array
{
if (($uuid = $this->getUid($entry)) !== null && ! $this->context->external) {
if (($uuid = $this->getUid($entry)) !== null && Uuid::isValid($uuid) && ! $this->context->external) {
$contactData['id'] = $uuid;
}

Expand All @@ -173,8 +173,8 @@ private function importUid(array $contactData, VCard $entry): array
*/
private function getUid(VCard $entry): ?string
{
if (! empty($uuid = (string) $entry->UID) && Uuid::isValid($uuid)) {
return $uuid;
if (! empty($uuid = (string) $entry->UID)) {
return (string) Str::of($uuid)->after('urn:uuid:');
}

return null;
Expand Down
2 changes: 0 additions & 2 deletions app/Domains/Contact/ManageContact/Services/CreateContact.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use App\Models\ContactFeedItem;
use App\Services\BaseService;
use Carbon\Carbon;
use Illuminate\Support\Facades\Log;

class CreateContact extends BaseService implements ServiceInterface
{
Expand Down Expand Up @@ -54,7 +53,6 @@ public function permissions(): array
*/
public function execute(array $data): Contact
{
Log::debug(__CLASS__, $data);
$this->data = $data;

$this->validate();
Expand Down
47 changes: 44 additions & 3 deletions app/Models/AddressBookSubscription.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ class AddressBookSubscription extends Model
{
use HasFactory, HasUuids;

public const WAY_PUSH = 0x1;

public const WAY_GET = 0x2;

public const WAY_BOTH = self::WAY_GET | self::WAY_PUSH;

protected $table = 'addressbook_subscriptions';

/**
Expand All @@ -28,8 +34,8 @@ class AddressBookSubscription extends Model
'capabilities',
'username',
'password',
'readonly',
'syncToken',
'sync_way',
'distant_sync_token',
'frequency',
'last_synchronized_at',
'active',
Expand All @@ -51,7 +57,6 @@ class AddressBookSubscription extends Model
'user_id' => 'string',
'vault_id' => 'string',
'last_synchronized_at' => 'datetime',
'readonly' => 'boolean',
'active' => 'boolean',
'capabilities' => 'array',
];
Expand Down Expand Up @@ -110,6 +115,42 @@ public function password(): Attribute
);
}

/**
* Get synchronization way.
*
* @return Attribute<bool,never>
*/
public function isWayPush(): Attribute
{
return Attribute::get(
fn (?bool $value, array $attributes) => ($attributes['sync_way'] & self::WAY_PUSH) === self::WAY_PUSH,

Check failure on line 126 in app/Models/AddressBookSubscription.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $get of static method Illuminate\Database\Eloquent\Casts\Attribute<mixed,mixed>::get() expects callable(mixed, mixed=): bool, Closure(bool|null, array): bool given.
);
}

/**
* Get synchronization way.
*
* @return Attribute<bool,never>
*/
public function isWayGet(): Attribute
{
return Attribute::get(
fn (?bool $value, array $attributes) => ($attributes['sync_way'] & self::WAY_GET) === self::WAY_GET,

Check failure on line 138 in app/Models/AddressBookSubscription.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $get of static method Illuminate\Database\Eloquent\Casts\Attribute<mixed,mixed>::get() expects callable(mixed, mixed=): bool, Closure(bool|null, array): bool given.
);
}

/**
* Get synchronization way.
*
* @return Attribute<bool,never>
*/
public function isWayBoth(): Attribute
{
return Attribute::get(
fn (?bool $value, array $attributes) => ($attributes['syncWay'] & self::WAY_BOTH) === self::WAY_BOTH,

Check failure on line 150 in app/Models/AddressBookSubscription.php

View workflow job for this annotation

GitHub Actions / phpstan

Parameter #1 $get of static method Illuminate\Database\Eloquent\Casts\Attribute<mixed,mixed>::get() expects callable(mixed, mixed=): bool, Closure(bool|null, array): bool given.
);
}

/**
* Scope a query to only include active subscriptions.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public function up()
$table->boolean('listed')->default(true);

$table->mediumText('vcard')->nullable();
$table->uuid('distant_uuid')->nullable();
$table->string('distant_uuid', 256)->nullable();
$table->string('distant_etag', 256)->nullable();
$table->string('distant_uri', 2096)->nullable();

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use App\Models\AddressBookSubscription;
use App\Models\SyncToken;
use App\Models\User;
use App\Models\Vault;
Expand All @@ -23,10 +24,10 @@ public function up()
$table->string('uri', 2096);
$table->string('username', 1024);
$table->string('password', 2048);
$table->boolean('readonly')->default(false);
$table->boolean('active')->default(true);
$table->unsignedTinyInteger('sync_way')->default(AddressBookSubscription::WAY_BOTH);
$table->string('capabilities', 2048);
$table->string('syncToken', 512)->nullable();
$table->string('distant_sync_token', 512)->nullable();
$table->string('last_batch')->nullable();
$table->foreignIdFor(SyncToken::class)->nullable()->constrained()->nullOnDelete();
$table->smallInteger('frequency')->default(180); // 3 hours
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public function up(): void
{
if (! Schema::hasColumn('contacts', 'distant_uuid')) {
Schema::table('contacts', function (Blueprint $table) {
$table->uuid('distant_uuid')->nullable()->after('vcard');
$table->string('distant_uuid', 256)->nullable()->after('vcard');
});
}
if (! Schema::hasColumn('contacts', 'distant_uri')) {
Expand Down
Loading

0 comments on commit 4efd85d

Please sign in to comment.