3 namespace Friendica\Module;
6 use Friendica\BaseModule;
7 use Friendica\Core\Addon;
8 use Friendica\Core\System;
11 * Standardized way of exposing metadata about a server running one of the distributed social networks.
12 * @see https://github.com/jhass/nodeinfo/blob/master/PROTOCOL.md
14 class NodeInfo extends BaseModule
16 public static function init()
18 $config = self::getApp()->getConfig();
20 if (!$config->get('system', 'nodeinfo')) {
21 System::httpExit(404);
25 public static function rawContent()
27 $app = self::getApp();
29 // @TODO: Replace with parameter from router
30 // if the first argument is ".well-known", print the well-known text
31 if (($app->argc > 1) && ($app->argv[0] == '.well-known')) {
32 self::printWellKnown($app);
33 // otherwise print the nodeinfo
35 self::printNodeInfo($app);
40 * Prints the well-known nodeinfo redirect
44 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
46 private static function printWellKnown(App $app)
48 $config = $app->getConfig();
50 if (!$config->get('system', 'nodeinfo')) {
51 System::httpExit(404);
56 'rel' => 'http://nodeinfo.diaspora.software/ns/schema/1.0',
57 'href' => $app->getBaseURL() . '/nodeinfo/1.0']]
60 header('Content-type: application/json; charset=utf-8');
61 echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
70 private static function printNodeInfo(App $app)
72 $config = $app->getConfig();
74 $smtp = (function_exists('imap_open') && !$config->get('system', 'imap_disabled') && !$config->get('system', 'dfrn_only'));
79 'name' => 'friendica',
80 'version' => FRIENDICA_VERSION . '-' . DB_UPDATE_VERSION,
95 'openRegistrations' => intval($config->get('config', 'register_policy')) !== Register::CLOSED,
97 'nodeName' => $config->get('config', 'sitename'),
101 if (!empty($config->get('system', 'diaspora_enabled'))) {
102 $nodeinfo['protocols']['inbound'][] = 'diaspora';
103 $nodeinfo['protocols']['outbound'][] = 'diaspora';
106 if (empty($config->get('system', 'ostatus_disabled'))) {
107 $nodeinfo['protocols']['inbound'][] = 'gnusocial';
108 $nodeinfo['protocols']['outbound'][] = 'gnusocial';
111 if (!empty($config->get('system', 'nodeinfo'))) {
113 $nodeinfo['usage']['users'] = [
114 'total' => intval($config->get('nodeinfo', 'total_users')),
115 'activeHalfyear' => intval($config->get('nodeinfo', 'active_users_halfyear')),
116 'activeMonth' => intval($config->get('nodeinfo', 'active_users_monthly'))
118 $nodeinfo['usage']['localPosts'] = intval($config->get('nodeinfo', 'local_posts'));
119 $nodeinfo['usage']['localComments'] = intval($config->get('nodeinfo', 'local_comments'));
121 if (Addon::isEnabled('blogger')) {
122 $nodeinfo['services']['outbound'][] = 'blogger';
124 if (Addon::isEnabled('dwpost')) {
125 $nodeinfo['services']['outbound'][] = 'dreamwidth';
127 if (Addon::isEnabled('statusnet')) {
128 $nodeinfo['services']['inbound'][] = 'gnusocial';
129 $nodeinfo['services']['outbound'][] = 'gnusocial';
131 if (Addon::isEnabled('ijpost')) {
132 $nodeinfo['services']['outbound'][] = 'insanejournal';
134 if (Addon::isEnabled('libertree')) {
135 $nodeinfo['services']['outbound'][] = 'libertree';
137 if (Addon::isEnabled('buffer')) {
138 $nodeinfo['services']['outbound'][] = 'linkedin';
140 if (Addon::isEnabled('ljpost')) {
141 $nodeinfo['services']['outbound'][] = 'livejournal';
143 if (Addon::isEnabled('buffer')) {
144 $nodeinfo['services']['outbound'][] = 'pinterest';
146 if (Addon::isEnabled('posterous')) {
147 $nodeinfo['services']['outbound'][] = 'posterous';
149 if (Addon::isEnabled('pumpio')) {
150 $nodeinfo['services']['inbound'][] = 'pumpio';
151 $nodeinfo['services']['outbound'][] = 'pumpio';
155 $nodeinfo['services']['outbound'][] = 'smtp';
157 if (Addon::isEnabled('tumblr')) {
158 $nodeinfo['services']['outbound'][] = 'tumblr';
160 if (Addon::isEnabled('twitter') || Addon::isEnabled('buffer')) {
161 $nodeinfo['services']['outbound'][] = 'twitter';
163 if (Addon::isEnabled('wppost')) {
164 $nodeinfo['services']['outbound'][] = 'wordpress';
166 $nodeinfo['metadata']['protocols'] = $nodeinfo['protocols'];
167 $nodeinfo['metadata']['protocols']['outbound'][] = 'atom1.0';
168 $nodeinfo['metadata']['protocols']['inbound'][] = 'atom1.0';
169 $nodeinfo['metadata']['protocols']['inbound'][] = 'rss2.0';
171 $nodeinfo['metadata']['services'] = $nodeinfo['services'];
173 if (Addon::isEnabled('twitter')) {
174 $nodeinfo['metadata']['services']['inbound'][] = 'twitter';
177 $nodeinfo['metadata']['explicitContent'] = $config->get('system', 'explicit_content', false) == true;
180 header('Content-type: application/json; charset=utf-8');
181 echo json_encode($nodeinfo, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);