kopia lustrzana https://github.com/nextcloud/social
Returns if a post is boosted, and allow unboost
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>pull/462/head
rodzic
36f7b7290b
commit
b4d773940c
|
@ -72,6 +72,7 @@ return [
|
||||||
['name' => 'Local#postDelete', 'url' => '/api/v1/post', 'verb' => 'DELETE'],
|
['name' => 'Local#postDelete', 'url' => '/api/v1/post', 'verb' => 'DELETE'],
|
||||||
|
|
||||||
['name' => 'Local#postBoost', 'url' => '/api/v1/post/boost', 'verb' => 'POST'],
|
['name' => 'Local#postBoost', 'url' => '/api/v1/post/boost', 'verb' => 'POST'],
|
||||||
|
['name' => 'Local#postUnboost', 'url' => '/api/v1/post/boost', 'verb' => 'DELETE'],
|
||||||
|
|
||||||
['name' => 'Local#actionFollow', 'url' => '/api/v1/current/follow', 'verb' => 'PUT'],
|
['name' => 'Local#actionFollow', 'url' => '/api/v1/current/follow', 'verb' => 'PUT'],
|
||||||
['name' => 'Local#actionUnfollow', 'url' => '/api/v1/current/follow', 'verb' => 'DELETE'],
|
['name' => 'Local#actionUnfollow', 'url' => '/api/v1/current/follow', 'verb' => 'DELETE'],
|
||||||
|
|
|
@ -30,10 +30,12 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\Social\Command;
|
namespace OCA\Social\Command;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use OC\Core\Command\Base;
|
use OC\Core\Command\Base;
|
||||||
use OCA\Social\Service\AccountService;
|
use OCA\Social\Service\AccountService;
|
||||||
use OCA\Social\Service\ActivityService;
|
use OCA\Social\Service\ActivityService;
|
||||||
|
use OCA\Social\Service\BoostService;
|
||||||
use OCA\Social\Service\ConfigService;
|
use OCA\Social\Service\ConfigService;
|
||||||
use OCA\Social\Service\CurlService;
|
use OCA\Social\Service\CurlService;
|
||||||
use OCA\Social\Service\MiscService;
|
use OCA\Social\Service\MiscService;
|
||||||
|
@ -44,6 +46,11 @@ use Symfony\Component\Console\Input\InputInterface;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NoteBoost
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Command
|
||||||
|
*/
|
||||||
class NoteBoost extends Base {
|
class NoteBoost extends Base {
|
||||||
|
|
||||||
|
|
||||||
|
@ -59,6 +66,9 @@ class NoteBoost extends Base {
|
||||||
/** @var AccountService */
|
/** @var AccountService */
|
||||||
private $accountService;
|
private $accountService;
|
||||||
|
|
||||||
|
/** @var BoostService */
|
||||||
|
private $boostService;
|
||||||
|
|
||||||
/** @var PostService */
|
/** @var PostService */
|
||||||
private $postService;
|
private $postService;
|
||||||
|
|
||||||
|
@ -70,11 +80,12 @@ class NoteBoost extends Base {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NoteCreate constructor.
|
* NoteBoost constructor.
|
||||||
*
|
*
|
||||||
* @param ActivityService $activityService
|
* @param ActivityService $activityService
|
||||||
* @param AccountService $accountService
|
* @param AccountService $accountService
|
||||||
* @param NoteService $noteService
|
* @param NoteService $noteService
|
||||||
|
* @param BoostService $boostService
|
||||||
* @param PostService $postService
|
* @param PostService $postService
|
||||||
* @param CurlService $curlService
|
* @param CurlService $curlService
|
||||||
* @param ConfigService $configService
|
* @param ConfigService $configService
|
||||||
|
@ -82,13 +93,14 @@ class NoteBoost extends Base {
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ActivityService $activityService, AccountService $accountService,
|
ActivityService $activityService, AccountService $accountService,
|
||||||
NoteService $noteService, PostService $postService, CurlService $curlService,
|
NoteService $noteService, BoostService $boostService, PostService $postService,
|
||||||
ConfigService $configService, MiscService $miscService
|
CurlService $curlService, ConfigService $configService, MiscService $miscService
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
$this->activityService = $activityService;
|
$this->activityService = $activityService;
|
||||||
$this->noteService = $noteService;
|
$this->noteService = $noteService;
|
||||||
|
$this->boostService = $boostService;
|
||||||
$this->accountService = $accountService;
|
$this->accountService = $accountService;
|
||||||
$this->postService = $postService;
|
$this->postService = $postService;
|
||||||
$this->curlService = $curlService;
|
$this->curlService = $curlService;
|
||||||
|
@ -105,6 +117,7 @@ class NoteBoost extends Base {
|
||||||
$this->setName('social:note:boost')
|
$this->setName('social:note:boost')
|
||||||
->addArgument('userid', InputArgument::REQUIRED, 'userId of the author')
|
->addArgument('userid', InputArgument::REQUIRED, 'userId of the author')
|
||||||
->addArgument('note', InputArgument::REQUIRED, 'Note to boost')
|
->addArgument('note', InputArgument::REQUIRED, 'Note to boost')
|
||||||
|
->addOption('unboost', '',InputOption::VALUE_NONE, 'Unboost')
|
||||||
->setDescription('Boost a note');
|
->setDescription('Boost a note');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +134,12 @@ class NoteBoost extends Base {
|
||||||
|
|
||||||
$actor = $this->accountService->getActorFromUserId($userId);
|
$actor = $this->accountService->getActorFromUserId($userId);
|
||||||
$this->noteService->setViewer($actor);
|
$this->noteService->setViewer($actor);
|
||||||
$token = $this->noteService->createBoost($actor, $noteId, $activity);
|
|
||||||
|
if ($input->getOption('unboost') === null) {
|
||||||
|
$activity = $this->boostService->create($actor, $noteId, $token);
|
||||||
|
} else {
|
||||||
|
$activity= $this->boostService->delete($actor, $noteId, $token );
|
||||||
|
}
|
||||||
|
|
||||||
echo 'object: ' . json_encode($activity, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
|
echo 'object: ' . json_encode($activity, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
|
||||||
echo 'token: ' . $token . "\n";
|
echo 'token: ' . $token . "\n";
|
||||||
|
|
|
@ -30,6 +30,7 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace OCA\Social\Command;
|
namespace OCA\Social\Command;
|
||||||
|
|
||||||
|
|
||||||
use Exception;
|
use Exception;
|
||||||
use OC\Core\Command\Base;
|
use OC\Core\Command\Base;
|
||||||
use OCA\Social\Model\Post;
|
use OCA\Social\Model\Post;
|
||||||
|
@ -45,6 +46,11 @@ use Symfony\Component\Console\Input\InputOption;
|
||||||
use Symfony\Component\Console\Output\OutputInterface;
|
use Symfony\Component\Console\Output\OutputInterface;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class NoteCreate
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Command
|
||||||
|
*/
|
||||||
class NoteCreate extends Base {
|
class NoteCreate extends Base {
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,9 +84,8 @@ class NoteCreate extends Base {
|
||||||
* @param MiscService $miscService
|
* @param MiscService $miscService
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
ActivityService $activityService, AccountService $accountService,
|
ActivityService $activityService, AccountService $accountService, PostService $postService,
|
||||||
PostService $postService, CurlService $curlService,
|
CurlService $curlService, ConfigService $configService, MiscService $miscService
|
||||||
ConfigService $configService, MiscService $miscService
|
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
@ -142,7 +147,7 @@ class NoteCreate extends Base {
|
||||||
$post->addTo(($to === null) ? '' : $to);
|
$post->addTo(($to === null) ? '' : $to);
|
||||||
$post->setHashtags(($hashtag === null) ? [] : [$hashtag]);
|
$post->setHashtags(($hashtag === null) ? [] : [$hashtag]);
|
||||||
|
|
||||||
$token = $this->postService->createPost($post, $activity);
|
$activity = $this->postService->createPost($post, $token);
|
||||||
|
|
||||||
echo 'object: ' . json_encode($activity, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
|
echo 'object: ' . json_encode($activity, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES) . "\n";
|
||||||
echo 'token: ' . $token . "\n";
|
echo 'token: ' . $token . "\n";
|
||||||
|
|
|
@ -41,6 +41,7 @@ use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
use OCA\Social\Model\ActivityPub\Stream;
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
use OCA\Social\Model\Post;
|
use OCA\Social\Model\Post;
|
||||||
use OCA\Social\Service\AccountService;
|
use OCA\Social\Service\AccountService;
|
||||||
|
use OCA\Social\Service\BoostService;
|
||||||
use OCA\Social\Service\CacheActorService;
|
use OCA\Social\Service\CacheActorService;
|
||||||
use OCA\Social\Service\DocumentService;
|
use OCA\Social\Service\DocumentService;
|
||||||
use OCA\Social\Service\FollowService;
|
use OCA\Social\Service\FollowService;
|
||||||
|
@ -77,6 +78,9 @@ class LocalController extends Controller {
|
||||||
/** @var FollowService */
|
/** @var FollowService */
|
||||||
private $followService;
|
private $followService;
|
||||||
|
|
||||||
|
/** @var BoostService */
|
||||||
|
private $boostService;
|
||||||
|
|
||||||
/** @var PostService */
|
/** @var PostService */
|
||||||
private $postService;
|
private $postService;
|
||||||
|
|
||||||
|
@ -111,6 +115,7 @@ class LocalController extends Controller {
|
||||||
* @param PostService $postService
|
* @param PostService $postService
|
||||||
* @param NoteService $noteService
|
* @param NoteService $noteService
|
||||||
* @param SearchService $searchService
|
* @param SearchService $searchService
|
||||||
|
* @param BoostService $boostService
|
||||||
* @param DocumentService $documentService
|
* @param DocumentService $documentService
|
||||||
* @param MiscService $miscService
|
* @param MiscService $miscService
|
||||||
*/
|
*/
|
||||||
|
@ -118,7 +123,7 @@ class LocalController extends Controller {
|
||||||
IRequest $request, $userId, AccountService $accountService,
|
IRequest $request, $userId, AccountService $accountService,
|
||||||
CacheActorService $cacheActorService, FollowService $followService,
|
CacheActorService $cacheActorService, FollowService $followService,
|
||||||
PostService $postService, NoteService $noteService, SearchService $searchService,
|
PostService $postService, NoteService $noteService, SearchService $searchService,
|
||||||
DocumentService $documentService, MiscService $miscService
|
BoostService $boostService, DocumentService $documentService, MiscService $miscService
|
||||||
) {
|
) {
|
||||||
parent::__construct(Application::APP_NAME, $request);
|
parent::__construct(Application::APP_NAME, $request);
|
||||||
|
|
||||||
|
@ -129,6 +134,7 @@ class LocalController extends Controller {
|
||||||
$this->searchService = $searchService;
|
$this->searchService = $searchService;
|
||||||
$this->postService = $postService;
|
$this->postService = $postService;
|
||||||
$this->followService = $followService;
|
$this->followService = $followService;
|
||||||
|
$this->boostService = $boostService;
|
||||||
$this->documentService = $documentService;
|
$this->documentService = $documentService;
|
||||||
$this->miscService = $miscService;
|
$this->miscService = $miscService;
|
||||||
}
|
}
|
||||||
|
@ -156,7 +162,7 @@ class LocalController extends Controller {
|
||||||
$post->setHashtags($this->getArray('hashtags', $data, []));
|
$post->setHashtags($this->getArray('hashtags', $data, []));
|
||||||
|
|
||||||
/** @var ACore $activity */
|
/** @var ACore $activity */
|
||||||
$token = $this->postService->createPost($post, $activity);
|
$activity = $this->postService->createPost($post, $token);
|
||||||
|
|
||||||
return $this->success(
|
return $this->success(
|
||||||
[
|
[
|
||||||
|
@ -208,8 +214,34 @@ class LocalController extends Controller {
|
||||||
public function postBoost(string $postId): DataResponse {
|
public function postBoost(string $postId): DataResponse {
|
||||||
try {
|
try {
|
||||||
$this->initViewer(true);
|
$this->initViewer(true);
|
||||||
|
$announce = $this->boostService->create($this->viewer, $postId, $token);
|
||||||
|
|
||||||
$token = $this->noteService->createBoost($this->viewer, $postId, $announce);
|
return $this->success(
|
||||||
|
[
|
||||||
|
'boost' => $announce,
|
||||||
|
'token' => $token
|
||||||
|
]
|
||||||
|
);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
return $this->fail($e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a boost.
|
||||||
|
*
|
||||||
|
* @NoAdminRequired
|
||||||
|
*
|
||||||
|
* @param string $postId
|
||||||
|
*
|
||||||
|
* @return DataResponse
|
||||||
|
*/
|
||||||
|
public function postUnboost(string $postId): DataResponse {
|
||||||
|
try {
|
||||||
|
$this->initViewer(true);
|
||||||
|
|
||||||
|
$token = $this->boostService->delete($this->viewer, $postId, $announce);
|
||||||
|
|
||||||
return $this->success(
|
return $this->success(
|
||||||
[
|
[
|
||||||
|
|
|
@ -36,10 +36,11 @@ use DateTime;
|
||||||
use Doctrine\DBAL\Query\QueryBuilder;
|
use Doctrine\DBAL\Query\QueryBuilder;
|
||||||
use Exception;
|
use Exception;
|
||||||
use OCA\Social\Exceptions\InvalidResourceException;
|
use OCA\Social\Exceptions\InvalidResourceException;
|
||||||
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Document;
|
use OCA\Social\Model\ActivityPub\Object\Document;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Follow;
|
use OCA\Social\Model\ActivityPub\Object\Follow;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Image;
|
use OCA\Social\Model\ActivityPub\Object\Image;
|
||||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
use OCA\Social\Model\StreamAction;
|
||||||
use OCA\Social\Service\ConfigService;
|
use OCA\Social\Service\ConfigService;
|
||||||
use OCA\Social\Service\MiscService;
|
use OCA\Social\Service\MiscService;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
|
@ -65,6 +66,8 @@ class CoreRequestBuilder {
|
||||||
const TABLE_CACHE_DOCUMENTS = 'social_cache_documents';
|
const TABLE_CACHE_DOCUMENTS = 'social_cache_documents';
|
||||||
|
|
||||||
const TABLE_QUEUE_STREAM = 'social_queue_stream';
|
const TABLE_QUEUE_STREAM = 'social_queue_stream';
|
||||||
|
const TABLE_STREAM_ACTIONS = 'social_stream_actions';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** @var IDBConnection */
|
/** @var IDBConnection */
|
||||||
|
@ -161,6 +164,28 @@ class CoreRequestBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the request to the StreamId
|
||||||
|
*
|
||||||
|
* @param IQueryBuilder $qb
|
||||||
|
* @param string $streamId
|
||||||
|
*/
|
||||||
|
protected function limitToStreamId(IQueryBuilder &$qb, string $streamId) {
|
||||||
|
$this->limitToDBField($qb, 'user_id', $streamId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit the request to the Type
|
||||||
|
*
|
||||||
|
* @param IQueryBuilder $qb
|
||||||
|
* @param string $type
|
||||||
|
*/
|
||||||
|
protected function limitToType(IQueryBuilder &$qb, string $type) {
|
||||||
|
$this->limitToDBField($qb, 'type', $type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Limit the request to the Preferred Username
|
* Limit the request to the Preferred Username
|
||||||
*
|
*
|
||||||
|
@ -410,6 +435,8 @@ class CoreRequestBuilder {
|
||||||
* @param IQueryBuilder $qb
|
* @param IQueryBuilder $qb
|
||||||
* @param int $since
|
* @param int $since
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function limitPaginate(IQueryBuilder &$qb, int $since = 0, int $limit = 5) {
|
protected function limitPaginate(IQueryBuilder &$qb, int $since = 0, int $limit = 5) {
|
||||||
if ($since > 0) {
|
if ($since > 0) {
|
||||||
|
@ -547,6 +574,8 @@ class CoreRequestBuilder {
|
||||||
* @param IQueryBuilder $qb
|
* @param IQueryBuilder $qb
|
||||||
* @param int $timestamp
|
* @param int $timestamp
|
||||||
* @param string $field
|
* @param string $field
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function limitToSince(IQueryBuilder $qb, int $timestamp, string $field) {
|
protected function limitToSince(IQueryBuilder $qb, int $timestamp, string $field) {
|
||||||
$dTime = new \DateTime();
|
$dTime = new \DateTime();
|
||||||
|
@ -666,6 +695,65 @@ class CoreRequestBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IQueryBuilder $qb
|
||||||
|
*/
|
||||||
|
protected function leftJoinStreamAction(IQueryBuilder &$qb) {
|
||||||
|
if ($qb->getType() !== QueryBuilder::SELECT || $this->viewer === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$expr = $qb->expr();
|
||||||
|
$func = $qb->func();
|
||||||
|
|
||||||
|
$pf = $this->defaultSelectAlias;
|
||||||
|
|
||||||
|
$qb->selectAlias('sa.id', 'streamaction_id')
|
||||||
|
->selectAlias('sa.actor_id', 'streamaction_actor_id')
|
||||||
|
->selectAlias('sa.stream_id', 'streamaction_stream_id')
|
||||||
|
->selectAlias('sa.values', 'streamaction_values');
|
||||||
|
|
||||||
|
$andX = $expr->andX();
|
||||||
|
$andX->add($expr->eq($func->lower($pf . '.id'), $func->lower('sa.stream_id')));
|
||||||
|
$andX->add(
|
||||||
|
$expr->eq(
|
||||||
|
$func->lower('sa.actor_id'),
|
||||||
|
$qb->createNamedParameter(strtolower($this->viewer->getId()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->leftJoin(
|
||||||
|
$this->defaultSelectAlias, CoreRequestBuilder::TABLE_STREAM_ACTIONS, 'sa',
|
||||||
|
$andX
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
* @throws InvalidResourceException
|
||||||
|
*/
|
||||||
|
protected function parseStreamActionsLeftJoin(array $data): StreamAction {
|
||||||
|
$new = [];
|
||||||
|
foreach ($data as $k => $v) {
|
||||||
|
if (substr($k, 0, 13) === 'streamaction_') {
|
||||||
|
$new[substr($k, 13)] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$action = new StreamAction();
|
||||||
|
$action->importFromDatabase($new);
|
||||||
|
|
||||||
|
if ($action->getId() === 0) {
|
||||||
|
throw new InvalidResourceException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $action;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param IQueryBuilder $qb
|
* @param IQueryBuilder $qb
|
||||||
* @param string $fieldDocumentId
|
* @param string $fieldDocumentId
|
||||||
|
@ -704,12 +792,12 @@ class CoreRequestBuilder {
|
||||||
*/
|
*/
|
||||||
protected function parseCacheDocumentsLeftJoin(array $data): Document {
|
protected function parseCacheDocumentsLeftJoin(array $data): Document {
|
||||||
$new = [];
|
$new = [];
|
||||||
|
|
||||||
foreach ($data as $k => $v) {
|
foreach ($data as $k => $v) {
|
||||||
if (substr($k, 0, 14) === 'cachedocument_') {
|
if (substr($k, 0, 14) === 'cachedocument_') {
|
||||||
$new[substr($k, 14)] = $v;
|
$new[substr($k, 14)] = $v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$document = new Document();
|
$document = new Document();
|
||||||
$document->importFromDatabase($new);
|
$document->importFromDatabase($new);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ namespace OCA\Social\Db;
|
||||||
use daita\MySmallPhpTools\Model\Cache;
|
use daita\MySmallPhpTools\Model\Cache;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
use Doctrine\DBAL\Exception\UniqueConstraintViolationException;
|
||||||
|
use Exception;
|
||||||
use OCA\Social\Exceptions\NoteNotFoundException;
|
use OCA\Social\Exceptions\NoteNotFoundException;
|
||||||
use OCA\Social\Model\ActivityPub\ACore;
|
use OCA\Social\Model\ActivityPub\ACore;
|
||||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
|
@ -62,6 +63,8 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Stream $stream
|
* @param Stream $stream
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function save(Stream $stream) {
|
public function save(Stream $stream) {
|
||||||
$qb = $this->saveStream($stream);
|
$qb = $this->saveStream($stream);
|
||||||
|
@ -103,10 +106,10 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @param bool $asViewer
|
* @param bool $asViewer
|
||||||
*
|
*
|
||||||
* @return Note
|
* @return Stream
|
||||||
* @throws NoteNotFoundException
|
* @throws NoteNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getNoteById(string $id, bool $asViewer = false): Note {
|
public function getNoteById(string $id, bool $asViewer = false): Stream {
|
||||||
if ($id === '') {
|
if ($id === '') {
|
||||||
throw new NoteNotFoundException();
|
throw new NoteNotFoundException();
|
||||||
};
|
};
|
||||||
|
@ -116,6 +119,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
|
|
||||||
if ($asViewer) {
|
if ($asViewer) {
|
||||||
$this->limitToViewer($qb);
|
$this->limitToViewer($qb);
|
||||||
|
$this->leftJoinStreamAction($qb);
|
||||||
}
|
}
|
||||||
|
|
||||||
$cursor = $qb->execute();
|
$cursor = $qb->execute();
|
||||||
|
@ -133,10 +137,10 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
/**
|
/**
|
||||||
* @param string $id
|
* @param string $id
|
||||||
*
|
*
|
||||||
* @return Note
|
* @return Stream
|
||||||
* @throws NoteNotFoundException
|
* @throws NoteNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getNoteByActivityId(string $id): Note {
|
public function getNoteByActivityId(string $id): Stream {
|
||||||
if ($id === '') {
|
if ($id === '') {
|
||||||
throw new NoteNotFoundException();
|
throw new NoteNotFoundException();
|
||||||
};
|
};
|
||||||
|
@ -156,6 +160,37 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Person $actor
|
||||||
|
* @param string $type
|
||||||
|
*
|
||||||
|
* @param string $objectId
|
||||||
|
*
|
||||||
|
* @return Stream
|
||||||
|
* @throws NoteNotFoundException
|
||||||
|
*/
|
||||||
|
public function getNoteByObjectId(Person $actor, string $type, string $objectId): Stream {
|
||||||
|
if ($objectId === '') {
|
||||||
|
throw new NoteNotFoundException('missing objectId');
|
||||||
|
};
|
||||||
|
|
||||||
|
$qb = $this->getNotesSelectSql();
|
||||||
|
$this->limitToObjectId($qb, $objectId);
|
||||||
|
$this->limitToType($qb, $type);
|
||||||
|
$this->limitToActorId($qb, $actor->getId());
|
||||||
|
|
||||||
|
$cursor = $qb->execute();
|
||||||
|
$data = $cursor->fetch();
|
||||||
|
$cursor->closeCursor();
|
||||||
|
|
||||||
|
if ($data === false) {
|
||||||
|
throw new NoteNotFoundException('Post not found');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->parseNotesSelectSql($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $actorId
|
* @param string $actorId
|
||||||
*
|
*
|
||||||
|
@ -182,7 +217,8 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $since
|
* @param int $since
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return Stream[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamHome(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamHome(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
$qb = $this->getNotesSelectSql();
|
$qb = $this->getNotesSelectSql();
|
||||||
|
@ -190,6 +226,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
$this->joinFollowing($qb, $actor);
|
$this->joinFollowing($qb, $actor);
|
||||||
$this->limitPaginate($qb, $since, $limit);
|
$this->limitPaginate($qb, $since, $limit);
|
||||||
$this->leftJoinCacheActors($qb, 'attributed_to');
|
$this->leftJoinCacheActors($qb, 'attributed_to');
|
||||||
|
$this->leftJoinStreamAction($qb);
|
||||||
|
|
||||||
$notes = [];
|
$notes = [];
|
||||||
$cursor = $qb->execute();
|
$cursor = $qb->execute();
|
||||||
|
@ -215,6 +252,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
$qb = $this->getNotesSelectSql();
|
$qb = $this->getNotesSelectSql();
|
||||||
|
@ -244,6 +282,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
||||||
$qb = $this->getNotesSelectSql();
|
$qb = $this->getNotesSelectSql();
|
||||||
|
@ -273,6 +312,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
$qb = $this->getNotesSelectSql();
|
$qb = $this->getNotesSelectSql();
|
||||||
|
@ -304,6 +344,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param bool $localOnly
|
* @param bool $localOnly
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamTimeline(int $since = 0, int $limit = 5, bool $localOnly = true
|
public function getStreamTimeline(int $since = 0, int $limit = 5, bool $localOnly = true
|
||||||
): array {
|
): array {
|
||||||
|
@ -339,6 +380,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return array
|
* @return array
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamTag(Person $actor, string $hashtag, int $since = 0, int $limit = 5
|
public function getStreamTag(Person $actor, string $hashtag, int $since = 0, int $limit = 5
|
||||||
): array {
|
): array {
|
||||||
|
@ -369,6 +411,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param int $since
|
* @param int $since
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getNotesSince(int $since): array {
|
public function getNotesSince(int $since): array {
|
||||||
$qb = $this->getNotesSelectSql();
|
$qb = $this->getNotesSelectSql();
|
||||||
|
@ -413,6 +456,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
* @param Stream $note
|
* @param Stream $note
|
||||||
*
|
*
|
||||||
* @return IQueryBuilder
|
* @return IQueryBuilder
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function saveStream(Stream $note): IQueryBuilder {
|
public function saveStream(Stream $note): IQueryBuilder {
|
||||||
$dTime = new DateTime();
|
$dTime = new DateTime();
|
||||||
|
@ -423,6 +467,12 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
$cache = json_encode($note->getCache(), JSON_UNESCAPED_SLASHES);
|
$cache = json_encode($note->getCache(), JSON_UNESCAPED_SLASHES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$attributedTo = $note->getAttributedTo();
|
||||||
|
if ($attributedTo === '' && $note->isLocal()) {
|
||||||
|
$attributedTo = $note->getActor()
|
||||||
|
->getId();
|
||||||
|
}
|
||||||
|
|
||||||
$qb = $this->getNotesInsertSql();
|
$qb = $this->getNotesInsertSql();
|
||||||
$qb->setValue('id', $qb->createNamedParameter($note->getId()))
|
$qb->setValue('id', $qb->createNamedParameter($note->getId()))
|
||||||
->setValue('type', $qb->createNamedParameter($note->getType()))
|
->setValue('type', $qb->createNamedParameter($note->getType()))
|
||||||
|
@ -448,7 +498,7 @@ class NotesRequest extends NotesRequestBuilder {
|
||||||
->setValue(
|
->setValue(
|
||||||
'published_time', $qb->createNamedParameter($dTime, IQueryBuilder::PARAM_DATE)
|
'published_time', $qb->createNamedParameter($dTime, IQueryBuilder::PARAM_DATE)
|
||||||
)
|
)
|
||||||
->setValue('attributed_to', $qb->createNamedParameter($note->getAttributedTo()))
|
->setValue('attributed_to', $qb->createNamedParameter($attributedTo))
|
||||||
->setValue('in_reply_to', $qb->createNamedParameter($note->getInReplyTo()))
|
->setValue('in_reply_to', $qb->createNamedParameter($note->getInReplyTo()))
|
||||||
->setValue('source', $qb->createNamedParameter($note->getSource()))
|
->setValue('source', $qb->createNamedParameter($note->getSource()))
|
||||||
->setValue('object_id', $qb->createNamedParameter($note->getObjectId()))
|
->setValue('object_id', $qb->createNamedParameter($note->getObjectId()))
|
||||||
|
|
|
@ -36,6 +36,7 @@ use OCA\Social\Exceptions\InvalidResourceException;
|
||||||
use OCA\Social\Model\ActivityPub\ACore;
|
use OCA\Social\Model\ActivityPub\ACore;
|
||||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||||
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
use OCA\Social\Model\InstancePath;
|
use OCA\Social\Model\InstancePath;
|
||||||
use OCP\DB\QueryBuilder\ICompositeExpression;
|
use OCP\DB\QueryBuilder\ICompositeExpression;
|
||||||
use OCP\DB\QueryBuilder\IQueryBuilder;
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
|
@ -353,9 +354,9 @@ class NotesRequestBuilder extends CoreRequestBuilder {
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
*
|
*
|
||||||
* @return Note
|
* @return Stream
|
||||||
*/
|
*/
|
||||||
protected function parseNotesSelectSql($data): Note {
|
protected function parseNotesSelectSql($data): Stream {
|
||||||
$note = new Note();
|
$note = new Note();
|
||||||
$note->importFromDatabase($data);
|
$note->importFromDatabase($data);
|
||||||
|
|
||||||
|
@ -375,6 +376,12 @@ class NotesRequestBuilder extends CoreRequestBuilder {
|
||||||
} catch (InvalidResourceException $e) {
|
} catch (InvalidResourceException $e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$action = $this->parseStreamActionsLeftJoin($data);
|
||||||
|
$note->setAction($action);
|
||||||
|
} catch (InvalidResourceException $e) {
|
||||||
|
}
|
||||||
|
|
||||||
return $note;
|
return $note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,118 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Social\Db;
|
||||||
|
|
||||||
|
|
||||||
|
use OCA\Social\Exceptions\StreamActionDoesNotExistException;
|
||||||
|
use OCA\Social\Model\StreamAction;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StreamActionsRequest
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Db
|
||||||
|
*/
|
||||||
|
class StreamActionsRequest extends StreamActionsRequestBuilder {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new Queue in the database.
|
||||||
|
*
|
||||||
|
* @param StreamAction $action
|
||||||
|
*/
|
||||||
|
public function create(StreamAction $action) {
|
||||||
|
$qb = $this->getStreamActionInsertSql();
|
||||||
|
$qb->setValue('actor_id', $qb->createNamedParameter($action->getActorId()))
|
||||||
|
->setValue('stream_id', $qb->createNamedParameter($action->getStreamId()))
|
||||||
|
->setValue(
|
||||||
|
'values', $qb->createNamedParameter(
|
||||||
|
json_encode($action->getValues(), JSON_UNESCAPED_SLASHES)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
$qb->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a new Queue in the database.
|
||||||
|
*
|
||||||
|
* @param StreamAction $action
|
||||||
|
*/
|
||||||
|
public function update(StreamAction $action) {
|
||||||
|
$qb = $this->getStreamActionUpdateSql();
|
||||||
|
|
||||||
|
$values = json_encode($action->getValues(), JSON_UNESCAPED_SLASHES);
|
||||||
|
$qb->set('values', $qb->createNamedParameter($values));
|
||||||
|
|
||||||
|
$this->limitToActorId($qb, $action->getActorId());
|
||||||
|
$this->limitToStreamId($qb, $action->getStreamId());
|
||||||
|
|
||||||
|
$qb->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $actorId
|
||||||
|
* @param string $streamId
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
* @throws StreamActionDoesNotExistException
|
||||||
|
*/
|
||||||
|
public function getAction(string $actorId, string $streamId): StreamAction {
|
||||||
|
$qb = $this->getStreamActionDeleteSql();
|
||||||
|
$this->limitToActorId($qb, $actorId);
|
||||||
|
$this->limitToStreamId($qb, $streamId);
|
||||||
|
|
||||||
|
$cursor = $qb->execute();
|
||||||
|
$data = $cursor->fetch();
|
||||||
|
if ($data === false) {
|
||||||
|
throw new StreamActionDoesNotExistException();
|
||||||
|
}
|
||||||
|
$cursor->closeCursor();
|
||||||
|
|
||||||
|
return $this->parseStreamActionsSelectSql($data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param StreamAction $action
|
||||||
|
*/
|
||||||
|
public function delete(StreamAction $action) {
|
||||||
|
$qb = $this->getStreamActionDeleteSql();
|
||||||
|
$this->limitToActorId($qb, $action->getActorId());
|
||||||
|
$this->limitToStreamId($qb, $action->getStreamId());
|
||||||
|
|
||||||
|
$qb->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,120 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Social\Db;
|
||||||
|
|
||||||
|
|
||||||
|
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||||
|
use OCA\Social\Model\RequestQueue;
|
||||||
|
use OCA\Social\Model\StreamAction;
|
||||||
|
use OCP\DB\QueryBuilder\IQueryBuilder;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StreamActionsRequestBuilder
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Db
|
||||||
|
*/
|
||||||
|
class StreamActionsRequestBuilder extends CoreRequestBuilder {
|
||||||
|
|
||||||
|
|
||||||
|
use TArrayTools;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base of the Sql Insert request
|
||||||
|
*
|
||||||
|
* @return IQueryBuilder
|
||||||
|
*/
|
||||||
|
protected function getStreamActionInsertSql(): IQueryBuilder {
|
||||||
|
$qb = $this->dbConnection->getQueryBuilder();
|
||||||
|
$qb->insert(self::TABLE_STREAM_ACTIONS);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base of the Sql Update request
|
||||||
|
*
|
||||||
|
* @return IQueryBuilder
|
||||||
|
*/
|
||||||
|
protected function getStreamActionUpdateSql(): IQueryBuilder {
|
||||||
|
$qb = $this->dbConnection->getQueryBuilder();
|
||||||
|
$qb->update(self::TABLE_STREAM_ACTIONS);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base of the Sql Select request for Shares
|
||||||
|
*
|
||||||
|
* @return IQueryBuilder
|
||||||
|
*/
|
||||||
|
protected function getStreamActionSelectSql(): IQueryBuilder {
|
||||||
|
$qb = $this->dbConnection->getQueryBuilder();
|
||||||
|
|
||||||
|
/** @noinspection PhpMethodParametersCountMismatchInspection */
|
||||||
|
$qb->select('sa.id', 'sa.actor_id', 'sa.stream_id', 'sa.values')
|
||||||
|
->from(self::TABLE_STREAM_ACTIONS, 'sa');
|
||||||
|
|
||||||
|
$this->defaultSelectAlias = 'sa';
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base of the Sql Delete request
|
||||||
|
*
|
||||||
|
* @return IQueryBuilder
|
||||||
|
*/
|
||||||
|
protected function getStreamActionDeleteSql(): IQueryBuilder {
|
||||||
|
$qb = $this->dbConnection->getQueryBuilder();
|
||||||
|
$qb->delete(self::TABLE_STREAM_ACTIONS);
|
||||||
|
|
||||||
|
return $qb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
protected function parseStreamActionsSelectSql($data): StreamAction {
|
||||||
|
$action = new StreamAction();
|
||||||
|
$action->importFromDatabase($data);
|
||||||
|
|
||||||
|
return $action;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\Social\Exceptions;
|
||||||
|
|
||||||
|
class StreamActionDoesNotExistException extends \Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -31,12 +31,14 @@ declare(strict_types=1);
|
||||||
namespace OCA\Social\Interfaces\Object;
|
namespace OCA\Social\Interfaces\Object;
|
||||||
|
|
||||||
|
|
||||||
|
use Exception;
|
||||||
use OCA\Social\Db\NotesRequest;
|
use OCA\Social\Db\NotesRequest;
|
||||||
use OCA\Social\Exceptions\InvalidOriginException;
|
use OCA\Social\Exceptions\InvalidOriginException;
|
||||||
use OCA\Social\Exceptions\ItemNotFoundException;
|
use OCA\Social\Exceptions\ItemNotFoundException;
|
||||||
use OCA\Social\Exceptions\NoteNotFoundException;
|
use OCA\Social\Exceptions\NoteNotFoundException;
|
||||||
use OCA\Social\Interfaces\IActivityPubInterface;
|
use OCA\Social\Interfaces\IActivityPubInterface;
|
||||||
use OCA\Social\Model\ActivityPub\ACore;
|
use OCA\Social\Model\ActivityPub\ACore;
|
||||||
|
use OCA\Social\Model\ActivityPub\Activity\Undo;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Announce;
|
use OCA\Social\Model\ActivityPub\Object\Announce;
|
||||||
use OCA\Social\Model\ActivityPub\Stream;
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
use OCA\Social\Model\StreamQueue;
|
use OCA\Social\Model\StreamQueue;
|
||||||
|
@ -81,11 +83,16 @@ class AnnounceInterface implements IActivityPubInterface {
|
||||||
/**
|
/**
|
||||||
* @param ACore $activity
|
* @param ACore $activity
|
||||||
* @param ACore $item
|
* @param ACore $item
|
||||||
|
*
|
||||||
|
* @throws InvalidOriginException
|
||||||
*/
|
*/
|
||||||
public function activity(Acore $activity, ACore $item) {
|
public function activity(Acore $activity, ACore $item) {
|
||||||
/** Stream $item */
|
$item->checkOrigin($activity->getId());
|
||||||
// TODO: Manage Undo Activity
|
|
||||||
$this->miscService->log('activity: ' . json_encode($activity));
|
if ($activity->getType() === Undo::TYPE) {
|
||||||
|
$item->checkOrigin($item->getId());
|
||||||
|
$this->delete($item);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -93,6 +100,7 @@ class AnnounceInterface implements IActivityPubInterface {
|
||||||
* @param ACore $item
|
* @param ACore $item
|
||||||
*
|
*
|
||||||
* @throws InvalidOriginException
|
* @throws InvalidOriginException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function processIncomingRequest(ACore $item) {
|
public function processIncomingRequest(ACore $item) {
|
||||||
/** @var Stream $item */
|
/** @var Stream $item */
|
||||||
|
@ -119,8 +127,11 @@ class AnnounceInterface implements IActivityPubInterface {
|
||||||
throw new ItemNotFoundException();
|
throw new ItemNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ACore $item
|
* @param ACore $item
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function save(ACore $item) {
|
public function save(ACore $item) {
|
||||||
/** @var Announce $item */
|
/** @var Announce $item */
|
||||||
|
@ -142,8 +153,14 @@ class AnnounceInterface implements IActivityPubInterface {
|
||||||
* @param ACore $item
|
* @param ACore $item
|
||||||
*/
|
*/
|
||||||
public function delete(ACore $item) {
|
public function delete(ACore $item) {
|
||||||
|
try {
|
||||||
|
$stream = $this->notesRequest->getNoteById($item->getId());
|
||||||
|
if ($stream->getType() === Announce::TYPE) {
|
||||||
|
$this->notesRequest->deleteNoteById($item->getId());
|
||||||
|
}
|
||||||
|
} catch (NoteNotFoundException $e) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Social\Migration;
|
||||||
|
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use Doctrine\DBAL\Types\Type;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class Version0002Date20190313133046
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Migration
|
||||||
|
*/
|
||||||
|
class Version0002Date20190313133046 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
*
|
||||||
|
* @return null|ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
|
||||||
|
/** @var ISchemaWrapper $schema */
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
if (!$schema->hasTable('social_stream_actions')) {
|
||||||
|
$table = $schema->createTable('social_stream_actions');
|
||||||
|
$table->addColumn(
|
||||||
|
'id', Type::INTEGER, [
|
||||||
|
'autoincrement' => true,
|
||||||
|
'notnull' => true,
|
||||||
|
'length' => 11,
|
||||||
|
'unsigned' => true
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$table->addColumn(
|
||||||
|
'actor_id', 'string', [
|
||||||
|
'notnull' => true,
|
||||||
|
'length' => 127,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$table->addColumn(
|
||||||
|
'stream_id', 'string', [
|
||||||
|
'notnull' => true,
|
||||||
|
'length' => 1000,
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$table->addColumn(
|
||||||
|
'values', Type::TEXT, [
|
||||||
|
'notnull' => false
|
||||||
|
]
|
||||||
|
);
|
||||||
|
$table->setPrimaryKey(['id']);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $schema;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -33,7 +33,9 @@ namespace OCA\Social\Model\ActivityPub;
|
||||||
use daita\MySmallPhpTools\Model\Cache;
|
use daita\MySmallPhpTools\Model\Cache;
|
||||||
use daita\MySmallPhpTools\Model\CacheItem;
|
use daita\MySmallPhpTools\Model\CacheItem;
|
||||||
use DateTime;
|
use DateTime;
|
||||||
|
use Exception;
|
||||||
use JsonSerializable;
|
use JsonSerializable;
|
||||||
|
use OCA\Social\Model\StreamAction;
|
||||||
|
|
||||||
|
|
||||||
class Stream extends ACore implements JsonSerializable {
|
class Stream extends ACore implements JsonSerializable {
|
||||||
|
@ -69,6 +71,9 @@ class Stream extends ACore implements JsonSerializable {
|
||||||
/** @var int */
|
/** @var int */
|
||||||
private $publishedTime = 0;
|
private $publishedTime = 0;
|
||||||
|
|
||||||
|
/** @var StreamAction */
|
||||||
|
private $action = null;
|
||||||
|
|
||||||
|
|
||||||
public function __construct($parent = null) {
|
public function __construct($parent = null) {
|
||||||
parent::__construct($parent);
|
parent::__construct($parent);
|
||||||
|
@ -208,6 +213,7 @@ class Stream extends ACore implements JsonSerializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function convertPublished() {
|
public function convertPublished() {
|
||||||
$dTime = new DateTime($this->getPublished());
|
$dTime = new DateTime($this->getPublished());
|
||||||
|
@ -255,6 +261,37 @@ class Stream extends ACore implements JsonSerializable {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
public function getAction(): StreamAction {
|
||||||
|
return $this->action;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param StreamAction $action
|
||||||
|
*
|
||||||
|
* @return Stream
|
||||||
|
*/
|
||||||
|
public function setAction(StreamAction $action): Stream {
|
||||||
|
$this->action = $action;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasAction(): bool {
|
||||||
|
return ($this->action !== null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
public function import(array $data) {
|
public function import(array $data) {
|
||||||
parent::import($data);
|
parent::import($data);
|
||||||
|
|
||||||
|
@ -270,6 +307,8 @@ class Stream extends ACore implements JsonSerializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $data
|
* @param array $data
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function importFromDatabase(array $data) {
|
public function importFromDatabase(array $data) {
|
||||||
parent::importFromDatabase($data);
|
parent::importFromDatabase($data);
|
||||||
|
@ -310,6 +349,7 @@ class Stream extends ACore implements JsonSerializable {
|
||||||
$result = array_merge(
|
$result = array_merge(
|
||||||
$result,
|
$result,
|
||||||
[
|
[
|
||||||
|
'action' => ($this->hasAction()) ? $this->getAction() : [],
|
||||||
'cache' => ($this->gotCache()) ? $this->getCache() : '',
|
'cache' => ($this->gotCache()) ? $this->getCache() : '',
|
||||||
'publishedTime' => $this->getPublishedTime()
|
'publishedTime' => $this->getPublishedTime()
|
||||||
]
|
]
|
||||||
|
|
|
@ -0,0 +1,214 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
namespace OCA\Social\Model;
|
||||||
|
|
||||||
|
|
||||||
|
use daita\MySmallPhpTools\Traits\TArrayTools;
|
||||||
|
use daita\MySmallPhpTools\Traits\TStringTools;
|
||||||
|
use JsonSerializable;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StreamAction
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Model
|
||||||
|
*/
|
||||||
|
class StreamAction implements JsonSerializable {
|
||||||
|
|
||||||
|
|
||||||
|
use TArrayTools;
|
||||||
|
use TStringTools;
|
||||||
|
|
||||||
|
|
||||||
|
/** @var integer */
|
||||||
|
private $id = 0;
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $actorId = '';
|
||||||
|
|
||||||
|
/** @var string */
|
||||||
|
private $streamId = '';
|
||||||
|
|
||||||
|
/** @var array */
|
||||||
|
private $values = [];
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamAction constructor.
|
||||||
|
*/
|
||||||
|
public function __construct() {
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getId(): int {
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $id
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
public function setId(int $id): StreamAction {
|
||||||
|
$this->id = $id;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getActorId(): string {
|
||||||
|
return $this->actorId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $actorId
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
public function setActorId(string $actorId): StreamAction {
|
||||||
|
$this->actorId = $actorId;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStreamId(): string {
|
||||||
|
return $this->streamId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $streamId
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
public function setStreamId(string $streamId): StreamAction {
|
||||||
|
$this->streamId = $streamId;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function updateValue(string $key, string $value) {
|
||||||
|
$this->values[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
* @param int $value
|
||||||
|
*/
|
||||||
|
public function updateValueInt(string $key, int $value) {
|
||||||
|
$this->values[$key] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasValue(string $key): bool {
|
||||||
|
return (array_key_exists($key, $this->values));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getValue(string $key): string {
|
||||||
|
return $this->values[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $key
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getValueInt(string $key): int {
|
||||||
|
return $this->values[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getValues(): array {
|
||||||
|
return $this->values;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $values
|
||||||
|
*
|
||||||
|
* @return StreamAction
|
||||||
|
*/
|
||||||
|
public function setValues(array $values): StreamAction {
|
||||||
|
$this->values = $values;
|
||||||
|
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
*/
|
||||||
|
public function importFromDatabase(array $data) {
|
||||||
|
$this->setId($this->getInt('id', $data, 0));
|
||||||
|
$this->setActorId($this->get('actor_id', $data, ''));
|
||||||
|
$this->setStreamId($this->get('stream_id', $data, ''));
|
||||||
|
$this->setValues($this->getArray('values', $data, []));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function jsonSerialize(): array {
|
||||||
|
return [
|
||||||
|
'id' => $this->getId(),
|
||||||
|
'actorId' => $this->getActorId(),
|
||||||
|
'streamId' => $this->getStreamId(),
|
||||||
|
'values' => $this->getValues(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Social\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use OCA\Social\Db\NotesRequest;
|
||||||
|
use OCA\Social\Exceptions\NoteNotFoundException;
|
||||||
|
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||||
|
use OCA\Social\Model\ActivityPub\ACore;
|
||||||
|
use OCA\Social\Model\ActivityPub\Activity\Undo;
|
||||||
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
|
use OCA\Social\Model\ActivityPub\Object\Announce;
|
||||||
|
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||||
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class BoostService
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Service
|
||||||
|
*/
|
||||||
|
class BoostService {
|
||||||
|
|
||||||
|
|
||||||
|
/** @var NotesRequest */
|
||||||
|
private $notesRequest;
|
||||||
|
|
||||||
|
/** @var NoteService */
|
||||||
|
private $noteService;
|
||||||
|
|
||||||
|
/** @var SignatureService */
|
||||||
|
private $signatureService;
|
||||||
|
|
||||||
|
/** @var ActivityService */
|
||||||
|
private $activityService;
|
||||||
|
|
||||||
|
/** @var StreamActionService */
|
||||||
|
private $streamActionService;
|
||||||
|
|
||||||
|
/** @var StreamQueueService */
|
||||||
|
private $streamQueueService;
|
||||||
|
|
||||||
|
/** @var MiscService */
|
||||||
|
private $miscService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BoostService constructor.
|
||||||
|
*
|
||||||
|
* @param NotesRequest $notesRequest
|
||||||
|
* @param NoteService $noteService
|
||||||
|
* @param SignatureService $signatureService
|
||||||
|
* @param ActivityService $activityService
|
||||||
|
* @param StreamActionService $streamActionService
|
||||||
|
* @param StreamQueueService $streamQueueService
|
||||||
|
* @param MiscService $miscService
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
NotesRequest $notesRequest, NoteService $noteService, SignatureService $signatureService,
|
||||||
|
ActivityService $activityService, StreamActionService $streamActionService,
|
||||||
|
StreamQueueService $streamQueueService, MiscService $miscService
|
||||||
|
) {
|
||||||
|
$this->notesRequest = $notesRequest;
|
||||||
|
$this->noteService = $noteService;
|
||||||
|
$this->signatureService = $signatureService;
|
||||||
|
$this->activityService = $activityService;
|
||||||
|
$this->streamActionService = $streamActionService;
|
||||||
|
$this->streamQueueService = $streamQueueService;
|
||||||
|
$this->miscService = $miscService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Person $actor
|
||||||
|
* @param string $postId
|
||||||
|
* @param string $token
|
||||||
|
*
|
||||||
|
* @return ACore
|
||||||
|
* @throws NoteNotFoundException
|
||||||
|
* @throws SocialAppConfigException
|
||||||
|
*/
|
||||||
|
public function create(Person $actor, string $postId, string &$token = ''): ACore {
|
||||||
|
|
||||||
|
try {
|
||||||
|
return $this->get($actor, $postId);
|
||||||
|
} catch (NoteNotFoundException $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
$announce = new Announce();
|
||||||
|
$this->noteService->assignItem($announce, $actor, Stream::TYPE_PUBLIC);
|
||||||
|
$announce->setActor($actor);
|
||||||
|
|
||||||
|
$note = $this->noteService->getNoteById($postId, true);
|
||||||
|
if ($note->getType() !== Note::TYPE) {
|
||||||
|
throw new NoteNotFoundException('Stream is not a Note');
|
||||||
|
}
|
||||||
|
|
||||||
|
$announce->addCc($note->getAttributedTo());
|
||||||
|
if ($note->isLocal()) {
|
||||||
|
$announce->setObject($note);
|
||||||
|
} else {
|
||||||
|
$announce->setObjectId($note->getId());
|
||||||
|
$announce->addCacheItem($note->getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->notesRequest->save($announce);
|
||||||
|
|
||||||
|
$this->streamActionService->setActionBool($actor->getActorId(), $postId, 'boosted', true);
|
||||||
|
$this->signatureService->signObject($actor, $announce);
|
||||||
|
$token = $this->activityService->request($announce);
|
||||||
|
|
||||||
|
$this->streamQueueService->cacheStreamByToken($token);
|
||||||
|
|
||||||
|
return $announce;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Person $actor
|
||||||
|
* @param string $postId
|
||||||
|
*
|
||||||
|
* @return Stream
|
||||||
|
* @throws NoteNotFoundException
|
||||||
|
*/
|
||||||
|
public function get(Person $actor, string $postId): Stream {
|
||||||
|
$stream = $this->notesRequest->getNoteByObjectId($actor, Announce::TYPE, $postId);
|
||||||
|
|
||||||
|
return $stream;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Person $actor
|
||||||
|
* @param string $postId
|
||||||
|
* @param ACore $undo
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws SocialAppConfigException
|
||||||
|
* @throws NoteNotFoundException
|
||||||
|
*/
|
||||||
|
public function delete(Person $actor, string $postId, ACore &$undo = null): string {
|
||||||
|
$undo = new Undo();
|
||||||
|
$this->noteService->assignItem($undo, $actor, Stream::TYPE_PUBLIC);
|
||||||
|
$undo->setActor($actor);
|
||||||
|
|
||||||
|
$note = $this->noteService->getNoteById($postId, true);
|
||||||
|
if ($note->getType() !== Note::TYPE) {
|
||||||
|
throw new NoteNotFoundException('Stream is not a Note');
|
||||||
|
}
|
||||||
|
|
||||||
|
$announce = $this->notesRequest->getNoteByObjectId($actor, Announce::TYPE, $postId);
|
||||||
|
$undo->setObject($announce);
|
||||||
|
$undo->setCcArray($announce->getCcArray());
|
||||||
|
|
||||||
|
$this->notesRequest->deleteNoteById($announce->getId());
|
||||||
|
$this->streamActionService->setActionBool($actor->getActorId(), $postId, 'boosted', false);
|
||||||
|
$this->signatureService->signObject($actor, $undo);
|
||||||
|
$token = $this->activityService->request($undo);
|
||||||
|
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ use OCA\Social\Exceptions\RequestServerException;
|
||||||
use OCA\Social\Exceptions\SocialAppConfigException;
|
use OCA\Social\Exceptions\SocialAppConfigException;
|
||||||
use OCA\Social\Model\ActivityPub\ACore;
|
use OCA\Social\Model\ActivityPub\ACore;
|
||||||
use OCA\Social\Model\ActivityPub\Actor\Person;
|
use OCA\Social\Model\ActivityPub\Actor\Person;
|
||||||
use OCA\Social\Model\ActivityPub\Object\Announce;
|
|
||||||
use OCA\Social\Model\ActivityPub\Object\Note;
|
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||||
use OCA\Social\Model\ActivityPub\Stream;
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
use OCA\Social\Model\InstancePath;
|
use OCA\Social\Model\InstancePath;
|
||||||
|
@ -122,66 +121,42 @@ class NoteService {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Person $actor
|
* @param ACore $stream
|
||||||
* @param string $postId
|
|
||||||
* @param ACore|null $announce
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
* @throws NoteNotFoundException
|
|
||||||
* @throws SocialAppConfigException
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
public function createBoost(Person $actor, string $postId, ACore &$announce = null): string {
|
|
||||||
|
|
||||||
$announce = new Announce();
|
|
||||||
$this->assignStream($announce, $actor, Stream::TYPE_PUBLIC);
|
|
||||||
$announce->setActor($actor);
|
|
||||||
|
|
||||||
$note = $this->getNoteById($postId, true);
|
|
||||||
if ($note->getType() !== Note::TYPE) {
|
|
||||||
throw new NoteNotFoundException('Stream is not a Note');
|
|
||||||
}
|
|
||||||
|
|
||||||
$announce->addCc($note->getAttributedTo());
|
|
||||||
if ($note->isLocal()) {
|
|
||||||
$announce->setObject($note);
|
|
||||||
} else {
|
|
||||||
$announce->setObjectId($note->getId());
|
|
||||||
$announce->addCacheItem($note->getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->signatureService->signObject($actor, $announce);
|
|
||||||
$token = $this->activityService->request($announce);
|
|
||||||
|
|
||||||
$this->streamQueueService->cacheStreamByToken($token);
|
|
||||||
|
|
||||||
return $token;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param Stream $stream
|
|
||||||
* @param Person $actor
|
* @param Person $actor
|
||||||
* @param string $type
|
* @param string $type
|
||||||
*
|
*
|
||||||
* @throws SocialAppConfigException
|
* @throws SocialAppConfigException
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function assignStream(Stream &$stream, Person $actor, string $type) {
|
public function assignItem(Acore &$stream, Person $actor, string $type) {
|
||||||
$stream->setId($this->configService->generateId('@' . $actor->getPreferredUsername()));
|
$stream->setId($this->configService->generateId('@' . $actor->getPreferredUsername()));
|
||||||
$stream->setPublished(date("c"));
|
$stream->setPublished(date("c"));
|
||||||
|
|
||||||
$this->setRecipient($stream, $actor, $type);
|
$this->setRecipient($stream, $actor, $type);
|
||||||
$stream->convertPublished();
|
|
||||||
$stream->setLocal(true);
|
$stream->setLocal(true);
|
||||||
|
|
||||||
|
if ($stream instanceof Stream) {
|
||||||
|
$this->assignStream($stream);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Stream $stream
|
* @param Stream $stream
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function assignStream(Stream &$stream) {
|
||||||
|
$stream->convertPublished();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ACore $stream
|
||||||
* @param Person $actor
|
* @param Person $actor
|
||||||
* @param string $type
|
* @param string $type
|
||||||
*/
|
*/
|
||||||
private function setRecipient(Stream $stream, Person $actor, string $type) {
|
private function setRecipient(ACore $stream, Person $actor, string $type) {
|
||||||
switch ($type) {
|
switch ($type) {
|
||||||
case Note::TYPE_UNLISTED:
|
case Note::TYPE_UNLISTED:
|
||||||
$stream->setTo($actor->getFollowers());
|
$stream->setTo($actor->getFollowers());
|
||||||
|
@ -370,6 +345,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamHome(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamHome(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamHome($actor, $since, $limit);
|
return $this->notesRequest->getStreamHome($actor, $since, $limit);
|
||||||
|
@ -382,6 +358,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamNotifications(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamNotifications($actor, $since, $limit);
|
return $this->notesRequest->getStreamNotifications($actor, $since, $limit);
|
||||||
|
@ -394,6 +371,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
public function getStreamAccount(string $actorId, int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamAccount($actorId, $since, $limit);
|
return $this->notesRequest->getStreamAccount($actorId, $since, $limit);
|
||||||
|
@ -406,6 +384,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
public function getStreamDirect(Person $actor, int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamDirect($actor, $since, $limit);
|
return $this->notesRequest->getStreamDirect($actor, $since, $limit);
|
||||||
|
@ -417,6 +396,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamLocalTimeline(int $since = 0, int $limit = 5): array {
|
public function getStreamLocalTimeline(int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamTimeline($since, $limit, true);
|
return $this->notesRequest->getStreamTimeline($since, $limit, true);
|
||||||
|
@ -430,6 +410,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamLocalTag(Person $actor, string $hashtag, int $since = 0, int $limit = 5
|
public function getStreamLocalTag(Person $actor, string $hashtag, int $since = 0, int $limit = 5
|
||||||
): array {
|
): array {
|
||||||
|
@ -455,6 +436,7 @@ class NoteService {
|
||||||
* @param int $limit
|
* @param int $limit
|
||||||
*
|
*
|
||||||
* @return Note[]
|
* @return Note[]
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
public function getStreamGlobalTimeline(int $since = 0, int $limit = 5): array {
|
public function getStreamGlobalTimeline(int $since = 0, int $limit = 5): array {
|
||||||
return $this->notesRequest->getStreamTimeline($since, $limit, false);
|
return $this->notesRequest->getStreamTimeline($since, $limit, false);
|
||||||
|
|
|
@ -88,26 +88,26 @@ class PostService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Post $post
|
* @param Post $post
|
||||||
* @param ACore $activity
|
* @param string $token
|
||||||
*
|
*
|
||||||
* @return string
|
* @return ACore
|
||||||
* @throws SocialAppConfigException
|
|
||||||
* @throws InvalidOriginException
|
* @throws InvalidOriginException
|
||||||
* @throws InvalidResourceException
|
* @throws InvalidResourceException
|
||||||
* @throws ItemUnknownException
|
* @throws ItemUnknownException
|
||||||
|
* @throws MalformedArrayException
|
||||||
* @throws NoteNotFoundException
|
* @throws NoteNotFoundException
|
||||||
* @throws RedundancyLimitException
|
* @throws RedundancyLimitException
|
||||||
* @throws RequestContentException
|
* @throws RequestContentException
|
||||||
* @throws RequestNetworkException
|
* @throws RequestNetworkException
|
||||||
|
* @throws RequestResultNotJsonException
|
||||||
* @throws RequestResultSizeException
|
* @throws RequestResultSizeException
|
||||||
* @throws RequestServerException
|
* @throws RequestServerException
|
||||||
* @throws MalformedArrayException
|
* @throws SocialAppConfigException
|
||||||
* @throws RequestResultNotJsonException
|
|
||||||
*/
|
*/
|
||||||
public function createPost(Post $post, ACore &$activity = null): string {
|
public function createPost(Post $post, string &$token = ''): ACore {
|
||||||
$note = new Note();
|
$note = new Note();
|
||||||
$actor = $post->getActor();
|
$actor = $post->getActor();
|
||||||
$this->noteService->assignStream($note, $actor, $post->getType());
|
$this->noteService->assignItem($note, $actor, $post->getType());
|
||||||
|
|
||||||
$note->setAttributedTo(
|
$note->setAttributedTo(
|
||||||
$this->configService->getUrlSocial() . '@' . $actor->getPreferredUsername()
|
$this->configService->getUrlSocial() . '@' . $actor->getPreferredUsername()
|
||||||
|
@ -119,10 +119,10 @@ class PostService {
|
||||||
$this->noteService->addRecipients($note, $post->getType(), $post->getTo());
|
$this->noteService->addRecipients($note, $post->getType(), $post->getTo());
|
||||||
$this->noteService->addHashtags($note, $post->getHashtags());
|
$this->noteService->addHashtags($note, $post->getHashtags());
|
||||||
|
|
||||||
$result = $this->activityService->createActivity($actor, $note, $activity);
|
$token = $this->activityService->createActivity($actor, $note, $activity);
|
||||||
$this->accountService->cacheLocalActorDetailCount($actor);
|
$this->accountService->cacheLocalActorDetailCount($actor);
|
||||||
|
|
||||||
return $result;
|
return $activity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nextcloud - Social Support
|
||||||
|
*
|
||||||
|
* This file is licensed under the Affero General Public License version 3 or
|
||||||
|
* later. See the COPYING file.
|
||||||
|
*
|
||||||
|
* @author Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @copyright 2018, Maxence Lange <maxence@artificial-owl.com>
|
||||||
|
* @license GNU AGPL version 3 or any later version
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OCA\Social\Service;
|
||||||
|
|
||||||
|
|
||||||
|
use daita\MySmallPhpTools\Exceptions\MalformedArrayException;
|
||||||
|
use Exception;
|
||||||
|
use OCA\Social\Db\NotesRequest;
|
||||||
|
use OCA\Social\Db\StreamActionsRequest;
|
||||||
|
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\ActivityPub\Actor\Person;
|
||||||
|
use OCA\Social\Model\ActivityPub\Object\Announce;
|
||||||
|
use OCA\Social\Model\ActivityPub\Object\Note;
|
||||||
|
use OCA\Social\Model\ActivityPub\Stream;
|
||||||
|
use OCA\Social\Model\InstancePath;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class StreamActionService
|
||||||
|
*
|
||||||
|
* @package OCA\Social\Service
|
||||||
|
*/
|
||||||
|
class StreamActionService {
|
||||||
|
|
||||||
|
|
||||||
|
/** @var StreamActionsRequest */
|
||||||
|
private $streamActionsRequest;
|
||||||
|
|
||||||
|
/** @var MiscService */
|
||||||
|
private $miscService;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* StreamActionService constructor.
|
||||||
|
*
|
||||||
|
* @param StreamActionsRequest $streamActionsRequest
|
||||||
|
* @param MiscService $miscService
|
||||||
|
*/
|
||||||
|
public function __construct(StreamActionsRequest $streamActionsRequest, MiscService $miscService
|
||||||
|
) {
|
||||||
|
$this->streamActionsRequest = $streamActionsRequest;
|
||||||
|
$this->miscService = $miscService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $actorId
|
||||||
|
* @param string $streamId
|
||||||
|
* @param string $key
|
||||||
|
* @param string $value
|
||||||
|
*/
|
||||||
|
public function setAction(string $actorId, string $streamId, string $key, string $value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $actorId
|
||||||
|
* @param string $streamId
|
||||||
|
* @param string $key
|
||||||
|
* @param int $value
|
||||||
|
*/
|
||||||
|
public function setActionInt(string $actorId, string $streamId, string $key, int $value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $actorId
|
||||||
|
* @param string $streamId
|
||||||
|
* @param string $key
|
||||||
|
* @param bool $value
|
||||||
|
*/
|
||||||
|
public function setActionBool(string $actorId, string $streamId, string $key, bool $value) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
Ładowanie…
Reference in New Issue