From 1bc3373b8f0ee7639976a857cccd42b936e4185d Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 13:31:08 -0100 Subject: [PATCH 01/22] almost looking for missing remote actors in cache Signed-off-by: Maxence Lange --- lib/Command/CacheRefresh.php | 3 +++ lib/Service/ActivityPub/PersonService.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/Command/CacheRefresh.php b/lib/Command/CacheRefresh.php index fae76806..26a688fe 100644 --- a/lib/Command/CacheRefresh.php +++ b/lib/Command/CacheRefresh.php @@ -105,6 +105,9 @@ class CacheRefresh extends Base { $result = $this->actorService->manageCacheLocalActors(); $output->writeLn($result . ' local accounts regenerated'); + $result = $this->personService->missingCacheRemoteActors(); + $output->writeLn($result . ' remote accounts created'); + $result = $this->personService->manageCacheRemoteActors(); $output->writeLn($result . ' remote accounts updated'); diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index c170f988..1d3c169a 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -260,6 +260,25 @@ class PersonService implements ICoreService { } + /** + * @throws Exception + * @return int + */ + public function missingCacheRemoteActors(): int { + // TODO - looking for missing cache remote actors... + $missing = []; + + foreach ($missing as $item) { + try { + $this->getFromId($item->getId()); + } catch (Exception $e) { + } + } + + return sizeof($missing); + } + + /** * @throws Exception * @return int From f2a97772e7bf0fd777c328de85b5983d455e94d3 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:39:55 -0100 Subject: [PATCH 02/22] details on Person Signed-off-by: Maxence Lange --- appinfo/database.xml | 7 ++++ appinfo/info.xml | 2 +- composer.lock | 8 ++-- lib/Db/CacheActorsRequest.php | 1 + lib/Model/ActivityPub/Person.php | 70 ++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/appinfo/database.xml b/appinfo/database.xml index 4f980f25..3852db08 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -380,6 +380,13 @@ true + + details + text + 3000 + false + + creation timestamp diff --git a/appinfo/info.xml b/appinfo/info.xml index 88ffacd0..18a81c7d 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Social 🎉 Nextcloud becomes part of the federated social networks! - 0.0.52 + 0.0.53 agpl Maxence Lange Julius Härtl diff --git a/composer.lock b/composer.lock index 0a63850a..37c1c411 100644 --- a/composer.lock +++ b/composer.lock @@ -12,12 +12,12 @@ "source": { "type": "git", "url": "https://github.com/daita/my-small-php-tools.git", - "reference": "39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e" + "reference": "36ea85a58ceb57a521c8f5a43effb4a7330e7b4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e", - "reference": "39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e", + "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/36ea85a58ceb57a521c8f5a43effb4a7330e7b4c", + "reference": "36ea85a58ceb57a521c8f5a43effb4a7330e7b4c", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ } ], "description": "My small PHP Tools", - "time": "2018-11-29T12:56:09+00:00" + "time": "2018-11-29T16:46:38+00:00" } ], "packages-dev": [], diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index f5b4454e..d247396b 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -85,6 +85,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { ->setValue('summary', $qb->createNamedParameter($actor->getSummary())) ->setValue('public_key', $qb->createNamedParameter($actor->getPublicKey())) ->setValue('source', $qb->createNamedParameter($actor->getSource())) + ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetails()))) ->setValue( 'creation', $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) diff --git a/lib/Model/ActivityPub/Person.php b/lib/Model/ActivityPub/Person.php index 41f3b375..03339d03 100644 --- a/lib/Model/ActivityPub/Person.php +++ b/lib/Model/ActivityPub/Person.php @@ -85,6 +85,10 @@ class Person extends ACore implements JsonSerializable { /** @var string */ private $featured = ''; + /** @var array */ + private $details = []; + + /** * Person constructor. * @@ -339,6 +343,61 @@ class Person extends ACore implements JsonSerializable { } + /** + * @return array + */ + public function getDetails(): array { + return $this->details; + } + + /** + * @param string $detail + * @param string $value + * + * @return Person + */ + public function addDetail(string $detail, string $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param string $detail + * @param int $value + * + * @return Person + */ + public function addDetailInt(string $detail, int $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param string $detail + * @param array $value + * + * @return Person + */ + public function addDetailArray(string $detail, array $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param array $details + * + * @return Person + */ + public function setDetails(array $details): Person { + $this->details = $details; + + return $this; + } + + /** * @param array $data * @@ -390,6 +449,7 @@ class Person extends ACore implements JsonSerializable { ->setFollowing($this->get('following', $data, '')) ->setSharedInbox($this->get('shared_inbox', $data, '')) ->setFeatured($this->get('featured', $data, '')) + ->setDetails($this->getArray('details', $data, [])) ->setCreation($this->getInt('creation', $data, 0)); // if ($this->getPreferredUsername() === '') { @@ -402,7 +462,7 @@ class Person extends ACore implements JsonSerializable { * @return array */ public function jsonSerialize(): array { - return array_merge( + $result = array_merge( parent::jsonSerialize(), [ 'aliases' => [ @@ -425,8 +485,12 @@ class Person extends ACore implements JsonSerializable { ] ] ); + + if ($this->isCompleteDetails()) { + $result['details'] = $this->getDetails(); + } + + return $result; } - } - From e7f5119e905eb895792641b81c91fcb1c6f0dcaa Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:40:29 -0100 Subject: [PATCH 03/22] do not import Local Signed-off-by: Maxence Lange --- lib/Model/ActivityPub/ACore.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Model/ActivityPub/ACore.php b/lib/Model/ActivityPub/ACore.php index 6cc36c17..80f134a4 100644 --- a/lib/Model/ActivityPub/ACore.php +++ b/lib/Model/ActivityPub/ACore.php @@ -872,7 +872,6 @@ abstract class ACore implements JsonSerializable { $this->setPublished($this->get('published', $data, '')); $this->setActorId($this->get('actor', $data, '')); $this->setObjectId($this->get('object', $data, '')); - $this->setLocal(($this->getInt('local', $data, 0) === 1)); } From aaafa82b4b8e1e3ec7e58abb2246e71de3e855b8 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:41:12 -0100 Subject: [PATCH 04/22] fixing Signed-off-by: Maxence Lange --- lib/Controller/NavigationController.php | 30 ------------------------- lib/Db/CoreRequestBuilder.php | 2 +- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/lib/Controller/NavigationController.php b/lib/Controller/NavigationController.php index 0409ef90..82713dbd 100644 --- a/lib/Controller/NavigationController.php +++ b/lib/Controller/NavigationController.php @@ -246,36 +246,6 @@ class NavigationController extends Controller { return $this->navigate(); } - /** - * @NoCSRFRequired - * @PublicPage - * - * @param $username - * - * @return RedirectResponse|PublicTemplateResponse - */ - public function public($username) { - // Redirect to external instances - if (preg_match('/@[\w._-]+@[\w._-]+/', $username) === 1) { - $actor = $this->personService->getFromAccount(substr($username, 1)); - return new RedirectResponse($actor->getUrl()); - } - if (\OC::$server->getUserSession() - ->isLoggedIn()) { - return $this->navigate(); - } - - $data = [ - 'serverData' => [ - 'public' => true, - ] - ]; - $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); - $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); - - return $page; - } - /** * diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 8d4179e6..f6622803 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -134,7 +134,7 @@ class CoreRequestBuilder { * @param string $username */ protected function limitToPreferredUsername(IQueryBuilder &$qb, string $username) { - $this->limitToDBField($qb, 'preferred_username', $username); + $this->limitToDBField($qb, 'preferred_username', $username, false); } /** From c005273e1f2a5226a3099a698f789b1de6502c2a Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:41:55 -0100 Subject: [PATCH 05/22] generate details on account info Signed-off-by: Maxence Lange --- lib/Controller/ActivityPubController.php | 2 +- lib/Controller/SocialPubController.php | 64 ++++++++++++++++++----- lib/Db/CacheActorsRequest.php | 26 +++++++++ lib/Service/ActivityPub/PersonService.php | 11 ++++ lib/Service/ActorService.php | 35 ++++++++++++- 5 files changed, 123 insertions(+), 15 deletions(-) diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php index acd79fa3..a958f7bc 100644 --- a/lib/Controller/ActivityPubController.php +++ b/lib/Controller/ActivityPubController.php @@ -128,7 +128,7 @@ class ActivityPubController extends Controller { */ public function actor(string $username): Response { if (!$this->checkSourceActivityStreams()) { - return $this->navigationController->public($username); + return $this->socialPubController->actor($username); } try { diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 4783c90e..36ab15be 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -31,13 +31,18 @@ namespace OCA\Social\Controller; use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; +use Exception; use OCA\Social\AppInfo\Application; -use OCA\Social\Service\ActivityService; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActorService; use OCA\Social\Service\MiscService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\Template\PublicTemplateResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IL10N; use OCP\IRequest; class SocialPubController extends Controller { @@ -45,12 +50,18 @@ class SocialPubController extends Controller { use TNCDataResponse; - /** @var ActivityService */ - private $activityService; + /** @var string */ + private $userId; + + /** @var IL10N */ + private $l10n; /** @var ActorService */ private $actorService; + /** @var PersonService */ + private $personService; + /** @var MiscService */ private $miscService; @@ -58,19 +69,23 @@ class SocialPubController extends Controller { /** * SocialPubController constructor. * - * @param ActivityService $activityService - * @param ActorService $actorService + * @param $userId * @param IRequest $request + * @param IL10N $l10n + * @param ActorService $actorService + * @param PersonService $personService * @param MiscService $miscService */ public function __construct( - ActivityService $activityService, ActorService $actorService, IRequest $request, - MiscService $miscService + $userId, IRequest $request, IL10N $l10n, ActorService $actorService, + PersonService $personService, MiscService $miscService ) { parent::__construct(Application::APP_NAME, $request); - $this->activityService = $activityService; + $this->userId = $userId; + $this->l10n = $l10n; $this->actorService = $actorService; + $this->personService = $personService; $this->miscService = $miscService; } @@ -81,14 +96,39 @@ class SocialPubController extends Controller { * * @NoCSRFRequired * @PublicPage - * e* * * @param string $username * - * @return TemplateResponse + * @return Response */ - public function actor(string $username): TemplateResponse { - return new TemplateResponse(Application::APP_NAME, 'actor', [], 'blank'); + public function actor(string $username): Response { + + try { + $actor = $this->personService->getFromLocalAccount($username); + + if ($this->userId !== null) { + $local = $this->actorService->getActorFromUserId($this->userId, true); + $this->actorService->acquaintLinksBetweenPersons($actor, $local); + $actor->setCompleteDetails(true); + } + + $data = [ + 'serverData' => [ + 'public' => true, + ], + 'actor' => $actor + ]; + $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); + $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); + + $this->miscService->log(json_encode($actor)); + + return $page; + } catch (CacheActorDoesNotExistException $e) { + return new NotFoundResponse(); + } catch (Exception $e) { + $this->fail($e); + } } diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index d247396b..7887ad12 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -153,6 +153,32 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { } + /** + * get Cached version of a local Actor, based on the preferred username + * + * @param string $account + * + * @return Person + * @throws CacheActorDoesNotExistException + */ + public function getFromLocalAccount(string $account): Person { + $qb = $this->getCacheActorsSelectSql(); + $this->limitToPreferredUsername($qb, $account); + $this->limitToLocal($qb, true); + $this->leftJoinCacheDocuments($qb, 'icon_id'); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new CacheActorDoesNotExistException(); + } + + return $this->parseCacheActorsSelectSql($data); + } + + /** * @param string $search * diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index 1d3c169a..77575dca 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -189,6 +189,17 @@ class PersonService implements ICoreService { } + /** + * @param string $account + * + * @return Person + * @throws CacheActorDoesNotExistException + */ + public function getFromLocalAccount(string $account): Person { + return $this->cacheActorsRequest->getFromLocalAccount($account); + } + + /** * @param array $object * diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index 70fb824e..dea05590 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -36,6 +36,7 @@ use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -114,15 +115,26 @@ class ActorService { /** * @param string $userId + * @param bool $create * * @return Person + * @throws AccountAlreadyExistsException * @throws ActorDoesNotExistException * @throws NoUserException * @throws SocialAppConfigException */ - public function getActorFromUserId(string $userId): Person { + public function getActorFromUserId(string $userId, bool $create = false): Person { $this->miscService->confirmUserId($userId); - $actor = $this->actorsRequest->getFromUserId($userId); + try { + $actor = $this->actorsRequest->getFromUserId($userId); + } catch (ActorDoesNotExistException $e) { + if ($create) { + $this->createActor($userId, $userId); + $actor = $this->actorsRequest->getFromUserId($userId); + } else { + throw new ActorDoesNotExistException(); + } + } return $actor; } @@ -177,6 +189,21 @@ class ActorService { } + /** + * @param Person $local + * @param Person $actor + */ + public function acquaintLinksBetweenPersons(Person $actor, Person $local) { + $actor->addDetailArray( + 'links', + [ + 'follower' => true, + 'following' => true + ] + ); + } + + /** * @param string $username * @param bool $refresh @@ -186,6 +213,10 @@ class ActorService { public function cacheLocalActorByUsername(string $username, bool $refresh = false) { try { $actor = $this->getActor($username); + $actor->addDetailInt('followers', 10); + $actor->addDetailInt('following', 10); + $actor->addDetailInt('post', 100); + $this->personService->cacheLocalActor($actor, $refresh); } catch (ActorDoesNotExistException $e) { } From 58d4e075dd9aa70db08aa179f423c83995ee1459 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:48:20 -0100 Subject: [PATCH 06/22] fix Signed-off-by: Maxence Lange --- lib/Controller/SocialPubController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 36ab15be..1b4fb5e4 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -105,11 +105,11 @@ class SocialPubController extends Controller { try { $actor = $this->personService->getFromLocalAccount($username); + $actor->setCompleteDetails(true); if ($this->userId !== null) { $local = $this->actorService->getActorFromUserId($this->userId, true); $this->actorService->acquaintLinksBetweenPersons($actor, $local); - $actor->setCompleteDetails(true); } $data = [ From ead09b10856543ab99280fd0a0ef58a522687721 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 17:28:37 -0100 Subject: [PATCH 07/22] count followers/following/posts on cache update Signed-off-by: Maxence Lange --- lib/Db/CoreRequestBuilder.php | 23 ++++++++++++++++++ lib/Db/FollowsRequest.php | 40 ++++++++++++++++++++++++++++++++ lib/Db/FollowsRequestBuilder.php | 16 +++++++++++++ lib/Db/NotesRequest.php | 17 ++++++++++++++ lib/Db/NotesRequestBuilder.php | 16 +++++++++++++ lib/Service/ActorService.php | 28 ++++++++++++++++------ 6 files changed, 133 insertions(+), 7 deletions(-) diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index f6622803..130dedd7 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -195,6 +195,18 @@ class CoreRequestBuilder { } + /** + * Limit the request to the FollowId + * + * @param IQueryBuilder $qb + * @param bool $accepted + */ + protected function limitToAccepted(IQueryBuilder &$qb, bool $accepted) { + $this->limitToDBField($qb, 'accepted', ($accepted) ? '1' : '0'); + + } + + /** * Limit the request to the ServiceId * @@ -272,6 +284,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the url + * + * @param IQueryBuilder $qb + * @param string $actorId + */ + protected function limitToAttributedTo(IQueryBuilder &$qb, string $actorId) { + $this->limitToDBField($qb, 'attributed_to', $actorId, false); + } + + /** * Limit the request to the status * diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index b4197b17..5b024414 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -31,6 +31,7 @@ declare(strict_types=1); namespace OCA\Social\Db; +use daita\MySmallPhpTools\Traits\TArrayTools; use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Model\ActivityPub\Follow; @@ -43,6 +44,9 @@ use OCA\Social\Model\ActivityPub\Follow; class FollowsRequest extends FollowsRequestBuilder { + use TArrayTools; + + /** * Insert a new Note in the database. * @@ -96,6 +100,42 @@ class FollowsRequest extends FollowsRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countFollowers(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToObjectId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + + /** + * @param string $actorId + * + * @return int + */ + public function countFollowing(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToActorId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $followId * diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index 1947dd4c..7a6882c4 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -92,6 +92,22 @@ class FollowsRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countFollowsSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_FOLLOWS, 'f'); + + $this->defaultSelectAlias = 'f'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php index e2c7d9c8..f4bf6842 100644 --- a/lib/Db/NotesRequest.php +++ b/lib/Db/NotesRequest.php @@ -137,6 +137,23 @@ class NotesRequest extends NotesRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countNotesFromActorId(string $actorId): int { + $qb = $this->countNotesSelectSql(); + $this->limitToAttributedTo($qb, $actorId); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $actorId * @param int $since diff --git a/lib/Db/NotesRequestBuilder.php b/lib/Db/NotesRequestBuilder.php index 90ff24e1..e6f2cb18 100644 --- a/lib/Db/NotesRequestBuilder.php +++ b/lib/Db/NotesRequestBuilder.php @@ -92,6 +92,22 @@ class NotesRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countNotesSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_NOTES, 'sn'); + + $this->defaultSelectAlias = 'sn'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index dea05590..aeb14860 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -34,9 +34,10 @@ use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; +use OCA\Social\Db\FollowsRequest; +use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -56,6 +57,12 @@ class ActorService { /** @var ActorsRequest */ private $actorsRequest; + /** @var FollowsRequest */ + private $followsRequest; + + /** @var NotesRequest */ + private $notesRequest; + /** @var PersonService */ private $personService; @@ -70,15 +77,19 @@ class ActorService { * ActorService constructor. * * @param ActorsRequest $actorsRequest + * @param FollowsRequest $followsRequest + * @param NotesRequest $notesRequest * @param PersonService $personService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - ActorsRequest $actorsRequest, PersonService $personService, ConfigService $configService, - MiscService $miscService + ActorsRequest $actorsRequest, FollowsRequest $followsRequest, NotesRequest $notesRequest, + PersonService $personService, ConfigService $configService, MiscService $miscService ) { $this->actorsRequest = $actorsRequest; + $this->followsRequest = $followsRequest; + $this->notesRequest = $notesRequest; $this->personService = $personService; $this->configService = $configService; $this->miscService = $miscService; @@ -212,10 +223,13 @@ class ActorService { */ public function cacheLocalActorByUsername(string $username, bool $refresh = false) { try { - $actor = $this->getActor($username); - $actor->addDetailInt('followers', 10); - $actor->addDetailInt('following', 10); - $actor->addDetailInt('post', 100); + $actor = $this->getActor($username);; + $count = [ + 'followers', $this->followsRequest->countFollowers($actor->getId()), + 'following', $this->followsRequest->countFollowing($actor->getId()), + 'post', $this->notesRequest->countNotesFromActorId($actor->getId()) + ]; + $actor->addDetailArray('count', $count); $this->personService->cacheLocalActor($actor, $refresh); } catch (ActorDoesNotExistException $e) { From 39ce6745e1587453bedafd13be53a2359318b260 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 17:52:09 -0100 Subject: [PATCH 08/22] info about links between viewer/account Signed-off-by: Maxence Lange --- lib/Controller/SocialPubController.php | 29 +++++++++++++++++++----- lib/Db/CacheActorsRequestBuilder.php | 2 +- lib/Service/ActorService.php | 31 +++++++++++++++++++------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 1b4fb5e4..f0ddb1d4 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -34,6 +34,7 @@ use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; use Exception; use OCA\Social\AppInfo\Application; use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActorService; use OCA\Social\Service\MiscService; @@ -107,22 +108,31 @@ class SocialPubController extends Controller { $actor = $this->personService->getFromLocalAccount($username); $actor->setCompleteDetails(true); + $logged = false; + $ownAccount = false; if ($this->userId !== null) { + $logged = true; $local = $this->actorService->getActorFromUserId($this->userId, true); - $this->actorService->acquaintLinksBetweenPersons($actor, $local); + if ($local->getId() === $actor->getId()) { + $ownAccount = true; + } else { + $this->fillActorWithLinks($actor, $local); + } } $data = [ 'serverData' => [ 'public' => true, ], - 'actor' => $actor + 'actor' => $actor, + 'logged' => $logged, + 'ownAccount' => $ownAccount ]; + + $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); - $this->miscService->log(json_encode($actor)); - return $page; } catch (CacheActorDoesNotExistException $e) { return new NotFoundResponse(); @@ -179,6 +189,15 @@ class SocialPubController extends Controller { return $this->success([$username, $postId]); } + + /** + * @param Person $actor + * @param Person $local + */ + private function fillActorWithLinks(Person $actor, Person $local) { + $links = $this->actorService->getLinksBetweenPersons($local, $actor); + $actor->addDetailArray('link', $links); + } + } - diff --git a/lib/Db/CacheActorsRequestBuilder.php b/lib/Db/CacheActorsRequestBuilder.php index 1d6e9668..cb9ce58a 100644 --- a/lib/Db/CacheActorsRequestBuilder.php +++ b/lib/Db/CacheActorsRequestBuilder.php @@ -80,7 +80,7 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder { '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.source', 'ca.creation' + 'ca.public_key', 'ca.local', 'ca.details', 'ca.source', 'ca.creation' ) ->from(self::TABLE_CACHE_ACTORS, 'ca'); diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index aeb14860..33ee2cfd 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -38,6 +38,7 @@ use OCA\Social\Db\FollowsRequest; use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; +use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -203,15 +204,29 @@ class ActorService { /** * @param Person $local * @param Person $actor + * + * @return array */ - public function acquaintLinksBetweenPersons(Person $actor, Person $local) { - $actor->addDetailArray( - 'links', - [ - 'follower' => true, - 'following' => true - ] - ); + public function getLinksBetweenPersons(Person $local, Person $actor): array { + + $links = [ + 'follower' => false, + 'following' => false + ]; + + try { + $this->followsRequest->getByPersons($local->getId(), $actor->getId()); + $links['following'] = true; + } catch (FollowDoesNotExistException $e) { + } + + try { + $this->followsRequest->getByPersons($actor->getId(), $local->getId()); + $links['follower'] = true; + } catch (FollowDoesNotExistException $e) { + } + + return $links; } From 93b7973cbdd6e46b9936f5a6ff9d0c2344f80c92 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 13:31:08 -0100 Subject: [PATCH 09/22] almost looking for missing remote actors in cache Signed-off-by: Maxence Lange --- lib/Command/CacheRefresh.php | 3 +++ lib/Service/ActivityPub/PersonService.php | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/lib/Command/CacheRefresh.php b/lib/Command/CacheRefresh.php index fae76806..26a688fe 100644 --- a/lib/Command/CacheRefresh.php +++ b/lib/Command/CacheRefresh.php @@ -105,6 +105,9 @@ class CacheRefresh extends Base { $result = $this->actorService->manageCacheLocalActors(); $output->writeLn($result . ' local accounts regenerated'); + $result = $this->personService->missingCacheRemoteActors(); + $output->writeLn($result . ' remote accounts created'); + $result = $this->personService->manageCacheRemoteActors(); $output->writeLn($result . ' remote accounts updated'); diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index c170f988..1d3c169a 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -260,6 +260,25 @@ class PersonService implements ICoreService { } + /** + * @throws Exception + * @return int + */ + public function missingCacheRemoteActors(): int { + // TODO - looking for missing cache remote actors... + $missing = []; + + foreach ($missing as $item) { + try { + $this->getFromId($item->getId()); + } catch (Exception $e) { + } + } + + return sizeof($missing); + } + + /** * @throws Exception * @return int From 54ce1b496a30c94a0ebd6e284b1e0913acf4ca2d Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:39:55 -0100 Subject: [PATCH 10/22] details on Person Signed-off-by: Maxence Lange --- appinfo/database.xml | 7 ++++ appinfo/info.xml | 2 +- composer.lock | 8 ++-- lib/Db/CacheActorsRequest.php | 1 + lib/Model/ActivityPub/Person.php | 70 ++++++++++++++++++++++++++++++-- 5 files changed, 80 insertions(+), 8 deletions(-) diff --git a/appinfo/database.xml b/appinfo/database.xml index 4f980f25..3852db08 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -380,6 +380,13 @@ true + + details + text + 3000 + false + + creation timestamp diff --git a/appinfo/info.xml b/appinfo/info.xml index 88ffacd0..18a81c7d 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Social 🎉 Nextcloud becomes part of the federated social networks! - 0.0.52 + 0.0.53 agpl Maxence Lange Julius Härtl diff --git a/composer.lock b/composer.lock index 0a63850a..37c1c411 100644 --- a/composer.lock +++ b/composer.lock @@ -12,12 +12,12 @@ "source": { "type": "git", "url": "https://github.com/daita/my-small-php-tools.git", - "reference": "39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e" + "reference": "36ea85a58ceb57a521c8f5a43effb4a7330e7b4c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e", - "reference": "39ea0ce3f9442cb507c0bfaa4be36c3e90d6903e", + "url": "https://api.github.com/repos/daita/my-small-php-tools/zipball/36ea85a58ceb57a521c8f5a43effb4a7330e7b4c", + "reference": "36ea85a58ceb57a521c8f5a43effb4a7330e7b4c", "shasum": "" }, "require": { @@ -40,7 +40,7 @@ } ], "description": "My small PHP Tools", - "time": "2018-11-29T12:56:09+00:00" + "time": "2018-11-29T16:46:38+00:00" } ], "packages-dev": [], diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index f5b4454e..d247396b 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -85,6 +85,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { ->setValue('summary', $qb->createNamedParameter($actor->getSummary())) ->setValue('public_key', $qb->createNamedParameter($actor->getPublicKey())) ->setValue('source', $qb->createNamedParameter($actor->getSource())) + ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetails()))) ->setValue( 'creation', $qb->createNamedParameter(new DateTime('now'), IQueryBuilder::PARAM_DATE) diff --git a/lib/Model/ActivityPub/Person.php b/lib/Model/ActivityPub/Person.php index 41f3b375..03339d03 100644 --- a/lib/Model/ActivityPub/Person.php +++ b/lib/Model/ActivityPub/Person.php @@ -85,6 +85,10 @@ class Person extends ACore implements JsonSerializable { /** @var string */ private $featured = ''; + /** @var array */ + private $details = []; + + /** * Person constructor. * @@ -339,6 +343,61 @@ class Person extends ACore implements JsonSerializable { } + /** + * @return array + */ + public function getDetails(): array { + return $this->details; + } + + /** + * @param string $detail + * @param string $value + * + * @return Person + */ + public function addDetail(string $detail, string $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param string $detail + * @param int $value + * + * @return Person + */ + public function addDetailInt(string $detail, int $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param string $detail + * @param array $value + * + * @return Person + */ + public function addDetailArray(string $detail, array $value): Person { + $this->details[$detail] = $value; + + return $this; + } + + /** + * @param array $details + * + * @return Person + */ + public function setDetails(array $details): Person { + $this->details = $details; + + return $this; + } + + /** * @param array $data * @@ -390,6 +449,7 @@ class Person extends ACore implements JsonSerializable { ->setFollowing($this->get('following', $data, '')) ->setSharedInbox($this->get('shared_inbox', $data, '')) ->setFeatured($this->get('featured', $data, '')) + ->setDetails($this->getArray('details', $data, [])) ->setCreation($this->getInt('creation', $data, 0)); // if ($this->getPreferredUsername() === '') { @@ -402,7 +462,7 @@ class Person extends ACore implements JsonSerializable { * @return array */ public function jsonSerialize(): array { - return array_merge( + $result = array_merge( parent::jsonSerialize(), [ 'aliases' => [ @@ -425,8 +485,12 @@ class Person extends ACore implements JsonSerializable { ] ] ); + + if ($this->isCompleteDetails()) { + $result['details'] = $this->getDetails(); + } + + return $result; } - } - From 56d87e9bdb111ec4dbc10bbab48457a379a5fc2f Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:40:29 -0100 Subject: [PATCH 11/22] do not import Local Signed-off-by: Maxence Lange --- lib/Model/ActivityPub/ACore.php | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Model/ActivityPub/ACore.php b/lib/Model/ActivityPub/ACore.php index 6cc36c17..80f134a4 100644 --- a/lib/Model/ActivityPub/ACore.php +++ b/lib/Model/ActivityPub/ACore.php @@ -872,7 +872,6 @@ abstract class ACore implements JsonSerializable { $this->setPublished($this->get('published', $data, '')); $this->setActorId($this->get('actor', $data, '')); $this->setObjectId($this->get('object', $data, '')); - $this->setLocal(($this->getInt('local', $data, 0) === 1)); } From 1c5ce8c2696257d5df87525db3decacbb4f48a7e Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:41:12 -0100 Subject: [PATCH 12/22] fixing Signed-off-by: Maxence Lange --- lib/Controller/NavigationController.php | 30 ------------------------- lib/Db/CoreRequestBuilder.php | 2 +- 2 files changed, 1 insertion(+), 31 deletions(-) diff --git a/lib/Controller/NavigationController.php b/lib/Controller/NavigationController.php index 3b76ea91..b14f46bd 100644 --- a/lib/Controller/NavigationController.php +++ b/lib/Controller/NavigationController.php @@ -251,36 +251,6 @@ class NavigationController extends Controller { return $this->navigate(); } - /** - * @NoCSRFRequired - * @PublicPage - * - * @param $username - * - * @return RedirectResponse|PublicTemplateResponse - */ - public function public($username) { - // Redirect to external instances - if (preg_match('/@[\w._-]+@[\w._-]+/', $username) === 1) { - $actor = $this->personService->getFromAccount(substr($username, 1)); - return new RedirectResponse($actor->getUrl()); - } - if (\OC::$server->getUserSession() - ->isLoggedIn()) { - return $this->navigate(); - } - - $data = [ - 'serverData' => [ - 'public' => true, - ] - ]; - $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); - $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); - - return $page; - } - /** * diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 8d4179e6..f6622803 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -134,7 +134,7 @@ class CoreRequestBuilder { * @param string $username */ protected function limitToPreferredUsername(IQueryBuilder &$qb, string $username) { - $this->limitToDBField($qb, 'preferred_username', $username); + $this->limitToDBField($qb, 'preferred_username', $username, false); } /** From 7ea1ef3c01e56a25c24b857e1fe9b78e1077cade Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:41:55 -0100 Subject: [PATCH 13/22] generate details on account info Signed-off-by: Maxence Lange --- lib/Controller/ActivityPubController.php | 2 +- lib/Controller/SocialPubController.php | 64 ++++++++++++++++++----- lib/Db/CacheActorsRequest.php | 26 +++++++++ lib/Service/ActivityPub/PersonService.php | 11 ++++ lib/Service/ActorService.php | 35 ++++++++++++- 5 files changed, 123 insertions(+), 15 deletions(-) diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php index acd79fa3..a958f7bc 100644 --- a/lib/Controller/ActivityPubController.php +++ b/lib/Controller/ActivityPubController.php @@ -128,7 +128,7 @@ class ActivityPubController extends Controller { */ public function actor(string $username): Response { if (!$this->checkSourceActivityStreams()) { - return $this->navigationController->public($username); + return $this->socialPubController->actor($username); } try { diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 4783c90e..36ab15be 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -31,13 +31,18 @@ namespace OCA\Social\Controller; use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; +use Exception; use OCA\Social\AppInfo\Application; -use OCA\Social\Service\ActivityService; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActorService; use OCA\Social\Service\MiscService; use OCP\AppFramework\Controller; +use OCP\AppFramework\Http\NotFoundResponse; use OCP\AppFramework\Http\Response; +use OCP\AppFramework\Http\Template\PublicTemplateResponse; use OCP\AppFramework\Http\TemplateResponse; +use OCP\IL10N; use OCP\IRequest; class SocialPubController extends Controller { @@ -45,12 +50,18 @@ class SocialPubController extends Controller { use TNCDataResponse; - /** @var ActivityService */ - private $activityService; + /** @var string */ + private $userId; + + /** @var IL10N */ + private $l10n; /** @var ActorService */ private $actorService; + /** @var PersonService */ + private $personService; + /** @var MiscService */ private $miscService; @@ -58,19 +69,23 @@ class SocialPubController extends Controller { /** * SocialPubController constructor. * - * @param ActivityService $activityService - * @param ActorService $actorService + * @param $userId * @param IRequest $request + * @param IL10N $l10n + * @param ActorService $actorService + * @param PersonService $personService * @param MiscService $miscService */ public function __construct( - ActivityService $activityService, ActorService $actorService, IRequest $request, - MiscService $miscService + $userId, IRequest $request, IL10N $l10n, ActorService $actorService, + PersonService $personService, MiscService $miscService ) { parent::__construct(Application::APP_NAME, $request); - $this->activityService = $activityService; + $this->userId = $userId; + $this->l10n = $l10n; $this->actorService = $actorService; + $this->personService = $personService; $this->miscService = $miscService; } @@ -81,14 +96,39 @@ class SocialPubController extends Controller { * * @NoCSRFRequired * @PublicPage - * e* * * @param string $username * - * @return TemplateResponse + * @return Response */ - public function actor(string $username): TemplateResponse { - return new TemplateResponse(Application::APP_NAME, 'actor', [], 'blank'); + public function actor(string $username): Response { + + try { + $actor = $this->personService->getFromLocalAccount($username); + + if ($this->userId !== null) { + $local = $this->actorService->getActorFromUserId($this->userId, true); + $this->actorService->acquaintLinksBetweenPersons($actor, $local); + $actor->setCompleteDetails(true); + } + + $data = [ + 'serverData' => [ + 'public' => true, + ], + 'actor' => $actor + ]; + $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); + $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); + + $this->miscService->log(json_encode($actor)); + + return $page; + } catch (CacheActorDoesNotExistException $e) { + return new NotFoundResponse(); + } catch (Exception $e) { + $this->fail($e); + } } diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index d247396b..7887ad12 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -153,6 +153,32 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { } + /** + * get Cached version of a local Actor, based on the preferred username + * + * @param string $account + * + * @return Person + * @throws CacheActorDoesNotExistException + */ + public function getFromLocalAccount(string $account): Person { + $qb = $this->getCacheActorsSelectSql(); + $this->limitToPreferredUsername($qb, $account); + $this->limitToLocal($qb, true); + $this->leftJoinCacheDocuments($qb, 'icon_id'); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + if ($data === false) { + throw new CacheActorDoesNotExistException(); + } + + return $this->parseCacheActorsSelectSql($data); + } + + /** * @param string $search * diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index 1d3c169a..77575dca 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -189,6 +189,17 @@ class PersonService implements ICoreService { } + /** + * @param string $account + * + * @return Person + * @throws CacheActorDoesNotExistException + */ + public function getFromLocalAccount(string $account): Person { + return $this->cacheActorsRequest->getFromLocalAccount($account); + } + + /** * @param array $object * diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index 70fb824e..dea05590 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -36,6 +36,7 @@ use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -114,15 +115,26 @@ class ActorService { /** * @param string $userId + * @param bool $create * * @return Person + * @throws AccountAlreadyExistsException * @throws ActorDoesNotExistException * @throws NoUserException * @throws SocialAppConfigException */ - public function getActorFromUserId(string $userId): Person { + public function getActorFromUserId(string $userId, bool $create = false): Person { $this->miscService->confirmUserId($userId); - $actor = $this->actorsRequest->getFromUserId($userId); + try { + $actor = $this->actorsRequest->getFromUserId($userId); + } catch (ActorDoesNotExistException $e) { + if ($create) { + $this->createActor($userId, $userId); + $actor = $this->actorsRequest->getFromUserId($userId); + } else { + throw new ActorDoesNotExistException(); + } + } return $actor; } @@ -177,6 +189,21 @@ class ActorService { } + /** + * @param Person $local + * @param Person $actor + */ + public function acquaintLinksBetweenPersons(Person $actor, Person $local) { + $actor->addDetailArray( + 'links', + [ + 'follower' => true, + 'following' => true + ] + ); + } + + /** * @param string $username * @param bool $refresh @@ -186,6 +213,10 @@ class ActorService { public function cacheLocalActorByUsername(string $username, bool $refresh = false) { try { $actor = $this->getActor($username); + $actor->addDetailInt('followers', 10); + $actor->addDetailInt('following', 10); + $actor->addDetailInt('post', 100); + $this->personService->cacheLocalActor($actor, $refresh); } catch (ActorDoesNotExistException $e) { } From 2a7d07cdaa74bc36e5e9dd8c229fb2c92f2e37a1 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 16:48:20 -0100 Subject: [PATCH 14/22] fix Signed-off-by: Maxence Lange --- lib/Controller/SocialPubController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 36ab15be..1b4fb5e4 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -105,11 +105,11 @@ class SocialPubController extends Controller { try { $actor = $this->personService->getFromLocalAccount($username); + $actor->setCompleteDetails(true); if ($this->userId !== null) { $local = $this->actorService->getActorFromUserId($this->userId, true); $this->actorService->acquaintLinksBetweenPersons($actor, $local); - $actor->setCompleteDetails(true); } $data = [ From 06ad4230eb5343cb5895a6803a6e54acee0b8284 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 17:28:37 -0100 Subject: [PATCH 15/22] count followers/following/posts on cache update Signed-off-by: Maxence Lange --- lib/Db/CoreRequestBuilder.php | 23 ++++++++++++++++++ lib/Db/FollowsRequest.php | 40 ++++++++++++++++++++++++++++++++ lib/Db/FollowsRequestBuilder.php | 16 +++++++++++++ lib/Db/NotesRequest.php | 17 ++++++++++++++ lib/Db/NotesRequestBuilder.php | 16 +++++++++++++ lib/Service/ActorService.php | 28 ++++++++++++++++------ 6 files changed, 133 insertions(+), 7 deletions(-) diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index f6622803..130dedd7 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -195,6 +195,18 @@ class CoreRequestBuilder { } + /** + * Limit the request to the FollowId + * + * @param IQueryBuilder $qb + * @param bool $accepted + */ + protected function limitToAccepted(IQueryBuilder &$qb, bool $accepted) { + $this->limitToDBField($qb, 'accepted', ($accepted) ? '1' : '0'); + + } + + /** * Limit the request to the ServiceId * @@ -272,6 +284,17 @@ class CoreRequestBuilder { } + /** + * Limit the request to the url + * + * @param IQueryBuilder $qb + * @param string $actorId + */ + protected function limitToAttributedTo(IQueryBuilder &$qb, string $actorId) { + $this->limitToDBField($qb, 'attributed_to', $actorId, false); + } + + /** * Limit the request to the status * diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index b4197b17..5b024414 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -31,6 +31,7 @@ declare(strict_types=1); namespace OCA\Social\Db; +use daita\MySmallPhpTools\Traits\TArrayTools; use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Model\ActivityPub\Follow; @@ -43,6 +44,9 @@ use OCA\Social\Model\ActivityPub\Follow; class FollowsRequest extends FollowsRequestBuilder { + use TArrayTools; + + /** * Insert a new Note in the database. * @@ -96,6 +100,42 @@ class FollowsRequest extends FollowsRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countFollowers(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToObjectId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + + /** + * @param string $actorId + * + * @return int + */ + public function countFollowing(string $actorId): int { + $qb = $this->countFollowsSelectSql(); + $this->limitToActorId($qb, $actorId); + $this->limitToAccepted($qb, true); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $followId * diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index 1947dd4c..7a6882c4 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -92,6 +92,22 @@ class FollowsRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countFollowsSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_FOLLOWS, 'f'); + + $this->defaultSelectAlias = 'f'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Db/NotesRequest.php b/lib/Db/NotesRequest.php index e2c7d9c8..f4bf6842 100644 --- a/lib/Db/NotesRequest.php +++ b/lib/Db/NotesRequest.php @@ -137,6 +137,23 @@ class NotesRequest extends NotesRequestBuilder { } + /** + * @param string $actorId + * + * @return int + */ + public function countNotesFromActorId(string $actorId): int { + $qb = $this->countNotesSelectSql(); + $this->limitToAttributedTo($qb, $actorId); + + $cursor = $qb->execute(); + $data = $cursor->fetch(); + $cursor->closeCursor(); + + return $this->getInt('count', $data, 0); + } + + /** * @param string $actorId * @param int $since diff --git a/lib/Db/NotesRequestBuilder.php b/lib/Db/NotesRequestBuilder.php index 90ff24e1..e6f2cb18 100644 --- a/lib/Db/NotesRequestBuilder.php +++ b/lib/Db/NotesRequestBuilder.php @@ -92,6 +92,22 @@ class NotesRequestBuilder extends CoreRequestBuilder { } + /** + * Base of the Sql Select request for Shares + * + * @return IQueryBuilder + */ + protected function countNotesSelectSql(): IQueryBuilder { + $qb = $this->dbConnection->getQueryBuilder(); + $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') + ->from(self::TABLE_SERVER_NOTES, 'sn'); + + $this->defaultSelectAlias = 'sn'; + + return $qb; + } + + /** * Base of the Sql Delete request * diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index dea05590..aeb14860 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -34,9 +34,10 @@ use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; use OC\User\NoUserException; use OCA\Social\Db\ActorsRequest; +use OCA\Social\Db\FollowsRequest; +use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -56,6 +57,12 @@ class ActorService { /** @var ActorsRequest */ private $actorsRequest; + /** @var FollowsRequest */ + private $followsRequest; + + /** @var NotesRequest */ + private $notesRequest; + /** @var PersonService */ private $personService; @@ -70,15 +77,19 @@ class ActorService { * ActorService constructor. * * @param ActorsRequest $actorsRequest + * @param FollowsRequest $followsRequest + * @param NotesRequest $notesRequest * @param PersonService $personService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( - ActorsRequest $actorsRequest, PersonService $personService, ConfigService $configService, - MiscService $miscService + ActorsRequest $actorsRequest, FollowsRequest $followsRequest, NotesRequest $notesRequest, + PersonService $personService, ConfigService $configService, MiscService $miscService ) { $this->actorsRequest = $actorsRequest; + $this->followsRequest = $followsRequest; + $this->notesRequest = $notesRequest; $this->personService = $personService; $this->configService = $configService; $this->miscService = $miscService; @@ -212,10 +223,13 @@ class ActorService { */ public function cacheLocalActorByUsername(string $username, bool $refresh = false) { try { - $actor = $this->getActor($username); - $actor->addDetailInt('followers', 10); - $actor->addDetailInt('following', 10); - $actor->addDetailInt('post', 100); + $actor = $this->getActor($username);; + $count = [ + 'followers', $this->followsRequest->countFollowers($actor->getId()), + 'following', $this->followsRequest->countFollowing($actor->getId()), + 'post', $this->notesRequest->countNotesFromActorId($actor->getId()) + ]; + $actor->addDetailArray('count', $count); $this->personService->cacheLocalActor($actor, $refresh); } catch (ActorDoesNotExistException $e) { From 011074646a68e7d80ff1edccbe627f06d4b401f6 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Thu, 29 Nov 2018 17:52:09 -0100 Subject: [PATCH 16/22] info about links between viewer/account Signed-off-by: Maxence Lange --- lib/Controller/SocialPubController.php | 29 +++++++++++++++++++----- lib/Db/CacheActorsRequestBuilder.php | 2 +- lib/Service/ActorService.php | 31 +++++++++++++++++++------- 3 files changed, 48 insertions(+), 14 deletions(-) diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index 1b4fb5e4..f0ddb1d4 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -34,6 +34,7 @@ use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; use Exception; use OCA\Social\AppInfo\Application; use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActorService; use OCA\Social\Service\MiscService; @@ -107,22 +108,31 @@ class SocialPubController extends Controller { $actor = $this->personService->getFromLocalAccount($username); $actor->setCompleteDetails(true); + $logged = false; + $ownAccount = false; if ($this->userId !== null) { + $logged = true; $local = $this->actorService->getActorFromUserId($this->userId, true); - $this->actorService->acquaintLinksBetweenPersons($actor, $local); + if ($local->getId() === $actor->getId()) { + $ownAccount = true; + } else { + $this->fillActorWithLinks($actor, $local); + } } $data = [ 'serverData' => [ 'public' => true, ], - 'actor' => $actor + 'actor' => $actor, + 'logged' => $logged, + 'ownAccount' => $ownAccount ]; + + $page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data); $page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username); - $this->miscService->log(json_encode($actor)); - return $page; } catch (CacheActorDoesNotExistException $e) { return new NotFoundResponse(); @@ -179,6 +189,15 @@ class SocialPubController extends Controller { return $this->success([$username, $postId]); } + + /** + * @param Person $actor + * @param Person $local + */ + private function fillActorWithLinks(Person $actor, Person $local) { + $links = $this->actorService->getLinksBetweenPersons($local, $actor); + $actor->addDetailArray('link', $links); + } + } - diff --git a/lib/Db/CacheActorsRequestBuilder.php b/lib/Db/CacheActorsRequestBuilder.php index 1d6e9668..cb9ce58a 100644 --- a/lib/Db/CacheActorsRequestBuilder.php +++ b/lib/Db/CacheActorsRequestBuilder.php @@ -80,7 +80,7 @@ class CacheActorsRequestBuilder extends CoreRequestBuilder { '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.source', 'ca.creation' + 'ca.public_key', 'ca.local', 'ca.details', 'ca.source', 'ca.creation' ) ->from(self::TABLE_CACHE_ACTORS, 'ca'); diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index aeb14860..33ee2cfd 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -38,6 +38,7 @@ use OCA\Social\Db\FollowsRequest; use OCA\Social\Db\NotesRequest; use OCA\Social\Exceptions\AccountAlreadyExistsException; use OCA\Social\Exceptions\ActorDoesNotExistException; +use OCA\Social\Exceptions\FollowDoesNotExistException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ActivityPub\PersonService; @@ -203,15 +204,29 @@ class ActorService { /** * @param Person $local * @param Person $actor + * + * @return array */ - public function acquaintLinksBetweenPersons(Person $actor, Person $local) { - $actor->addDetailArray( - 'links', - [ - 'follower' => true, - 'following' => true - ] - ); + public function getLinksBetweenPersons(Person $local, Person $actor): array { + + $links = [ + 'follower' => false, + 'following' => false + ]; + + try { + $this->followsRequest->getByPersons($local->getId(), $actor->getId()); + $links['following'] = true; + } catch (FollowDoesNotExistException $e) { + } + + try { + $this->followsRequest->getByPersons($actor->getId(), $local->getId()); + $links['follower'] = true; + } catch (FollowDoesNotExistException $e) { + } + + return $links; } From 8a2fd1842b9b783b53f666da8be68a689eda23e8 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 09:54:48 -0100 Subject: [PATCH 17/22] type in database for Follow Signed-off-by: Maxence Lange --- appinfo/database.xml | 7 +++++ appinfo/info.xml | 2 +- lib/Db/FollowsRequest.php | 1 + lib/Db/FollowsRequestBuilder.php | 7 ++--- lib/Model/ActivityPub/Follow.php | 10 +++++++ whenanaccountisdeleter.json | 45 ++++++++++++++++++++++++++++++++ 6 files changed, 66 insertions(+), 6 deletions(-) create mode 100644 whenanaccountisdeleter.json diff --git a/appinfo/database.xml b/appinfo/database.xml index 3852db08..c4c3184f 100644 --- a/appinfo/database.xml +++ b/appinfo/database.xml @@ -77,6 +77,13 @@ true + + type + text + 31 + false + + actor_id text diff --git a/appinfo/info.xml b/appinfo/info.xml index 18a81c7d..60acb624 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Social 🎉 Nextcloud becomes part of the federated social networks! - 0.0.53 + 0.0.54 agpl Maxence Lange Julius Härtl diff --git a/lib/Db/FollowsRequest.php b/lib/Db/FollowsRequest.php index 5b024414..fdcb04ff 100644 --- a/lib/Db/FollowsRequest.php +++ b/lib/Db/FollowsRequest.php @@ -56,6 +56,7 @@ class FollowsRequest extends FollowsRequestBuilder { $qb = $this->getFollowsInsertSql(); $qb->setValue('id', $qb->createNamedParameter($follow->getId())) ->setValue('actor_id', $qb->createNamedParameter($follow->getActorId())) + ->setValue('type', $qb->createNamedParameter($follow->getType())) ->setValue('object_id', $qb->createNamedParameter($follow->getObjectId())) ->setValue('follow_id', $qb->createNamedParameter($follow->getFollowId())); diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index 7a6882c4..0f50b37e 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -83,7 +83,7 @@ class FollowsRequestBuilder extends CoreRequestBuilder { $qb = $this->dbConnection->getQueryBuilder(); /** @noinspection PhpMethodParametersCountMismatchInspection */ - $qb->select('f.id', 'f.actor_id', 'f.object_id', 'f.follow_id', 'f.creation') + $qb->select('f.id', 'f.type', 'f.actor_id', 'f.object_id', 'f.follow_id', 'f.creation') ->from(self::TABLE_SERVER_FOLLOWS, 'f'); $this->defaultSelectAlias = 'f'; @@ -128,10 +128,7 @@ class FollowsRequestBuilder extends CoreRequestBuilder { */ protected function parseFollowsSelectSql($data): Follow { $follow = new Follow(); - $follow->setId($data['id']) - ->setActorId($data['actor_id']) - ->setObjectId($data['object_id']); - $follow->setFollowId($data['follow_id']); + $follow->importFromDatabase($data); try { $actor = $this->parseCacheActorsLeftJoin($data); diff --git a/lib/Model/ActivityPub/Follow.php b/lib/Model/ActivityPub/Follow.php index c7818826..26546265 100644 --- a/lib/Model/ActivityPub/Follow.php +++ b/lib/Model/ActivityPub/Follow.php @@ -88,6 +88,16 @@ class Follow extends ACore implements JsonSerializable { } + /** + * @param array $data + */ + public function importFromDatabase(array $data) { + parent::importFromDatabase($data); + + $this->setFollowId($this->get('follow_id', $data, '')); + } + + /** * @return array */ diff --git a/whenanaccountisdeleter.json b/whenanaccountisdeleter.json new file mode 100644 index 00000000..af8c879e --- /dev/null +++ b/whenanaccountisdeleter.json @@ -0,0 +1,45 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "movedTo": { + "@id": "as:movedTo", + "@type": "@id" + }, + "Hashtag": "as:Hashtag", + "ostatus": "http://ostatus.org#", + "atomUri": "ostatus:atomUri", + "inReplyToAtomUri": "ostatus:inReplyToAtomUri", + "conversation": "ostatus:conversation", + "toot": "http://joinmastodon.org/ns#", + "Emoji": "toot:Emoji", + "focalPoint": { + "@container": "@list", + "@id": "toot:focalPoint" + }, + "featured": { + "@id": "toot:featured", + "@type": "@id" + }, + "schema": "http://schema.org#", + "PropertyValue": "schema:PropertyValue", + "value": "schema:value" + } + ], + "id": "https://mastodon.social/users/twospirit#delete", + "type": "Delete", + "actor": "https://mastodon.social/users/twospirit", + "to": [ + "https://www.w3.org/ns/activitystreams#Public" + ], + "object": "https://mastodon.social/users/twospirit", + "signature": { + "type": "RsaSignature2017", + "creator": "https://mastodon.social/users/twospirit#main-key", + "created": "2018-11-26T14:33:30Z", + "signatureValue": "e20O0AYwAGLgHyb/xD1fO+v7gnE8aONFR3iMb/4ULd+Qjz4fV1/ay0IRFdatWGRP4uG/XzjdW6hJTR69wjQUag9k0JOvHkOssUHIXkmBEsKZURyEVWrjT1+Dyx1ZFwsbhjSXCkvbz70mq+1JPx2zDK+fTsG8TPIKBpvj9LYmQbF3Z4n7wRRxibCCL8oGlrHlwWwABYkZKoruLYJya9a6eVvbCD1P5TO+M1CUdMHhqez8k3ll50ZsGRlHqnojR0V9AjMixuMNMx4qvcC+wwJb4QBorfPJDh843Pw4lybwbs5/bXwErxR+Infc61w/dkyw1MvZdPYD2dy+uOHdndRRdQ==" + } +} From 378a43d23e8599587bab32718a0953adf5d2dadd Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 09:56:54 -0100 Subject: [PATCH 18/22] left join follow in search Signed-off-by: Maxence Lange --- lib/Controller/LocalController.php | 13 ++++++ lib/Db/CacheActorsRequest.php | 55 +++++++++++++++++++++-- lib/Db/CoreRequestBuilder.php | 72 +++++++++++++++++++++++++++++- 3 files changed, 134 insertions(+), 6 deletions(-) diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index eab56caa..73a05cec 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -294,12 +294,22 @@ class LocalController extends Controller { * @param string $search * * @return DataResponse + * @throws Exception */ public function accountsSearch(string $search): DataResponse { + try { + $viewer = $this->actorService->getActorFromUserId($this->userId, true); + } catch (Exception $e) { + throw new Exception(); + } + + $this->personService->setViewerId($viewer->getId()); + /* Look for an exactly matching account */ $match = null; try { $match = $this->personService->getFromAccount($search, false); + $match->setCompleteDetails(true); } catch (Exception $e) { } @@ -410,6 +420,7 @@ class LocalController extends Controller { * @NoCSRFRequired * @NoAdminRequired * @NoSubAdminRequired + * * @param string $id * @return DataResponse */ @@ -419,8 +430,10 @@ class LocalController extends Controller { if ($actor->gotIcon()) { $avatar = $actor->getIcon(); $document = $this->documentService->getFromCache($avatar->getId()); + return new FileDisplayResponse($document); } + return new NotFoundResponse(); } catch (Exception $e) { return $this->fail($e); diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index 7887ad12..b882f9d7 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -33,6 +33,7 @@ namespace OCA\Social\Db; use DateTime; use Exception; use OCA\Social\Exceptions\CacheActorDoesNotExistException; +use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ConfigService; use OCA\Social\Service\MiscService; @@ -133,14 +134,21 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { * * @param string $account * + * @param string $viewerId + * * @return Person * @throws CacheActorDoesNotExistException */ - public function getFromAccount(string $account): Person { + public function getFromAccount(string $account, string $viewerId = ''): Person { $qb = $this->getCacheActorsSelectSql(); $this->limitToAccount($qb, $account); $this->leftJoinCacheDocuments($qb, 'icon_id'); + if ($viewerId !== '') { + $this->leftJoinFollowAsViewer($qb, 'id', $viewerId, true, 'as_follower'); + $this->leftJoinFollowAsViewer($qb, 'id', $viewerId, false, 'as_followed'); + } + $cursor = $qb->execute(); $data = $cursor->fetch(); $cursor->closeCursor(); @@ -149,7 +157,21 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { throw new CacheActorDoesNotExistException(); } - return $this->parseCacheActorsSelectSql($data); + $account = $this->parseCacheActorsSelectSql($data); + + try { + $this->parseFollowLeftJoin($data, 'as_follower'); + $account->addDetailBool('follower', true); + } catch (InvalidResourceException $e) { + } + + try { + $this->parseFollowLeftJoin($data, 'as_following'); + $account->addDetailBool('following', true); + } catch (InvalidResourceException $e) { + } + + return $account; } @@ -181,18 +203,43 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { /** * @param string $search + * @param string $viewerId * * @return Person[] */ - public function searchAccounts(string $search): array { + public function searchAccounts(string $search, string $viewerId = ''): array { $qb = $this->getCacheActorsSelectSql(); $this->searchInAccount($qb, $search); $this->leftJoinCacheDocuments($qb, 'icon_id'); + if ($viewerId !== '') { + $this->leftJoinFollowAsViewer($qb, 'id', $viewerId, true, 'as_follower'); + $this->leftJoinFollowAsViewer($qb, 'id', $viewerId, false, 'as_followed'); + } + + $accounts = []; $cursor = $qb->execute(); while ($data = $cursor->fetch()) { - $accounts[] = $this->parseCacheActorsSelectSql($data); + $account = $this->parseCacheActorsSelectSql($data); + + if ($viewerId !== '') { + try { + $this->parseFollowLeftJoin($data, 'as_follower'); + $account->addDetailBool('following', true); + } catch (InvalidResourceException $e) { + } + + try { + $this->parseFollowLeftJoin($data, 'as_followed'); + $account->addDetailBool('follower', true); + } catch (InvalidResourceException $e) { + } + + $account->setCompleteDetails(true); + } + + $accounts[] = $account; } $cursor->closeCursor(); diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index 130dedd7..114dc671 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -37,6 +37,7 @@ use Doctrine\DBAL\Query\QueryBuilder; use Exception; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Model\ActivityPub\Document; +use OCA\Social\Model\ActivityPub\Follow; use OCA\Social\Model\ActivityPub\Image; use OCA\Social\Model\ActivityPub\Person; use OCA\Social\Service\ConfigService; @@ -530,7 +531,6 @@ class CoreRequestBuilder { $expr = $qb->expr(); $pf = $this->defaultSelectAlias; -// /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->selectAlias('ca.id', 'cacheactor_id') ->selectAlias('ca.type', 'cacheactor_type') ->selectAlias('ca.account', 'cacheactor_account') @@ -592,7 +592,6 @@ class CoreRequestBuilder { $expr = $qb->expr(); $pf = $this->defaultSelectAlias; -// /** @noinspection PhpMethodParametersCountMismatchInspection */ $qb->selectAlias('cd.id', 'cachedocument_id') ->selectAlias('cd.type', 'cachedocument_type') ->selectAlias('cd.mime_type', 'cachedocument_mime_type') @@ -635,6 +634,75 @@ class CoreRequestBuilder { return $document; } + + /** + * @param IQueryBuilder $qb + * @param string $fieldActorId + * @param string $viewerId + * @param bool $asFollower + * @param string $prefix + */ + protected function leftJoinFollowAsViewer( + IQueryBuilder &$qb, string $fieldActorId, string $viewerId, bool $asFollower = true, + string $prefix = 'follow' + ) { + if ($qb->getType() !== QueryBuilder::SELECT) { + return; + } + + $expr = $qb->expr(); + $pf = $this->defaultSelectAlias; + + $andX = $expr->andX(); + if ($asFollower === true) { + $andX->add($expr->eq($pf . '.' . $fieldActorId, $prefix . '_f.object_id')); + $andX->add($expr->eq($prefix . '_f.actor_id', $qb->createNamedParameter($viewerId))); + } else { + $andX->add($expr->eq($pf . '.' . $fieldActorId, $prefix . '_f.actor_id')); + $andX->add($expr->eq($prefix . '_f.object_id', $qb->createNamedParameter($viewerId))); + } + + $qb->selectAlias($prefix . '_f.id', $prefix . '_id') + ->selectAlias($prefix . '_f.type', $prefix . '_type') + ->selectAlias($prefix . '_f.actor_id', $prefix . '_actor_id') + ->selectAlias($prefix . '_f.object_id', $prefix . '_object_id') + ->selectAlias($prefix . '_f.follow_id', $prefix . '_follow_id') + ->selectAlias($prefix . '_f.creation', $prefix . '_creation') + ->leftJoin( + $this->defaultSelectAlias, CoreRequestBuilder::TABLE_SERVER_FOLLOWS, $prefix . '_f', + $andX + ); + } + + + /** + * @param array $data + * @param string $prefix + * + * @return Follow + * @throws InvalidResourceException + */ + protected function parseFollowLeftJoin(array $data, string $prefix): Follow { + $new = []; + + $length = strlen($prefix) + 1; + foreach ($data as $k => $v) { + if (substr($k, 0, $length) === $prefix . '_') { + $new[substr($k, $length)] = $v; + } + } + + $follow = new Follow(); + $follow->importFromDatabase($new); + + if ($follow->getType() !== Follow::TYPE) { + throw new InvalidResourceException(); + } + + return $follow; + } + + } From 7d8e2b106526d279447bdaea8c85e50b8bc5e48f Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 09:57:35 -0100 Subject: [PATCH 19/22] setViewerId() to specify a PoV Signed-off-by: Maxence Lange --- lib/Service/ActivityPub/PersonService.php | 33 +++++++++++++---------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/lib/Service/ActivityPub/PersonService.php b/lib/Service/ActivityPub/PersonService.php index 77575dca..c6d9a074 100644 --- a/lib/Service/ActivityPub/PersonService.php +++ b/lib/Service/ActivityPub/PersonService.php @@ -76,6 +76,10 @@ class PersonService implements ICoreService { private $miscService; + /** @var string */ + private $viewerId = ''; + + /** * UndoService constructor. * @@ -97,6 +101,18 @@ class PersonService implements ICoreService { } + /** + * @param string $viewerId + */ + public function setViewerId(string $viewerId) { + $this->viewerId = $viewerId; + } + + public function getViewerId(): string { + return $this->viewerId; + } + + /** * @param Person $actor * @param bool $refresh @@ -169,7 +185,7 @@ class PersonService implements ICoreService { public function getFromAccount(string $account, bool $retrieve = true): Person { try { - $actor = $this->cacheActorsRequest->getFromAccount($account); + $actor = $this->cacheActorsRequest->getFromAccount($account, $this->getViewerId()); } catch (CacheActorDoesNotExistException $e) { if (!$retrieve) { throw new CacheActorDoesNotExistException(); @@ -219,18 +235,7 @@ class PersonService implements ICoreService { } $actor->setSource(json_encode($object, JSON_UNESCAPED_SLASHES)); -// $actor->setPreferredUsername($this->get('preferredUsername', $object, '')); -// $actor->setPublicKey($this->get('publicKey.publicKeyPem', $object)); -// $actor->setSharedInbox($this->get('endpoints.sharedInbox', $object)); -// $actor->setAccount($actor->getPreferredUsername() . '@' . $this->get('_host', $object)); -// -// $icon = new Image($actor); -// $icon->setUrlCloud($this->configService->getCloudAddress()); -// $icon->import($this->getArray('icon', $object, [])); -// if ($icon->getType() === Image::TYPE) { -// $actor->setIcon($icon); -// } -// + return $actor; } @@ -240,7 +245,7 @@ class PersonService implements ICoreService { * @return Person[] */ public function searchCachedAccounts(string $search): array { - return $this->cacheActorsRequest->searchAccounts($search); + return $this->cacheActorsRequest->searchAccounts($search, $this->getViewerId()); } From ccf7433235bc2916e36461746a4fb58bc0b3897d Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 09:57:49 -0100 Subject: [PATCH 20/22] cleaning Signed-off-by: Maxence Lange --- lib/Model/ActivityPub/Person.php | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/lib/Model/ActivityPub/Person.php b/lib/Model/ActivityPub/Person.php index 03339d03..bfa25a16 100644 --- a/lib/Model/ActivityPub/Person.php +++ b/lib/Model/ActivityPub/Person.php @@ -386,6 +386,18 @@ class Person extends ACore implements JsonSerializable { return $this; } + /** + * @param string $detail + * @param bool $value + * + * @return Person + */ + public function addDetailBool(string $detail, bool $value): Person { + $this->details[$detail] = $value; + + return $this; + } + /** * @param array $details * @@ -424,12 +436,6 @@ class Person extends ACore implements JsonSerializable { $this->setIcon($icon); } - -// ->setCreation($this->getInt('creation', $data, 0)); - -// if ($this->getPreferredUsername() === '') { -// $this->setType('Invalid'); -// } } @@ -451,10 +457,6 @@ class Person extends ACore implements JsonSerializable { ->setFeatured($this->get('featured', $data, '')) ->setDetails($this->getArray('details', $data, [])) ->setCreation($this->getInt('creation', $data, 0)); - -// if ($this->getPreferredUsername() === '') { -// $this->setType('Invalid'); -// } } From 8b9ca910ba3b0fa7e33c664689954413f0430700 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 09:59:16 -0100 Subject: [PATCH 21/22] fixing Signed-off-by: Maxence Lange --- lib/Db/CacheActorsRequest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index b882f9d7..85c4a2e8 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -166,7 +166,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { } try { - $this->parseFollowLeftJoin($data, 'as_following'); + $this->parseFollowLeftJoin($data, 'as_followed'); $account->addDetailBool('following', true); } catch (InvalidResourceException $e) { } From c27f697f0a64ac253b938d2b4535e108b0cca7e1 Mon Sep 17 00:00:00 2001 From: Maxence Lange Date: Fri, 30 Nov 2018 10:21:11 -0100 Subject: [PATCH 22/22] cleaning Signed-off-by: Maxence Lange --- appinfo/info.xml | 2 +- lib/AppInfo/Application.php | 1 - lib/Command/QueueProcess.php | 2 -- lib/Controller/ActivityPubController.php | 7 +----- lib/Controller/ConfigController.php | 17 +++++---------- lib/Controller/LocalController.php | 3 +++ lib/Controller/NavigationController.php | 20 +++++++++--------- lib/Controller/QueueController.php | 2 -- lib/Controller/SocialPubController.php | 2 +- lib/Cron/Queue.php | 7 ------ lib/Db/CacheActorsRequest.php | 27 ------------------------ lib/Db/FollowsRequestBuilder.php | 16 -------------- lib/Db/RequestQueueRequest.php | 1 - lib/Service/ActivityPub/NoteService.php | 5 ++++- lib/Service/ActivityService.php | 4 ++++ lib/Service/ConfigService.php | 2 -- lib/Service/CurlService.php | 2 -- lib/Service/MiscService.php | 1 - lib/Service/PostService.php | 1 - lib/Service/QueueService.php | 1 + 20 files changed, 30 insertions(+), 93 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 60acb624..c6c624be 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -5,7 +5,7 @@ Social 🎉 Nextcloud becomes part of the federated social networks! - 0.0.54 + 0.0.60 agpl Maxence Lange Julius Härtl diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 243217e2..d20ff7f1 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -32,7 +32,6 @@ namespace OCA\Social\AppInfo; use OCP\AppFramework\App; -use OCP\AppFramework\IAppContainer; class Application extends App { diff --git a/lib/Command/QueueProcess.php b/lib/Command/QueueProcess.php index 780a87da..d9991b9d 100644 --- a/lib/Command/QueueProcess.php +++ b/lib/Command/QueueProcess.php @@ -31,9 +31,7 @@ declare(strict_types=1); namespace OCA\Social\Command; -use Exception; use OC\Core\Command\Base; -use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\RequestException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Service\ActivityService; diff --git a/lib/Controller/ActivityPubController.php b/lib/Controller/ActivityPubController.php index a958f7bc..83646e36 100644 --- a/lib/Controller/ActivityPubController.php +++ b/lib/Controller/ActivityPubController.php @@ -74,9 +74,6 @@ class ActivityPubController extends Controller { /** @var MiscService */ private $miscService; - /** @var NavigationController */ - private $navigationController; - /** * ActivityPubController constructor. @@ -94,13 +91,11 @@ class ActivityPubController extends Controller { IRequest $request, SocialPubController $socialPubController, ActivityService $activityService, ImportService $importService, FollowService $followService, ActorService $actorService, NotesRequest $notesRequest, - NavigationController $navigationController, MiscService $miscService ) { parent::__construct(Application::APP_NAME, $request); $this->socialPubController = $socialPubController; - $this->navigationController = $navigationController; $this->activityService = $activityService; $this->importService = $importService; @@ -258,7 +253,7 @@ class ActivityPubController extends Controller { * * @return Response */ - public function followers(string $username, $data): Response { + public function followers(string $username): Response { if (!$this->checkSourceActivityStreams()) { return $this->socialPubController->followers($username); diff --git a/lib/Controller/ConfigController.php b/lib/Controller/ConfigController.php index dc2ee989..3059ec14 100644 --- a/lib/Controller/ConfigController.php +++ b/lib/Controller/ConfigController.php @@ -25,11 +25,8 @@ declare(strict_types=1); namespace OCA\Social\Controller; -use OCA\Activity\Data; -use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Service\ConfigService; use OCP\AppFramework\Controller; -use OCP\AppFramework\Http; use OCP\AppFramework\Http\DataResponse; use OCP\IRequest; @@ -46,16 +43,12 @@ class ConfigController extends Controller { /** * @param string $cloudAddress + * * @return DataResponse */ public function setCloudAddress(string $cloudAddress): DataResponse { - try { - $this->configService->setCloudAddress($cloudAddress); - return new DataResponse([]); - } catch (SocialAppConfigException $e) { - return new DataResponse([ - 'message' => $e->getMessage() - ], Http::STATUS_BAD_REQUEST); - } + $this->configService->setCloudAddress($cloudAddress); + + return new DataResponse([]); } -} \ No newline at end of file +} diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index 73a05cec..03dba180 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -219,6 +219,9 @@ class LocalController extends Controller { * @NoAdminRequired * @NoSubAdminRequired * + * @param int $since + * @param int $limit + * * @return DataResponse */ public function streamDirect(int $since = 0, int $limit = 5): DataResponse { diff --git a/lib/Controller/NavigationController.php b/lib/Controller/NavigationController.php index b14f46bd..0911b12f 100644 --- a/lib/Controller/NavigationController.php +++ b/lib/Controller/NavigationController.php @@ -30,11 +30,9 @@ declare(strict_types=1); namespace OCA\Social\Controller; -use daita\MySmallPhpTools\Traits\TArrayTools; use daita\MySmallPhpTools\Traits\Nextcloud\TNCDataResponse; +use daita\MySmallPhpTools\Traits\TArrayTools; use Exception; -use OC\Files\Node\File; -use OC\Files\SimpleFS\SimpleFile; use OC\User\NoUserException; use OCA\Social\AppInfo\Application; use OCA\Social\Exceptions\AccountAlreadyExistsException; @@ -48,9 +46,7 @@ use OCP\AppFramework\Controller; use OCP\AppFramework\Http\ContentSecurityPolicy; use OCP\AppFramework\Http\DataResponse; use OCP\AppFramework\Http\FileDisplayResponse; -use OCP\AppFramework\Http\RedirectResponse; use OCP\AppFramework\Http\Response; -use OCP\AppFramework\Http\Template\PublicTemplateResponse; use OCP\AppFramework\Http\TemplateResponse; use OCP\IConfig; use OCP\IL10N; @@ -132,9 +128,11 @@ class NavigationController extends Controller { * @NoAdminRequired * @NoSubAdminRequired * + * @param string $path + * * @return TemplateResponse */ - public function navigate($path = ''): TemplateResponse { + public function navigate(string $path = ''): TemplateResponse { $data = [ 'serverData' => [ 'public' => false, @@ -230,10 +228,11 @@ class NavigationController extends Controller { * @NoAdminRequired * @NoSubAdminRequired * + * @param string $path + * * @return TemplateResponse - * @throws NoUserException */ - public function timeline($path = ''): TemplateResponse { + public function timeline(string $path = ''): TemplateResponse { return $this->navigate(); } @@ -244,10 +243,11 @@ class NavigationController extends Controller { * @NoAdminRequired * @NoSubAdminRequired * + * @param string $path + * * @return TemplateResponse - * @throws NoUserException */ - public function account($path = ''): TemplateResponse { + public function account(string $path = ''): TemplateResponse { return $this->navigate(); } diff --git a/lib/Controller/QueueController.php b/lib/Controller/QueueController.php index 26cdddfa..c85dee2b 100644 --- a/lib/Controller/QueueController.php +++ b/lib/Controller/QueueController.php @@ -32,12 +32,10 @@ namespace OCA\Social\Controller; use daita\MySmallPhpTools\Traits\TAsync; use OCA\Social\AppInfo\Application; -use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\RequestException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\RequestQueue; use OCA\Social\Service\ActivityService; -use OCA\Social\Service\CurlService; use OCA\Social\Service\MiscService; use OCA\Social\Service\QueueService; use OCP\AppFramework\Controller; diff --git a/lib/Controller/SocialPubController.php b/lib/Controller/SocialPubController.php index f0ddb1d4..efd35049 100644 --- a/lib/Controller/SocialPubController.php +++ b/lib/Controller/SocialPubController.php @@ -137,7 +137,7 @@ class SocialPubController extends Controller { } catch (CacheActorDoesNotExistException $e) { return new NotFoundResponse(); } catch (Exception $e) { - $this->fail($e); + return $this->fail($e); } } diff --git a/lib/Cron/Queue.php b/lib/Cron/Queue.php index 58e759a4..1dd1b8c4 100644 --- a/lib/Cron/Queue.php +++ b/lib/Cron/Queue.php @@ -31,18 +31,11 @@ declare(strict_types=1); namespace OCA\Social\Cron; -use Exception; use OC\BackgroundJob\TimedJob; use OCA\Social\AppInfo\Application; -use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\RequestException; use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Service\ActivityPub\DocumentService; -use OCA\Social\Service\ActivityPub\PersonService; use OCA\Social\Service\ActivityService; -use OCA\Social\Service\ActorService; -use OCA\Social\Service\CacheService; -use OCA\Social\Service\ConfigService; use OCA\Social\Service\MiscService; use OCA\Social\Service\QueueService; use OCP\AppFramework\QueryException; diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index 1be44384..3a9a07b0 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -201,32 +201,6 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { } - /** - * get Cached version of a local Actor, based on the preferred username - * - * @param string $account - * - * @return Person - * @throws CacheActorDoesNotExistException - */ - public function getFromLocalAccount(string $account): Person { - $qb = $this->getCacheActorsSelectSql(); - $this->limitToPreferredUsername($qb, $account); - $this->limitToLocal($qb, true); - $this->leftJoinCacheDocuments($qb, 'icon_id'); - - $cursor = $qb->execute(); - $data = $cursor->fetch(); - $cursor->closeCursor(); - - if ($data === false) { - throw new CacheActorDoesNotExistException(); - } - - return $this->parseCacheActorsSelectSql($data); - } - - /** * @param string $search * @param string $viewerId @@ -243,7 +217,6 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { $this->leftJoinFollowAsViewer($qb, 'id', $viewerId, false, 'as_followed'); } - $accounts = []; $cursor = $qb->execute(); while ($data = $cursor->fetch()) { diff --git a/lib/Db/FollowsRequestBuilder.php b/lib/Db/FollowsRequestBuilder.php index 3a1d9445..0f50b37e 100644 --- a/lib/Db/FollowsRequestBuilder.php +++ b/lib/Db/FollowsRequestBuilder.php @@ -108,22 +108,6 @@ class FollowsRequestBuilder extends CoreRequestBuilder { } - /** - * Base of the Sql Select request for Shares - * - * @return IQueryBuilder - */ - protected function countFollowsSelectSql(): IQueryBuilder { - $qb = $this->dbConnection->getQueryBuilder(); - $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') - ->from(self::TABLE_SERVER_FOLLOWS, 'f'); - - $this->defaultSelectAlias = 'f'; - - return $qb; - } - - /** * Base of the Sql Delete request * diff --git a/lib/Db/RequestQueueRequest.php b/lib/Db/RequestQueueRequest.php index 4e07ffba..941c1913 100644 --- a/lib/Db/RequestQueueRequest.php +++ b/lib/Db/RequestQueueRequest.php @@ -35,7 +35,6 @@ use DateTime; use Exception; use OCA\Social\Exceptions\QueueStatusException; use OCA\Social\Model\RequestQueue; -use OCA\Social\Service\QueueService; use OCP\DB\QueryBuilder\IQueryBuilder; diff --git a/lib/Service/ActivityPub/NoteService.php b/lib/Service/ActivityPub/NoteService.php index e457e135..ebce852b 100644 --- a/lib/Service/ActivityPub/NoteService.php +++ b/lib/Service/ActivityPub/NoteService.php @@ -336,9 +336,12 @@ class NoteService implements ICoreService { /** * @param Person $actor * + * @param int $since + * @param int $limit + * * @return Note[] */ - public function getDirectNotesForActor(Person $actor, $since, $limit): array { + public function getDirectNotesForActor(Person $actor, int $since = 0, int $limit = 5): array { return $this->notesRequest->getDirectNotesForActorId($actor->getId(), $since, $limit); } diff --git a/lib/Service/ActivityService.php b/lib/Service/ActivityService.php index 37bf5606..57ba561c 100644 --- a/lib/Service/ActivityService.php +++ b/lib/Service/ActivityService.php @@ -284,8 +284,12 @@ class ActivityService { ); } catch (ActorDoesNotExistException $e) { $this->queueService->deleteRequest($queue); + + return; } catch (Request410Exception $e) { $this->queueService->deleteRequest($queue); + + return; } try { diff --git a/lib/Service/ConfigService.php b/lib/Service/ConfigService.php index 968859dd..83741f16 100644 --- a/lib/Service/ConfigService.php +++ b/lib/Service/ConfigService.php @@ -237,8 +237,6 @@ class ConfigService { /** * @param string $cloudAddress - * - * @return string */ public function setCloudAddress(string $cloudAddress) { $this->setAppValue(self::SOCIAL_ADDRESS, $cloudAddress); diff --git a/lib/Service/CurlService.php b/lib/Service/CurlService.php index 2218a52d..e073cdf7 100644 --- a/lib/Service/CurlService.php +++ b/lib/Service/CurlService.php @@ -249,8 +249,6 @@ class CurlService { /** * @param int $code * - * @param Request $request - * * @throws Request410Exception */ private function parseRequestResultCode410(int $code) { diff --git a/lib/Service/MiscService.php b/lib/Service/MiscService.php index 0feb57fc..6be52d60 100644 --- a/lib/Service/MiscService.php +++ b/lib/Service/MiscService.php @@ -31,7 +31,6 @@ declare(strict_types=1); namespace OCA\Social\Service; -use Exception; use OC\User\NoUserException; use OCA\Social\AppInfo\Application; use OCP\ILogger; diff --git a/lib/Service/PostService.php b/lib/Service/PostService.php index 980b6089..0ea482be 100644 --- a/lib/Service/PostService.php +++ b/lib/Service/PostService.php @@ -33,7 +33,6 @@ namespace OCA\Social\Service; use Exception; use OC\User\NoUserException; use OCA\Social\Exceptions\ActorDoesNotExistException; -use OCA\Social\Exceptions\RequestException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\Post; diff --git a/lib/Service/QueueService.php b/lib/Service/QueueService.php index 36cc46dd..d7228acb 100644 --- a/lib/Service/QueueService.php +++ b/lib/Service/QueueService.php @@ -78,6 +78,7 @@ class QueueService { /** * @param array $instancePaths * @param ACore $item + * @param string $author * * @return string * @throws Exception