]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
[NodeInfo] New endpoint and formula for computing active users
authorDiogo Cordeiro <diogo@fc.up.pt>
Mon, 12 Aug 2019 03:45:25 +0000 (04:45 +0100)
committerDiogo Cordeiro <diogo@fc.up.pt>
Mon, 12 Aug 2019 04:35:27 +0000 (05:35 +0100)
Seriously improved documentation
Now NodeInfo 2.0 is available at /api/nodeinfo/2.0.json
For active users we now also consider favourites and recently created accounts
Some further minor bug fixes and full review of the implementation

lib/util.php
plugins/Nodeinfo/NodeinfoPlugin.php
plugins/Nodeinfo/README.md
plugins/Nodeinfo/actions/nodeinfo_2_0.php
plugins/Nodeinfo/actions/nodeinfojrd.php
plugins/Nodeinfo/classes/Usage_stats.php
plugins/Nodeinfo/scripts/fix_stats.php

index 966c415024a8f05ac0e51cf29b45ff96e593176b..704dd0bf4ca39863d6157e2edf5a4031e3c9d280 100644 (file)
@@ -2657,7 +2657,7 @@ function common_strip_html($html, $trim=true, $save_whitespace=false)
  * @param string|bool $size
  * @return int the php.ini upload limit in machine-readable format
  */
-function _common_size_str_to_int($size) : int
+function _common_size_str_to_int($size): int
 {
     // `memory_limit` can be -1 and `post_max_size` can be 0
     // for unlimited. Consistency.
@@ -2692,7 +2692,7 @@ function _common_size_str_to_int($size) : int
  *
  * @return int
  */
-function common_get_preferred_php_upload_limit() : int {
+function common_get_preferred_php_upload_limit(): int {
     return min(_common_size_str_to_int(ini_get('post_max_size')),
                _common_size_str_to_int(ini_get('upload_max_filesize')),
                _common_size_str_to_int(ini_get('memory_limit')));
index 3417603c996aa0b796eadcb71a541ca00e479344..6a3d4e84b3e8cfd2d96fb93c2e1622c609b9bc74 100644 (file)
@@ -1,20 +1,52 @@
 <?php
-
-if (!defined('GNUSOCIAL')) {
-    exit(1);
-}
-
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU social is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Plugin that presents basic instance information using the [NodeInfo standard](http://nodeinfo.diaspora.software/).
+ *
+ * @package   NodeInfo
+ * @author    Stéphane Bérubé <chimo@chromic.org>
+ * @author    Diogo Cordeiro <diogo@fc.up.pt>
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
+
+defined('GNUSOCIAL') || die();
+
+/**
+ * Controls cache and routes
+ *
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
 class NodeinfoPlugin extends Plugin
 {
-    const PLUGIN_VERSION = '1.0.2';
+    const PLUGIN_VERSION = '2.0.0';
 
-    public function onRouterInitialized($m)
+    public function onRouterInitialized($m): bool
     {
-        $m->connect('.well-known/nodeinfo',
-                    ['action' => 'nodeinfojrd']);
+        $m->connect(
+            '.well-known/nodeinfo',
+            ['action' => 'nodeinfojrd']
+        );
 
-        $m->connect('main/nodeinfo/2.0',
-                    ['action' => 'nodeinfo_2_0']);
+        $m->connect(
+            'api/nodeinfo/2.0.json',
+            ['action' => 'nodeinfo_2_0']
+        );
 
         return true;
     }
@@ -22,9 +54,10 @@ class NodeinfoPlugin extends Plugin
     /**
      * Make sure necessary tables are filled out.
      *
-     * @return boolean hook true
+     * @return bool hook true
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-    public function onCheckSchema()
+    public function onCheckSchema(): bool
     {
         // Ensure schema
         $schema = Schema::get();
@@ -55,10 +88,11 @@ class NodeinfoPlugin extends Plugin
     /**
      * Increment notices/replies counter
      *
-     * @return boolean hook flag
+     * @param  Notice $notice
+     * @return bool hook flag
      * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-    public function onStartNoticeDistribute($notice)
+    public function onStartNoticeDistribute(Notice $notice): bool
     {
         assert($notice->id > 0);        // Ignore if not a valid notice
 
@@ -68,16 +102,18 @@ class NodeinfoPlugin extends Plugin
             return true;
         }
 
-        // Ignore for activity/non-post-verb notices
+        // Ignore for activity/non-(post/share)-verb notices
         if (method_exists('ActivityUtils', 'compareVerbs')) {
-            $is_post_verb = ActivityUtils::compareVerbs(
+            $is_valid_verb = ActivityUtils::compareVerbs(
                 $notice->verb,
-                [ActivityVerb::POST]
+                [ActivityVerb::POST,
+                 ActivityVerb::SHARE]
             );
         } else {
-            $is_post_verb = ($notice->verb == ActivityVerb::POST ? true : false);
+            $is_valid_verb = ($notice->verb == ActivityVerb::POST ||
+                              $notice->verb == ActivityVerb::SHARE);
         }
-        if ($notice->source == 'activity' || !$is_post_verb) {
+        if ($notice->source == 'activity' || !$is_valid_verb) {
             return true;
         }
 
@@ -105,10 +141,13 @@ class NodeinfoPlugin extends Plugin
     /**
      * Decrement notices/replies counter
      *
-     * @return boolean hook flag
+     * @param  User $user
+     * @param  Notice $notice
+     * @return bool hook flag
+     * @throws UserNoProfileException
      * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-    public function onStartDeleteOwnNotice($user, $notice)
+    public function onStartDeleteOwnNotice(User $user, Notice $notice): bool
     {
         $profile = $user->getProfile();
 
@@ -133,10 +172,10 @@ class NodeinfoPlugin extends Plugin
     /**
      * Increment users counter
      *
-     * @return boolean hook flag
+     * @return bool hook flag
      * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-    public function onEndRegistrationTry()
+    public function onEndRegistrationTry(): bool
     {
         $us = Usage_stats::getKV('type', 'users');
         $us->count += 1;
@@ -147,10 +186,10 @@ class NodeinfoPlugin extends Plugin
     /**
      * Decrement users counter
      *
-     * @return boolean hook flag
+     * @return bool hook flag
      * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-    public function onEndDeleteUser()
+    public function onEndDeleteUser(): bool
     {
         $us = Usage_stats::getKV('type', 'users');
         $us->count -= 1;
@@ -158,23 +197,38 @@ class NodeinfoPlugin extends Plugin
         return true;
     }
 
-
-    public function onPluginVersion(array &$versions)
+    /**
+     * Plugin version information
+     *
+     * @param  array $versions
+     * @return bool hook true
+     * @throws Exception
+     */
+    public function onPluginVersion(array &$versions): bool
     {
-        $versions[] = ['name' => 'Nodeinfo',
+        $versions[] = [
+            'name' => 'Nodeinfo',
             'version' => self::PLUGIN_VERSION,
-            'author' => 'chimo',
-            'homepage' => 'https://github.com/chimo/gs-nodeinfo',
-            'description' => _m('Plugin that presents basic instance information using the NodeInfo standard.')];
+            'author' => 'Stéphane Bérubé, Diogo Cordeiro',
+            'homepage' => 'https://code.chromic.org/chimo/gs-nodeinfo',
+            'description' => _m('Plugin that presents basic instance information using the NodeInfo standard.')
+        ];
         return true;
     }
 
-    public function onEndUpgrade()
+    /**
+     * Cache was added in a newer version of the plugin, this ensures we fix cached values on upgrade
+     *
+     * @return bool hook flag
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     */
+    public function onEndUpgrade(): bool
     {
         $users = new Usage_stats();
         if ($users->getUserCount() == 0) {
             define('NODEINFO_UPGRADE', true);
             require_once __DIR__ . DIRECTORY_SEPARATOR . 'scripts' . DIRECTORY_SEPARATOR . 'fix_stats.php';
         }
+        return true;
     }
 }
index 872e201470b99546d05011db5a04555f67f21c4a..78f976c56031871cde8446e8f887dcd0ac0c31af 100644 (file)
@@ -1,7 +1,8 @@
-# Nodeinfo plugin for GNU social
+# Nodeinfo support for GNU social
 
 Plugin that presents basic instance information using the [NodeInfo standard](http://nodeinfo.diaspora.software/).
 
-At the moment, the information is presented at the "/main/nodeinfo/2.0" endpoint.
+The information is presented at the "/nodeinfo/2.0.json" endpoint.
 
-Other tools can then scrape that information and present it in various ways. For example: [https://fediverse.network/](https://fediverse.network/)
+Other tools can then scrape that information and present it in various ways.
+For example: [https://fediverse.network/](https://fediverse.network/)
index 63f59e11e4bccfd9542067e25e9d96dddec6ec8a..2150bfb5e899fe68c940a23dfb3c12e26d5fbb8f 100644 (file)
@@ -1,43 +1,78 @@
 <?php
-
-if (!defined('GNUSOCIAL')) {
-    exit(1);
-}
-
-class Nodeinfo_2_0Action extends ApiAction
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU social is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * The information is presented at the "api/nodeinfo/2.0.json" endpoint.
+ *
+ * @package   NodeInfo
+ * @author    Stéphane Bérubé <chimo@chromic.org>
+ * @author    Diogo Cordeiro <diogo@fc.up.pt>
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
+
+defined('GNUSOCIAL') || die();
+
+/**
+ * NodeInfo 2.0
+ *
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
+class Nodeinfo_2_0Action extends Action
 {
     private $plugins;
 
-    protected function handle()
+    protected function handle(): void
     {
         parent::handle();
-
+        header('Access-Control-Allow-Origin: *');
         $this->plugins = $this->getActivePluginList();
-
         $this->showNodeInfo();
     }
 
-    public function getActivePluginList()
+    /**
+     * Most functionality depends on the active plugins, this gives us enough information concerning that
+     *
+     * @return array
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     */
+    public function getActivePluginList(): array
     {
-        $pluginversions = array();
-        $plugins = array();
+        $plugin_version = [];
+        $plugins = [];
 
-        Event::handle('PluginVersion', array(&$pluginversions));
+        Event::handle('PluginVersion', [&$plugin_version]);
 
-        foreach ($pluginversions as $plugin) {
-            $plugins[strtolower($plugin['name'])] = 1;
+        foreach ($plugin_version as $plugin) {
+            $plugins[str_replace(' ', '', strtolower($plugin['name']))] = true;
         }
 
         return $plugins;
     }
 
-    /*
-     * Technically, the NodeInfo spec defines 'active' as 'signed in at least once',
-     * but GNU social doesn't keep track of when users last logged in, so let's return
-     * the number of users that 'posted at least once', I guess.
+    /**
+     * The NodeInfo page
+     *
+     * @return void
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
      */
-
-    public function showNodeInfo()
+    public function showNodeInfo(): void
     {
         $openRegistrations = $this->getRegistrationsStatus();
         $userCount = $this->getUserCount();
@@ -51,129 +86,316 @@ class Nodeinfo_2_0Action extends ApiAction
         $inboundServices = $this->getInboundServices();
         $outboundServices = $this->getOutboundServices();
 
+        $metadata = $this->getMetadata();
+
+        /* Required NodeInfo fields
+              "version",
+              "software",
+              "protocols",
+              "services",
+              "openRegistrations",
+              "usage",
+              "metadata"
+         */
+
         $json = json_encode([
+            // The schema version, must be 2.0.
             'version' => '2.0',
 
+            // [Mandatory] Metadata about server software in use.
             'software' => [
-                'name' => 'gnusocial',
-                'version' => GNUSOCIAL_VERSION
+                'name' => 'gnusocial', // The canonical name of this server software.
+                'version' => GNUSOCIAL_VERSION // The version of this server software.
             ],
 
+            // The protocols supported on this server.
+            // The spec requires an array containing at least 1 item but we can't ensure that.
             'protocols' => $protocols,
 
-            // TODO: Have plugins register services
+            // The third party sites this server can connect to via their application API.
             'services' => [
+                // The third party sites this server can retrieve messages from for combined display with regular traffic.
                 'inbound' => $inboundServices,
+                // The third party sites this server can publish messages to on the behalf of a user.
                 'outbound' => $outboundServices
             ],
 
+            // Whether this server allows open self-registration.
             'openRegistrations' => $openRegistrations,
 
+            // Usage statistics for this server.
             'usage' => [
                 'users' => [
+                    // The total amount of on this server registered users.
                     'total' => $userCount,
+                    // The amount of users that signed in at least once in the last 180 days.
                     'activeHalfyear' => $usersActiveHalfyear,
+                    // The amount of users that signed in at least once in the last 30 days.
                     'activeMonth' => $usersActiveMonth
                 ],
+                // The amount of posts that were made by users that are registered on this server.
                 'localPosts' => $postCount,
+                // The amount of comments that were made by users that are registered on this server.
                 'localComments' => $commentCount
             ],
 
-            'metadata' => new stdClass()
+            // Free form key value pairs for software specific values. Clients should not rely on any specific key present.
+            'metadata' => $metadata
         ]);
 
-        $this->initDocument('json');
+        header('Content-Type: application/json; profile=http://nodeinfo.diaspora.software/ns/schema/2.0#; charset=utf-8');
         print $json;
-        $this->endDocument('json');
     }
 
-    public function getRegistrationsStatus()
-    {
-        $areRegistrationsClosed = (common_config('site', 'closed')) ? true : false;
-        $isSiteInviteOnly = (common_config('site', 'inviteonly')) ? true : false;
-
-        return !($areRegistrationsClosed || $isSiteInviteOnly);
-    }
-
-    public function getUserCount()
-    {
-        $users = new Usage_stats();
-        $userCount = $users->getUserCount();
-
-        return $userCount;
-    }
-
-    public function getPostCount()
-    {
-        $posts = new Usage_stats();
-        $postCount = $posts->getPostCount();
-
-        return $postCount;
-    }
-
-    public function getCommentCount()
-    {
-        $comments = new Usage_stats();
-        $commentCount = $comments->getCommentCount();
-
-        return $commentCount;
-    }
-
-    public function getActiveUsers($days)
-    {
-        $notices = new Notice();
-        $notices->joinAdd(array('profile_id', 'user:id'));
-        $notices->whereAdd('notice.created >= NOW() - INTERVAL ' . $days . ' DAY');
-
-        $activeUsersCount = $notices->count('distinct profile_id');
-
-        return $activeUsersCount;
-    }
-
-    public function getProtocols()
+    /**
+     * The protocols supported on this server.
+     * The spec requires an array containing at least 1 item but we can't ensure that
+     *
+     * These can only be one of:
+     *  - activitypub,
+     *  - buddycloud,
+     *  - dfrn,
+     *  - diaspora,
+     *  - libertree,
+     *  - ostatus,
+     *  - pumpio,
+     *  - tent,
+     *  - xmpp,
+     *  - zot
+     *
+     * @return array
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     */
+    public function getProtocols(): array
     {
         $protocols = [];
 
-        Event::handle('NodeInfoProtocols', array(&$protocols));
+        Event::handle('NodeInfoProtocols', [&$protocols]);
 
         return $protocols;
     }
 
-    public function getInboundServices()
+    /**
+     * The third party sites this server can retrieve messages from for combined display with regular traffic.
+     *
+     * These can only be one of:
+     *  - atom1.0,
+     *  - gnusocial,
+     *  - imap,
+     *  - pnut,
+     *  - pop3,
+     *  - pumpio,
+     *  - rss2.0,
+     *  - twitter
+     *
+     * @return array
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getInboundServices(): array
     {
-        // FIXME: Are those always on?
-        $inboundServices = array('atom1.0', 'rss2.0');
+        $inboundServices = [];
+        $ostatusEnabled = array_key_exists('ostatus', $this->plugins);
+
+        // We need those two to read feeds (despite WebSub).
+        if ($ostatusEnabled && array_key_exists('feedpoller', $this->plugins)) {
+            $inboundServices[] = 'atom1.0';
+            $inboundServices[] = 'rss2.0';
+        }
 
         if (array_key_exists('twitterbridge', $this->plugins) && common_config('twitterimport', 'enabled')) {
             $inboundServices[] = 'twitter';
         }
 
-        if (array_key_exists('ostatus', $this->plugins)) {
+        if (array_key_exists('imap', $this->plugins)) {
+            $inboundServices[] = 'imap';
+        }
+
+        // We can receive messages from another GNU social instance if we have at least one of those enabled.
+        // And the same happens in the other instance
+        if ($ostatusEnabled || array_key_exists('activitypub', $this->plugins)) {
             $inboundServices[] = 'gnusocial';
         }
 
         return $inboundServices;
     }
 
-    public function getOutboundServices()
+    /**
+     * The third party sites this server can publish messages to on the behalf of a user.
+     *
+     * These can only be one of:
+     *  - atom1.0,
+     *  - blogger,
+     *  - buddycloud,
+     *  - diaspora,
+     *  - dreamwidth,
+     *  - drupal,
+     *  - facebook,
+     *  - friendica,
+     *  - gnusocial,
+     *  - google,
+     *  - insanejournal,
+     *  - libertree,
+     *  - linkedin,
+     *  - livejournal,
+     *  - mediagoblin,
+     *  - myspace,
+     *  - pinterest,
+     *  - pnut,
+     *  - posterous,
+     *  - pumpio,
+     *  - redmatrix,
+     *  - rss2.0,
+     *  - smtp,
+     *  - tent,
+     *  - tumblr,
+     *  - twitter,
+     *  - wordpress,
+     *  - xmpp
+     *
+     * @return array
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getOutboundServices(): array
     {
-        $xmppEnabled = (array_key_exists('xmpp', $this->plugins) && common_config('xmpp', 'enabled')) ? true : false;
-
-        // FIXME: Are those always on?
-        $outboundServices = array('atom1.0', 'rss2.0');
+        // Those two are always available
+        $outboundServices = ['atom1.0', 'rss2.0'];
 
         if (array_key_exists('twitterbridge', $this->plugins)) {
             $outboundServices[] = 'twitter';
         }
 
-        if (array_key_exists('ostatus', $this->plugins)) {
+        // We can send messages to another GNU social instance if we have at least one of those enabled.
+        // And the same happens in the other instance
+        if (array_key_exists('ostatus', $this->plugins) ||
+            array_key_exists('activitypub', $this->plugins)) {
             $outboundServices[] = 'gnusocial';
         }
 
+        $xmppEnabled = (array_key_exists('xmpp', $this->plugins) && common_config('xmpp', 'enabled')) ? true : false;
         if ($xmppEnabled) {
             $outboundServices[] = 'xmpp';
         }
 
         return $outboundServices;
     }
+
+    /**
+     * Whether this server allows open self-registration.
+     *
+     * @return bool
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getRegistrationsStatus(): bool
+    {
+        $areRegistrationsClosed = (common_config('site', 'closed')) ? true : false;
+        $isSiteInviteOnly = (common_config('site', 'inviteonly')) ? true : false;
+
+        return !($areRegistrationsClosed || $isSiteInviteOnly);
+    }
+
+    /**
+     * The total amount of on this server registered users.
+     *
+     * @return int
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getUserCount(): int
+    {
+        $users = new Usage_stats();
+        $userCount = $users->getUserCount();
+
+        return $userCount;
+    }
+
+    /**
+     * The amount of users that were active at least once in the last $days days.
+     *
+     * Technically, the NodeInfo spec defines 'active' as 'signed in at least once in the
+     * last {180, 30} days depending on request', but GNU social doesn't keep track of when
+     * users last logged in.
+     *
+     * Therefore, we use Favourites, Notices and Date of account creation to underestimate a
+     * value. Underestimate because a user that only logs in to see his feed is too an active
+     * user.
+     *
+     * @param  int $days
+     * @return int
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     */
+    public function getActiveUsers(int $days): int
+    {
+        $query = "
+         SELECT COUNT(DISTINCT profile_id) as active_users_count
+         FROM (
+            SELECT profile_id FROM notice WHERE notice.created >= NOW() - INTERVAL {$days} DAY AND notice.is_local = 1
+            UNION ALL
+            SELECT user_id FROM fave INNER JOIN user ON fave.user_id = user.id WHERE fave.created >= NOW() - INTERVAL {$days} DAY
+            UNION ALL
+            SELECT id FROM user WHERE user.created >= NOW() - INTERVAL {$days} DAY
+         ) as source";
+
+        $activeUsersCount = new DB_DataObject();
+        $activeUsersCount->query($query);
+        $activeUsersCount->fetch();
+        return $activeUsersCount->active_users_count;
+    }
+
+    /**
+     * The amount of posts that were made by users that are registered on this server.
+     *
+     * @return int
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getPostCount(): int
+    {
+        $posts = new Usage_stats();
+        $postCount = $posts->getPostCount();
+
+        return $postCount;
+    }
+
+    /**
+     * The amount of comments that were made by users that are registered on this server.
+     *
+     * @return int
+     * @author Stéphane Bérubé <chimo@chromic.org>
+     */
+    public function getCommentCount(): int
+    {
+        $comments = new Usage_stats();
+        $commentCount = $comments->getCommentCount();
+
+        return $commentCount;
+    }
+
+    /**
+     * Some additional information related to this GNU social instance
+     *
+     * @return array
+     * @author Diogo Cordeiro <diogo@fc.up.pt>
+     */
+    public function getMetadata(): array
+    {
+        $metadata = [
+            'nodeName' => common_config('site', 'name'),
+            'software' => [
+                'homepage' => 'https://gnu.social/',
+                'repository' => 'https://notabug.org/diogo/gnu-social',
+            ],
+            'uploadLimit' => common_get_preferred_php_upload_limit(),
+            'postFormats' => [
+                'text/plain',
+                'text/html'
+            ],
+            'features' => []
+        ];
+
+        if (array_key_exists('poll', $this->plugins)) {
+            $metadata['features'][] = 'polls';
+        }
+
+        return $metadata;
+    }
 }
index d7a28291449a3d6babbc7f51449fece5cf4ba3a3..4efb3302acca601a05f490c4e4ba3faff2dfa5e2 100644 (file)
@@ -1,9 +1,36 @@
 <?php
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU social is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
 
-if (!defined('GNUSOCIAL')) {
-    exit(1);
-}
+/**
+ * Provided in /.well-known/nodeinfo
+ *
+ * @package   NodeInfo
+ * @author    Stéphane Bérubé <chimo@chromic.org>
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
+
+defined('GNUSOCIAL') || die();
 
+/**
+ * JRD document for NodeInfo
+ *
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
+ */
 class NodeinfoJRDAction extends XrdAction
 {
     const NODEINFO_2_0_REL = 'http://nodeinfo.diaspora.software/ns/schema/2.0';
index 48148b015cefab012e6120b26eb4af90d0405c60..64cc64934baec39b9f918a413aca27118c0e9e5e 100644 (file)
@@ -1,72 +1,91 @@
 <?php
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU social is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
- * GNU social - a federating social network
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
+ * Table for storing Nodeinfo statistics
  *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * @package   NodeInfo
+ * @author    Diogo Cordeiro <diogo@fc.up.pt>
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  */
 
-if (!defined('GNUSOCIAL')) {
-    exit(1);
-}
+defined('GNUSOCIAL') || die();
 
 /**
- * Table Definition for Usage_stats
+ * Table Definition for usage_stats and some getters
+ *
+ * @copyright 2018-2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  */
 class Usage_stats extends Managed_DataObject
 {
-    ###START_AUTOCODE
-    /* the code below is auto generated do not remove the above tag */
-
     public $__table = 'usage_stats';         // table name
     public $type;                            // varchar(191)  unique_key   not 255 because utf8mb4 takes more space
     public $count;                           // int(4)
-    public $modified;                        // timestamp()   not_null default_CURRENT_TIMESTAMP
+    public $modified;                        // datetime()   not_null default_CURRENT_TIMESTAMP
 
-    /* the code above is auto generated do not remove the tag below */
-    ###END_AUTOCODE
-
-    public static function schemaDef()
+    /**
+     * Table Definition for usage_stats
+     *
+     * @return array
+     */
+    public static function schemaDef(): array
     {
         return [
             'description' => 'node stats',
             'fields' => [
-                'type' => ['type' => 'varchar', 'length' => 191, 'description' => 'Type of countable entity'],
+                'type' => ['type' => 'varchar', 'not null' => true, 'length' => 191, 'description' => 'Type of countable entity'],
                 'count' => ['type' => 'int', 'size' => 'int', 'default' => 0, 'description' => 'Number of entities of this type'],
-                'modified' => ['type' => 'timestamp', 'not null' => true, 'description' => 'date this record was modified'],
+                'modified' => ['type' => 'datetime', 'not null' => true, 'default' => 'CURRENT_TIMESTAMP', 'description' => 'date this record was modified'],
             ],
             'primary key' => ['type'],
-            'unique keys' => [
-                'usage_stats_key' => ['type'],
-            ],
             'indexes' => [
                 'user_stats_idx' => ['type'],
             ],
         ];
     }
 
-    public function getUserCount()
+    /**
+     * Total number of users
+     *
+     * @return int
+     */
+    public function getUserCount(): int
     {
-        return intval(Usage_stats::getKV('type', 'users')->count);
+        return Usage_stats::getKV('type', 'users')->count;
     }
 
-    public function getPostCount()
+    /**
+     * Total number of dents
+     *
+     * @return int
+     */
+    public function getPostCount(): int
     {
-        return intval(Usage_stats::getKV('type', 'posts')->count);
+        return Usage_stats::getKV('type', 'posts')->count;
     }
 
-    public function getCommentCount()
+    /**
+     * Total number of replies
+     *
+     * @return int
+     */
+    public function getCommentCount(): int
     {
-        return intval(Usage_stats::getKV('type', 'comments')->count);
+        return Usage_stats::getKV('type', 'comments')->count;
     }
 }
index a34e24f8273457683c834e769c9750c0e33329a1..7876442da61090e4c74f96528c62e38bd7280559 100755 (executable)
@@ -1,32 +1,32 @@
 #!/usr/bin/env php
 <?php
+// This file is part of GNU social - https://www.gnu.org/software/social
+//
+// GNU social is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// GNU social is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with GNU social.  If not, see <http://www.gnu.org/licenses/>.
+
 /**
- * GNU social - a federating social network
- *
- * LICENCE: This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ * Fix Nodeinfo statistics
  *
- * @category  Plugin
- * @package   GNUsocial
- * @copyright 2018 Free Software Foundation http://fsf.org
- * @license   http://www.fsf.org/licensing/licenses/agpl-3.0.html GNU Affero General Public License version 3.0
- * @link      https://www.gnu.org/software/social/
+ * @package   NodeInfo
+ * @author    Diogo Cordeiro <diogo@fc.up.pt>
+ * @copyright 2019 Free Software Foundation, Inc http://www.fsf.org
+ * @license   https://www.gnu.org/licenses/agpl.html GNU AGPL v3 or later
  */
 
-define('INSTALLDIR', realpath(__DIR__ . '/../../..'));
+define('INSTALLDIR', dirname(dirname(dirname(__DIR__))));
 
 if (!defined('NODEINFO_UPGRADE')) {
-
     $longoptions = ['type='];
 
     $helptext = <<<END_OF_HELP
@@ -53,7 +53,6 @@ END_OF_HELP;
     if ($verbose) {
         echo "Started.\n\n";
     }
-
 } else {
     echo "Nodeinfo will now fix stats\n";
     $type_to_fix = 'all';
@@ -95,7 +94,13 @@ if ($verbose) {
  * Counting functions
  */
 
-function getUserCount()
+/**
+ * Total number of users
+ *
+ * @return int
+ * @author Stéphane Bérubé <chimo@chromic.org>
+ */
+function getUserCount(): int
 {
     $users = new User();
     $userCount = $users->count();
@@ -103,6 +108,12 @@ function getUserCount()
     return $userCount;
 }
 
+/**
+ * Total number of dents
+ *
+ * @return int
+ * @author Stéphane Bérubé <chimo@chromic.org>
+ */
 function getPostCount()
 {
     $notices = new Notice();
@@ -113,6 +124,12 @@ function getPostCount()
     return $noticeCount;
 }
 
+/**
+ * Total number of replies
+ *
+ * @return int
+ * @author Stéphane Bérubé <chimo@chromic.org>
+ */
 function getCommentCount()
 {
     $notices = new Notice();