diff options
40 files changed, 846 insertions, 186 deletions
diff --git a/lib/Command/Fediverse.php b/lib/Command/Fediverse.php index 0a2dbf6e..ac8ce4ab 100644 --- a/lib/Command/Fediverse.php +++ b/lib/Command/Fediverse.php @@ -33,6 +33,7 @@ namespace OCA\Social\Command; use Exception; use OC\Core\Command\Base; +use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\UnauthorizedFediverseException; use OCA\Social\Service\ConfigService; use OCA\Social\Service\FediverseService; @@ -208,6 +209,8 @@ class Fediverse extends Base { /** * @param string $address + * + * @throws SocialAppConfigException */ private function testAddress(string $address) { try { diff --git a/lib/Db/CacheActorsRequest.php b/lib/Db/CacheActorsRequest.php index 4abfe820..3867d7bd 100644 --- a/lib/Db/CacheActorsRequest.php +++ b/lib/Db/CacheActorsRequest.php @@ -31,6 +31,7 @@ namespace OCA\Social\Db; use DateTime; +use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use Exception; use OCA\Social\Exceptions\CacheActorDoesNotExistException; use OCA\Social\Model\ActivityPub\Actor\Person; @@ -84,7 +85,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { ->setValue('summary', $qb->createNamedParameter($actor->getSummary())) ->setValue('public_key', $qb->createNamedParameter($actor->getPublicKey())) ->setValue('source', $qb->createNamedParameter($actor->getSource())) - ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetails()))); + ->setValue('details', $qb->createNamedParameter(json_encode($actor->getDetailsAll()))); try { if ($actor->getCreation() > 0) { @@ -112,7 +113,10 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { $this->generatePrimaryKey($qb, $actor->getId()); - $qb->execute(); + try { + $qb->execute(); + } catch (UniqueConstraintViolationException $e) { + } } @@ -140,7 +144,7 @@ class CacheActorsRequest extends CacheActorsRequestBuilder { ->set('summary', $qb->createNamedParameter($actor->getSummary())) ->set('public_key', $qb->createNamedParameter($actor->getPublicKey())) ->set('source', $qb->createNamedParameter($actor->getSource())) - ->set('details', $qb->createNamedParameter(json_encode($actor->getDetails()))); + ->set('details', $qb->createNamedParameter(json_encode($actor->getDetailsAll()))); try { if ($actor->getCreation() > 0) { diff --git a/lib/Db/CoreRequestBuilder.php b/lib/Db/CoreRequestBuilder.php index a8cb3009..259b0374 100644 --- a/lib/Db/CoreRequestBuilder.php +++ b/lib/Db/CoreRequestBuilder.php @@ -652,8 +652,9 @@ class CoreRequestBuilder { /** * @param IQueryBuilder $qb * @param string $fieldActorId + * @param string $alias */ - protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId) { + protected function leftJoinCacheActors(IQueryBuilder &$qb, string $fieldActorId, string $alias = '') { if ($qb->getType() !== QueryBuilder::SELECT) { return; } @@ -661,7 +662,7 @@ class CoreRequestBuilder { $expr = $qb->expr(); $func = $qb->func(); - $pf = $this->defaultSelectAlias; + $pf = ($alias === '') ? $this->defaultSelectAlias : $alias; $qb->selectAlias('ca.id', 'cacheactor_id') ->selectAlias('ca.type', 'cacheactor_type') @@ -949,16 +950,16 @@ class CoreRequestBuilder { try { $this->parseFollowLeftJoin($data, 'as_follower'); - $actor->addDetailBool('following', true); + $actor->setDetailBool('following', true); } catch (InvalidResourceException $e) { - $actor->addDetailBool('following', false); + $actor->setDetailBool('following', false); } try { $this->parseFollowLeftJoin($data, 'as_followed'); - $actor->addDetailBool('followed', true); + $actor->setDetailBool('followed', true); } catch (InvalidResourceException $e) { - $actor->addDetailBool('followed', false); + $actor->setDetailBool('followed', false); } $actor->setCompleteDetails(true); diff --git a/lib/Db/StreamRequest.php b/lib/Db/StreamRequest.php index 745b30d3..db16ad95 100644 --- a/lib/Db/StreamRequest.php +++ b/lib/Db/StreamRequest.php @@ -32,9 +32,13 @@ namespace OCA\Social\Db; use daita\MySmallPhpTools\Model\Cache; use DateTime; +use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Exception\UniqueConstraintViolationException; +use Doctrine\DBAL\Query\QueryBuilder; use Exception; use OCA\Social\Exceptions\DateTimeException; +use OCA\Social\Exceptions\ItemUnknownException; +use OCA\Social\Exceptions\SocialAppConfigException; use OCA\Social\Exceptions\StreamNotFoundException; use OCA\Social\Model\ActivityPub\ACore; use OCA\Social\Model\ActivityPub\Actor\Person; @@ -73,7 +77,6 @@ class StreamRequest extends StreamRequestBuilder { */ public function save(Stream $stream) { $qb = $this->saveStream($stream); - if ($stream->getType() === Note::TYPE) { /** @var Note $stream */ $qb->setValue( @@ -86,7 +89,30 @@ class StreamRequest extends StreamRequestBuilder { ); } - $qb->execute(); + try { + $qb->execute(); + } catch (UniqueConstraintViolationException $e) { + } + } + + + /** + * @param Stream $stream \ + * + * @return Statement|int + */ + public function update(Stream $stream) { + $qb = $this->getStreamUpdateSql(); + + $qb->set('details', $qb->createNamedParameter(json_encode($stream->getDetailsAll()))); + $qb->set( + 'cc', $qb->createNamedParameter( + json_encode($stream->getCcArray(), JSON_UNESCAPED_SLASHES) + ) + ); + $this->limitToIdString($qb, $stream->getId()); + + return $qb->execute(); } @@ -100,10 +126,21 @@ class StreamRequest extends StreamRequestBuilder { $this->limitToIdString($qb, $stream->getId()); - try { - $qb->execute(); - } catch (UniqueConstraintViolationException $e) { - } + $qb->execute(); + } + + + /** + * @param string $itemId + * @param string $to + */ + public function updateAttributedTo(string $itemId, string $to) { + $qb = $this->getStreamUpdateSql(); + $qb->set('attributed_to', $qb->createNamedParameter($to)); + + $this->limitToIdString($qb, $itemId); + + $qb->execute(); } @@ -176,15 +213,15 @@ class StreamRequest extends StreamRequestBuilder { /** - * @param Person $actor * @param string $type - * * @param string $objectId * * @return Stream * @throws StreamNotFoundException + * @throws ItemUnknownException + * @throws SocialAppConfigException */ - public function getStreamByObjectId(Person $actor, string $type, string $objectId): Stream { + public function getStreamByObjectId(string $objectId, string $type): Stream { if ($objectId === '') { throw new StreamNotFoundException('missing objectId'); }; @@ -192,7 +229,6 @@ class StreamRequest extends StreamRequestBuilder { $qb = $this->getStreamSelectSql(); $this->limitToObjectId($qb, $objectId); $this->limitToType($qb, $type); - $this->limitToAttributedTo($qb, $actor->getId()); $cursor = $qb->execute(); $data = $cursor->fetch(); @@ -200,8 +236,7 @@ class StreamRequest extends StreamRequestBuilder { if ($data === false) { throw new StreamNotFoundException( - 'StreamByObjectId not found - ' . $actor->getId() . ' - ' . $type . ' - ' - . $objectId + 'StreamByObjectId not found - ' . $type . ' - ' . $objectId ); } @@ -245,11 +280,12 @@ class StreamRequest extends StreamRequestBuilder { $this->joinFollowing($qb, $actor); $this->limitPaginate($qb, $since, $limit); - $this->filterHiddenOnTimeline($qb); - $this->leftJoinCacheActors($qb, 'attributed_to'); + $this->leftJoinCacheActors($qb, 'object_id', 'f'); $this->leftJoinStreamAction($qb); + $this->filterDuplicate($qb); + $streams = []; $cursor = $qb->execute(); while ($data = $cursor->fetch()) { @@ -357,7 +393,7 @@ class StreamRequest extends StreamRequestBuilder { $this->limitToRecipient($qb, $actor->getId(), true); $this->filterRecipient($qb, ACore::CONTEXT_PUBLIC); $this->filterRecipient($qb, $actor->getFollowers()); - $this->filterHiddenOnTimeline($qb); +// $this->filterHiddenOnTimeline($qb); $this->leftJoinCacheActors($qb, 'attributed_to'); @@ -391,11 +427,12 @@ class StreamRequest extends StreamRequestBuilder { $qb = $this->getStreamSelectSql(); $this->limitPaginate($qb, $since, $limit); - if ($localOnly) { - $this->limitToLocal($qb, true); - } +// if ($localOnly) { + $this->limitToLocal($qb, $localOnly); +// } + + $this->limitToType($qb, Note::TYPE); - $this->filterHiddenOnTimeline($qb); $this->leftJoinCacheActors($qb, 'attributed_to'); $this->leftJoinStreamAction($qb); @@ -442,7 +479,7 @@ class StreamRequest extends StreamRequestBuilder { $qb->andWhere($this->exprValueWithinJsonFormat($qb, 'hashtags', '' . $hashtag)); $this->limitPaginate($qb, $since, $limit); - $this->filterHiddenOnTimeline($qb); +// $this->filterHiddenOnTimeline($qb); $this->leftJoinCacheActors($qb, 'attributed_to'); $this->leftJoinStreamAction($qb); @@ -463,6 +500,8 @@ class StreamRequest extends StreamRequestBuilder { * * @return Stream[] * @throws DateTimeException + * @throws ItemUnknownException + * @throws SocialAppConfigException */ public function getNoteSince(int $since): array { $qb = $this->getStreamSelectSql(); @@ -561,6 +600,7 @@ class StreamRequest extends StreamRequestBuilder { ->setValue('source', $qb->createNamedParameter($stream->getSource())) ->setValue('activity_id', $qb->createNamedParameter($stream->getActivityId())) ->setValue('object_id', $qb->createNamedParameter($stream->getObjectId())) + ->setValue('details', $qb->createNamedParameter(json_encode($stream->getDetailsAll()))) ->setValue('cache', $qb->createNamedParameter($cache)) ->setValue( 'hidden_on_timeline', @@ -591,5 +631,70 @@ class StreamRequest extends StreamRequestBuilder { return $qb; } + + /** + * @param IQueryBuilder $qb + * @param Person $actor + */ + private function leftJoinFollowStatus(IQueryBuilder $qb, Person $actor) { + if ($qb->getType() !== QueryBuilder::SELECT) { + return; + } + + $expr = $qb->expr(); + $func = $qb->func(); + $pf = $this->defaultSelectAlias . '.'; + + $on = $expr->andX(); + $on->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'fs')); + $on->add($expr->eq($func->lower($pf . 'attributed_to'), $func->lower('fs.object_id'))); + $on->add($this->exprLimitToDBFieldInt($qb, 'accepted', 1, 'fs')); + + $qb->leftJoin($this->defaultSelectAlias, CoreRequestBuilder::TABLE_FOLLOWS, 'fs', $on); + } + + + /** + * @param IQueryBuilder $qb + */ + private function filterDuplicate(IQueryBuilder $qb) { + $actor = $this->viewer; + + if ($actor === null) { + return; + } + + $this->leftJoinFollowStatus($qb, $actor); + + $func = $qb->func(); + $expr = $qb->expr(); + + $filter = $expr->orX(); + $filter->add($this->exprLimitToDBFieldInt($qb, 'hidden_on_timeline', 0, 's')); + + $follower = $expr->andX(); + $follower->add( + $expr->neq( + $func->lower('attributed_to'), + $func->lower($qb->createNamedParameter($actor->getId())) + ) + ); + $follower->add($expr->isNull('fs.id')); +// $follower->add( +// $expr->eq( +// $func->lower('f.object_id'), +// $func->lower('s.attributed_to') +// ) +// ); + // needed ? +// $follower->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'f')); +// $follower->add($this->exprLimitToDBFieldInt($qb, 'accepted', 1, 'f')); + + $filter->add($follower); + + $qb->andWhere($filter); + } + + } diff --git a/lib/Db/StreamRequestBuilder.php b/lib/Db/StreamRequestBuilder.php index 910d4641..3198887b 100644 --- a/lib/Db/StreamRequestBuilder.php +++ b/lib/Db/StreamRequestBuilder.php @@ -39,6 +39,7 @@ use OCA\Social\Exceptions\ItemUnknownException; 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\Stream; use OCA\Social\Model\InstancePath; use OCP\DB\QueryBuilder\ICompositeExpression; @@ -98,7 +99,8 @@ class StreamRequestBuilder extends CoreRequestBuilder { 's.object_id', 's.attributed_to', 's.in_reply_to', 's.source', 's.local', 's.instances', 's.creation', 's.hidden_on_timeline' ) - ->from(self::TABLE_STREAMS, 's'); + ->from(self::TABLE_STREAMS, 's') + ->groupBy('s.id'); $this->defaultSelectAlias = 's'; @@ -160,19 +162,26 @@ class StreamRequestBuilder extends CoreRequestBuilder { $func = $qb->func(); $expr = $qb->expr(); + $filter = $expr->orX(); + $filter->add($this->exprLimitToDBFieldInt($qb, 'hidden_on_timeline', 0)); + $filter->add( $expr->neq( $func->lower('attributed_to'), $func->lower($qb->createNamedParameter($actor->getId())) ) ); - $filter->add( + + $follower = $expr->andX(); + $follower->add( $expr->eq( - 'hidden_on_timeline', - $qb->createNamedParameter('0') + $func->lower('f.object_id'), + $func->lower('attributed_to') ) ); + $follower->add($this->exprLimitToDBField($qb, 'actor_id', $actor->getId(), false, 'f')); + $filter->add($follower); $qb->andwhere($filter); } @@ -188,6 +197,7 @@ class StreamRequestBuilder extends CoreRequestBuilder { } $on = $this->exprJoinFollowing($qb, $actor); + $qb->selectAlias('f.object_id', 'following_actor_id'); $qb->join($this->defaultSelectAlias, CoreRequestBuilder::TABLE_FOLLOWS, 'f', $on); } @@ -431,6 +441,10 @@ class StreamRequestBuilder extends CoreRequestBuilder { $item->setAction($action); + if ($item->getType() === Announce::TYPE) { + $item->setAttributedTo($this->get('following_actor_id', $data, '')); + } + return $item; } diff --git a/lib/Interfaces/Activity/AcceptInterface.php b/lib/Interfaces/Activity/AcceptInterface.php index 5e3aa5fb..fc726028 100644 --- a/lib/Interfaces/Activity/AcceptInterface.php +++ b/lib/Interfaces/Activity/AcceptInterface.php @@ -98,12 +98,31 @@ class AcceptInterface implements IActivityPubInterface { } + + /** + * @param ACore $item + */ + public function update(ACore $item) { + } + + /** * @param ACore $item */ public function delete(ACore $item) { } + + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + + /** * @param ACore $activity * @param ACore $item diff --git a/lib/Interfaces/Activity/AddInterface.php b/lib/Interfaces/Activity/AddInterface.php index 706460ab..8aa7da89 100644 --- a/lib/Interfaces/Activity/AddInterface.php +++ b/lib/Interfaces/Activity/AddInterface.php @@ -101,9 +101,25 @@ class AddInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + /** * @param ACore $activity * @param ACore $item diff --git a/lib/Interfaces/Activity/BlockInterface.php b/lib/Interfaces/Activity/BlockInterface.php index 4bc2f792..3fe46f94 100644 --- a/lib/Interfaces/Activity/BlockInterface.php +++ b/lib/Interfaces/Activity/BlockInterface.php @@ -101,9 +101,25 @@ class BlockInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + /** * @param ACore $activity * @param ACore $item diff --git a/lib/Interfaces/Activity/CreateInterface.php b/lib/Interfaces/Activity/CreateInterface.php index e7a72d32..a625655b 100644 --- a/lib/Interfaces/Activity/CreateInterface.php +++ b/lib/Interfaces/Activity/CreateInterface.php @@ -101,9 +101,25 @@ class CreateInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + /** * @param ACore $activity * @param ACore $item diff --git a/lib/Interfaces/Activity/DeleteInterface.php b/lib/Interfaces/Activity/DeleteInterface.php index 9b631f4d..6f86d8d0 100644 --- a/lib/Interfaces/Activity/DeleteInterface.php +++ b/lib/Interfaces/Activity/DeleteInterface.php @@ -128,14 +128,29 @@ class DeleteInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function save(ACore $item) { + } + + + /** + * @param ACore $item + */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } /** * @param ACore $item + * @param string $source */ - public function save(ACore $item) { + public function event(ACore $item, string $source) { } diff --git a/lib/Interfaces/Activity/LikeInterface.php b/lib/Interfaces/Activity/LikeInterface.php index d1e78abc..fba4a6e3 100644 --- a/lib/Interfaces/Activity/LikeInterface.php +++ b/lib/Interfaces/Activity/LikeInterface.php @@ -101,9 +101,25 @@ class LikeInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + /** * @param ACore $activity * @param ACore $item diff --git a/lib/Interfaces/Activity/RejectInterface.php b/lib/Interfaces/Activity/RejectInterface.php index be46e6d3..6f21ba1a 100644 --- a/lib/Interfaces/Activity/RejectInterface.php +++ b/lib/Interfaces/Activity/RejectInterface.php @@ -101,9 +101,25 @@ class RejectInterface implements IActivityPubInterface { /** * @param ACore $item */ + public function update(ACore $item) { + } + + + /** + * @param ACore $item + */ public function delete(ACore $item) { } + + /** + * @param ACore $item + * @param string $source + */ + public function event(ACore $item, string $source) { + } + + /** * @param ACore $activity * @param ACore $item |