diff --git a/doc/htconfig.md b/doc/htconfig.md index 3f21dccba..0b9d1cdd2 100644 --- a/doc/htconfig.md +++ b/doc/htconfig.md @@ -85,11 +85,6 @@ Example: To set the automatic database cleanup process add this line to your .ht * **proxy_cache_time** - Time after which the cache is cleared. Default value is one day. * **pushpoll_frequency** - * **qsearch_limit** - Default value is 100. -* **relay_server** - Experimental Diaspora feature. Address of the relay server where public posts should be send to. For example https://podrelay.net -* **relay_subscribe** (Boolean) - Enables the receiving of public posts from the relay. They will be included in the search and on the community page when it is set up to show all public items. -* **relay_scope** - Can be "all" or "tags". "all" means that every public post should be received. "tags" means that only posts with selected tags should be received. -* **relay_server_tags** - Comma separated list of tags for the "tags" subscription (see "relay_scrope") -* **relay_user_tags** (Boolean) - If enabled, the tags from the saved searches will used for the "tags" subscription in addition to the "relay_server_tags". * **remove_multiplicated_lines** (Boolean) - If enabled, multiple linefeeds in items are stripped to a single one. * **show_unsupported_addons** (Boolean) - Show all addons including the unsupported ones. * **show_unsupported_themes** (Boolean) - Show all themes including the unsupported ones. diff --git a/mod/admin.php b/mod/admin.php index 7fed765a7..e4d3b0a75 100644 --- a/mod/admin.php +++ b/mod/admin.php @@ -960,11 +960,19 @@ function admin_page_site_post(App $a) $only_tag_search = ((x($_POST,'only_tag_search')) ? True : False); $rino = ((x($_POST,'rino')) ? intval($_POST['rino']) : 0); $check_new_version_url = ((x($_POST, 'check_new_version_url')) ? notags(trim($_POST['check_new_version_url'])) : 'none'); + $worker_queues = ((x($_POST,'worker_queues')) ? intval($_POST['worker_queues']) : 4); $worker_dont_fork = ((x($_POST,'worker_dont_fork')) ? True : False); $worker_fastlane = ((x($_POST,'worker_fastlane')) ? True : False); $worker_frontend = ((x($_POST,'worker_frontend')) ? True : False); + $relay_directly = ((x($_POST,'relay_directly')) ? True : False); + $relay_server = ((x($_POST,'relay_server')) ? notags(trim($_POST['relay_server'])) : ''); + $relay_subscribe = ((x($_POST,'relay_subscribe')) ? True : False); + $relay_scope = ((x($_POST,'relay_scope')) ? notags(trim($_POST['relay_scope'])) : ''); + $relay_server_tags = ((x($_POST,'relay_server_tags')) ? notags(trim($_POST['relay_server_tags'])) : ''); + $relay_user_tags = ((x($_POST,'relay_user_tags')) ? True : False); + // Has the directory url changed? If yes, then resubmit the existing profiles there if ($global_directory != Config::get('system', 'directory') && ($global_directory != '')) { Config::set('system', 'directory', $global_directory); @@ -1118,10 +1126,19 @@ function admin_page_site_post(App $a) Config::set('system', 'basepath', $basepath); Config::set('system', 'proxy_disabled', $proxy_disabled); Config::set('system', 'only_tag_search', $only_tag_search); + Config::set('system', 'worker_queues', $worker_queues); Config::set('system', 'worker_dont_fork', $worker_dont_fork); Config::set('system', 'worker_fastlane', $worker_fastlane); Config::set('system', 'frontend_worker', $worker_frontend); + + Config::set('system', 'relay_directly', $relay_directly); + Config::set('system', 'relay_server', $relay_server); + Config::set('system', 'relay_subscribe', $relay_subscribe); + Config::set('system', 'relay_scope', $relay_scope); + Config::set('system', 'relay_server_tags', $relay_server_tags); + Config::set('system', 'relay_user_tags', $relay_user_tags); + Config::set('system', 'rino_encrypt', $rino); info(L10n::t('Site settings updated.') . EOL); @@ -1270,6 +1287,7 @@ function admin_page_site(App $a) '$portable_contacts' => L10n::t('Auto Discovered Contact Directory'), '$performance' => L10n::t('Performance'), '$worker_title' => L10n::t('Worker'), + '$relay_title' => L10n::t('Message Relay'), '$relocate' => L10n::t('Relocate - WARNING: advanced function. Could make this server unreachable.'), '$baseurl' => System::baseUrl(true), // name, label, value, help string, extra data... @@ -1349,13 +1367,20 @@ function admin_page_site(App $a) '$relocate_url' => ['relocate_url', L10n::t("New base url"), System::baseUrl(), L10n::t("Change base url for this server. Sends relocate message to all Friendica and Diaspora* contacts of all users.")], - '$rino' => ['rino', L10n::t("RINO Encryption"), intval(Config::get('system','rino_encrypt')), L10n::t("Encryption layer between nodes."), [0 => "Disabled", 1 => "Enabled"]], + '$rino' => ['rino', L10n::t("RINO Encryption"), intval(Config::get('system','rino_encrypt')), L10n::t("Encryption layer between nodes."), [0 => L10n::t("Disabled"), 1 => L10n::t("Enabled")]], '$worker_queues' => ['worker_queues', L10n::t("Maximum number of parallel workers"), Config::get('system','worker_queues'), L10n::t("On shared hosters set this to 2. On larger systems, values of 10 are great. Default value is 4.")], '$worker_dont_fork' => ['worker_dont_fork', L10n::t("Don't use 'proc_open' with the worker"), Config::get('system','worker_dont_fork'), L10n::t("Enable this if your system doesn't allow the use of 'proc_open'. This can happen on shared hosters. If this is enabled you should increase the frequency of worker calls in your crontab.")], '$worker_fastlane' => ['worker_fastlane', L10n::t("Enable fastlane"), Config::get('system','worker_fastlane'), L10n::t("When enabed, the fastlane mechanism starts an additional worker if processes with higher priority are blocked by processes of lower priority.")], '$worker_frontend' => ['worker_frontend', L10n::t('Enable frontend worker'), Config::get('system','frontend_worker'), L10n::t('When enabled the Worker process is triggered when backend access is performed \x28e.g. messages being delivered\x29. On smaller sites you might want to call %s/worker on a regular basis via an external cron job. You should only enable this option if you cannot utilize cron/scheduled jobs on your server.', System::baseUrl())], + '$relay_subscribe' => ['relay_subscribe', L10n::t("Subscribe to relay"), Config::get('system','relay_subscribe'), L10n::t("Enables the receiving of public posts from the relay. They will be included in the search, subscribed tags and on the global community page.")], + '$relay_server' => ['relay_server', L10n::t("Relay server"), Config::get('system','relay_server'), L10n::t("Address of the relay server where public posts should be send to. For example https://relay.diasp.org")], + '$relay_directly' => ['relay_directly', L10n::t("Direct relay transfer"), Config::get('system','relay_directly'), L10n::t("Enables the direct transfer to other servers without using the relay servers")], + '$relay_scope' => ['relay_scope', L10n::t("Relay scope"), Config::get('system','relay_scope'), L10n::t("Can be 'all' or 'tags'. 'all' means that every public post should be received. 'tags' means that only posts with selected tags should be received."), ['' => L10n::t('Disabled'), 'all' => L10n::t('all'), 'tags' => L10n::t('tags')]], + '$relay_server_tags' => ['relay_server_tags', L10n::t("Server tags"), Config::get('system','relay_server_tags'), L10n::t("Comma separated list of tags for the 'tags' subscription.")], + '$relay_user_tags' => ['relay_user_tags', L10n::t("Allow user tags"), Config::get('system','relay_user_tags'), L10n::t("If enabled, the tags from the saved searches will used for the 'tags' subscription in addition to the 'relay_server_tags'.")], + '$form_security_token' => get_form_security_token("admin_site") ]); } diff --git a/src/Protocol/Diaspora.php b/src/Protocol/Diaspora.php index f925dc9b5..23bc575dd 100644 --- a/src/Protocol/Diaspora.php +++ b/src/Protocol/Diaspora.php @@ -47,60 +47,100 @@ class Diaspora /** * @brief Return a list of relay servers * - * This is an experimental Diaspora feature. + * The list contains not only the official relays but also servers that we serve directly * + * @param integer $item_id The id of the item that is sent * @return array of relay servers */ - public static function relayList() + public static function relayList($item_id) { + $serverlist = []; + + // Fetching relay servers $serverdata = Config::get("system", "relay_server"); - if ($serverdata == "") { - return []; - } - - $relay = []; - - $servers = explode(",", $serverdata); - - foreach ($servers as $server) { - $server = trim($server); - $addr = "relay@".str_replace("http://", "", normalise_link($server)); - $batch = $server."/receive/public"; - - $relais = q( - "SELECT `batch`, `id`, `name`,`network` FROM `contact` WHERE `uid` = 0 AND `batch` = '%s' AND `addr` = '%s' AND `nurl` = '%s' LIMIT 1", - dbesc($batch), - dbesc($addr), - dbesc(normalise_link($server)) - ); - - if (!$relais) { - $r = q( - "INSERT INTO `contact` (`uid`, `created`, `name`, `nick`, `addr`, `url`, `nurl`, `batch`, `network`, `rel`, `blocked`, `pending`, `writable`, `name-date`, `uri-date`, `avatar-date`) - VALUES (0, '%s', '%s', 'relay', '%s', '%s', '%s', '%s', '%s', %d, 0, 0, 1, '%s', '%s', '%s')", - DateTimeFormat::utcNow(), - dbesc($addr), - dbesc($addr), - dbesc($server), - dbesc(normalise_link($server)), - dbesc($batch), - dbesc(NETWORK_DIASPORA), - intval(CONTACT_IS_FOLLOWER), - dbesc(DateTimeFormat::utcNow()), - dbesc(DateTimeFormat::utcNow()), - dbesc(DateTimeFormat::utcNow()) - ); - - $relais = q("SELECT `batch`, `id`, `name`,`network` FROM `contact` WHERE `uid` = 0 AND `batch` = '%s' LIMIT 1", dbesc($batch)); - if ($relais) { - $relay[] = $relais[0]; - } - } else { - $relay[] = $relais[0]; + if ($serverdata != "") { + $servers = explode(",", $serverdata); + foreach ($servers as $server) { + $serverlist[$server] = trim($server); } } - return $relay; + if (Config::get("system", "relay_directly", false)) { + // Servers that want to get all content + $servers = dba::select('gserver', ['url'], ['relay-subscribe' => true, 'relay-scope' => 'all']); + while ($server = dba::fetch($servers)) { + $serverlist[$server['url']] = $server['url']; + } + + // All tags of the current post + $condition = ['otype' => TERM_OBJ_POST, 'type' => TERM_HASHTAG, 'oid' => $item_id]; + $tags = dba::select('term', ['term'], $condition); + $taglist = []; + while ($tag = dba::fetch($tags)) { + $taglist[] = $tag['term']; + } + + // All servers who wants content with this tag + $tagserverlist = []; + $tagserver = dba::select('gserver-tag', ['gserver-id'], ['tag' => $taglist]); + while ($server = dba::fetch($tagserver)) { + $tagserverlist[] = $server['gserver-id']; + } + + // All adresses with the given id + $servers = dba::select('gserver', ['url'], ['relay-subscribe' => true, 'relay-scope' => 'tags', 'id' => $tagserverlist]); + while ($server = dba::fetch($servers)) { + $serverlist[$server['url']] = $server['url']; + } + } + + // Now we are collecting all relay contacts + $contacts = []; + foreach ($serverlist as $server_url) { + // We don't send messages to ourselves + if (!link_compare($server_url, System::baseUrl())) { + $contacts[] = self::getRelayContactId($server_url); + } + } + + return $contacts; + } + + /** + * @brief Return a contact for a given server address or creates a dummy entry + * + * @param string $server_url The url of the server + * @return array with the contact + */ + private static function getRelayContactId($server_url) + { + $batch = $server_url . '/receive/public'; + + $fields = ['batch', 'id', 'name', 'network']; + $condition = ['uid' => 0, 'network' => NETWORK_DIASPORA, 'batch' => $batch, + 'archive' => false, 'blocked' => false]; + $contact = dba::selectFirst('contact', $fields, $condition); + if (DBM::is_result($contact)) { + return $contact; + } else { + $fields = ['uid' => 0, 'created' => DateTimeFormat::utcNow(), + 'name' => 'relay', 'nick' => 'relay', + 'url' => $server_url, 'nurl' => normalise_link($server_url), + 'batch' => $batch, 'network' => NETWORK_DIASPORA, + 'rel' => CONTACT_IS_FOLLOWER, 'blocked' => false, + 'pending' => false, 'writable' => true]; + dba::insert('contact', $fields); + + $fields = ['batch', 'id', 'name', 'network']; + $contact = dba::selectFirst('contact', $fields, $condition); + if (DBM::is_result($contact)) { + return $contact; + } + + } + + // It should never happen that we arrive here + return []; } /** diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php index edb0df33a..49fd5e318 100644 --- a/src/Worker/Notifier.php +++ b/src/Worker/Notifier.php @@ -485,7 +485,7 @@ class Notifier { if ($diaspora_delivery) { if (!$followup) { - $r0 = Diaspora::relayList(); + $r0 = Diaspora::relayList($item_id); } $r1 = q("SELECT `batch`, ANY_VALUE(`id`) AS `id`, ANY_VALUE(`name`) AS `name`, ANY_VALUE(`network`) AS `network` diff --git a/view/templates/admin/site.tpl b/view/templates/admin/site.tpl index 160804f62..11a51649d 100644 --- a/view/templates/admin/site.tpl +++ b/view/templates/admin/site.tpl @@ -146,6 +146,15 @@ {{include file="field_checkbox.tpl" field=$worker_dont_fork}} {{include file="field_checkbox.tpl" field=$worker_fastlane}} {{include file="field_checkbox.tpl" field=$worker_frontend}} + +