diff --git a/appinfo/routes.php b/appinfo/routes.php index dca8dc8d..47d0a763 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -93,6 +93,8 @@ return [ ['name' => 'Api#statusAction', 'url' => '/api/v1/statuses/{nid}/{act}', 'verb' => 'POST'], ['name' => 'Api#accountStatuses', 'url' => '/api/v1/accounts/{account}/statuses', 'verb' => 'GET'], + ['name' => 'Api#accountFollowers', 'url' => '/api/v1/accounts/{account}/followers', 'verb' => 'GET'], + ['name' => 'Api#accountFollowing', 'url' => '/api/v1/accounts/{account}/following', 'verb' => 'GET'], // Api for local front-end // TODO: front-end should be using the new ApiController @@ -124,14 +126,14 @@ return [ ['name' => 'Local#currentFollowing', 'url' => '/api/v1/current/following', 'verb' => 'GET'], ['name' => 'Local#accountInfo', 'url' => '/api/v1/account/{username}/info', 'verb' => 'GET'], - [ - 'name' => 'Local#accountFollowers', 'url' => '/api/v1/account/{username}/followers', - 'verb' => 'GET' - ], - [ - 'name' => 'Local#accountFollowing', 'url' => '/api/v1/account/{username}/following', - 'verb' => 'GET' - ], + // [ + // 'name' => 'Local#accountFollowers', 'url' => '/api/v1/account/{username}/followers', + // 'verb' => 'GET' + // ], + // [ + // 'name' => 'Local#accountFollowing', 'url' => '/api/v1/account/{username}/following', + // 'verb' => 'GET' + // ], ['name' => 'Local#globalAccountInfo', 'url' => '/api/v1/global/account/info', 'verb' => 'GET'], ['name' => 'Local#globalActorInfo', 'url' => '/api/v1/global/actor/info', 'verb' => 'GET'], diff --git a/lib/Command/Timeline.php b/lib/Command/Timeline.php index 55932954..3eee7c3f 100644 --- a/lib/Command/Timeline.php +++ b/lib/Command/Timeline.php @@ -34,7 +34,7 @@ namespace OCA\Social\Command; use Exception; use OCA\Social\Db\StreamRequest; use OCA\Social\Model\ActivityPub\Stream; -use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Service\AccountService; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\ConfigService; @@ -130,7 +130,7 @@ class Timeline extends ExtendedBase { $this->streamRequest->setViewer($actor); - $options = new TimelineOptions(); + $options = new ProbeOptions(); $options->setFormat(Stream::FORMAT_LOCAL); $options->setLimit(intval($input->getOption('limit'))) ->setMinId(intval($input->getOption('min_id'))) @@ -140,7 +140,7 @@ class Timeline extends ExtendedBase { if ($input->getOption('local')) { $options->setLocal(true); } - $options->setTimeline($input->getArgument('timeline')); + $options->setProbe($input->getArgument('timeline')); if ($input->getOption('account') !== '') { $local = $this->cacheActorService->getFromLocalAccount($input->getOption('account')); diff --git a/lib/Controller/ApiController.php b/lib/Controller/ApiController.php index 1f775500..70d94ee6 100644 --- a/lib/Controller/ApiController.php +++ b/lib/Controller/ApiController.php @@ -36,12 +36,13 @@ use OCA\Social\AppInfo\Application; use OCA\Social\Exceptions\AccountDoesNotExistException; use OCA\Social\Exceptions\ClientNotFoundException; use OCA\Social\Exceptions\InstanceDoesNotExistException; +use OCA\Social\Exceptions\UnknownProbeException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Object\Document; use OCA\Social\Model\ActivityPub\Stream; use OCA\Social\Model\Client\MediaAttachment; -use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Model\Client\SocialClient; use OCA\Social\Model\Client\Status; use OCA\Social\Model\Post; @@ -412,9 +413,23 @@ class ApiController extends Controller { try { $this->initViewer(true); - $options = new TimelineOptions($this->request); + if (!in_array( + strtolower($timeline), + [ + ProbeOptions::HOME, + ProbeOptions::ACCOUNT, + ProbeOptions::PUBLIC, + ProbeOptions::DIRECT, + ProbeOptions::FAVOURITES, + ProbeOptions::NOTIFICATIONS + ] + )) { + throw new UnknownProbeException('unknown timeline'); + } + + $options = new ProbeOptions($this->request); $options->setFormat(ACore::FORMAT_LOCAL); - $options->setTimeline($timeline) + $options->setProbe($timeline) ->setLocal($local) ->setLimit($limit) ->setMaxId($max_id) @@ -519,9 +534,9 @@ class ApiController extends Controller { $local = $this->cacheActorService->getFromLocalAccount($account); - $options = new TimelineOptions($this->request); + $options = new ProbeOptions($this->request); $options->setFormat(ACore::FORMAT_LOCAL); - $options->setTimeline(TimelineOptions::TIMELINE_ACCOUNT) + $options->setProbe(ProbeOptions::ACCOUNT) ->setAccountId($local->getId()) ->setLimit($limit) ->setMaxId($max_id) @@ -537,6 +552,77 @@ class ApiController extends Controller { } + /** + * @NoCSRFRequired + * @PublicPage + * + * @param string $account + * + * @return DataResponse + */ + public function accountFollowing( + string $account, + int $limit = 20, + int $max_id = 0, + int $min_id = 0, + int $since = 0 + ): DataResponse { + try { + $this->initViewer(true); + $local = $this->cacheActorService->getFromLocalAccount($account); + + $options = new ProbeOptions($this->request); + $options->setFormat(ACore::FORMAT_LOCAL); + $options->setProbe(ProbeOptions::FOLLOWING) + ->setAccountId($local->getId()) + ->setLimit($limit) + ->setMaxId($max_id) + ->setMinId($min_id) + ->setSince($since); + + return new DataResponse($this->cacheActorService->probeActors($options), Http::STATUS_OK); + } catch (Exception $e) { + return $this->error($e->getMessage()); + } + } + + + /** + * @NoCSRFRequired + * @PublicPage + * + * @param string $account + * + * @return DataResponse + */ + public function accountFollowers( + string $account, + int $limit = 20, + int $max_id = 0, + int $min_id = 0, + int $since = 0 + ): DataResponse { + try { + $this->initViewer(true); + + $local = $this->cacheActorService->getFromLocalAccount($account); + + $options = new ProbeOptions($this->request); + $options->setFormat(ACore::FORMAT_LOCAL); + $options->setProbe(ProbeOptions::FOLLOWERS) + ->setAccountId($local->getId()) + ->setLimit($limit) + ->setMaxId($max_id) + ->setMinId($min_id) + ->setSince($since); + + return new DataResponse($this->cacheActorService->probeActors($options), Http::STATUS_OK); + } catch (Exception $e) { + return $this->error($e->getMessage()); + } + } + + /** * @NoCSRFRequired * @PublicPage @@ -557,9 +643,9 @@ class ApiController extends Controller { try { $this->initViewer(true); - $options = new TimelineOptions($this->request); + $options = new ProbeOptions($this->request); $options->setFormat(ACore::FORMAT_LOCAL); - $options->setTimeline(TimelineOptions::TIMELINE_FAVOURITES) + $options->setProbe(ProbeOptions::FAVOURITES) ->setLimit($limit) ->setMaxId($max_id) ->setMinId($min_id) @@ -592,9 +678,9 @@ class ApiController extends Controller { try { $this->initViewer(true); - $options = new TimelineOptions($this->request); + $options = new ProbeOptions($this->request); $options->setFormat(ACore::FORMAT_LOCAL); - $options->setTimeline(TimelineOptions::TIMELINE_NOTIFICATIONS) + $options->setProbe(ProbeOptions::NOTIFICATIONS) ->setLimit($limit) ->setMaxId($max_id) ->setMinId($min_id) @@ -630,9 +716,9 @@ class ApiController extends Controller { try { $this->initViewer(true); - $options = new TimelineOptions($this->request); + $options = new ProbeOptions($this->request); $options->setFormat(ACore::FORMAT_LOCAL); - $options->setTimeline('hashtag') + $options->setProbe('hashtag') ->setLimit($limit) ->setMaxId($max_id) ->setMinId($min_id) diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index c5ef106e..4c17abed 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -34,6 +34,8 @@ use DateTime; use Exception; use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Model\ActivityPub\Actor\Person; +use OCA\Social\Model\ActivityPub\Object\Follow; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCP\DB\Exception as DBException; use OCP\DB\QueryBuilder\IQueryBuilder; @@ -262,4 +264,85 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { return $inbox; } + + + /** + * @param ProbeOptions $options + * + * @return Person[] + */ + public function probeActors(ProbeOptions $options): array { + switch (strtolower($options->getProbe())) { + case ProbeOptions::FOLLOWING: + $result = $this->probeActorsFollowing($options); + break; + case ProbeOptions::FOLLOWERS: + $result = $this->probeActorsFollowers($options); + break; + default: + return []; + } + + if ($options->isInverted()) { + // in case we inverted the order during the request, we revert the results + $result = array_reverse($result); + } + + return $result; + } + + /** + * @param ProbeOptions $options + * + * @return Person[] + */ + public function probeActorsFollowing(ProbeOptions $options): array { + $qb = $this->getCacheActorsSelectSql($options->getFormat()); + + $qb->paginate($options); + + $qb->leftJoin( + $qb->getDefaultSelectAlias(), + CoreRequestBuilder::TABLE_FOLLOWS, + 'ca_f', + // object_id of follow is equal to actor's id + $qb->expr()->eq('ca.id_prim', 'ca_f.object_id_prim') + ); + + // follow must be accepted + $qb->limitToType(Follow::TYPE, 'ca_f'); + $qb->limitToAccepted(true, 'ca_f'); + // actor_id of follow is equal to requested account + $qb->limitToActorIdPrim($qb->prim($options->getAccountId()), 'ca_f'); + + return $this->getCacheActorsFromRequest($qb); + } + + + /** + * @param ProbeOptions $options + * + * @return Person[] + */ + public function probeActorsFollowers(ProbeOptions $options): array { + $qb = $this->getCacheActorsSelectSql($options->getFormat()); + + $qb->paginate($options); + + $qb->leftJoin( + $qb->getDefaultSelectAlias(), + CoreRequestBuilder::TABLE_FOLLOWS, + 'ca_f', + // actor_id of follow is equal to actor's id + $qb->expr()->eq('ca.id_prim', 'ca_f.actor_id_prim') + ); + + // follow must be accepted + $qb->limitToType(Follow::TYPE, 'ca_f'); + $qb->limitToAccepted(true, 'ca_f'); + // object_id of follow is equal to requested account + $qb->limitToObjectIdPrim($qb->prim($options->getAccountId()), 'ca_f'); + + return $this->getCacheActorsFromRequest($qb); + } } diff --git a/lib/Db/CacheActorsRequestBuilder.php b/lib/Db/CacheActorsRequestBuilder.php index b79e5348..9fd35e26 100644 --- a/lib/Db/CacheActorsRequestBuilder.php +++ b/lib/Db/CacheActorsRequestBuilder.php @@ -30,11 +30,12 @@ declare(strict_types=1); namespace OCA\Social\Db; -use OCA\Social\Tools\Exceptions\RowNotFoundException; -use OCA\Social\Tools\Traits\TArrayTools; use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Actor\Person; +use OCA\Social\Model\ActivityPub\Stream; +use OCA\Social\Tools\Exceptions\RowNotFoundException; +use OCA\Social\Tools\Traits\TArrayTools; use OCP\DB\QueryBuilder\IQueryBuilder; class CacheActorsRequestBuilder extends CoreRequestBuilder { @@ -72,14 +73,15 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder { * * @return SocialQueryBuilder */ - protected function getCacheActorsSelectSql(): SocialQueryBuilder { + protected function getCacheActorsSelectSql(int $format = Stream::FORMAT_ACTIVITYPUB): SocialQueryBuilder { $qb = $this->getQueryBuilder(); + $qb->setFormat($format); /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->select( - 'ca.id', 'ca.account', 'ca.following', 'ca.followers', 'ca.inbox', 'ca.shared_inbox', - 'ca.outbox', 'ca.featured', 'ca.url', 'ca.type', 'ca.preferred_username', 'ca.name', 'ca.summary', - 'ca.public_key', 'ca.local', 'ca.details', 'ca.source', 'ca.creation' + 'ca.nid', 'ca.id', 'ca.account', 'ca.following', 'ca.followers', 'ca.inbox', + 'ca.shared_inbox', 'ca.outbox', 'ca.featured', 'ca.url', 'ca.type', 'ca.preferred_username', + 'ca.name', 'ca.summary', 'ca.public_key', 'ca.local', 'ca.details', 'ca.source', 'ca.creation' ) ->from(self::TABLE_CACHE_ACTORS, 'ca'); @@ -87,7 +89,6 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder { /** @deprecated */ $this->defaultSelectAlias = 'ca'; - $qb->setDefaultSelectAlias('ca'); return $qb; } diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index 43a7643e..edf6e76a 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -217,7 +217,7 @@ class FollowsRequest extends FollowsRequestBuilder { */ public function getFollowersByActorId(string $actorId): array { $qb = $this->getFollowsSelectSql(); - $this->limitToOBjectId($qb, $actorId); + $this->limitToObjectId($qb, $actorId); $this->limitToAccepted($qb, true); $this->leftJoinCacheActors($qb, 'actor_id'); $this->leftJoinDetails($qb, 'id', 'ca'); diff --git a/lib/Db/SocialLimitsQueryBuilder.php b/lib/Db/SocialLimitsQueryBuilder.php index f3f395b9..24bb37ac 100644 --- a/lib/Db/SocialLimitsQueryBuilder.php +++ b/lib/Db/SocialLimitsQueryBuilder.php @@ -36,7 +36,7 @@ use DateInterval; use DateTime; use Exception; use OCA\Social\Model\ActivityPub\ACore; -use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCP\DB\QueryBuilder\ICompositeExpression; /** @@ -45,15 +45,8 @@ use OCP\DB\QueryBuilder\ICompositeExpression; * @package OCA\Social\Db */ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { - /** - * Limit the request to the Type - * - * @param string $type - * - * @return SocialQueryBuilder - */ - public function limitToType(string $type): self { - $this->limitToDBField('type', $type, true); + public function limitToType(string $type, string $alias = ''): self { + $this->limitToDBField('type', $type, true, $alias); return $this; } @@ -328,10 +321,10 @@ class SocialLimitsQueryBuilder extends SocialCrossQueryBuilder { /** - * @param TimelineOptions $options + * @param ProbeOptions $options * */ - public function paginate(TimelineOptions $options) { + public function paginate(ProbeOptions $options) { $expr = $this->expr(); $pf = $this->getDefaultSelectAlias(); diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php index 3f22dab6..3bb0ff03 100644 --- a/lib/Db/StreamRequest.php +++ b/lib/Db/StreamRequest.php @@ -39,7 +39,7 @@ use OCA\Social\Model\ActivityPub\Internal\SocialAppNotification; use OCA\Social\Model\ActivityPub\Object\Document; use OCA\Social\Model\ActivityPub\Object\Note; use OCA\Social\Model\ActivityPub\Stream; -use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Service\ConfigService; use OCA\Social\Service\MiscService; use OCA\Social\Tools\Exceptions\DateTimeException; @@ -376,32 +376,32 @@ class StreamRequest extends StreamRequestBuilder { } /** - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - public function getTimeline(TimelineOptions $options): array { - switch (strtolower($options->getTimeline())) { - case TimelineOptions::TIMELINE_ACCOUNT: + public function getTimeline(ProbeOptions $options): array { + switch (strtolower($options->getProbe())) { + case ProbeOptions::ACCOUNT: $result = $this->getTimelineAccount($options); break; - case TimelineOptions::TIMELINE_HOME: + case ProbeOptions::HOME: $result = $this->getTimelineHome($options); break; - case TimelineOptions::TIMELINE_DIRECT: + case ProbeOptions::DIRECT: $result = $this->getTimelineDirect($options); break; - case TimelineOptions::TIMELINE_FAVOURITES: + case ProbeOptions::FAVOURITES: $result = $this->getTimelineFavourites($options); break; - case TimelineOptions::TIMELINE_HASHTAG: + case ProbeOptions::HASHTAG: $result = $this->getTimelineHashtag($options, $options->getArgument()); break; - case TimelineOptions::TIMELINE_NOTIFICATIONS: + case ProbeOptions::NOTIFICATIONS: $options->setFormat(ACore::FORMAT_NOTIFICATION); $result = $this->getTimelineNotifications($options); break; - case TimelineOptions::TIMELINE_PUBLIC: + case ProbeOptions::PUBLIC: $result = $this->getTimelinePublic($options); break; default: @@ -409,7 +409,7 @@ class StreamRequest extends StreamRequestBuilder { } if ($options->isInverted()) { - // in cae we inverted the order during the request, we revert the results + // in case we inverted the order during the request, we revert the results $result = array_reverse($result); } @@ -421,11 +421,11 @@ class StreamRequest extends StreamRequestBuilder { * * Own posts, * * Followed accounts * - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineHome(TimelineOptions $options): array { + private function getTimelineHome(ProbeOptions $options): array { $qb = $this->getStreamSelectSql($options->getFormat()); $qb->filterType(SocialAppNotification::TYPE); @@ -446,11 +446,11 @@ class StreamRequest extends StreamRequestBuilder { * * Private message. * - group messages. (not yet) * - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineDirect(TimelineOptions $options): array { + private function getTimelineDirect(ProbeOptions $options): array { $qb = $this->getStreamSelectSql(); $qb->filterType(SocialAppNotification::TYPE); @@ -471,11 +471,11 @@ class StreamRequest extends StreamRequestBuilder { * - public message from actorId. * - followers-only if logged and follower. * - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineAccount(TimelineOptions $options): array { + private function getTimelineAccount(ProbeOptions $options): array { $qb = $this->getStreamSelectSql(); $qb->filterType(SocialAppNotification::TYPE); @@ -501,11 +501,11 @@ class StreamRequest extends StreamRequestBuilder { /** - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineFavourites(TimelineOptions $options): array { + private function getTimelineFavourites(ProbeOptions $options): array { $qb = $this->getStreamSelectSql($options->getFormat()); $actor = $qb->getViewer(); $expr = $qb->expr(); @@ -524,11 +524,11 @@ class StreamRequest extends StreamRequestBuilder { /** - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineHashtag(TimelineOptions $options, string $hashtag): array { + private function getTimelineHashtag(ProbeOptions $options, string $hashtag): array { $qb = $this->getStreamSelectSql($options->getFormat()); return []; @@ -538,11 +538,11 @@ class StreamRequest extends StreamRequestBuilder { /** - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelineNotifications(TimelineOptions $options): array { + private function getTimelineNotifications(ProbeOptions $options): array { $qb = $this->getStreamSelectSql($options->getFormat()); $actor = $qb->getViewer(); @@ -682,11 +682,11 @@ class StreamRequest extends StreamRequestBuilder { * Should return: * * All local public/federated posts * - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Stream[] */ - private function getTimelinePublic(TimelineOptions $options): array { + private function getTimelinePublic(ProbeOptions $options): array { $qb = $this->getStreamSelectSql($options->getFormat()); $qb->paginate($options); diff --git a/lib/Exceptions/UnknownTimelineException.php b/lib/Exceptions/UnknownProbeException.php similarity index 95% rename from lib/Exceptions/UnknownTimelineException.php rename to lib/Exceptions/UnknownProbeException.php index 56644f44..de0dffde 100644 --- a/lib/Exceptions/UnknownTimelineException.php +++ b/lib/Exceptions/UnknownProbeException.php @@ -31,5 +31,5 @@ namespace OCA\Social\Exceptions; use Exception; -class UnknownTimelineException extends Exception { +class UnknownProbeException extends Exception { } diff --git a/lib/Migration/Version1000Date20221118000001.php b/lib/Migration/Version1000Date20221118000001.php index a6b535c4..20753467 100644 --- a/lib/Migration/Version1000Date20221118000001.php +++ b/lib/Migration/Version1000Date20221118000001.php @@ -746,6 +746,15 @@ class Version1000Date20221118000001 extends SimpleMigrationStep { } $table = $schema->createTable('social_cache_actor'); + $table->addColumn( + 'nid', Types::BIGINT, + [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 14, + 'unsigned' => true, + ] + ); $table->addColumn( 'id', Types::TEXT, [ @@ -888,7 +897,7 @@ class Version1000Date20221118000001 extends SimpleMigrationStep { ] ); - $table->setPrimaryKey(['id_prim']); + $table->setPrimaryKey(['nid']); $table->addUniqueIndex(['id_prim']); } diff --git a/lib/Migration/Version1000Date20230217000001.php b/lib/Migration/Version1000Date20230217000001.php index e352433e..93df7982 100644 --- a/lib/Migration/Version1000Date20230217000001.php +++ b/lib/Migration/Version1000Date20230217000001.php @@ -47,6 +47,14 @@ class Version1000Date20230217000001 extends SimpleMigrationStep { } } + if ($schema->hasTable('social_cache_actor')) { + $table = $schema->getTable('social_cache_actor'); + + if (!$table->hasColumn('nid')) { + $table->dropPrimaryKey(); + } + } + return $schema; } } diff --git a/lib/Migration/Version1000Date20230217000002.php b/lib/Migration/Version1000Date20230217000002.php index 67ce0d4c..e6aaf0cc 100644 --- a/lib/Migration/Version1000Date20230217000002.php +++ b/lib/Migration/Version1000Date20230217000002.php @@ -55,6 +55,26 @@ class Version1000Date20230217000002 extends SimpleMigrationStep { } } + + // fix nid as primary on social_cache_actor + if ($schema->hasTable('social_cache_actor')) { + $table = $schema->getTable('social_cache_actor'); + + if (!$table->hasColumn('nid')) { + $table->addColumn( + 'nid', Types::BIGINT, + [ + 'autoincrement' => true, + 'notnull' => true, + 'length' => 14, + 'unsigned' => true, + ] + ); + $table->setPrimaryKey(['nid']); + } + } + + if ($schema->hasTable('social_cache_doc')) { $table = $schema->getTable('social_cache_doc'); diff --git a/lib/Model/Client/Options/TimelineOptions.php b/lib/Model/Client/Options/ProbeOptions.php similarity index 78% rename from lib/Model/Client/Options/TimelineOptions.php rename to lib/Model/Client/Options/ProbeOptions.php index fabb45a3..fe3a0855 100644 --- a/lib/Model/Client/Options/TimelineOptions.php +++ b/lib/Model/Client/Options/ProbeOptions.php @@ -32,27 +32,29 @@ declare(strict_types=1); namespace OCA\Social\Model\Client\Options; use JsonSerializable; -use OCA\Social\Exceptions\UnknownTimelineException; use OCA\Social\Tools\Traits\TArrayTools; use OCP\IRequest; /** - * Class TimelineOptions + * Class ProbeOptions * * @package OCA\Social\Model\Client\Options */ -class TimelineOptions extends CoreOptions implements JsonSerializable { +class ProbeOptions extends CoreOptions implements JsonSerializable { use TArrayTools; - public const TIMELINE_HOME = 'home'; - public const TIMELINE_PUBLIC = 'public'; - public const TIMELINE_DIRECT = 'direct'; - public const TIMELINE_ACCOUNT = 'account'; - public const TIMELINE_FAVOURITES = 'favourites'; - public const TIMELINE_HASHTAG = 'hashtag'; - public const TIMELINE_NOTIFICATIONS = 'notifications'; + public const HOME = 'home'; + public const PUBLIC = 'public'; + public const DIRECT = 'direct'; + public const ACCOUNT = 'account'; + public const FAVOURITES = 'favourites'; + public const HASHTAG = 'hashtag'; + public const NOTIFICATIONS = 'notifications'; - private string $timeline = ''; + public const FOLLOWERS = 'followers'; + public const FOLLOWING = 'following'; + + private string $probe = ''; private bool $local = false; private bool $remote = false; private bool $onlyMedia = false; @@ -66,17 +68,9 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { private array $excludeTypes = []; private string $accountId = ''; - public static array $availableTimelines = [ - self::TIMELINE_HOME, - self::TIMELINE_ACCOUNT, - self::TIMELINE_PUBLIC, - self::TIMELINE_DIRECT, - self::TIMELINE_FAVOURITES, - self::TIMELINE_NOTIFICATIONS - ]; /** - * TimelineOptions constructor. + * ProbeOptions constructor. * * @param IRequest|null $request */ @@ -90,25 +84,17 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @return string */ - public function getTimeline(): string { - return $this->timeline; + public function getProbe(): string { + return $this->probe; } /** - * @param string $timeline + * @param string $probe * - * @return TimelineOptions - * @throws UnknownTimelineException + * @return ProbeOptions */ - public function setTimeline(string $timeline): self { - $timeline = strtolower($timeline); - if (!in_array($timeline, self::$availableTimelines)) { - throw new UnknownTimelineException( - 'unknown timeline: ' . implode(', ', self::$availableTimelines) - ); - } - - $this->timeline = $timeline; + public function setProbe(string $probe): self { + $this->probe = strtolower($probe); return $this; } @@ -124,7 +110,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param bool $local * - * @return TimelineOptions + * @return ProbeOptions */ public function setLocal(bool $local): self { $this->local = $local; @@ -143,7 +129,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param bool $remote * - * @return TimelineOptions + * @return ProbeOptions */ public function setRemote(bool $remote): self { $this->remote = $remote; @@ -162,7 +148,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param bool $onlyMedia * - * @return TimelineOptions + * @return ProbeOptions */ public function setOnlyMedia(bool $onlyMedia): self { $this->onlyMedia = $onlyMedia; @@ -181,7 +167,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param int $minId * - * @return TimelineOptions + * @return ProbeOptions */ public function setMinId(int $minId): self { $this->minId = $minId; @@ -200,7 +186,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param int $maxId * - * @return TimelineOptions + * @return ProbeOptions */ public function setMaxId(int $maxId): self { $this->maxId = $maxId; @@ -219,7 +205,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param int $since * - * @return TimelineOptions + * @return ProbeOptions */ public function setSince(int $since): self { $this->since = $since; @@ -238,7 +224,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param int $limit * - * @return TimelineOptions + * @return ProbeOptions */ public function setLimit(int $limit): self { $this->limit = $limit; @@ -257,7 +243,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param bool $inverted * - * @return TimelineOptions + * @return ProbeOptions */ public function setInverted(bool $inverted): self { $this->inverted = $inverted; @@ -269,7 +255,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param string $argument * - * @return TimelineOptions + * @return ProbeOptions */ public function setArgument(string $argument): self { $this->argument = $argument; @@ -288,7 +274,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param array $types * - * @return TimelineOptions + * @return ProbeOptions */ public function setTypes(array $types): self { $this->types = $types; @@ -307,7 +293,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param array $excludeTypes * - * @return TimelineOptions + * @return ProbeOptions */ public function setExcludeTypes(array $excludeTypes): self { $this->excludeTypes = $excludeTypes; @@ -326,7 +312,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param string $accountId * - * @return TimelineOptions + * @return ProbeOptions */ public function setAccountId(string $accountId): self { $this->accountId = $accountId; @@ -346,7 +332,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { /** * @param array $arr * - * @return TimelineOptions + * @return ProbeOptions */ public function fromArray(array $arr): self { $this->setLocal($this->getBool('local', $arr, $this->isLocal())); @@ -368,7 +354,7 @@ class TimelineOptions extends CoreOptions implements JsonSerializable { public function jsonSerialize(): array { return [ - 'timeline' => $this->getTimeline(), + 'probe' => $this->getProbe(), 'accountId' => $this->getAccountId(), 'local' => $this->isLocal(), 'remote' => $this->isRemote(), diff --git a/lib/Service/CacheActorService.php b/lib/Service/CacheActorService.php index 2773f6d1..e64f21fd 100644 --- a/lib/Service/CacheActorService.php +++ b/lib/Service/CacheActorService.php @@ -44,6 +44,7 @@ use OCA\Social\Exceptions\RetrieveAccountFormatException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\UnauthorizedFediverseException; use OCA\Social\Model\ActivityPub\Actor\Person; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Tools\Exceptions\MalformedArrayException; use OCA\Social\Tools\Exceptions\RequestContentException; use OCA\Social\Tools\Exceptions\RequestNetworkException; @@ -327,4 +328,14 @@ class CacheActorService { } catch (ItemUnknownException $e) { } } + + + /** + * @param ProbeOptions $options + * + * @return Person[] + */ + public function probeActors(ProbeOptions $options): array { + return $this->cacheActorsRequest->probeActors($options); + } } diff --git a/lib/Service/StreamService.php b/lib/Service/StreamService.php index 69e741f0..e2c8168c 100644 --- a/lib/Service/StreamService.php +++ b/lib/Service/StreamService.php @@ -43,7 +43,7 @@ use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Object\Note; use OCA\Social\Model\ActivityPub\Stream; -use OCA\Social\Model\Client\Options\TimelineOptions; +use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Model\InstancePath; use OCA\Social\Tools\Exceptions\DateTimeException; use OCA\Social\Tools\Exceptions\MalformedArrayException; @@ -405,11 +405,11 @@ class StreamService { /** - * @param TimelineOptions $options + * @param ProbeOptions $options * * @return Note[] */ - public function getTimeline(TimelineOptions $options): array { + public function getTimeline(ProbeOptions $options): array { return $this->streamRequest->getTimeline($options); }