From 3a8929be1f9db32f39c4e6010c4608a30aaeb257 Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Mon, 20 Feb 2023 15:31:15 -0500 Subject: [PATCH 1/5] Add dislike counts to Mastodon API Statuses in FriendicaExtension --- src/Factory/Api/Mastodon/Status.php | 12 ++++++++++-- src/Object/Api/Mastodon/Status.php | 2 +- src/Object/Api/Mastodon/Status/Counts.php | 13 +++++++++---- .../Api/Mastodon/Status/FriendicaExtension.php | 8 ++++++-- 4 files changed, 26 insertions(+), 9 deletions(-) diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 9f6d3bcde..4d93d0892 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -144,10 +144,18 @@ class Status extends BaseFactory 'deleted' => false ]); + $count_dislike = Post::countPosts([ + 'thr-parent-id' => $uriId, + 'gravity' => Item::GRAVITY_ACTIVITY, + 'vid' => Verb::getID(Activity::DISLIKE), + 'deleted' => false + ]); + $counts = new \Friendica\Object\Api\Mastodon\Status\Counts( Post::countPosts(['thr-parent-id' => $uriId, 'gravity' => Item::GRAVITY_COMMENT, 'deleted' => false], []), $count_announce, - $count_like + $count_like, + $count_dislike ); $origin_like = ($count_like == 0) ? false : Post::exists([ @@ -323,7 +331,7 @@ class Status extends BaseFactory $replies = $this->dba->count('mail', ['thr-parent-id' => $item['uri-id'], 'reply' => true]); - $counts = new \Friendica\Object\Api\Mastodon\Status\Counts($replies, 0, 0); + $counts = new \Friendica\Object\Api\Mastodon\Status\Counts($replies, 0, 0, 0); $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes(false, false, false, false, false); diff --git a/src/Object/Api/Mastodon/Status.php b/src/Object/Api/Mastodon/Status.php index 51f0b1c39..30f554bdf 100644 --- a/src/Object/Api/Mastodon/Status.php +++ b/src/Object/Api/Mastodon/Status.php @@ -151,7 +151,7 @@ class Status extends BaseDataTransferObject $this->emojis = []; $this->card = $card->toArray() ?: null; $this->poll = $poll; - $this->friendica = new FriendicaExtension($item['title']); + $this->friendica = new FriendicaExtension($item['title'], $counts->dislikes); } /** diff --git a/src/Object/Api/Mastodon/Status/Counts.php b/src/Object/Api/Mastodon/Status/Counts.php index 26eb361cf..207f78a43 100644 --- a/src/Object/Api/Mastodon/Status/Counts.php +++ b/src/Object/Api/Mastodon/Status/Counts.php @@ -35,6 +35,9 @@ class Counts /** @var int */ protected $favourites; + /** @var int */ + protected $dislikes; + /** * Creates a status count object * @@ -43,14 +46,16 @@ class Counts * @param int $favourites * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function __construct(int $replies, int $reblogs, int $favourites) + public function __construct(int $replies, int $reblogs, int $favourites, int $dislikes) { - $this->replies = $replies; - $this->reblogs = $reblogs; + $this->replies = $replies; + $this->reblogs = $reblogs; $this->favourites = $favourites; + $this->dislikes = $dislikes; } - public function __get($name) { + public function __get($name) + { return $this->$name; } } diff --git a/src/Object/Api/Mastodon/Status/FriendicaExtension.php b/src/Object/Api/Mastodon/Status/FriendicaExtension.php index 050c5a026..1db70f731 100644 --- a/src/Object/Api/Mastodon/Status/FriendicaExtension.php +++ b/src/Object/Api/Mastodon/Status/FriendicaExtension.php @@ -35,14 +35,18 @@ class FriendicaExtension extends BaseDataTransferObject /** @var string */ protected $title; + /** @var int */ + protected $dislikes_count; + /** * Creates a status count object * * @param string $title * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public function __construct(string $title) + public function __construct(string $title, int $dislikes_count) { - $this->title = $title; + $this->title = $title; + $this->dislikes_count = $dislikes_count; } } From dba74c7940da2b074bb12bb507a8e4c566313fce Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Mon, 20 Feb 2023 15:32:03 -0500 Subject: [PATCH 2/5] Fix phpcbf style errors in part of code I didn't change --- src/Factory/Api/Mastodon/Status.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Factory/Api/Mastodon/Status.php b/src/Factory/Api/Mastodon/Status.php index 4d93d0892..788841a9b 100644 --- a/src/Factory/Api/Mastodon/Status.php +++ b/src/Factory/Api/Mastodon/Status.php @@ -59,12 +59,18 @@ class Status extends BaseFactory /** @var ContentItem */ private $contentItem; - public function __construct(LoggerInterface $logger, Database $dba, - Account $mstdnAccountFactory, Mention $mstdnMentionFactory, - Tag $mstdnTagFactory, Card $mstdnCardFactory, - Attachment $mstdnAttachementFactory, Error $mstdnErrorFactory, - Poll $mstdnPollFactory, ContentItem $contentItem) - { + public function __construct( + LoggerInterface $logger, + Database $dba, + Account $mstdnAccountFactory, + Mention $mstdnMentionFactory, + Tag $mstdnTagFactory, + Card $mstdnCardFactory, + Attachment $mstdnAttachementFactory, + Error $mstdnErrorFactory, + Poll $mstdnPollFactory, + ContentItem $contentItem + ) { parent::__construct($logger); $this->dba = $dba; $this->mstdnAccountFactory = $mstdnAccountFactory; From c235bf299eb82ab08f922e8c229d4ff2c69a6aaf Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Mon, 20 Feb 2023 15:33:36 -0500 Subject: [PATCH 3/5] Add Mastodon format compatible (un)dislike endpoint in Friendica API space --- src/Module/Api/Friendica/Statuses/Dislike.php | 54 +++++++++++++++++++ .../Api/Friendica/Statuses/Undislike.php | 54 +++++++++++++++++++ static/routes.config.php | 2 + 3 files changed, 110 insertions(+) create mode 100644 src/Module/Api/Friendica/Statuses/Dislike.php create mode 100644 src/Module/Api/Friendica/Statuses/Undislike.php diff --git a/src/Module/Api/Friendica/Statuses/Dislike.php b/src/Module/Api/Friendica/Statuses/Dislike.php new file mode 100644 index 000000000..e9690d485 --- /dev/null +++ b/src/Module/Api/Friendica/Statuses/Dislike.php @@ -0,0 +1,54 @@ +. + * + */ + +namespace Friendica\Module\Api\Friendica\Statuses; + +use Friendica\Core\System; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Post; +use Friendica\Module\BaseApi; + +/** + * @see https://docs.joinmastodon.org/methods/statuses/ + */ +class Dislike extends BaseApi +{ + protected function post(array $request = []) + { + self::checkAllowedScope(self::SCOPE_WRITE); + $uid = self::getCurrentUserID(); + + if (empty($this->parameters['id'])) { + DI::mstdnError()->UnprocessableEntity(); + } + + $item = Post::selectFirstForUser($uid, ['id'], ['uri-id' => $this->parameters['id'], 'uid' => [$uid, 0]]); + if (!DBA::isResult($item)) { + DI::mstdnError()->RecordNotFound(); + } + + Item::performActivity($item['id'], 'dislike', $uid); + + System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid, self::appSupportsQuotes())->toArray()); + } +} diff --git a/src/Module/Api/Friendica/Statuses/Undislike.php b/src/Module/Api/Friendica/Statuses/Undislike.php new file mode 100644 index 000000000..933d7a1ed --- /dev/null +++ b/src/Module/Api/Friendica/Statuses/Undislike.php @@ -0,0 +1,54 @@ +. + * + */ + +namespace Friendica\Module\Api\Friendica\Statuses; + +use Friendica\Core\System; +use Friendica\Database\DBA; +use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Post; +use Friendica\Module\BaseApi; + +/** + * @see https://docs.joinmastodon.org/methods/statuses/ + */ +class Undislike extends BaseApi +{ + protected function post(array $request = []) + { + self::checkAllowedScope(self::SCOPE_WRITE); + $uid = self::getCurrentUserID(); + + if (empty($this->parameters['id'])) { + DI::mstdnError()->UnprocessableEntity(); + } + + $item = Post::selectFirstForUser($uid, ['id'], ['uri-id' => $this->parameters['id'], 'uid' => [$uid, 0]]); + if (!DBA::isResult($item)) { + DI::mstdnError()->RecordNotFound(); + } + + Item::performActivity($item['id'], 'undislike', $uid); + + System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid, self::appSupportsQuotes())->toArray()); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index 58fce7277..caf24242b 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -80,6 +80,8 @@ $apiRoutes = [ '/friendica' => [ '/activity/{verb:attendmaybe|attendno|attendyes|dislike|like|unattendmaybe|unattendno|unattendyes|undislike|unlike}[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Activity::class, [ R::POST]], + '/statuses/{id:\d+}/dislike' => [Module\Api\Friendica\Statuses\Dislike::class, [ R::POST]], + '/statuses/{id:\d+}/undislike' => [Module\Api\Friendica\Statuses\Undislike::class, [ R::POST]], '/notification/seen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Notification\Seen::class, [ R::POST]], '/notification[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Notification::class, [R::GET ]], '/notifications[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Notification::class, [R::GET ]], From c419aabee42f79abe8df31d4c26bc1e63faae72f Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Mon, 20 Feb 2023 15:50:21 -0500 Subject: [PATCH 4/5] Add deleted check to FavouritedBy Mastodon endpoint --- src/Module/Api/Mastodon/Statuses/FavouritedBy.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Module/Api/Mastodon/Statuses/FavouritedBy.php b/src/Module/Api/Mastodon/Statuses/FavouritedBy.php index 3bf165798..8f9fe02f1 100644 --- a/src/Module/Api/Mastodon/Statuses/FavouritedBy.php +++ b/src/Module/Api/Mastodon/Statuses/FavouritedBy.php @@ -49,7 +49,7 @@ class FavouritedBy extends BaseApi DI::mstdnError()->RecordNotFound(); } - $activities = Post::selectPosts(['author-id'], ['thr-parent-id' => $id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::LIKE]); + $activities = Post::selectPosts(['author-id'], ['thr-parent-id' => $id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::LIKE, 'deleted' => false]); $accounts = []; From 155e3a701e33d526f6af4fe308917c421751bb4b Mon Sep 17 00:00:00 2001 From: Hank Grabowski Date: Mon, 20 Feb 2023 15:51:17 -0500 Subject: [PATCH 5/5] Add DislikedBy Mastodon compatible endpoint in the Friendica API space --- .../Api/Friendica/Statuses/DislikedBy.php | 62 +++++++++++++++++++ static/routes.config.php | 1 + 2 files changed, 63 insertions(+) create mode 100644 src/Module/Api/Friendica/Statuses/DislikedBy.php diff --git a/src/Module/Api/Friendica/Statuses/DislikedBy.php b/src/Module/Api/Friendica/Statuses/DislikedBy.php new file mode 100644 index 000000000..81860bc40 --- /dev/null +++ b/src/Module/Api/Friendica/Statuses/DislikedBy.php @@ -0,0 +1,62 @@ +. + * + */ + +namespace Friendica\Module\Api\Friendica\Statuses; + +use Friendica\Core\System; +use Friendica\DI; +use Friendica\Model\Item; +use Friendica\Model\Post; +use Friendica\Module\BaseApi; +use Friendica\Protocol\Activity; + +/** + * @see https://docs.joinmastodon.org/methods/statuses/ + */ +class DislikedBy extends BaseApi +{ + /** + * @throws \Friendica\Network\HTTPException\InternalServerErrorException + */ + protected function rawContent(array $request = []) + { + $uid = self::getCurrentUserID(); + + if (empty($this->parameters['id'])) { + DI::mstdnError()->UnprocessableEntity(); + } + + $id = $this->parameters['id']; + if (!Post::exists(['uri-id' => $id, 'uid' => [0, $uid]])) { + DI::mstdnError()->RecordNotFound(); + } + + $activities = Post::selectPosts(['author-id'], ['thr-parent-id' => $id, 'gravity' => Item::GRAVITY_ACTIVITY, 'verb' => Activity::DISLIKE, 'deleted' => false]); + + $accounts = []; + + while ($activity = Post::fetch($activities)) { + $accounts[] = DI::mstdnAccount()->createFromContactId($activity['author-id'], $uid); + } + + System::jsonExit($accounts); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index caf24242b..eb55c64ab 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -81,6 +81,7 @@ $apiRoutes = [ '/activity/{verb:attendmaybe|attendno|attendyes|dislike|like|unattendmaybe|unattendno|unattendyes|undislike|unlike}[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Activity::class, [ R::POST]], '/statuses/{id:\d+}/dislike' => [Module\Api\Friendica\Statuses\Dislike::class, [ R::POST]], + '/statuses/{id:\d+}/disliked_by' => [Module\Api\Friendica\Statuses\DislikedBy::class, [R::GET ]], '/statuses/{id:\d+}/undislike' => [Module\Api\Friendica\Statuses\Undislike::class, [ R::POST]], '/notification/seen[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Notification\Seen::class, [ R::POST]], '/notification[.{extension:json|xml|rss|atom}]' => [Module\Api\Friendica\Notification::class, [R::GET ]],