Merge pull request #4912 from annando/archivecontacts

Added console command to manually archive contacts
This commit is contained in:
Hypolite Petovan 2018-04-23 02:07:53 -04:00 committed by GitHub
commit a25c07b162
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 102 additions and 4 deletions

View File

@ -21,6 +21,7 @@ class Console extends \Asika\SimpleConsole\Console
'extract' => __NAMESPACE__ . '\Console\Extract', 'extract' => __NAMESPACE__ . '\Console\Extract',
'globalcommunityblock' => __NAMESPACE__ . '\Console\GlobalCommunityBlock', 'globalcommunityblock' => __NAMESPACE__ . '\Console\GlobalCommunityBlock',
'globalcommunitysilence' => __NAMESPACE__ . '\Console\GlobalCommunitySilence', 'globalcommunitysilence' => __NAMESPACE__ . '\Console\GlobalCommunitySilence',
'archivecontact' => __NAMESPACE__ . '\Console\ArchiveContact',
'autoinstall' => __NAMESPACE__ . '\Console\AutomaticInstallation', 'autoinstall' => __NAMESPACE__ . '\Console\AutomaticInstallation',
'maintenance' => __NAMESPACE__ . '\Console\Maintenance', 'maintenance' => __NAMESPACE__ . '\Console\Maintenance',
'newpassword' => __NAMESPACE__ . '\Console\NewPassword', 'newpassword' => __NAMESPACE__ . '\Console\NewPassword',
@ -42,6 +43,7 @@ Commands:
extract Generate translation string file for the Friendica project (deprecated) extract Generate translation string file for the Friendica project (deprecated)
globalcommunityblock Block remote profile from interacting with this node globalcommunityblock Block remote profile from interacting with this node
globalcommunitysilence Silence remote profile from global community page globalcommunitysilence Silence remote profile from global community page
archivecontact Archive a contact when you know that it isn't existing anymore
help Show help about a command, e.g (bin/console help config) help Show help about a command, e.g (bin/console help config)
autoinstall Starts automatic installation of friendica based on values from htconfig.php autoinstall Starts automatic installation of friendica based on values from htconfig.php
maintenance Set maintenance mode for this node maintenance Set maintenance mode for this node

View File

@ -0,0 +1,79 @@
<?php
namespace Friendica\Core\Console;
use Friendica\Core\L10n;
use dba;
/**
* @brief tool to archive a contact on the server
*
* With this tool you can archive a contact when you know that it isn't existing anymore.
* Normally this does happen automatically after a few days.
*
* License: AGPLv3 or later, same as Friendica
*
*/
class ArchiveContact extends \Asika\SimpleConsole\Console
{
protected $helpOptions = ['h', 'help', '?'];
protected function getHelp()
{
$help = <<<HELP
console archivecontact - archive a contact
Usage
bin/console archivecontact <profile_url> [-h|--help|-?] [-v]
Description
Archive a contact when you know that it isn't existing anymore. Normally this does happen automatically after a few days.
Options
-h|--help|-? Show help information
-v Show more debug information.
HELP;
return $help;
}
protected function doExecute()
{
$a = get_app();
if ($this->getOption('v')) {
$this->out('Class: ' . __CLASS__);
$this->out('Arguments: ' . var_export($this->args, true));
$this->out('Options: ' . var_export($this->options, true));
}
if (count($this->args) == 0) {
$this->out($this->getHelp());
return 0;
}
if (count($this->args) > 1) {
throw new \Asika\SimpleConsole\CommandArgsException('Too many arguments');
}
require_once '.htconfig.php';
$result = \dba::connect($db_host, $db_user, $db_pass, $db_data);
unset($db_host, $db_user, $db_pass, $db_data);
if (!$result) {
throw new \RuntimeException('Unable to connect to database');
}
$nurl = normalise_link($this->getArgument(0));
if (!dba::exists('contact', ['nurl' => $nurl, 'archive' => false])) {
throw new \RuntimeException(L10n::t('Could not find any unarchived contact entry for this URL (%s)', $nurl));
}
if (dba::update('contact', ['archive' => true], ['nurl' => $nurl])) {
$condition = ["`cid` IN (SELECT `id` FROM `contact` WHERE `archive`)"];
dba::delete('queue', $condition);
$this->out(L10n::t('The contact entries have been archived'));
} else {
throw new \RuntimeException('The contact archival failed.');
}
return 0;
}
}

View File

@ -1197,6 +1197,7 @@ class DFRN
$ret = Network::curl($url); $ret = Network::curl($url);
if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) { if ($ret['errno'] == CURLE_OPERATION_TIMEDOUT) {
Contact::markForArchival($contact);
return -2; // timed out return -2; // timed out
} }
@ -1204,24 +1205,28 @@ class DFRN
$curl_stat = $a->get_curl_code(); $curl_stat = $a->get_curl_code();
if (empty($curl_stat)) { if (empty($curl_stat)) {
Contact::markForArchival($contact);
return -3; // timed out return -3; // timed out
} }
logger('dfrn_deliver: ' . $xml, LOGGER_DATA); logger('dfrn_deliver: ' . $xml, LOGGER_DATA);
if (empty($xml)) { if (empty($xml)) {
Contact::markForArchival($contact);
return 3; return 3;
} }
if (strpos($xml, '<?xml') === false) { if (strpos($xml, '<?xml') === false) {
logger('dfrn_deliver: no valid XML returned'); logger('dfrn_deliver: no valid XML returned');
logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA); logger('dfrn_deliver: returned XML: ' . $xml, LOGGER_DATA);
Contact::markForArchival($contact);
return 3; return 3;
} }
$res = XML::parseString($xml); $res = XML::parseString($xml);
if ((intval($res->status) != 0) || (! strlen($res->challenge)) || (! strlen($res->dfrn_id))) { if ((intval($res->status) != 0) || !strlen($res->challenge) || !strlen($res->dfrn_id)) {
Contact::markForArchival($contact);
return ($res->status ? $res->status : 3); return ($res->status ? $res->status : 3);
} }
@ -1274,6 +1279,7 @@ class DFRN
if ($final_dfrn_id != $orig_id) { if ($final_dfrn_id != $orig_id) {
logger('dfrn_deliver: wrong dfrn_id.'); logger('dfrn_deliver: wrong dfrn_id.');
// did not decode properly - cannot trust this site // did not decode properly - cannot trust this site
Contact::markForArchival($contact);
return 3; return 3;
} }
@ -1309,6 +1315,7 @@ class DFRN
break; break;
default: default:
logger("rino: invalid requested version '$rino_remote_version'"); logger("rino: invalid requested version '$rino_remote_version'");
Contact::markForArchival($contact);
return -8; return -8;
} }
@ -1346,22 +1353,26 @@ class DFRN
$curl_stat = $a->get_curl_code(); $curl_stat = $a->get_curl_code();
if (empty($curl_stat) || empty($xml)) { if (empty($curl_stat) || empty($xml)) {
Contact::markForArchival($contact);
return -9; // timed out return -9; // timed out
} }
if (($curl_stat == 503) && stristr($a->get_curl_headers(), 'retry-after')) { if (($curl_stat == 503) && stristr($a->get_curl_headers(), 'retry-after')) {
Contact::markForArchival($contact);
return -10; return -10;
} }
if (strpos($xml, '<?xml') === false) { if (strpos($xml, '<?xml') === false) {
logger('dfrn_deliver: phase 2: no valid XML returned'); logger('dfrn_deliver: phase 2: no valid XML returned');
logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA); logger('dfrn_deliver: phase 2: returned XML: ' . $xml, LOGGER_DATA);
Contact::markForArchival($contact);
return 3; return 3;
} }
$res = XML::parseString($xml); $res = XML::parseString($xml);
if (!isset($res->status)) { if (!isset($res->status)) {
Contact::markForArchival($contact);
return -11; return -11;
} }
@ -1374,7 +1385,7 @@ class DFRN
logger('Delivery returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG); logger('Delivery returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG);
} }
if ($res->status == 200) { if (($res->status >= 200) && ($res->status <= 299)) {
Contact::unmarkForArchival($contact); Contact::unmarkForArchival($contact);
} }
@ -1403,6 +1414,7 @@ class DFRN
if (empty($contact['addr'])) { if (empty($contact['addr'])) {
logger('Unable to find contact handle for ' . $contact['id'] . ' - ' . $contact['url']); logger('Unable to find contact handle for ' . $contact['id'] . ' - ' . $contact['url']);
Contact::markForArchival($contact);
return -21; return -21;
} }
} }
@ -1410,6 +1422,7 @@ class DFRN
$fcontact = Diaspora::personByHandle($contact['addr']); $fcontact = Diaspora::personByHandle($contact['addr']);
if (empty($fcontact)) { if (empty($fcontact)) {
logger('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']); logger('Unable to find contact details for ' . $contact['id'] . ' - ' . $contact['addr']);
Contact::markForArchival($contact);
return -22; return -22;
} }
@ -1433,22 +1446,26 @@ class DFRN
$curl_stat = $a->get_curl_code(); $curl_stat = $a->get_curl_code();
if (empty($curl_stat) || empty($xml)) { if (empty($curl_stat) || empty($xml)) {
logger('Empty answer from ' . $contact['id'] . ' - ' . $dest_url); logger('Empty answer from ' . $contact['id'] . ' - ' . $dest_url);
Contact::markForArchival($contact);
return -9; // timed out return -9; // timed out
} }
if (($curl_stat == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) { if (($curl_stat == 503) && (stristr($a->get_curl_headers(), 'retry-after'))) {
Contact::markForArchival($contact);
return -10; return -10;
} }
if (strpos($xml, '<?xml') === false) { if (strpos($xml, '<?xml') === false) {
logger('No valid XML returned from ' . $contact['id'] . ' - ' . $dest_url); logger('No valid XML returned from ' . $contact['id'] . ' - ' . $dest_url);
logger('Returned XML: ' . $xml, LOGGER_DATA); logger('Returned XML: ' . $xml, LOGGER_DATA);
Contact::markForArchival($contact);
return 3; return 3;
} }
$res = XML::parseString($xml); $res = XML::parseString($xml);
if (empty($res->status)) { if (empty($res->status)) {
Contact::markForArchival($contact);
return -23; return -23;
} }
@ -1456,7 +1473,7 @@ class DFRN
logger('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG); logger('Transmit to ' . $dest_url . ' returned status '.$res->status.' - '.$res->message, LOGGER_DEBUG);
} }
if ($res->status == 200) { if (($res->status >= 200) && ($res->status <= 299)) {
Contact::unmarkForArchival($contact); Contact::unmarkForArchival($contact);
} }

View File

@ -63,7 +63,7 @@ class Queue
return; return;
} }
if (empty($contact['notify'])) { if (empty($contact['notify']) || $contact['archive']) {
QueueModel::removeItem($q_item['id']); QueueModel::removeItem($q_item['id']);
return; return;
} }