diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Controller/ActivityPubController.php | 25 | ||||
-rw-r--r-- | lib/Db/FollowsRequest.php | 6 | ||||
-rw-r--r-- | lib/Model/ActivityPub/OrderedCollection.php | 79 | ||||
-rw-r--r-- | lib/Service/FollowService.php | 75 | ||||
-rw-r--r-- | lib/Service/StreamService.php | 46 |
5 files changed, 123 insertions, 108 deletions
diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php index 65370503..498a6261 100644 --- a/lib/Controller/ActivityPubController.php +++ b/lib/Controller/ActivityPubController.php @@ -278,7 +278,17 @@ class ActivityPubController extends Controller { * @return Response */ public function outbox(string $username): Response { - return $this->success([$username]); +// if (!$this->checkSourceActivityStreams()) { +// return $this->socialPubController->outbox($username); +// } + + try { + $actor = $this->cacheActorService->getFromLocalAccount($username); + + return $this->directSuccess($this->streamService->getOutboxCollection($actor)); + } catch (Exception $e) { + return $this->fail($e); + } } @@ -301,11 +311,8 @@ class ActivityPubController extends Controller { try { $actor = $this->cacheActorService->getFromLocalAccount($username); - $followers = $this->followService->getFollowersCollection($actor); -// $followers->setTopLevel(true); - - return $this->directSuccess($followers); + return $this->directSuccess($this->followService->getFollowersCollection($actor)); } catch (Exception $e) { return $this->fail($e); } @@ -329,7 +336,13 @@ class ActivityPubController extends Controller { return $this->socialPubController->following($username); } - return $this->success([$username]); + try { + $actor = $this->cacheActorService->getFromLocalAccount($username); + + return $this->directSuccess($this->followService->getFollowingCollection($actor)); + } catch (Exception $e) { + return $this->fail($e); + } } diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index 920fe44b..4cf41653 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -136,8 +136,8 @@ class FollowsRequest extends FollowsRequestBuilder { */ public function getByPersons(string $actorId, string $remoteActorId): Follow { $qb = $this->getFollowsSelectSql(); - $this->limitToActorId($qb, $actorId); - $this->limitToObjectId($qb, $remoteActorId); + $qb->limitToActorIdPrim($qb->prim($actorId)); + $qb->limitToObjectIdPrim($qb->prim($remoteActorId)); return $this->getFollowFromRequest($qb); } @@ -223,6 +223,8 @@ class FollowsRequest extends FollowsRequestBuilder { $this->leftJoinDetails($qb, 'id', 'ca'); $qb->orderBy('f.creation', 'desc'); + // TODO: pagination + return $this->getFollowsFromRequest($qb); } diff --git a/lib/Model/ActivityPub/OrderedCollection.php b/lib/Model/ActivityPub/OrderedCollection.php index 8343f87d..39be0a65 100644 --- a/lib/Model/ActivityPub/OrderedCollection.php +++ b/lib/Model/ActivityPub/OrderedCollection.php @@ -2,7 +2,6 @@ declare(strict_types=1); - /** * Nextcloud - Social Support * @@ -28,103 +27,69 @@ declare(strict_types=1); * */ - namespace OCA\Social\Model\ActivityPub; use JsonSerializable; -/** - * Class OrderedCollection - * - * @package OCA\Social\Model\ActivityPub - */ class OrderedCollection extends ACore implements JsonSerializable { public const TYPE = 'OrderedCollection'; - private int $totalItems = 0; - private string $first = ''; + private string $last = ''; - /** - * Activity constructor. - * - * @param ACore $parent - */ public function __construct($parent = null) { parent::__construct($parent); $this->setType(self::TYPE); } - - /** - * @return int - */ public function getTotalItems(): int { return $this->totalItems; } - /** - * @param int $totalItems - * - * @return OrderedCollection - */ - public function setTotalItems(int $totalItems): OrderedCollection { + public function setTotalItems(int $totalItems): self { $this->totalItems = $totalItems; return $this; } - - /** - * @return string - */ public function getFirst(): string { return $this->first; } - /** - * @param string $first - * - * @return OrderedCollection - */ - public function setFirst(string $first): OrderedCollection { + public function setFirst(string $first): self { $this->first = $first; return $this; } + public function getLast(): string { + return $this->last; + } + public function setLast(string $last): self { + $this->last = $last; + return $this; + } - - - - //"id": "https://pub.pontapreta.net/users/admin/following", - //"type": "OrderedCollection", - //"totalItems": 1, - //"first": "https://pub.pontapreta.net/users/admin/following?page=1" - - - /** - * @param array $data - */ - public function import(array $data) { + public function import(array $data): self { parent::import($data); - } + return $this; + } - /** - * @return array - */ public function jsonSerialize(): array { - return array_merge( - parent::jsonSerialize(), - [ - 'totalItems' => $this->getTotalItems(), - 'first' => $this->getFirst() - ] + return array_filter( + array_merge( + parent::jsonSerialize(), + [ + 'totalItems' => $this->getTotalItems(), + 'first' => $this->getFirst(), + 'last' => $this->getLast() + ] + ) ); } } diff --git a/lib/Service/FollowService.php b/lib/Service/FollowService.php index cab69ab0..682b30ed 100644 --- a/lib/Service/FollowService.php +++ b/lib/Service/FollowService.php @@ -56,18 +56,19 @@ use OCA\Social\Tools\Exceptions\RequestResultNotJsonException; use OCA\Social\Tools\Exceptions\RequestResultSizeException; use OCA\Social\Tools\Exceptions\RequestServerException; use OCA\Social\Tools\Traits\TArrayTools; +use OCP\IURLGenerator; use Psr\Log\LoggerInterface; class FollowService { use TArrayTools; + private IURLGenerator $urlGenerator; private FollowsRequest $followsRequest; private ActivityService $activityService; private CacheActorService $cacheActorService; private ConfigService $configService; private LoggerInterface $logger; - private ?Person $viewer = null; @@ -81,12 +82,14 @@ class FollowService { * @param LoggerInterface $logger */ public function __construct( + IURLGenerator $urlGenerator, FollowsRequest $followsRequest, ActivityService $activityService, CacheActorService $cacheActorService, ConfigService $configService, LoggerInterface $logger ) { + $this->urlGenerator = $urlGenerator; $this->followsRequest = $followsRequest; $this->activityService = $activityService; $this->cacheActorService = $cacheActorService; @@ -138,11 +141,6 @@ class FollowService { $follow->setObjectId($remoteActor->getId()); $follow->setFollowId($remoteActor->getFollowers()); - if ($remoteActor->isLocal()) { - // TODO: check user's setting about locked account/auto-accept followers - $follow->setAccepted(true); - } - try { $this->followsRequest->getByPersons($actor->getId(), $remoteActor->getId()); } catch (FollowNotFoundException $e) { @@ -250,8 +248,14 @@ class FollowService { public function getFollowersCollection(Person $actor): OrderedCollection { $collection = new OrderedCollection(); $collection->setId($actor->getFollowers()); - $collection->setTotalItems(20); - $collection->setFirst('...'); + $collection->setTotalItems($this->getInt('followers', $actor->getDetails('count'))); + + $first = $this->urlGenerator->linkToRouteAbsolute( + 'social.ActivityPub.followers', + ['username' => $actor->getPreferredUsername()] + ) + . '?page=1'; + $collection->setFirst($first); return $collection; } @@ -276,9 +280,15 @@ class FollowService { */ public function getFollowingCollection(Person $actor): OrderedCollection { $collection = new OrderedCollection(); -// $collection->setId($actor->getFollowers()); -// $collection->setTotalItems(20); -// $collection->setFirst('...'); + $collection->setId($actor->getFollowing()); + $collection->setTotalItems($this->getInt('following', $actor->getDetails('count'))); + + $first = $this->urlGenerator->linkToRouteAbsolute( + 'social.ActivityPub.following', + ['username' => $actor->getPreferredUsername()] + ) + . '?page=1'; + $collection->setFirst($first); return $collection; } @@ -304,42 +314,43 @@ class FollowService { $actorNids[$actor->getNid()] = $actor->getId(); } - $follows = $this->followsRequest->getFollows(array_values($actorNids)); foreach ($actorNids as $actorNid => $actorId) { if ($actorNid === $this->viewer->getNid()) { continue; // ignore current session } - // might be resource heavy, need to be checked/optimized ? - $relationships[] = $this->generateRelationship($actorNid, $actorId, $follows); + $relationships[] = $this->generateRelationship($actorNid, $this->viewer->getId(), $actorId); } return $relationships; } /** - * @param int $objectNid - * @param string $objectId - * @param Follow[] $follows + * @param int $nid + * @param string $viewerId + * @param string $actorId * * @return Relationship */ - private function generateRelationship(int $objectNid, string $objectId, array $follows): Relationship { - $relationship = new Relationship($objectNid); - - foreach ($follows as $follow) { - if ($follow->getType() === Follow::TYPE) { - if ($follow->getObjectId() === $objectId) { - if ($follow->isAccepted()) { - $relationship->setFollowing(true); - } else { - $relationship->setRequested(true); - } - } - if ($follow->getActorId() === $objectId && $follow->isAccepted()) { - $relationship->setFollowedBy(true); - } + private function generateRelationship(int $nid, string $viewerId, string $actorId): Relationship { + $relationship = new Relationship($nid); + + try { + $follow = $this->followsRequest->getByPersons($viewerId, $actorId); + if ($follow->isAccepted()) { + $relationship->setFollowing(true); + } else { + $relationship->setRequested(true); } + } catch (FollowNotFoundException $e) { + } + + try { + $follow = $this->followsRequest->getByPersons($actorId, $viewerId); + if ($follow->isAccepted()) { + $relationship->setFollowedBy(true); + } + } catch (FollowNotFoundException $e) { } return $relationship; diff --git a/lib/Service/StreamService.php b/lib/Service/StreamService.php index f619f132..4788df46 100644 --- a/lib/Service/StreamService.php +++ b/lib/Service/StreamService.php @@ -42,6 +42,7 @@ use OCA\Social\Exceptions\UnauthorizedFediverseException; 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\OrderedCollection; use OCA\Social\Model\ActivityPub\Stream; use OCA\Social\Model\Client\Options\ProbeOptions; use OCA\Social\Model\InstancePath; @@ -52,8 +53,13 @@ use OCA\Social\Tools\Exceptions\RequestNetworkException; use OCA\Social\Tools\Exceptions\RequestResultNotJsonException; use OCA\Social\Tools\Exceptions\RequestResultSizeException; use OCA\Social\Tools\Exceptions\RequestServerException; +use OCA\Social\Tools\Traits\TArrayTools; +use OCP\IURLGenerator; class StreamService { + use TArrayTools; + + private IUrlGenerator $urlGenerator; private StreamRequest $streamRequest; private ActivityService $activityService; private CacheActorService $cacheActorService; @@ -61,20 +67,14 @@ class StreamService { private const ANCESTOR_LIMIT = 5; - /** - * NoteService constructor. - * - * @param StreamRequest $streamRequest - * @param ActivityService $activityService - * @param CacheActorService $cacheActorService - * @param ConfigService $configService - */ public function __construct( + IUrlGenerator $urlGenerator, StreamRequest $streamRequest, ActivityService $activityService, CacheActorService $cacheActorService, ConfigService $configService ) { + $this->urlGenerator = $urlGenerator; $this->streamRequest = $streamRequest; $this->activityService = $activityService; $this->cacheActorService = $cacheActorService; @@ -282,8 +282,6 @@ class StreamService { } - - /** * @param Note $note * @param string $replyTo @@ -403,7 +401,11 @@ class StreamService { * @throws StreamNotFoundException * @throws DateTimeException */ - public function getRepliesByParentId(string $id, int $since = 0, int $limit = 5, bool $asViewer = false + public function getRepliesByParentId( + string $id, + int $since = 0, + int $limit = 5, + bool $asViewer = false ): array { return $this->streamRequest->getRepliesByParentId($id, $since, $limit, $asViewer); } @@ -563,4 +565,26 @@ class StreamService { return $this->cacheActorService->getFromId($note->getAttributedTo()); } + + + /** + * @param Person $actor + * + * @return OrderedCollection + */ + public function getOutboxCollection(Person $actor): OrderedCollection { + $collection = new OrderedCollection(); + $collection->setId($actor->getOutbox()); + $collection->setTotalItems($this->getInt('post', $actor->getDetails('count'))); + + $link = $this->urlGenerator->linkToRouteAbsolute( + 'social.ActivityPub.outbox', + ['username' => $actor->getPreferredUsername()] + ); + + $collection->setFirst($link . '?page=1'); + $collection->setLast($link . '?page=1&min_id=0'); + + return $collection; + } } |