diff options
Diffstat (limited to 'Digitigrade/Model')
| -rw-r--r-- | Digitigrade/Model/Actor.php | 41 | ||||
| -rw-r--r-- | Digitigrade/Model/FetchableModel.php | 11 |
2 files changed, 52 insertions, 0 deletions
diff --git a/Digitigrade/Model/Actor.php b/Digitigrade/Model/Actor.php index d7fde42..d18c1f5 100644 --- a/Digitigrade/Model/Actor.php +++ b/Digitigrade/Model/Actor.php @@ -2,10 +2,13 @@ namespace Digitigrade\Model; use Digitigrade\Db; +use Digitigrade\Job\ProcessIncomingPush; +use Digitigrade\Job\ProcessIncomingSimplePush; use Digitigrade\Notification\PendingFollowActionedNotif; use Digitigrade\Notification\PokeNotif; use Digitigrade\Notification\UnblockNotif; use Digitigrade\Notification\UnfollowNotif; +use Digitigrade\Pagination; use Digitigrade\PokeVerb; use Digitigrade\RpcException; use Digitigrade\RpcReceiver; @@ -90,6 +93,10 @@ class Actor extends PushableModel implements RpcReceiver { $this->saveExtensions(); } + protected function onNewlyDiscovered() { + $this->backfill(); + } + private function findExtensions() { $pdo = Db::getInstance()->getPdo(); $stmt = $pdo->prepare('SELECT uri, data FROM actor_extension WHERE actor_id = ?'); @@ -139,6 +146,40 @@ class Actor extends PushableModel implements RpcReceiver { return self::findByUri($uri); } + /** + * Fetches this actor's remote feeds and all objects listed by them. + * @param ?int $limit Maximum number of objects to fetch + * @return void + */ + public function backfill(?int $limit = null) { + if (isset($this->endpoints->fullFeed)) { + $this->backfillFromFullFeed($limit); + } else { + $this->backfillFromBasicFeed($limit); + } + } + + private function backfillFromFullFeed(?int $limit) { + $pagination = Pagination::fromUri($this->endpoints->fullFeed); + for ($i = 0; isset($limit) ? ($i < $limit) : true; $i++) { + $item = $pagination->next(); + if ($item === false) + break; + // pretend they're pushes ... it's good enough + (new ProcessIncomingPush($item))->submit(); + } + } + + private function backfillFromBasicFeed(?int $limit) { + $pagination = Pagination::fromUri($this->endpoints->basicFeed); + for ($i = 0; isset($limit) ? ($i < $limit) : true; $i++) { + $uri = $pagination->next(); + if ($uri === false) + break; + (new ProcessIncomingSimplePush($uri))->submit(); + } + } + public function rpcCall(string $method, array $args, string $customEndpoint = null) { // $args = [Actor $actingAs, ?string $requestBody] if (!$this->isLocal) { diff --git a/Digitigrade/Model/FetchableModel.php b/Digitigrade/Model/FetchableModel.php index c6bc291..fff7aeb 100644 --- a/Digitigrade/Model/FetchableModel.php +++ b/Digitigrade/Model/FetchableModel.php @@ -85,6 +85,14 @@ abstract class FetchableModel extends Model implements RemoteFetchable { if (!$obj->validate() || !PolicyManager::getInstance()->check($obj)) { return null; // and don't save } + + if (isset($obj->uri)) { + $isNew = $obj::countWhere('uri = ?', [$obj->uri]) == 0; + if ($isNew) { + $obj->onNewlyDiscovered(); + } + } + if ($autoSave) { $obj->save(); $obj->finaliseAfterSave(); @@ -99,6 +107,9 @@ abstract class FetchableModel extends Model implements RemoteFetchable { protected function finaliseAfterSave() { } + protected function onNewlyDiscovered() { + } + public static function findByUri(string $uri, bool $autoSave = true, bool $forceRefetch = false): ?static { if (!$forceRefetch) { $obj = static::findWhere('uri = ?', [$uri]); |
