From 8480194479e68277f65b032ca3b96db80d8a6b89 Mon Sep 17 00:00:00 2001 From: Diogo Cordeiro Date: Thu, 10 May 2018 16:01:14 +0100 Subject: [PATCH] Add implementation of Followers endpoint --- ActivityPubPlugin.php | 8 +++ actions/apactorfollowers.php | 100 +++++++++++++++++++++++++++++ actions/apactorlikedcollection.php | 2 +- actions/apactorprofile.php | 4 +- 4 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 actions/apactorfollowers.php diff --git a/ActivityPubPlugin.php b/ActivityPubPlugin.php index 920665b..187cec4 100644 --- a/ActivityPubPlugin.php +++ b/ActivityPubPlugin.php @@ -47,6 +47,14 @@ class ActivityPubPlugin extends Plugin $m->connect(':nickname/liked.json', ['action' => 'apActorLikedCollection'], ['nickname' => Nickname::DISPLAY_FMT]); + + $m->connect(':nickname/followers.json', + ['action' => 'apActorFollowers'], + ['nickname' => Nickname::DISPLAY_FMT]); + + /*$m->connect(':nickname/following.json', + ['action' => 'apActorFollowing'], + ['nickname' => Nickname::DISPLAY_FMT]);*/ } public function onPluginVersion(array &$versions) diff --git a/actions/apactorfollowers.php b/actions/apactorfollowers.php new file mode 100644 index 0000000..42f0c70 --- /dev/null +++ b/actions/apactorfollowers.php @@ -0,0 +1,100 @@ +. + * + * @category Plugin + * @package GNUsocial + * @author Diogo Cordeiro + * @author Daniel Supernault + * @copyright 2015 Free Software Foundaction, Inc. + * @license http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0 + * @link https://gnu.io/social + */ + +if (!defined('GNUSOCIAL')) { exit(1); } + +class apActorFollowersAction extends ManagedAction +{ + protected $needLogin = false; + protected $canPost = true; + + protected function handle() + { + $nickname = $this->trimmed('nickname'); + try { + $user = User::getByNickname($nickname); + $profile = $user->getProfile(); + $url = $profile->profileurl; + } catch (Exception $e) { + throw new \Exception('Invalid username'); + } + + $page = intval($this->trimmed('page')); + + if ($page <= 0) + throw new \Exception('Invalid page number'); + + /* Fetch Followers */ + try { + $since = ($page-1) * PROFILES_PER_MINILIST; + $limit = (($page-1) == 0 ? 1 : $page)*PROFILES_PER_MINILIST; + $sub = $profile->getSubscribers($since, $limit); + } catch (NoResultException $e) { + throw new \Exception('This user has no followers'); + } + + /* Calculate total items */ + $total_subs = $profile->subscriberCount(); + $total_pages = ceil($total_subs/PROFILES_PER_MINILIST); + + if ($total_pages == 0) + throw new \Exception('This user has no followers'); + + if ($page > $total_pages) + throw new \Exception("There are only {$total_pages} pages"); + + /* Get followers' URLs */ + $subs = []; + while ($sub->fetch()) + $subs[] = $this->pretty_sub (clone($sub)); + + $res = [ + '@context' => [ + "https://www.w3.org/ns/activitystreams", + "https://w3id.org/security/v1", + ], + 'id' => "{$url}/followers.json", + 'type' => ($page == 0 ? 'OrderedCollection' : 'OrderedCollectionPage'), + 'totalItems' => $total_subs, + 'next' => $page+1 > $total_pages ? null : "{$url}/followers.json?page=".($page+1 == 1 ? 2 : $page+1), + 'prev' => $page == 1 ? null : "{$url}/followers.json?page=".($page-1 <= 0 ? 1 : $page-1), + 'orderedItems' => $subs + ]; + + header('Content-Type: application/activity+json'); + + echo json_encode($res, JSON_UNESCAPED_SLASHES | (isset($_GET["pretty"]) ? JSON_PRETTY_PRINT : null)); + } + + protected function pretty_sub ($sub_object) + { + return $sub_object->profileurl; + } +} diff --git a/actions/apactorlikedcollection.php b/actions/apactorlikedcollection.php index e36a332..c41c842 100644 --- a/actions/apactorlikedcollection.php +++ b/actions/apactorlikedcollection.php @@ -78,7 +78,7 @@ class apActorLikedCollectionAction extends ManagedAction 'orderedItems' => $faves ]; - header('Content-Type: application/json'); + header('Content-Type: application/activity+json'); echo json_encode($res, JSON_UNESCAPED_SLASHES | (isset($_GET["pretty"]) ? JSON_PRETTY_PRINT : null)); } diff --git a/actions/apactorprofile.php b/actions/apactorprofile.php index b89de7c..68cab8c 100644 --- a/actions/apactorprofile.php +++ b/actions/apactorprofile.php @@ -31,7 +31,7 @@ if (!defined('GNUSOCIAL')) { exit(1); } class apActorProfileAction extends ManagedAction -{ +{ protected $needLogin = false; protected $canPost = true; @@ -45,7 +45,7 @@ class apActorProfileAction extends ManagedAction throw new \Exception('Invalid username'); } - header('Content-Type: application/json'); + header('Content-Type: application/activity+json'); $res = Activitypub_profile::profileToObject($profile);