kopia lustrzana https://github.com/nextcloud/social
Merge pull request #82 from nextcloud-gmbh/more-for-local-accounts
links between accountspull/89/head
commit
049aeec99b
|
@ -77,6 +77,13 @@
|
|||
<primary>true</primary>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>type</name>
|
||||
<type>text</type>
|
||||
<length>31</length>
|
||||
<notnull>false</notnull>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>actor_id</name>
|
||||
<type>text</type>
|
||||
|
@ -380,6 +387,13 @@
|
|||
<notnull>true</notnull>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>details</name>
|
||||
<type>text</type>
|
||||
<length>3000</length>
|
||||
<notnull>false</notnull>
|
||||
</field>
|
||||
|
||||
<field>
|
||||
<name>creation</name>
|
||||
<type>timestamp</type>
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
<name>Social</name>
|
||||
<summary>🎉 Nextcloud becomes part of the federated social networks!</summary>
|
||||
<description><![CDATA[test]]></description>
|
||||
<version>0.0.52</version>
|
||||
<version>0.0.60</version>
|
||||
<licence>agpl</licence>
|
||||
<author mail="maxence@artificial-owl.com">Maxence Lange</author>
|
||||
<author mail="jus@bitgrid.net">Julius Härtl</author>
|
||||
|
|
|
@ -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": [],
|
||||
|
|
|
@ -32,7 +32,6 @@ namespace OCA\Social\AppInfo;
|
|||
|
||||
|
||||
use OCP\AppFramework\App;
|
||||
use OCP\AppFramework\IAppContainer;
|
||||
|
||||
|
||||
class Application extends App {
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -128,7 +123,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 {
|
||||
|
@ -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);
|
||||
|
|
|
@ -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([]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
@ -294,12 +297,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 +423,7 @@ class LocalController extends Controller {
|
|||
* @NoCSRFRequired
|
||||
* @NoAdminRequired
|
||||
* @NoSubAdminRequired
|
||||
*
|
||||
* @param string $id
|
||||
* @return DataResponse
|
||||
*/
|
||||
|
@ -419,8 +433,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);
|
||||
|
|
|
@ -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,43 +243,14 @@ 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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -31,13 +31,19 @@ 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\Model\ActivityPub\Person;
|
||||
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 +51,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 +70,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 +97,48 @@ 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);
|
||||
$actor->setCompleteDetails(true);
|
||||
|
||||
$logged = false;
|
||||
$ownAccount = false;
|
||||
if ($this->userId !== null) {
|
||||
$logged = true;
|
||||
$local = $this->actorService->getActorFromUserId($this->userId, true);
|
||||
if ($local->getId() === $actor->getId()) {
|
||||
$ownAccount = true;
|
||||
} else {
|
||||
$this->fillActorWithLinks($actor, $local);
|
||||
}
|
||||
}
|
||||
|
||||
$data = [
|
||||
'serverData' => [
|
||||
'public' => true,
|
||||
],
|
||||
'actor' => $actor,
|
||||
'logged' => $logged,
|
||||
'ownAccount' => $ownAccount
|
||||
];
|
||||
|
||||
|
||||
$page = new PublicTemplateResponse(Application::APP_NAME, 'main', $data);
|
||||
$page->setHeaderTitle($this->l10n->t('Social') . ' ' . $username);
|
||||
|
||||
return $page;
|
||||
} catch (CacheActorDoesNotExistException $e) {
|
||||
return new NotFoundResponse();
|
||||
} catch (Exception $e) {
|
||||
return $this->fail($e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
@ -85,6 +86,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)
|
||||
|
@ -132,14 +134,61 @@ 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();
|
||||
|
||||
if ($data === false) {
|
||||
throw new CacheActorDoesNotExistException();
|
||||
}
|
||||
|
||||
$account = $this->parseCacheActorsSelectSql($data);
|
||||
|
||||
try {
|
||||
$this->parseFollowLeftJoin($data, 'as_follower');
|
||||
$account->addDetailBool('follower', true);
|
||||
} catch (InvalidResourceException $e) {
|
||||
}
|
||||
|
||||
try {
|
||||
$this->parseFollowLeftJoin($data, 'as_followed');
|
||||
$account->addDetailBool('following', true);
|
||||
} catch (InvalidResourceException $e) {
|
||||
}
|
||||
|
||||
return $account;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
@ -154,18 +203,42 @@ 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();
|
||||
|
||||
|
|
|
@ -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');
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
@ -134,7 +135,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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,6 +196,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 +285,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
|
||||
*
|
||||
|
@ -507,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')
|
||||
|
@ -569,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')
|
||||
|
@ -612,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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
@ -52,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()));
|
||||
|
||||
|
@ -96,6 +101,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
|
||||
*
|
||||
|
|
|
@ -83,7 +83,23 @@ 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';
|
||||
|
||||
return $qb;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 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';
|
||||
|
@ -112,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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -85,6 +85,10 @@ class Person extends ACore implements JsonSerializable {
|
|||
/** @var string */
|
||||
private $featured = '';
|
||||
|
||||
/** @var array */
|
||||
private $details = [];
|
||||
|
||||
|
||||
/**
|
||||
* Person constructor.
|
||||
*
|
||||
|
@ -339,6 +343,73 @@ 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 string $detail
|
||||
* @param bool $value
|
||||
*
|
||||
* @return Person
|
||||
*/
|
||||
public function addDetailBool(string $detail, bool $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
|
||||
*
|
||||
|
@ -365,12 +436,6 @@ class Person extends ACore implements JsonSerializable {
|
|||
$this->setIcon($icon);
|
||||
}
|
||||
|
||||
|
||||
// ->setCreation($this->getInt('creation', $data, 0));
|
||||
|
||||
// if ($this->getPreferredUsername() === '') {
|
||||
// $this->setType('Invalid');
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -390,11 +455,8 @@ 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() === '') {
|
||||
// $this->setType('Invalid');
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
@ -402,7 +464,7 @@ class Person extends ACore implements JsonSerializable {
|
|||
* @return array
|
||||
*/
|
||||
public function jsonSerialize(): array {
|
||||
return array_merge(
|
||||
$result = array_merge(
|
||||
parent::jsonSerialize(),
|
||||
[
|
||||
'aliases' => [
|
||||
|
@ -425,8 +487,12 @@ class Person extends ACore implements JsonSerializable {
|
|||
]
|
||||
]
|
||||
);
|
||||
|
||||
if ($this->isCompleteDetails()) {
|
||||
$result['details'] = $this->getDetails();
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
@ -189,6 +205,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
|
||||
*
|
||||
|
@ -208,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;
|
||||
}
|
||||
|
||||
|
@ -229,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());
|
||||
}
|
||||
|
||||
|
||||
|
@ -260,6 +276,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
|
||||
|
|
|
@ -284,8 +284,12 @@ class ActivityService {
|
|||
);
|
||||
} catch (ActorDoesNotExistException $e) {
|
||||
$this->queueService->deleteRequest($queue);
|
||||
|
||||
return;
|
||||
} catch (Request410Exception $e) {
|
||||
$this->queueService->deleteRequest($queue);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
|
|
@ -34,8 +34,11 @@ 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\FollowDoesNotExistException;
|
||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||
use OCA\Social\Model\ActivityPub\Person;
|
||||
use OCA\Social\Service\ActivityPub\PersonService;
|
||||
|
@ -55,6 +58,12 @@ class ActorService {
|
|||
/** @var ActorsRequest */
|
||||
private $actorsRequest;
|
||||
|
||||
/** @var FollowsRequest */
|
||||
private $followsRequest;
|
||||
|
||||
/** @var NotesRequest */
|
||||
private $notesRequest;
|
||||
|
||||
/** @var PersonService */
|
||||
private $personService;
|
||||
|
||||
|
@ -69,15 +78,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;
|
||||
|
@ -114,15 +127,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 +201,35 @@ class ActorService {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param Person $local
|
||||
* @param Person $actor
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @param bool $refresh
|
||||
|
@ -185,7 +238,14 @@ class ActorService {
|
|||
*/
|
||||
public function cacheLocalActorByUsername(string $username, bool $refresh = false) {
|
||||
try {
|
||||
$actor = $this->getActor($username);
|
||||
$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) {
|
||||
}
|
||||
|
|
|
@ -237,8 +237,6 @@ class ConfigService {
|
|||
|
||||
/**
|
||||
* @param string $cloudAddress
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function setCloudAddress(string $cloudAddress) {
|
||||
$this->setAppValue(self::SOCIAL_ADDRESS, $cloudAddress);
|
||||
|
|
|
@ -249,8 +249,6 @@ class CurlService {
|
|||
/**
|
||||
* @param int $code
|
||||
*
|
||||
* @param Request $request
|
||||
*
|
||||
* @throws Request410Exception
|
||||
*/
|
||||
private function parseRequestResultCode410(int $code) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -78,6 +78,7 @@ class QueueService {
|
|||
/**
|
||||
* @param array $instancePaths
|
||||
* @param ACore $item
|
||||
* @param string $author
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
|
|
|
@ -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=="
|
||||
}
|
||||
}
|
Ładowanie…
Reference in New Issue