diff options
author | Maxence Lange <maxence@artificial-owl.com> | 2019-01-16 12:06:20 -0100 |
---|---|---|
committer | Backportbot <backportbot-noreply@rullzer.com> | 2019-01-20 22:35:38 +0000 |
commit | 83bf668b690bc1962987129d88194517e6b8c50a (patch) | |
tree | f39d77b7b06c0ef77d55e3b6960862f66beed847 | |
parent | 2ef1b97342f0388e82c5b9c87fa421d2030c0446 (diff) |
cache Actor on followed/unfollowed + following/unfollowing
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
-rw-r--r-- | lib/Command/NoteCreate.php | 3 | ||||
-rw-r--r-- | lib/Controller/LocalController.php | 8 | ||||
-rw-r--r-- | lib/Db/CacheActorsRequest.php | 7 | ||||
-rw-r--r-- | lib/Interfaces/Activity/FollowInterface.php | 18 | ||||
-rw-r--r-- | lib/Model/Post.php | 19 | ||||
-rw-r--r-- | lib/Service/AccountService.php | 46 | ||||
-rw-r--r-- | lib/Service/ActorService.php | 22 | ||||
-rw-r--r-- | lib/Service/NoteService.php | 14 | ||||
-rw-r--r-- | lib/Service/PostService.php | 36 | ||||
-rw-r--r-- | tagmention.html | 6 | ||||
-rw-r--r-- | test.json | 74 |
11 files changed, 192 insertions, 61 deletions
diff --git a/lib/Command/NoteCreate.php b/lib/Command/NoteCreate.php index 5b12d52b..1d16de9d 100644 --- a/lib/Command/NoteCreate.php +++ b/lib/Command/NoteCreate.php @@ -128,7 +128,8 @@ class NoteCreate extends Base { $replyTo = $input->getOption('replyTo'); $type = $input->getOption('type'); - $post = new Post($userId); + $actor = $this->accountService->getActorFromUserId($userId); + $post = new Post($actor); $post->setContent($content); $post->setType(($type === null) ? '' : $type); $post->setReplyTo(($replyTo === null) ? '' : $replyTo); diff --git a/lib/Controller/LocalController.php b/lib/Controller/LocalController.php index ddecb6d0..a0a7ed48 100644 --- a/lib/Controller/LocalController.php +++ b/lib/Controller/LocalController.php @@ -139,7 +139,9 @@ class LocalController extends Controller { */ public function postCreate(array $data): DataResponse { try { - $post = new Post($this->userId); + $actor = $this->accountService->getActorFromUserId($this->userId); + + $post = new Post($actor); $post->setContent($this->get('content', $data, '')); $post->setReplyTo($this->get('replyTo', $data, '')); $post->setTo($this->getArray('to', $data, [])); @@ -149,6 +151,8 @@ class LocalController extends Controller { /** @var ACore $activity */ $token = $this->postService->createPost($post, $activity); + $this->accountService->cacheLocalActorDetailCount($actor); + return $this->success( [ 'post' => $activity->getObject(), @@ -324,6 +328,7 @@ class LocalController extends Controller { try { $actor = $this->accountService->getActorFromUserId($this->userId); $this->followService->followAccount($actor, $account); + $this->accountService->cacheLocalActorDetailCount($actor); return $this->success([]); } catch (Exception $e) { @@ -343,6 +348,7 @@ class LocalController extends Controller { try { $actor = $this->accountService->getActorFromUserId($this->userId); $this->followService->unfollowAccount($actor, $account); + $this->accountService->cacheLocalActorDetailCount($actor); return $this->success([]); } catch (Exception $e) { diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index 82a2f5de..8ea1438c 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -114,8 +114,10 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { * insert cache about an Actor in database. * * @param Person $actor + * + * @return int */ - public function update(Person $actor) { + public function update(Person $actor): int { if ($actor->getCreation() > 0) { $dTime = new DateTime(); @@ -155,7 +157,8 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { $qb->set('icon_id', $qb->createNamedParameter($iconId)); $this->limitToIdString($qb, $actor->getId()); - $qb->execute(); + + return $qb->execute(); } diff --git a/lib/Interfaces/Activity/FollowInterface.php b/lib/Interfaces/Activity/FollowInterface.php index d73070a0..da6ebd49 100644 --- a/lib/Interfaces/Activity/FollowInterface.php +++ b/lib/Interfaces/Activity/FollowInterface.php @@ -53,6 +53,7 @@ use OCA\Social\Model\ActivityPub\Activity\Follow; use OCA\Social\Model\ActivityPub\Activity\Reject; use OCA\Social\Model\ActivityPub\Activity\Undo; use OCA\Social\Model\InstancePath; +use OCA\Social\Service\AccountService; use OCA\Social\Service\ActivityService; use OCA\Social\Service\CacheActorService; use OCA\Social\Service\ConfigService; @@ -68,6 +69,9 @@ class FollowInterface implements IActivityPubInterface { /** @var CacheActorService */ private $cacheActorService; + /** @var AccountService */ + private $accountService; + /** @var ActivityService */ private $activityService; @@ -83,16 +87,19 @@ class FollowInterface implements IActivityPubInterface { * * @param FollowsRequest $followsRequest * @param CacheActorService $cacheActorService + * @param AccountService $accountService * @param ActivityService $activityService * @param ConfigService $configService * @param MiscService $miscService */ public function __construct( FollowsRequest $followsRequest, CacheActorService $cacheActorService, - ActivityService $activityService, ConfigService $configService, MiscService $miscService + AccountService $accountService, ActivityService $activityService, + ConfigService $configService, MiscService $miscService ) { $this->followsRequest = $followsRequest; $this->cacheActorService = $cacheActorService; + $this->accountService = $accountService; $this->activityService = $activityService; $this->configService = $configService; $this->miscService = $miscService; @@ -127,8 +134,12 @@ class FollowInterface implements IActivityPubInterface { $this->activityService->request($accept); $this->followsRequest->accepted($follow); + + $actor = $this->cacheActorService->getFromId($follow->getObjectId()); + $this->accountService->cacheLocalActorDetailCount($actor); } catch (Exception $e) { } + } @@ -153,9 +164,8 @@ class FollowInterface implements IActivityPubInterface { $follow->checkOrigin($follow->getActorId()); try { - $knownFollow = $this->followsRequest->getByPersons( - $follow->getActorId(), $follow->getObjectId() - ); + $knownFollow = + $this->followsRequest->getByPersons($follow->getActorId(), $follow->getObjectId()); if ($knownFollow->getId() === $follow->getId() && !$knownFollow->isAccepted()) { $this->confirmFollowRequest($follow); diff --git a/lib/Model/Post.php b/lib/Model/Post.php index 422729cd..7ce1c6bd 100644 --- a/lib/Model/Post.php +++ b/lib/Model/Post.php @@ -32,6 +32,7 @@ namespace OCA\Social\Model; use daita\MySmallPhpTools\Traits\TArrayTools; use JsonSerializable; +use OCA\Social\Model\ActivityPub\Actor\Person; /** @@ -45,8 +46,8 @@ class Post implements JsonSerializable { use TArrayTools; - /** @var string */ - private $userId = ''; + /** @var Person */ + private $actor; /** @var array */ private $to = []; @@ -64,17 +65,17 @@ class Post implements JsonSerializable { /** * Post constructor. * - * @param string $userId + * @param Person $actor */ - public function __construct(string $userId = '') { - $this->userId = $userId; + public function __construct(Person $actor) { + $this->actor = $actor; } /** - * @return string + * @return Person */ - public function getUserId(): string { - return $this->userId; + public function getActor(): Person { + return $this->actor; } @@ -167,7 +168,7 @@ class Post implements JsonSerializable { */ public function jsonSerialize(): array { return [ - 'userId' => $this->getUserId(), + 'actor' => $this->getActor(), 'to' => $this->getTo(), 'replyTo' => $this->getReplyTo(), 'content' => $this->getContent(), diff --git a/lib/Service/AccountService.php b/lib/Service/AccountService.php index ff868350..dbc2d530 100644 --- a/lib/Service/AccountService.php +++ b/lib/Service/AccountService.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\ItemUnknownException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\ActivityPub\Actor\Person; @@ -194,6 +195,7 @@ class AccountService { * @throws NoUserException * @throws SocialAppConfigException * @throws UrlCloudException + * @throws ItemUnknownException */ public function createActor(string $userId, string $username) { @@ -224,18 +226,18 @@ class AccountService { $this->actorsRequest->create($actor); // generate cache. - $this->cacheLocalActorByUsername($username, true); + $this->cacheLocalActorByUsername($username); } /** * @param string $username - * @param bool $refresh * * @throws SocialAppConfigException * @throws UrlCloudException + * @throws ItemUnknownException */ - public function cacheLocalActorByUsername(string $username, bool $refresh = false) { + public function cacheLocalActorByUsername(string $username) { try { $actor = $this->getActor($username); @@ -248,14 +250,8 @@ class AccountService { $iconId = $this->documentService->cacheLocalAvatarByUsername($actor); $actor->setIconId($iconId); - $count = [ - 'followers' => $this->followsRequest->countFollowers($actor->getId()), - 'following' => $this->followsRequest->countFollowing($actor->getId()), - 'post' => $this->notesRequest->countNotesFromActorId($actor->getId()) - ]; - $actor->addDetailArray('count', $count); - - $this->actorService->cacheLocalActor($actor, $refresh); + $this->addLocalActorDetailCount($actor); + $this->actorService->cacheLocalActor($actor); } catch (ActorDoesNotExistException $e) { } } @@ -263,6 +259,32 @@ class AccountService { /** * @param Person $actor + */ + public function cacheLocalActorDetailCount(Person $actor) { + if (!$actor->isLocal()) { + return; + } + + $this->addLocalActorDetailCount($actor); + $this->actorService->cacheLocalActor($actor); + } + + + /** + * @param Person $actor + */ + public function addLocalActorDetailCount(Person &$actor) { + $count = [ + 'followers' => $this->followsRequest->countFollowers($actor->getId()), + 'following' => $this->followsRequest->countFollowing($actor->getId()), + 'post' => $this->notesRequest->countNotesFromActorId($actor->getId()) + ]; + $actor->addDetailArray('count', $count); + } + + + /** + * @param Person $actor * * @throws NoUserException */ @@ -304,7 +326,7 @@ class AccountService { $update = $this->actorsRequest->getAll(); foreach ($update as $item) { try { - $this->cacheLocalActorByUsername($item->getPreferredUsername(), true); + $this->cacheLocalActorByUsername($item->getPreferredUsername()); } catch (Exception $e) { } } diff --git a/lib/Service/ActorService.php b/lib/Service/ActorService.php index 8dea61bd..e15dbae5 100644 --- a/lib/Service/ActorService.php +++ b/lib/Service/ActorService.php @@ -33,6 +33,7 @@ namespace OCA\Social\Service; use daita\MySmallPhpTools\Traits\TArrayTools; use OCA\Social\Db\CacheActorsRequest; use OCA\Social\Db\CacheDocumentsRequest; +use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Exceptions\CacheDocumentDoesNotExistException; use OCA\Social\Model\ActivityPub\Actor\Person; @@ -106,17 +107,17 @@ class ActorService { /** * @param Person $actor - * @param bool $refresh */ - public function cacheLocalActor(Person $actor, bool $refresh = false) { - if ($refresh) { - $this->cacheActorsRequest->deleteFromId($actor->getId()); - } - + public function cacheLocalActor(Person $actor) { $actor->setLocal(true); $actor->setSource(json_encode($actor, JSON_UNESCAPED_SLASHES)); - $this->save($actor); + try { + $this->cacheActorsRequest->getFromId($actor->getId()); + $this->update($actor); + } catch (CacheActorDoesNotExistException $e) { + $this->save($actor); + } } @@ -131,10 +132,13 @@ class ActorService { /** * @param Person $actor + * + * @return int */ - public function update(Person $actor) { + public function update(Person $actor): int { $this->cacheDocumentIfNeeded($actor); - $this->cacheActorsRequest->update($actor); + + return $this->cacheActorsRequest->update($actor); } diff --git a/lib/Service/NoteService.php b/lib/Service/NoteService.php index 373dab72..db6f5afc 100644 --- a/lib/Service/NoteService.php +++ b/lib/Service/NoteService.php @@ -32,10 +32,7 @@ namespace OCA\Social\Service; use daita\MySmallPhpTools\Exceptions\MalformedArrayException; use Exception; -use OC\User\NoUserException; use OCA\Social\Db\NotesRequest; -use OCA\Social\Exceptions\AccountAlreadyExistsException; -use OCA\Social\Exceptions\ActorDoesNotExistException; use OCA\Social\Exceptions\InvalidOriginException; use OCA\Social\Exceptions\InvalidResourceException; use OCA\Social\Exceptions\ItemUnknownException; @@ -46,7 +43,6 @@ use OCA\Social\Exceptions\RequestNetworkException; use OCA\Social\Exceptions\RequestResultSizeException; use OCA\Social\Exceptions\RequestServerException; use OCA\Social\Exceptions\SocialAppConfigException; -use OCA\Social\Exceptions\UrlCloudException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; use OCA\Social\Model\ActivityPub\Object\Note; @@ -116,22 +112,16 @@ class NoteService { /** - * @param string $userId + * @param Person $actor * @param string $content * * @param string $type * * @return Note - * @throws ActorDoesNotExistException - * @throws NoUserException * @throws SocialAppConfigException - * @throws AccountAlreadyExistsException - * @throws UrlCloudException */ - public function generateNote(string $userId, string $content, string $type) { + public function generateNote(Person $actor, string $content, string $type) { $note = new Note(); - $actor = $this->accountService->getActorFromUserId($userId); - $note->setId($this->configService->generateId('@' . $actor->getPreferredUsername())); $note->setPublished(date("c")); $note->setAttributedTo( diff --git a/lib/Service/PostService.php b/lib/Service/PostService.php index b2f39ac8..a1e08e3f 100644 --- a/lib/Service/PostService.php +++ b/lib/Service/PostService.php @@ -30,9 +30,17 @@ declare(strict_types=1); namespace OCA\Social\Service; -use Exception; -use OC\User\NoUserException; -use OCA\Social\Exceptions\ActorDoesNotExistException; +use daita\MySmallPhpTools\Exceptions\MalformedArrayException; +use OCA\Social\Exceptions\InvalidOriginException; +use OCA\Social\Exceptions\InvalidResourceException; +use OCA\Social\Exceptions\ItemUnknownException; +use OCA\Social\Exceptions\NoteNotFoundException; +use OCA\Social\Exceptions\RedundancyLimitException; +use OCA\Social\Exceptions\RequestContentException; +use OCA\Social\Exceptions\RequestNetworkException; +use OCA\Social\Exceptions\RequestResultNotJsonException; +use OCA\Social\Exceptions\RequestResultSizeException; +use OCA\Social\Exceptions\RequestServerException; use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\Post; @@ -77,23 +85,29 @@ class PostService { * @param ACore $activity * * @return string - * @throws ActorDoesNotExistException - * @throws NoUserException * @throws SocialAppConfigException - * @throws Exception + * @throws InvalidOriginException + * @throws InvalidResourceException + * @throws ItemUnknownException + * @throws NoteNotFoundException + * @throws RedundancyLimitException + * @throws RequestContentException + * @throws RequestNetworkException + * @throws RequestResultNotJsonException + * @throws RequestResultSizeException + * @throws RequestServerException + * @throws MalformedArrayException */ public function createPost(Post $post, ACore &$activity = null): string { $note = $this->noteService->generateNote( - $post->getUserId(), htmlentities($post->getContent(), ENT_QUOTES), $post->getType() + $post->getActor(), htmlentities($post->getContent(), ENT_QUOTES), $post->getType() ); - + $this->noteService->replyTo($note, $post->getReplyTo()); $this->noteService->addRecipients($note, $post->getType(), $post->getTo()); - $actor = $this->actorService->getActorFromUserId($post->getUserId()); - - return $this->activityService->createActivity($actor, $note, $activity); + return $this->activityService->createActivity($post->getActor(), $note, $activity); } diff --git a/tagmention.html b/tagmention.html new file mode 100644 index 00000000..64b75028 --- /dev/null +++ b/tagmention.html @@ -0,0 +1,6 @@ +<p><span class="h-card"><a href="https://mastodon.xyz/@nextcloud" + class="u-url mention">@<span>nextcloud</span></a></span> <span class="h-card"><a + href="https://mastodon.social/@meneer" class="u-url mention">@<span>meneer</span></a></span> + Ticking boxes makes me wary; where are the brains? <a href="https://mastodon.nl/tags/gdpr" + class="mention hashtag" + rel="tag">#<span>GDPR</span></a></p> diff --git a/test.json b/test.json new file mode 100644 index 00000000..bd449578 --- /dev/null +++ b/test.json @@ -0,0 +1,74 @@ +{ + "@context": [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + { + "vcard": "http://www.w3.org/2006/vcard/ns#", + "dfrn": "http://purl.org/macgirvin/dfrn/1.0/", + "diaspora": "https://diasporafoundation.org/ns/", + "manuallyApprovesFollowers": "as:manuallyApprovesFollowers", + "sensitive": "as:sensitive", + "Hashtag": "as:Hashtag" + } + ], + "id": "https://squeet.me/objects/962c3e10-545c-3887-87f2-ac8261867719#Create", + "type": "Create", + "actor": "https://squeet.me/profile/cult", + "published": "2019-01-11T12:09:44Z", + "instrument": { + "type": "Service", + "name": "Friendica 'The Tazmans Flax-lily' 2019.01-rc-1292; https://squeet.me" + }, + "to": [ + "https://www.w3.org/ns/activitystreams#Public", + "https://test.artificial-owl.com/apps/social/@cult" + ], + "cc": [ + "https://squeet.me/followers/cult" + ], + "object": { + "id": "https://squeet.me/objects/962c3e10-545c-3887-87f2-ac8261867719", + "type": "Article", + "summary": null, + "inReplyTo": null, + "diaspora:guid": "962c3e10-545c-3887-87f2-ac8261867719", + "published": "2019-01-11T12:09:44Z", + "url": "https://squeet.me/display/962c3e10-545c-3887-87f2-ac8261867719", + "attributedTo": "https://squeet.me/profile/cult", + "sensitive": false, + "context": "https://squeet.me/objects/962c3e10-545c-3887-87f2-ac8261867719#context", + "name": "testing 2", + "content": "@<span class=\"vcard\"><a href=\"https://test.artificial-owl.com/apps/social/@cult\" class=\"url\" title=\"cult\"><span class=\"fn nickname mention\">cult</span></a></span> #<a href=\"https://squeet.me/search?tag=test\" class=\"tag\" title=\"test\">test</a> ouila", + "source": { + "content": "@[url=https://test.artificial-owl.com/apps/social/@cult]cult[/url] #[url=https://squeet.me/search?tag=test]test[/url] ouila", + "mediaType": "text/bbcode" + }, + "attachment": [], + "tag": [ + { + "type": "Hashtag", + "href": "", + "name": "#test" + }, + { + "type": "Mention", + "href": "https://test.artificial-owl.com/apps/social/@cult", + "name": "@cult@test.artificial-owl.com" + } + ], + "to": [ + "https://www.w3.org/ns/activitystreams#Public", + "https://test.artificial-owl.com/apps/social/@cult" + ], + "cc": [ + "https://squeet.me/followers/cult" + ] + }, + "signature": { + "type": "RsaSignature2017", + "nonce": "33dd0f8268d032ef3f0ca39f917304f8e71025e7290c49a094412c46d4ab4b09", + "creator": "https://squeet.me/profile/cult#main-key", + "created": "2019-01-11T12:15:14Z", + "signatureValue": "AdGwxg9snx60MTr13yS524BS2K4C24knn4raSORP5/45bCctZpW+nK9PlVqXELNukNujYyj4/NxHkEZ3rex5tOAPXUSpd86Nz4oziAdZQplhLKaIlQPstUt3Zav1I+MWSb1tDYNdx6H5Ib+3hv/onwV3WdECyN3KCbHZxMYdYfoYjbuGeYgdcRL0eXP/3v+/DcqcY4gKTuY68NHySpWfV1QkNrQCQB5GVDjpKo/K+OToxeO1J0AMk4YCjsIKbAmlO5uQaWTq2vzwKmadl6Q3h1gycerEqNd/11QDHgIsv44rV2Npo8sgQCadfsE2R4Z+W99SjHX+dPCTkYg7N+8JAIcUTx8O61+gKE82loUHOA6N39s+ziqUBuboYAS1brs9UiPkJT3LNe/2Szx5txKy1sc9NBz5wHcS1LoXzOt+XEI9G6Wp8p+zRZKtWkeL4dR7rwm3OXb0Y1t3tYaMaxuYbG9tVlLNf4N3j/nBI5XFRx9hIDp3ZM5aLlK1ZoyxPyQrJzx5txx9QeU/w2uTiSkM34N38BUC/lZn7d7YphI5LUKhqcgFAt1K+pFm0gwuOn1umf+uvQKaZhSkTKatYkj2xCbO8ToLaYBeDVE40TqUqC2ITHFzjkqPKK6q1as4wPIc/974gflIB/TMiwkKZGTC5sS7tA9FOU2+r6mfHxV/oNc=" + } +} |