From 1958bde4c0739f14c46c00195a9892329350535b Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 10 Dec 2019 21:27:09 +0000 Subject: [PATCH 1/5] API: Added endpoints /instance and /instance/peers --- doc/API-Mastodon.md | 2 + src/Module/Api/Mastodon/Instance.php | 74 ++++++++++++++++++++++ src/Module/Api/Mastodon/Instance/Peers.php | 41 ++++++++++++ static/routes.config.php | 2 + 4 files changed, 119 insertions(+) create mode 100644 src/Module/Api/Mastodon/Instance.php create mode 100644 src/Module/Api/Mastodon/Instance/Peers.php diff --git a/doc/API-Mastodon.md b/doc/API-Mastodon.md index d885e6ab3c..a711e367fb 100644 --- a/doc/API-Mastodon.md +++ b/doc/API-Mastodon.md @@ -16,6 +16,8 @@ These endpoints use the [Mastodon API entities](https://docs.joinmastodon.org/ap ## Implemented endpoints - [GET /api/v1/follow_requests](https://docs.joinmastodon.org/api/rest/follow-requests/#get-api-v1-follow-requests) +- [GET /api/v1/instance](https://docs.joinmastodon.org/api/rest/instances) +- GET /api/v1/instance/peers - undocumented, but implemented by Mastodon and Pleroma ## Non-implemented endpoints diff --git a/src/Module/Api/Mastodon/Instance.php b/src/Module/Api/Mastodon/Instance.php new file mode 100644 index 0000000000..f6f2657448 --- /dev/null +++ b/src/Module/Api/Mastodon/Instance.php @@ -0,0 +1,74 @@ + $app->getBaseURL(), + 'title' => Config::get('config', 'sitename'), + 'short_description' => '', // Not supported + 'description' => Config::get('config', 'info'), + 'email' => Config::get('config', 'admin_email'), + 'version' => FRIENDICA_VERSION, + 'urls' => [], // Not supported + 'stats' => [], + 'thumbnail' => $app->getBaseURL() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'), + 'languages' => [Config::get('system', 'language')], + 'registrations' => ($register_policy != Register::CLOSED), + 'approval_required' => ($register_policy == Register::APPROVE), + 'contact_account' => [] // Currently unsupported + ]; + + if (!empty(Config::get('system', 'nodeinfo'))) { + $count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); + $return['stats'] = [ + 'user_count' => intval(Config::get('nodeinfo', 'total_users')), + 'status_count' => Config::get('nodeinfo', 'local_posts') + Config::get('nodeinfo', 'local_comments'), + 'domain_count' => $count + ]; + } + + /// @ToDo will be done, once that we have an API function for that + /* + if (!empty(Config::get('config', 'admin_email'))) { + $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); + $administrator = User::getByEmail($adminList[0], ['nickname']); + if (!empty($administrator)) { + $adminContact = DBA::selectFirst('contact', [], ['nick' => $administrator['nickname'], 'self' => true]); + $return['contact_account'] = Api::getAccountArray($adminContact); + } + } + */ + + System::jsonExit($return); + } +} diff --git a/src/Module/Api/Mastodon/Instance/Peers.php b/src/Module/Api/Mastodon/Instance/Peers.php new file mode 100644 index 0000000000..4dc4f482e7 --- /dev/null +++ b/src/Module/Api/Mastodon/Instance/Peers.php @@ -0,0 +1,41 @@ += `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); + while ($instance = DBA::fetch($instances)) { + $urldata = parse_url($instance['url']); + unset($urldata['scheme']); + $return[] = ltrim(Network::unparseURL($urldata), '/'); + } + DBA::close($instances); + + System::jsonExit($return); + } +} diff --git a/static/routes.config.php b/static/routes.config.php index d8113c5c53..824354690d 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -30,6 +30,8 @@ return [ '/api' => [ '/v1' => [ '/follow_requests' => [Module\Api\Mastodon\FollowRequests::class, [R::GET ]], + '/instance' => [Module\Api\Mastodon\Instance::class, [R::GET]], + '/instance/peers' => [Module\Api\Mastodon\Instance\Peers::class, [R::GET]], ], ], From 4e2804d7834ab6ed12daca12dc49cd0a80578e9e Mon Sep 17 00:00:00 2001 From: Michael Date: Tue, 10 Dec 2019 23:05:25 +0000 Subject: [PATCH 2/5] Added some more data --- src/Module/Api/Mastodon/Instance.php | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Module/Api/Mastodon/Instance.php b/src/Module/Api/Mastodon/Instance.php index f6f2657448..321dbf7caf 100644 --- a/src/Module/Api/Mastodon/Instance.php +++ b/src/Module/Api/Mastodon/Instance.php @@ -2,6 +2,7 @@ namespace Friendica\Module\Api\Mastodon; +use Friendica\Api\Mastodon\Account; use Friendica\Core\Config; use Friendica\Core\Protocol; use Friendica\Core\System; @@ -35,7 +36,6 @@ class Instance extends Api $return = [ 'uri' => $app->getBaseURL(), 'title' => Config::get('config', 'sitename'), - 'short_description' => '', // Not supported 'description' => Config::get('config', 'info'), 'email' => Config::get('config', 'admin_email'), 'version' => FRIENDICA_VERSION, @@ -43,11 +43,16 @@ class Instance extends Api 'stats' => [], 'thumbnail' => $app->getBaseURL() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'), 'languages' => [Config::get('system', 'language')], + 'max_toot_chars' => (int)Config::get('config', 'api_import_size', Config::get('config', 'max_import_size')), 'registrations' => ($register_policy != Register::CLOSED), 'approval_required' => ($register_policy == Register::APPROVE), - 'contact_account' => [] // Currently unsupported + 'contact_account' => [] ]; + if (!$return['registrations']) { + unset($return['approval_required']); + } + if (!empty(Config::get('system', 'nodeinfo'))) { $count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); $return['stats'] = [ @@ -57,17 +62,14 @@ class Instance extends Api ]; } - /// @ToDo will be done, once that we have an API function for that - /* if (!empty(Config::get('config', 'admin_email'))) { $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); $administrator = User::getByEmail($adminList[0], ['nickname']); if (!empty($administrator)) { $adminContact = DBA::selectFirst('contact', [], ['nick' => $administrator['nickname'], 'self' => true]); - $return['contact_account'] = Api::getAccountArray($adminContact); + $return['contact_account'] = Account::createFromContact($adminContact); } } - */ System::jsonExit($return); } From 9296a55dfb5f075b13f1998d0ed8c782acf32b09 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 11 Dec 2019 06:51:59 +0000 Subject: [PATCH 3/5] Added entities --- src/Api/Mastodon/Instance.php | 83 ++++++++++++++++++++++++++++ src/Api/Mastodon/Stats.php | 38 +++++++++++++ src/Module/Api/Mastodon/Instance.php | 58 +------------------ 3 files changed, 123 insertions(+), 56 deletions(-) create mode 100644 src/Api/Mastodon/Instance.php create mode 100644 src/Api/Mastodon/Stats.php diff --git a/src/Api/Mastodon/Instance.php b/src/Api/Mastodon/Instance.php new file mode 100644 index 0000000000..fef7394cc6 --- /dev/null +++ b/src/Api/Mastodon/Instance.php @@ -0,0 +1,83 @@ +uri = $app->getBaseURL(); + $instance->title = Config::get('config', 'sitename'); + $instance->description = Config::get('config', 'info'); + $instance->email = Config::get('config', 'admin_email'); + $instance->version = FRIENDICA_VERSION; + $instance->urls = []; // Not supported + $instance->stats = Stats::get(); + $instance->thumbnail = $app->getBaseURL() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'); + $instance->languages = [Config::get('system', 'language')]; + $instance->max_toot_chars = (int)Config::get('config', 'api_import_size', Config::get('config', 'max_import_size')); + $instance->registrations = ($register_policy != Register::CLOSED); + $instance->approval_required = ($register_policy == Register::APPROVE); + $instance->contact_account = []; + + if (!empty(Config::get('config', 'admin_email'))) { + $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); + $administrator = User::getByEmail($adminList[0], ['nickname']); + if (!empty($administrator)) { + $adminContact = DBA::selectFirst('contact', [], ['nick' => $administrator['nickname'], 'self' => true]); + $instance->contact_account = Account::createFromContact($adminContact); + } + } + + return $instance; + } +} diff --git a/src/Api/Mastodon/Stats.php b/src/Api/Mastodon/Stats.php new file mode 100644 index 0000000000..895a58e060 --- /dev/null +++ b/src/Api/Mastodon/Stats.php @@ -0,0 +1,38 @@ +user_count = intval(Config::get('nodeinfo', 'total_users')); + $stats->status_count = Config::get('nodeinfo', 'local_posts') + Config::get('nodeinfo', 'local_comments'); + $stats->domain_count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); + } + return $stats; + } +} diff --git a/src/Module/Api/Mastodon/Instance.php b/src/Module/Api/Mastodon/Instance.php index 321dbf7caf..6a2b3abb63 100644 --- a/src/Module/Api/Mastodon/Instance.php +++ b/src/Module/Api/Mastodon/Instance.php @@ -2,75 +2,21 @@ namespace Friendica\Module\Api\Mastodon; -use Friendica\Api\Mastodon\Account; -use Friendica\Core\Config; -use Friendica\Core\Protocol; +use Friendica\Api\Mastodon\Instance as InstanceEntity; use Friendica\Core\System; -use Friendica\Database\DBA; -use Friendica\Model\User; use Friendica\Module\Base\Api; -use Friendica\Module\Register; -use Friendica\Network\HTTPException; -use Friendica\Util\Network; /** * @see https://docs.joinmastodon.org/api/rest/instances/ */ class Instance extends Api { - public static function init(array $parameters = []) - { - parent::init($parameters); - } - /** * @param array $parameters * @throws HTTPException\InternalServerErrorException */ public static function rawContent(array $parameters = []) { - $app = self::getApp(); - - $register_policy = intval(Config::get('config', 'register_policy')); - - $return = [ - 'uri' => $app->getBaseURL(), - 'title' => Config::get('config', 'sitename'), - 'description' => Config::get('config', 'info'), - 'email' => Config::get('config', 'admin_email'), - 'version' => FRIENDICA_VERSION, - 'urls' => [], // Not supported - 'stats' => [], - 'thumbnail' => $app->getBaseURL() . (Config::get('system', 'shortcut_icon') ?? 'images/friendica-32.png'), - 'languages' => [Config::get('system', 'language')], - 'max_toot_chars' => (int)Config::get('config', 'api_import_size', Config::get('config', 'max_import_size')), - 'registrations' => ($register_policy != Register::CLOSED), - 'approval_required' => ($register_policy == Register::APPROVE), - 'contact_account' => [] - ]; - - if (!$return['registrations']) { - unset($return['approval_required']); - } - - if (!empty(Config::get('system', 'nodeinfo'))) { - $count = DBA::count('gserver', ["`network` in (?, ?) AND `last_contact` >= `last_failure`", Protocol::DFRN, Protocol::ACTIVITYPUB]); - $return['stats'] = [ - 'user_count' => intval(Config::get('nodeinfo', 'total_users')), - 'status_count' => Config::get('nodeinfo', 'local_posts') + Config::get('nodeinfo', 'local_comments'), - 'domain_count' => $count - ]; - } - - if (!empty(Config::get('config', 'admin_email'))) { - $adminList = explode(',', str_replace(' ', '', Config::get('config', 'admin_email'))); - $administrator = User::getByEmail($adminList[0], ['nickname']); - if (!empty($administrator)) { - $adminContact = DBA::selectFirst('contact', [], ['nick' => $administrator['nickname'], 'self' => true]); - $return['contact_account'] = Account::createFromContact($adminContact); - } - } - - System::jsonExit($return); + System::jsonExit(InstanceEntity::get(self::getApp())); } } From 203857ede051eeea2013b9160960dcebbe40eccf Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 11 Dec 2019 06:54:31 +0000 Subject: [PATCH 4/5] Added parameter description --- src/Api/Mastodon/Instance.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Api/Mastodon/Instance.php b/src/Api/Mastodon/Instance.php index fef7394cc6..890c83c092 100644 --- a/src/Api/Mastodon/Instance.php +++ b/src/Api/Mastodon/Instance.php @@ -2,8 +2,7 @@ namespace Friendica\Api\Mastodon; -use Friendica\Core\Protocol; - +use Friendica\App; use Friendica\Api\Mastodon\Account; use Friendica\Api\Mastodon\Stats; use Friendica\Core\Config; @@ -48,10 +47,12 @@ class Instance /** * Creates an instance record * + * @param App $app + * * @return Instance * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ - public static function get($app) { + public static function get(App $app) { $register_policy = intval(Config::get('config', 'register_policy')); $instance = new Instance(); From 3388274f9a37e9a2ebaf78be5ef44ae0e2deada0 Mon Sep 17 00:00:00 2001 From: Michael Date: Wed, 11 Dec 2019 08:26:18 +0000 Subject: [PATCH 5/5] Removed unneeded function --- src/Module/Api/Mastodon/Instance/Peers.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/Module/Api/Mastodon/Instance/Peers.php b/src/Module/Api/Mastodon/Instance/Peers.php index 4dc4f482e7..5eaf355cc2 100644 --- a/src/Module/Api/Mastodon/Instance/Peers.php +++ b/src/Module/Api/Mastodon/Instance/Peers.php @@ -14,11 +14,6 @@ use Friendica\Util\Network; */ class Peers extends Api { - public static function init(array $parameters = []) - { - parent::init($parameters); - } - /** * @param array $parameters * @throws HTTPException\InternalServerErrorException