cache Actor on followed/unfollowed + following/unfollowing

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
pull/340/head
Maxence Lange 2019-01-16 12:06:20 -01:00
rodzic 3a1ccc4c87
commit 4a6c8f12af
11 zmienionych plików z 192 dodań i 61 usunięć

Wyświetl plik

@ -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);

Wyświetl plik

@ -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) {

Wyświetl plik

@ -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();
}

Wyświetl plik

@ -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);

Wyświetl plik

@ -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(),

Wyświetl plik

@ -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,19 +250,39 @@ 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) {
}
}
/**
* @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
*
@ -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) {
}
}

Wyświetl plik

@ -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);
}

Wyświetl plik

@ -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(

Wyświetl plik

@ -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);
}

6
tagmention.html 100644
Wyświetl plik

@ -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>

74
test.json 100644
Wyświetl plik

@ -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="
}
}