Merge pull request #10202 from mexon/mat/contact-console-command

Add console contact command
This commit is contained in:
Hypolite Petovan 2021-05-04 09:50:49 -04:00 committed by GitHub
commit 53d4312903
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 289 additions and 0 deletions

287
src/Console/Contact.php Normal file
View file

@ -0,0 +1,287 @@
<?php
/**
* @copyright Copyright (C) 2010-2021, the Friendica project
*
* @license GNU AGPL version 3 or any later version
*
* 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 <https://www.gnu.org/licenses/>.
*
*/
namespace Friendica\Console;
use Console_Table;
use Friendica\App;
use Friendica\Model\Contact as ContactModel;
use Friendica\Model\User as UserModel;
use Friendica\Util\Temporal;
use RuntimeException;
use Seld\CliPrompt\CliPrompt;
/**
* tool to manage contacts of users of the current node
*/
class Contact extends \Asika\SimpleConsole\Console
{
protected $helpOptions = ['h', 'help', '?'];
/**
* @var App\Mode
*/
private $appMode;
/**
* @var IPConfig
*/
private $pConfig;
protected function getHelp()
{
$help = <<<HELP
console contact - Modify contact settings per console commands.
Usage
bin/console contact add <user nick> <URL> [<network>] [-h|--help|-?] [-v]
bin/console contact remove <CID> [-h|--help|-?] [-v]
bin/console contact search id <CID> [-h|--help|-?] [-v]
bin/console contact search url <user nick> <URL> [-h|--help|-?] [-v]
bin/console contact terminate <CID> [-h|--help|-?] [-v]
Description
Modify contact settings per console commands.
Options
-h|--help|-? Show help information
-v Show more debug information
-y Non-interactive mode, assume "yes" as answer to the user deletion prompt
HELP;
return $help;
}
public function __construct(App\Mode $appMode, array $argv = null)
{
parent::__construct($argv);
$this->appMode = $appMode;
}
protected function doExecute()
{
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 ($this->appMode->isInstall()) {
throw new RuntimeException('Database isn\'t ready or populated yet');
}
$command = $this->getArgument(0);
switch ($command) {
case 'add':
return $this->addContact();
case 'remove':
return $this->removeContact();
case 'search':
return $this->searchContact();
case 'terminate':
return $this->terminateContact();
default:
throw new \Asika\SimpleConsole\CommandArgsException('Wrong command.');
}
}
/**
* Retrieves the user from a nick supplied as an argument or from a prompt
*
* @param int $arg_index Index of the nick argument in the arguments list
*
* @return array|boolean User record with uid field, or false if user is not found
* @throws \Friendica\Network\HTTPException\InternalServerErrorException
*/
private function getUserByNick($arg_index)
{
$nick = $this->getArgument($arg_index);
if (empty($nick)) {
$this->out('Enter user nickname: ');
$nick = CliPrompt::prompt();
if (empty($nick)) {
throw new RuntimeException('A user nickname must be specified.');
}
}
$user = UserModel::getByNickname($nick, ['uid', 'nickname']);
if (empty($user)) {
throw new RuntimeException('User not found');
}
return $user;
}
/**
* Adds a contact to a user from a URL
*
* @return bool True, if the command was successful
*/
private function addContact()
{
$user = $this->getUserByNick(1);
$url = $this->getArgument(2);
if (empty($url)) {
$this->out('Enter contact URL: ');
$url = CliPrompt::prompt();
if (empty($url)) {
throw new RuntimeException('A contact URL must be specified.');
}
}
$contact = ContactModel::getByURLForUser($url, $user['uid']);
if (!empty($contact)) {
throw new RuntimeException('Contact already exists');
}
$network = $this->getArgument(3);
if ($network === null) {
$this->out('Enter network, or leave blank: ');
$network = CliPrompt::prompt();
}
$result = ContactModel::createFromProbe($user, $url, false, $network);
if ($result['success']) {
$this->out('User ' . $user['nickname'] . ' now connected to ' . $url . ', contact ID ' . $result['cid']);
} else {
throw new RuntimeException($result['message']);
}
}
/**
* Sends an unfriend message. Does not remove the contact
*
* @return bool True, if the command was successful
*/
private function terminateContact()
{
$cid = $this->getArgument(1);
if (empty($cid)) {
$this->out('Enter contact ID: ');
$cid = CliPrompt::prompt();
if (empty($cid)) {
throw new RuntimeException('A contact ID must be specified.');
}
}
$contact = ContactModel::getById($cid);
if (empty($contact)) {
throw new RuntimeException('Contact not found');
}
$user = UserModel::getById($contact['uid']);
$result = ContactModel::terminateFriendship($user, $contact);
}
/**
* Marks a contact for removal
*
* @return bool True, if the command was successful
*/
private function removeContact()
{
$cid = $this->getArgument(1);
if (empty($cid)) {
$this->out('Enter contact ID: ');
$cid = CliPrompt::prompt();
if (empty($cid)) {
throw new RuntimeException('A contact ID must be specified.');
}
}
$result = ContactModel::remove($cid);
}
/**
* Returns a contact based on search parameter
*
* @return bool True, if the command was successful
*/
private function searchContact()
{
$fields = [
'id',
'uid',
'network',
'name',
'nick',
'url',
'addr',
'created',
'updated',
'blocked',
'deleted',
];
$subCmd = $this->getArgument(1);
$table = new Console_Table();
$table->setHeaders(['ID', 'UID', 'Network', 'Name', 'Nick', 'URL', 'E-Mail', 'Created', 'Updated', 'Blocked', 'Deleted']);
$addRow = function ($row) use (&$table) {
$table->addRow([
$row['id'],
$row['uid'],
$row['network'],
$row['name'],
$row['nick'],
$row['url'],
$row['addr'],
Temporal::getRelativeDate($row['created']),
Temporal::getRelativeDate($row['updated']),
$row['blocked'],
$row['deleted'],
]);
};
switch ($subCmd) {
case 'id':
$cid = $this->getArgument(2);
$contact = ContactModel::getById($cid, $fields);
if (!empty($contact)) {
$addRow($contact);
}
break;
case 'url':
$user = $this->getUserByNick(2);
$url = $this->getArgument(3);
$contact = ContactModel::getByURLForUser($url, $user['uid'], false, $fields);
if (!empty($contact)) {
$addRow($contact);
}
break;
default:
$this->out($this->getHelp());
return false;
}
$this->out($table->getTable());
return true;
}
}

View file

@ -47,6 +47,7 @@ Commands:
addon Addon management addon Addon management
cache Manage node cache cache Manage node cache
config Edit site config config Edit site config
contact Contact management
createdoxygen Generate Doxygen headers createdoxygen Generate Doxygen headers
dbstructure Do database updates dbstructure Do database updates
docbloxerrorchecker Check the file tree for DocBlox errors docbloxerrorchecker Check the file tree for DocBlox errors
@ -78,6 +79,7 @@ HELP;
'addon' => Friendica\Console\Addon::class, 'addon' => Friendica\Console\Addon::class,
'cache' => Friendica\Console\Cache::class, 'cache' => Friendica\Console\Cache::class,
'config' => Friendica\Console\Config::class, 'config' => Friendica\Console\Config::class,
'contact' => Friendica\Console\Contact::class,
'createdoxygen' => Friendica\Console\CreateDoxygen::class, 'createdoxygen' => Friendica\Console\CreateDoxygen::class,
'docbloxerrorchecker' => Friendica\Console\DocBloxErrorChecker::class, 'docbloxerrorchecker' => Friendica\Console\DocBloxErrorChecker::class,
'dbstructure' => Friendica\Console\DatabaseStructure::class, 'dbstructure' => Friendica\Console\DatabaseStructure::class,