From 88fddc81d730978f2a4d8a671936b54041e3fe45 Mon Sep 17 00:00:00 2001 From: Yassine Doghri Date: Thu, 6 Jan 2022 14:26:03 +0000 Subject: [PATCH] feat(nodeinfo2): add .well-known route for nodeinfo2 containing metadata about the castopod instance --- modules/Fediverse/Config/Routes.php | 5 ++ .../Controllers/NodeInfo2Controller.php | 53 +++++++++++++++ modules/Fediverse/Models/ActorModel.php | 67 +++++++++++++++++++ modules/Fediverse/Models/PostModel.php | 26 +++++++ modules/Fediverse/Objects/ActorObject.php | 3 + 5 files changed, 154 insertions(+) create mode 100644 modules/Fediverse/Controllers/NodeInfo2Controller.php diff --git a/modules/Fediverse/Config/Routes.php b/modules/Fediverse/Config/Routes.php index 5df9c97d..c3bf55bc 100644 --- a/modules/Fediverse/Config/Routes.php +++ b/modules/Fediverse/Config/Routes.php @@ -29,6 +29,11 @@ $routes->group('', [ 'as' => 'webfinger', ]); + // nodeInfo2 + $routes->get('.well-known/x-nodeinfo2', 'NodeInfo2Controller', [ + 'as' => 'nodeInfo2', + ]); + // Actor $routes->group('@(:actorUsername)', function ($routes): void { // Actor diff --git a/modules/Fediverse/Controllers/NodeInfo2Controller.php b/modules/Fediverse/Controllers/NodeInfo2Controller.php new file mode 100644 index 00000000..d1ea326d --- /dev/null +++ b/modules/Fediverse/Controllers/NodeInfo2Controller.php @@ -0,0 +1,53 @@ +getTotalLocalActors(); + $totalPosts = model('PostModel') + ->getTotalLocalPosts(); + $activeMonth = model('ActorModel') + ->getActiveLocalActors(1); + $activeHalfyear = model('ActorModel') + ->getActiveLocalActors(6); + + $nodeInfo2 = [ + 'version' => '1.0', + 'server' => [ + 'baseUrl' => base_url(), + 'name' => service('settings') + ->get('App.siteName'), + 'software' => 'Castopod Host', + 'version' => CP_VERSION, + ], + 'protocols' => ['activitypub'], + 'openRegistrations' => config('Auth') + ->allowRegistration, + 'usage' => [ + 'users' => [ + 'total' => $totalUsers, + 'activeMonth' => $activeMonth, + 'activeHalfyear' => $activeHalfyear, + ], + 'localPosts' => $totalPosts, + ], + ]; + + return $this->response->setJSON($nodeInfo2); + } +} diff --git a/modules/Fediverse/Models/ActorModel.php b/modules/Fediverse/Models/ActorModel.php index 3f0592ed..628cca05 100644 --- a/modules/Fediverse/Models/ActorModel.php +++ b/modules/Fediverse/Models/ActorModel.php @@ -205,6 +205,73 @@ class ActorModel extends BaseModel Events::trigger('on_unblock_actor', $actorId); } + public function getTotalLocalActors(): int + { + helper('fediverse'); + + $cacheName = config('Fediverse') + ->cachePrefix . 'blocked_actors'; + if (! ($found = cache($cacheName))) { + $result = $this->select('COUNT(*) as total_local_actors') + ->where('domain', get_current_domain()) + ->get() + ->getResultArray(); + + $found = (int) $result[0]['total_local_actors']; + + cache() + ->save($cacheName, $found, DECADE); + } + + return $found; + } + + public function getActiveLocalActors(int $lastNumberOfMonths = 1): int + { + helper('fediverse'); + + $cacheName = config('Fediverse') + ->cachePrefix . 'blocked_actors'; + if (! ($found = cache($cacheName))) { + $tablePrefix = config('Database') + ->default['DBPrefix'] . config('Fediverse') + ->tablesPrefix; + $result = $this->select('COUNT(DISTINCT `cp_fediverse_actors`.`id`) as `total_active_actors`', false) + ->join( + $tablePrefix . 'posts', + $tablePrefix . 'actors.id = ' . $tablePrefix . 'posts.actor_id', + 'left outer' + ) + ->join( + $tablePrefix . 'favourites', + $tablePrefix . 'actors.id = ' . $tablePrefix . 'favourites.actor_id', + 'left outer' + ) + ->where($tablePrefix . 'actors.domain', get_current_domain()) + ->groupStart() + ->where( + "`{$tablePrefix}posts`.`created_at` >= NOW() - INTERVAL {$lastNumberOfMonths} month", + null, + false + ) + ->orWhere( + "`{$tablePrefix}favourites`.`created_at` >= NOW() - INTERVAL {$lastNumberOfMonths} month", + null, + false + ) + ->groupEnd() + ->get() + ->getResultArray(); + + $found = (int) $result[0]['total_active_actors']; + + cache() + ->save($cacheName, $found, DAY); + } + + return $found; + } + public function clearCache(Actor $actor): void { $cachePrefix = config('Fediverse') diff --git a/modules/Fediverse/Models/PostModel.php b/modules/Fediverse/Models/PostModel.php index 2d390eb3..b3f162f8 100644 --- a/modules/Fediverse/Models/PostModel.php +++ b/modules/Fediverse/Models/PostModel.php @@ -470,6 +470,7 @@ class PostModel extends BaseUuidModel 'actor_id' => $actor->id, 'reblog_of_id' => $post->id, 'published_at' => Time::now(), + 'created_by' => user_id(), ]); // add reblog @@ -593,6 +594,31 @@ class PostModel extends BaseUuidModel } } + public function getTotalLocalPosts(): int + { + helper('fediverse'); + + $cacheName = config('Fediverse') + ->cachePrefix . 'blocked_actors'; + if (! ($found = cache($cacheName))) { + $tablePrefix = config('Fediverse') + ->tablesPrefix; + $result = $this->select('COUNT(*) as total_local_posts') + ->join($tablePrefix . 'actors', $tablePrefix . 'actors.id = ' . $tablePrefix . 'posts.actor_id') + ->where($tablePrefix . 'actors.domain', get_current_domain()) + ->where('`published_at` <= NOW()', null, false) + ->get() + ->getResultArray(); + + $found = (int) $result[0]['total_local_posts']; + + cache() + ->save($cacheName, $found, DECADE); + } + + return $found; + } + public function clearCache(Post $post): void { $cachePrefix = config('Fediverse') diff --git a/modules/Fediverse/Objects/ActorObject.php b/modules/Fediverse/Objects/ActorObject.php index 0914f309..ee1c3890 100644 --- a/modules/Fediverse/Objects/ActorObject.php +++ b/modules/Fediverse/Objects/ActorObject.php @@ -36,6 +36,8 @@ class ActorObject extends ObjectType protected string $url; + protected string $nodeInfo2Url; + /** * @var array */ @@ -59,6 +61,7 @@ class ActorObject extends ObjectType $this->preferredUsername = $actor->username; $this->summary = $actor->summary; $this->url = $actor->uri; + $this->nodeInfo2Url = url_to('nodeInfo2'); $this->inbox = $actor->inbox_url; $this->outbox = $actor->outbox_url;