From 2a1e6e1a74c9a6836b8528a76fdd382d7d7a5160 Mon Sep 17 00:00:00 2001 From: Michael Date: Sun, 12 Jul 2020 21:53:17 +0000 Subject: [PATCH] Support Nodeinfo2 --- src/Model/Nodeinfo.php | 1 + src/Model/User.php | 7 ++++ src/Module/NodeInfo.php | 87 +++++++++++++++++++++++++++++++++++++--- static/routes.config.php | 1 + 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/src/Model/Nodeinfo.php b/src/Model/Nodeinfo.php index d2e168fa5..7ccfefd00 100644 --- a/src/Model/Nodeinfo.php +++ b/src/Model/Nodeinfo.php @@ -55,6 +55,7 @@ class Nodeinfo $config->set('nodeinfo', 'total_users', $userStats['total_users']); $config->set('nodeinfo', 'active_users_halfyear', $userStats['active_users_halfyear']); $config->set('nodeinfo', 'active_users_monthly', $userStats['active_users_monthly']); + $config->set('nodeinfo', 'active_users_weekly', $userStats['active_users_weekly']); $logger->debug('user statistics', $userStats); diff --git a/src/Model/User.php b/src/Model/User.php index 16dfb5122..b4ada344e 100644 --- a/src/Model/User.php +++ b/src/Model/User.php @@ -1272,6 +1272,7 @@ class User 'total_users' => 0, 'active_users_halfyear' => 0, 'active_users_monthly' => 0, + 'active_users_weekly' => 0, ]; $userStmt = DBA::select('owner-view', ['uid', 'login_date', 'last-item'], @@ -1284,6 +1285,7 @@ class User $halfyear = time() - (180 * 24 * 60 * 60); $month = time() - (30 * 24 * 60 * 60); + $week = time() - (7 * 24 * 60 * 60); while ($user = DBA::fetch($userStmt)) { $statistics['total_users']++; @@ -1297,6 +1299,11 @@ class User ) { $statistics['active_users_monthly']++; } + + if ((strtotime($user['login_date']) > $week) || (strtotime($user['last-item']) > $week) + ) { + $statistics['active_users_weekly']++; + } } DBA::close($userStmt); diff --git a/src/Module/NodeInfo.php b/src/Module/NodeInfo.php index 87321489f..eca0ae3e3 100644 --- a/src/Module/NodeInfo.php +++ b/src/Module/NodeInfo.php @@ -24,6 +24,7 @@ namespace Friendica\Module; use Friendica\BaseModule; use Friendica\Core\Addon; use Friendica\DI; +use Friendica\Model\User; use stdClass; /** @@ -34,10 +35,12 @@ class NodeInfo extends BaseModule { public static function rawContent(array $parameters = []) { - if ($parameters['version'] == '1.0') { + if (empty($parameters['version'])) { + self::printNodeInfo2(); + } elseif ($parameters['version'] == '1.0') { self::printNodeInfo1(); } elseif ($parameters['version'] == '2.0') { - self::printNodeInfo2(); + self::printNodeInfo20(); } else { throw new \Friendica\Network\HTTPException\NotFoundException(); } @@ -48,7 +51,7 @@ class NodeInfo extends BaseModule * * @return Object with supported services */ - private static function getUsage() + private static function getUsage(bool $version2 = false) { $config = DI::config(); @@ -62,6 +65,10 @@ class NodeInfo extends BaseModule ]; $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; @@ -189,9 +196,9 @@ class NodeInfo extends BaseModule } /** - * Print the nodeinfo version 2 + * Print the nodeinfo version 2.0 */ - private static function printNodeInfo2() + private static function printNodeInfo20() { $config = DI::config(); @@ -242,4 +249,74 @@ class NodeInfo extends BaseModule 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/static/routes.config.php b/static/routes.config.php index 074c1f571..cb569e01a 100644 --- a/static/routes.config.php +++ b/static/routes.config.php @@ -37,6 +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-social-relay' => [Module\WellKnown\XSocialRelay::class, [R::GET]], ],