diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php index 7ccfefd00..44181ac94 100644 --- a/src/Model/Nodeinfo.php +++ b/src/Model/Nodeinfo.php @@ -24,6 +24,7 @@ namespace Friendica\Model; use Friendica\Core\Addon; use Friendica\Database\DBA; use Friendica\DI; +use stdClass; /** * Model interaction for the nodeinfo @@ -70,4 +71,109 @@ class Nodeinfo } DBA::close($items); } + + /** + * Return the supported services + * + * @return Object with supported services + */ + public static function getUsage(bool $version2 = false) + { + $config = DI::config(); + + $usage = new stdClass(); + + if (!empty($config->get('system', 'nodeinfo'))) { + $usage->users = [ + 'total' => intval($config->get('nodeinfo', 'total_users')), + 'activeHalfyear' => intval($config->get('nodeinfo', 'active_users_halfyear')), + 'activeMonth' => intval($config->get('nodeinfo', 'active_users_monthly')) + ]; + $usage->localPosts = intval($config->get('nodeinfo', 'local_posts')); + $usage->localComments = intval($config->get('nodeinfo', 'local_comments')); + + if ($version2) { + $usage->users['activeWeek'] = intval($config->get('nodeinfo', 'active_users_weekly')); + } + } + + return $usage; + } + + /** + * Return the supported services + * + * @return array with supported services + */ + public static function getServices() + { + $services = [ + 'inbound' => [], + 'outbound' => [], + ]; + + if (Addon::isEnabled('blogger')) { + $services['outbound'][] = 'blogger'; + } + if (Addon::isEnabled('dwpost')) { + $services['outbound'][] = 'dreamwidth'; + } + if (Addon::isEnabled('statusnet')) { + $services['inbound'][] = 'gnusocial'; + $services['outbound'][] = 'gnusocial'; + } + if (Addon::isEnabled('ijpost')) { + $services['outbound'][] = 'insanejournal'; + } + if (Addon::isEnabled('libertree')) { + $services['outbound'][] = 'libertree'; + } + if (Addon::isEnabled('buffer')) { + $services['outbound'][] = 'linkedin'; + } + if (Addon::isEnabled('ljpost')) { + $services['outbound'][] = 'livejournal'; + } + if (Addon::isEnabled('buffer')) { + $services['outbound'][] = 'pinterest'; + } + if (Addon::isEnabled('posterous')) { + $services['outbound'][] = 'posterous'; + } + if (Addon::isEnabled('pumpio')) { + $services['inbound'][] = 'pumpio'; + $services['outbound'][] = 'pumpio'; + } + + $services['outbound'][] = 'smtp'; + + if (Addon::isEnabled('tumblr')) { + $services['outbound'][] = 'tumblr'; + } + if (Addon::isEnabled('twitter') || Addon::isEnabled('buffer')) { + $services['outbound'][] = 'twitter'; + } + if (Addon::isEnabled('wppost')) { + $services['outbound'][] = 'wordpress'; + } + + return $services; + } + + public static function getOrganization($config) + { + $organization = ['name' => null, 'contact' => null, 'account' => null]; + + if (!empty($config->get('config', 'admin_email'))) { + $adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email'))); + $organization['contact'] = $adminList[0]; + $administrator = User::getByEmail($adminList[0], ['username', 'nickname']); + if (!empty($administrator)) { + $organization['name'] = $administrator['username']; + $organization['account'] = DI::baseUrl()->get() . '/profile/' . $administrator['nickname']; + } + } + + return $organization; + } } diff --git a/src/Module/NodeInfo.php b/src/Module/NodeInfo.php deleted file mode 100644 index eca0ae3e3..000000000 --- a/src/Module/NodeInfo.php +++ /dev/null @@ -1,322 +0,0 @@ -. - * - */ - -namespace Friendica\Module; - -use Friendica\BaseModule; -use Friendica\Core\Addon; -use Friendica\DI; -use Friendica\Model\User; -use stdClass; - -/** - * Standardized way of exposing metadata about a server running one of the distributed social networks. - * @see https://github.com/jhass/nodeinfo/blob/master/PROTOCOL.md - */ -class NodeInfo extends BaseModule -{ - public static function rawContent(array $parameters = []) - { - if (empty($parameters['version'])) { - self::printNodeInfo2(); - } elseif ($parameters['version'] == '1.0') { - self::printNodeInfo1(); - } elseif ($parameters['version'] == '2.0') { - self::printNodeInfo20(); - } else { - throw new \Friendica\Network\HTTPException\NotFoundException(); - } - } - - /** - * Return the supported services - * - * @return Object with supported services - */ - private static function getUsage(bool $version2 = false) - { - $config = DI::config(); - - $usage = new stdClass(); - - if (!empty($config->get('system', 'nodeinfo'))) { - $usage->users = [ - 'total' => intval($config->get('nodeinfo', 'total_users')), - 'activeHalfyear' => intval($config->get('nodeinfo', 'active_users_halfyear')), - 'activeMonth' => intval($config->get('nodeinfo', 'active_users_monthly')) - ]; - $usage->localPosts = intval($config->get('nodeinfo', 'local_posts')); - $usage->localComments = intval($config->get('nodeinfo', 'local_comments')); - - if ($version2) { - $usage->users['activeWeek'] = intval($config->get('nodeinfo', 'active_users_weekly')); - } - } - - return $usage; - } - - /** - * Return the supported services - * - * @return array with supported services - */ - private static function getServices() - { - $services = [ - 'inbound' => [], - 'outbound' => [], - ]; - - if (Addon::isEnabled('blogger')) { - $services['outbound'][] = 'blogger'; - } - if (Addon::isEnabled('dwpost')) { - $services['outbound'][] = 'dreamwidth'; - } - if (Addon::isEnabled('statusnet')) { - $services['inbound'][] = 'gnusocial'; - $services['outbound'][] = 'gnusocial'; - } - if (Addon::isEnabled('ijpost')) { - $services['outbound'][] = 'insanejournal'; - } - if (Addon::isEnabled('libertree')) { - $services['outbound'][] = 'libertree'; - } - if (Addon::isEnabled('buffer')) { - $services['outbound'][] = 'linkedin'; - } - if (Addon::isEnabled('ljpost')) { - $services['outbound'][] = 'livejournal'; - } - if (Addon::isEnabled('buffer')) { - $services['outbound'][] = 'pinterest'; - } - if (Addon::isEnabled('posterous')) { - $services['outbound'][] = 'posterous'; - } - if (Addon::isEnabled('pumpio')) { - $services['inbound'][] = 'pumpio'; - $services['outbound'][] = 'pumpio'; - } - - $services['outbound'][] = 'smtp'; - - if (Addon::isEnabled('tumblr')) { - $services['outbound'][] = 'tumblr'; - } - if (Addon::isEnabled('twitter') || Addon::isEnabled('buffer')) { - $services['outbound'][] = 'twitter'; - } - if (Addon::isEnabled('wppost')) { - $services['outbound'][] = 'wordpress'; - } - - return $services; - } - - /** - * Print the nodeinfo version 1 - */ - private static function printNodeInfo1() - { - $config = DI::config(); - - $nodeinfo = [ - 'version' => '1.0', - 'software' => [ - 'name' => 'friendica', - 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, - ], - 'protocols' => [ - 'inbound' => [ - 'friendica' - ], - 'outbound' => [ - 'friendica' - ], - ], - 'services' => [], - 'usage' => [], - 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, - 'metadata' => [ - 'nodeName' => $config->get('config', 'sitename'), - ], - ]; - - if (!empty($config->get('system', 'diaspora_enabled'))) { - $nodeinfo['protocols']['inbound'][] = 'diaspora'; - $nodeinfo['protocols']['outbound'][] = 'diaspora'; - } - - if (empty($config->get('system', 'ostatus_disabled'))) { - $nodeinfo['protocols']['inbound'][] = 'gnusocial'; - $nodeinfo['protocols']['outbound'][] = 'gnusocial'; - } - - $nodeinfo['usage'] = self::getUsage(); - - $nodeinfo['services'] = self::getServices(); - - $nodeinfo['metadata']['protocols'] = $nodeinfo['protocols']; - $nodeinfo['metadata']['protocols']['outbound'][] = 'atom1.0'; - $nodeinfo['metadata']['protocols']['inbound'][] = 'atom1.0'; - $nodeinfo['metadata']['protocols']['inbound'][] = 'rss2.0'; - - $nodeinfo['metadata']['services'] = $nodeinfo['services']; - - if (Addon::isEnabled('twitter')) { - $nodeinfo['metadata']['services']['inbound'][] = 'twitter'; - } - - $nodeinfo['metadata']['explicitContent'] = $config->get('system', 'explicit_content', false) == true; - - header('Content-type: application/json; charset=utf-8'); - echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - exit; - } - - /** - * Print the nodeinfo version 2.0 - */ - private static function printNodeInfo20() - { - $config = DI::config(); - - $imap = (function_exists('imap_open') && !$config->get('system', 'imap_disabled') && !$config->get('system', 'dfrn_only')); - - $nodeinfo = [ - 'version' => '2.0', - 'software' => [ - 'name' => 'friendica', - 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, - ], - 'protocols' => ['dfrn', 'activitypub'], - 'services' => [], - 'usage' => [], - 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, - 'metadata' => [ - 'nodeName' => $config->get('config', 'sitename'), - ], - ]; - - if (!empty($config->get('system', 'diaspora_enabled'))) { - $nodeinfo['protocols'][] = 'diaspora'; - } - - if (empty($config->get('system', 'ostatus_disabled'))) { - $nodeinfo['protocols'][] = 'ostatus'; - } - - $nodeinfo['usage'] = self::getUsage(); - - $nodeinfo['services'] = self::getServices(); - - if (Addon::isEnabled('twitter')) { - $nodeinfo['services']['inbound'][] = 'twitter'; - } - - $nodeinfo['services']['inbound'][] = 'atom1.0'; - $nodeinfo['services']['inbound'][] = 'rss2.0'; - $nodeinfo['services']['outbound'][] = 'atom1.0'; - - if ($imap) { - $nodeinfo['services']['inbound'][] = 'imap'; - } - - $nodeinfo['metadata']['explicitContent'] = $config->get('system', 'explicit_content', false) == true; - - header('Content-type: application/json; charset=utf-8'); - echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - exit; - } - - /** - * Print the nodeinfo version 2 - */ - private static function printNodeInfo2() - { - $config = DI::config(); - - $imap = (function_exists('imap_open') && !$config->get('system', 'imap_disabled') && !$config->get('system', 'dfrn_only')); - - $nodeinfo = [ - 'version' => '1.0', - 'server' => [ - 'baseUrl' => DI::baseUrl()->get(), - 'name' => $config->get('config', 'sitename'), - 'software' => 'friendica', - 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, - ], - 'organization' => self::getOrganization($config), - 'protocols' => ['dfrn', 'activitypub'], - 'services' => [], - 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, - 'usage' => [], - ]; - - if (!empty($config->get('system', 'diaspora_enabled'))) { - $nodeinfo['protocols'][] = 'diaspora'; - } - - if (empty($config->get('system', 'ostatus_disabled'))) { - $nodeinfo['protocols'][] = 'ostatus'; - } - - $nodeinfo['usage'] = self::getUsage(true); - - $nodeinfo['services'] = self::getServices(); - - if (Addon::isEnabled('twitter')) { - $nodeinfo['services']['inbound'][] = 'twitter'; - } - - $nodeinfo['services']['inbound'][] = 'atom1.0'; - $nodeinfo['services']['inbound'][] = 'rss2.0'; - $nodeinfo['services']['outbound'][] = 'atom1.0'; - - if ($imap) { - $nodeinfo['services']['inbound'][] = 'imap'; - } - - header('Content-type: application/json; charset=utf-8'); - echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - exit; - } - - private static function getOrganization($config) - { - $organization = ['name' => null, 'contact' => null, 'account' => null]; - - if (!empty($config->get('config', 'admin_email'))) { - $adminList = explode(',', str_replace(' ', '', $config->get('config', 'admin_email'))); - $organization['contact'] = $adminList[0]; - $administrator = User::getByEmail($adminList[0], ['username', 'nickname']); - if (!empty($administrator)) { - $organization['name'] = $administrator['username']; - $organization['account'] = DI::baseUrl()->get() . '/profile/' . $administrator['nickname']; - } - } - - return $organization; - } -} diff --git a/src/Module/NodeInfo110.php b/src/Module/NodeInfo110.php new file mode 100644 index 000000000..954f36219 --- /dev/null +++ b/src/Module/NodeInfo110.php @@ -0,0 +1,92 @@ +. + * + */ + +namespace Friendica\Module; + +use Friendica\BaseModule; +use Friendica\Core\Addon; +use Friendica\DI; +use Friendica\Model\Nodeinfo; + +/** + * Version 1.0 of Nodeinfo, a standardized way of exposing metadata about a server running one of the distributed social networks. + * @see https://github.com/jhass/nodeinfo/blob/master/PROTOCOL.md + */ +class NodeInfo110 extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + $config = DI::config(); + + $nodeinfo = [ + 'version' => '1.0', + 'software' => [ + 'name' => 'friendica', + 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, + ], + 'protocols' => [ + 'inbound' => [ + 'friendica' + ], + 'outbound' => [ + 'friendica' + ], + ], + 'services' => [], + 'usage' => [], + 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, + 'metadata' => [ + 'nodeName' => $config->get('config', 'sitename'), + ], + ]; + + if (!empty($config->get('system', 'diaspora_enabled'))) { + $nodeinfo['protocols']['inbound'][] = 'diaspora'; + $nodeinfo['protocols']['outbound'][] = 'diaspora'; + } + + if (empty($config->get('system', 'ostatus_disabled'))) { + $nodeinfo['protocols']['inbound'][] = 'gnusocial'; + $nodeinfo['protocols']['outbound'][] = 'gnusocial'; + } + + $nodeinfo['usage'] = Nodeinfo::getUsage(); + + $nodeinfo['services'] = Nodeinfo::getServices(); + + $nodeinfo['metadata']['protocols'] = $nodeinfo['protocols']; + $nodeinfo['metadata']['protocols']['outbound'][] = 'atom1.0'; + $nodeinfo['metadata']['protocols']['inbound'][] = 'atom1.0'; + $nodeinfo['metadata']['protocols']['inbound'][] = 'rss2.0'; + + $nodeinfo['metadata']['services'] = $nodeinfo['services']; + + if (Addon::isEnabled('twitter')) { + $nodeinfo['metadata']['services']['inbound'][] = 'twitter'; + } + + $nodeinfo['metadata']['explicitContent'] = $config->get('system', 'explicit_content', false) == true; + + header('Content-type: application/json; charset=utf-8'); + echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + exit; + } +} diff --git a/src/Module/NodeInfo120.php b/src/Module/NodeInfo120.php new file mode 100644 index 000000000..330c5e10d --- /dev/null +++ b/src/Module/NodeInfo120.php @@ -0,0 +1,86 @@ +. + * + */ + +namespace Friendica\Module; + +use Friendica\BaseModule; +use Friendica\Core\Addon; +use Friendica\DI; +use Friendica\Model\Nodeinfo; + +/** + * Version 2.0 of Nodeinfo, a standardized way of exposing metadata about a server running one of the distributed social networks. + * @see https://github.com/jhass/nodeinfo/blob/master/PROTOCOL.md + */ +class NodeInfo120 extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + $config = DI::config(); + + $imap = (function_exists('imap_open') && !$config->get('system', 'imap_disabled') && !$config->get('system', 'dfrn_only')); + + $nodeinfo = [ + 'version' => '2.0', + 'software' => [ + 'name' => 'friendica', + 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, + ], + 'protocols' => ['dfrn', 'activitypub'], + 'services' => [], + 'usage' => [], + 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, + 'metadata' => [ + 'nodeName' => $config->get('config', 'sitename'), + ], + ]; + + if (!empty($config->get('system', 'diaspora_enabled'))) { + $nodeinfo['protocols'][] = 'diaspora'; + } + + if (empty($config->get('system', 'ostatus_disabled'))) { + $nodeinfo['protocols'][] = 'ostatus'; + } + + $nodeinfo['usage'] = Nodeinfo::getUsage(); + + $nodeinfo['services'] = Nodeinfo::getServices(); + + if (Addon::isEnabled('twitter')) { + $nodeinfo['services']['inbound'][] = 'twitter'; + } + + $nodeinfo['services']['inbound'][] = 'atom1.0'; + $nodeinfo['services']['inbound'][] = 'rss2.0'; + $nodeinfo['services']['outbound'][] = 'atom1.0'; + + if ($imap) { + $nodeinfo['services']['inbound'][] = 'imap'; + } + + $nodeinfo['metadata']['explicitContent'] = $config->get('system', 'explicit_content', false) == true; + + header('Content-type: application/json; charset=utf-8'); + echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + exit; + } +} diff --git a/src/Module/NodeInfo210.php b/src/Module/NodeInfo210.php new file mode 100644 index 000000000..63a174983 --- /dev/null +++ b/src/Module/NodeInfo210.php @@ -0,0 +1,84 @@ +. + * + */ + +namespace Friendica\Module; + +use Friendica\BaseModule; +use Friendica\Core\Addon; +use Friendica\DI; +use Friendica\Model\Nodeinfo; + +/** + * Version 1.0 of Nodeinfo 2, a sStandardized way of exposing metadata about a server running one of the distributed social networks. + * @see https://github.com/jhass/nodeinfo/blob/master/PROTOCOL.md + */ +class NodeInfo210 extends BaseModule +{ + public static function rawContent(array $parameters = []) + { + $config = DI::config(); + + $imap = (function_exists('imap_open') && !$config->get('system', 'imap_disabled') && !$config->get('system', 'dfrn_only')); + + $nodeinfo = [ + 'version' => '1.0', + 'server' => [ + 'baseUrl' => DI::baseUrl()->get(), + 'name' => $config->get('config', 'sitename'), + 'software' => 'friendica', + 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION, + ], + 'organization' => Nodeinfo::getOrganization($config), + 'protocols' => ['dfrn', 'activitypub'], + 'services' => [], + 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED, + 'usage' => [], + ]; + + if (!empty($config->get('system', 'diaspora_enabled'))) { + $nodeinfo['protocols'][] = 'diaspora'; + } + + if (empty($config->get('system', 'ostatus_disabled'))) { + $nodeinfo['protocols'][] = 'ostatus'; + } + + $nodeinfo['usage'] = Nodeinfo::getUsage(true); + + $nodeinfo['services'] = Nodeinfo::getServices(); + + if (Addon::isEnabled('twitter')) { + $nodeinfo['services']['inbound'][] = 'twitter'; + } + + $nodeinfo['services']['inbound'][] = 'atom1.0'; + $nodeinfo['services']['inbound'][] = 'rss2.0'; + $nodeinfo['services']['outbound'][] = 'atom1.0'; + + if ($imap) { + $nodeinfo['services']['inbound'][] = 'imap'; + } + + header('Content-type: application/json; charset=utf-8'); + echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + exit; + } +} diff --git a/static/routes.config.php b/static/routes.config.php index cb569e01a..ac7882693 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -37,7 +37,7 @@ return [ '/host-meta' => [Module\WellKnown\HostMeta::class, [R::GET]], '/nodeinfo' => [Module\WellKnown\NodeInfo::class, [R::GET]], '/webfinger' => [Module\Xrd::class, [R::GET]], - '/x-nodeinfo2' => [Module\NodeInfo::class, [R::GET]], + '/x-nodeinfo2' => [Module\NodeInfo210::class, [R::GET]], '/x-social-relay' => [Module\WellKnown\XSocialRelay::class, [R::GET]], ], @@ -200,7 +200,8 @@ return [ '/manifest' => [Module\Manifest::class, [R::GET]], '/modexp/{nick}' => [Module\PublicRSAKey::class, [R::GET]], '/newmember' => [Module\Welcome::class, [R::GET]], - '/nodeinfo/{version}' => [Module\NodeInfo::class, [R::GET]], + '/nodeinfo/1.0' => [Module\NodeInfo110::class, [R::GET]], + '/nodeinfo/2.0' => [Module\NodeInfo120::class, [R::GET]], '/nogroup' => [Module\Group::class, [R::GET]], '/noscrape' => [