From e43fb27ac9695273495e95a3ad683a5b93638d46 Mon Sep 17 00:00:00 2001 From: nicolas Date: Wed, 6 Sep 2017 11:02:14 +0200 Subject: [PATCH] feat(Cli.cpp) : add the --cli-help option to display the help of the cli --- assets/languages/en.ts | 66 ++++++++++++++++----- assets/languages/fr.ts | 66 ++++++++++++++++----- src/app/App.cpp | 9 ++- src/app/cli/Cli.cpp | 130 +++++++++++++++++++++++++++++++++++++---- src/app/cli/Cli.hpp | 20 ++++++- 5 files changed, 246 insertions(+), 45 deletions(-) diff --git a/assets/languages/en.ts b/assets/languages/en.ts index 36d9a4c37..387cc6166 100644 --- a/assets/languages/en.ts +++ b/assets/languages/en.ts @@ -60,14 +60,6 @@ commandLineOptionConfigArg file - - commandLineOptionCmd - run a command line - - - commandLineOptionCmdArg - command line - commandLineOptionHelp show this help @@ -76,6 +68,14 @@ commandLineOptionVersion show app version + + commandLineCliHelp + displays the help menu to use Linphone with the CLI. + + + commandLineDescription + send aan order to the application towards a command line. + AssistantAbstractView @@ -413,25 +413,61 @@ Server url not configured. Cli + + linphoneCliDescription + Way to control the Linphone application through command lines. + + + uriCommandLineSyntax + linphone sip:<sip-address>?method=<method>([&<argument>=<base64-encoded-value>]*) + + + cliCommandLineSyntax + linphone "<method> ([<argument>=<value>]*)" + + + commandsName + commands list : + showFunctionDescription - + Shows the main window of the application. - showFunctionCall - + showCliDescription + "show" - joinConferenceFunctionDescription - + callFunctionDescription + Initiates a call towards <sip-address>. + + + callCliDescription + "call sip-address=<sip-address>" initiateConferenceFunctionDescription - + Initiates a conference of id <id>. + + + initiateConferenceCliDescription + "initiate-conference sip-address=<my sip-address> conference-id=<id>" + + + joinConferenceFunctionDescription + Joins the n°<id> conference hosted by the <host sip-address> as <name>. If you are connected to a proxy config, see join-conference-as. + + + joinConferenceCliDescription + "join-conference sip-address=<host sip-address> conference-id=<id> display-name=<name>" joinConferenceAsFunctionDescription - + Joins the n°<id> conference hosted by the <host sip-address> as<my sip-address>. If you are not connected to a proxy-config, see join-conference. + + + joinConferenceAsCliDescription + "join-conference-as sip-address=<host sip-address> conference-id=<id> guest-sip-address=<my sip-address>" diff --git a/assets/languages/fr.ts b/assets/languages/fr.ts index 7017c1cb7..eb4ee7b8a 100644 --- a/assets/languages/fr.ts +++ b/assets/languages/fr.ts @@ -60,14 +60,6 @@ commandLineOptionConfigArg file - - commandLineOptionCmd - éxécuter une ligne de commande - - - commandLineOptionCmdArg - ligne de commande - commandLineOptionHelp affiche cette aide @@ -76,6 +68,14 @@ commandLineOptionVersion affiche la version de l'application + + commandLineCliHelp + affiche le menu d'aide pour l'utilisation de Linphone en CLI. + + + commandLineDescription + envoie un ordre à l'application Linphone, voir --cli-help pour plus de détails. + AssistantAbstractView @@ -413,25 +413,61 @@ Url du serveur non configurée. Cli + + linphoneCliDescription + Moyen d'effectuer des actions sur l'application Linphone en ligne de commande. + + + uriCommandLineSyntax + linphone sip:<sip-address>?method=<method>([&<argument>=<valeur-en-base64>]*) + + + cliCommandLineSyntax + linphone "<method> ([<argument>=<valeur>]*)" + + + commandsName + liste des commandes : + showFunctionDescription - + Affiche la fenêtre principale de l'application. - showFunctionCall - + showCliDescription + "show" - joinConferenceFunctionDescription - + callFunctionDescription + Initie un appel vers <sip-address>. + + + callCliDescription + "call sip-address=<sip-address>" initiateConferenceFunctionDescription - + Initie une conférence d'id <id>. + + + initiateConferenceCliDescription + "initiate-conference sip-address=<ma sip-address> conference-id=<id>" + + + joinConferenceFunctionDescription + Rejoint la conférence n°<id> hébergée par la <sip-address de l'host> en tant que <nom>. Si vous êtes connecté à une proxy config, voir join-conference-as. + + + joinConferenceCliDescription + "join-conference sip-address=<sip-address de l'host> conference-id=<id> display-name=<nom>" joinConferenceAsFunctionDescription - + Rejoint la conférence n°<id> hébergée par la <sip-address de l'host> en tant que <ma sip-address>. Si vous n'êtes pas connecté à une proxy-config, voir join-conference. + + + joinConferenceAsCliDescription + "join-conference-as sip-address=<sip-address de l'host> conference-id=<id> guest-sip-address=<ma sip-address>" diff --git a/src/app/App.cpp b/src/app/App.cpp index 1f55524ec..3e1db1798 100644 --- a/src/app/App.cpp +++ b/src/app/App.cpp @@ -100,6 +100,12 @@ App::App (int &argc, char *argv[]) : SingleApplication(argc, argv, true, Mode::U mParser->showHelp(); } + if(mParser->isSet("cli-help")){ + mCli = new Cli(this); + mCli->showHelp(); + ::exit(EXIT_SUCCESS); + } + if (mParser->isSet("version")) mParser->showVersion(); @@ -327,11 +333,12 @@ void App::createParser () { mParser = new QCommandLineParser(); mParser->setApplicationDescription(tr("applicationDescription")); + mParser->addPositionalArgument("command",tr("commandLineDescription"),"[command]"); mParser->addOptions({ { { "h", "help" }, tr("commandLineOptionHelp") }, + { "cli-help", tr("commandLineCliHelp") }, { { "v", "version" }, tr("commandLineOptionVersion") }, { "config", tr("commandLineOptionConfig"), tr("commandLineOptionConfigArg") }, - { { "c", "cmd" }, tr("commandLineOptionCmd"), tr("commandLineOptionCmdArg") }, #ifndef Q_OS_MACOS { "iconified", tr("commandLineOptionIconified") }, #endif // ifndef Q_OS_MACOS diff --git a/src/app/cli/Cli.cpp b/src/app/cli/Cli.cpp index 565281e9b..8e3a5cc93 100644 --- a/src/app/cli/Cli.cpp +++ b/src/app/cli/Cli.cpp @@ -137,12 +137,14 @@ static void cliInitiateConference (QHash &args) { Cli::Command::Command ( const QString &functionName, - const QString &description, + const QString &functionDescription, + const QString &cliDescription, Cli::Function function, const QHash &argsScheme ) : mFunctionName(functionName), - mDescription(description), + mFunctionDescription(functionDescription), + mCliDescription(cliDescription), mFunction(function), mArgsScheme(argsScheme) {} @@ -200,17 +202,17 @@ QRegExp Cli::mRegExpArgs("(?:(?:([\\w-]+)\\s*)=\\s*(?:\"([^\"\\\\]*(?:\\\\.[^\"\ QRegExp Cli::mRegExpFunctionName("^\\s*([a-z-]+)\\s*"); Cli::Cli (QObject *parent) : QObject(parent) { - addCommand("show", tr("showFunctionDescription"), ::cliShow); - addCommand("call", tr("showFunctionCall"), ::cliCall, { + addCommand("show", tr("showFunctionDescription"), tr("showCliDescription"), ::cliShow); + addCommand("call", tr("callFunctionDescription"), tr("callCliDescription"), ::cliCall, { { "sip-address", {} } }); - addCommand("initiate-conference", tr("initiateConferenceFunctionDescription"), ::cliInitiateConference, { + addCommand("initiate-conference", tr("initiateConferenceFunctionDescription"), tr("initiateConferenceCliDescription"), ::cliInitiateConference, { { "sip-address", {} }, { "conference-id", {} } }); - addCommand("join-conference", tr("joinConferenceFunctionDescription"), ::cliJoinConference, { + addCommand("join-conference", tr("joinConferenceFunctionDescription"), tr("joinConferenceCliDescription"), ::cliJoinConference, { { "sip-address", {} }, { "conference-id", {} }, { "display-name", {} } }); - addCommand("join-conference-as", tr("joinConferenceAsFunctionDescription"), ::cliJoinConferenceAs, { + addCommand("join-conference-as", tr("joinConferenceAsFunctionDescription"), tr("joinConferenceAsCliDescription"), ::cliJoinConferenceAs, { { "sip-address", {} }, { "conference-id", {} }, { "guest-sip-address", {} } }); } @@ -219,14 +221,22 @@ Cli::Cli (QObject *parent) : QObject(parent) { void Cli::addCommand ( const QString &functionName, - const QString &description, + const QString &functionDescription, + const QString &cliDescription, Function function, const QHash &argsScheme ) { - if (mCommands.contains(functionName)) + if (mCommands.contains(functionName)) { qWarning() << QStringLiteral("Command already exists: `%1`.").arg(functionName); - else - mCommands[functionName] = Cli::Command(functionName, description, function, argsScheme); + return; + } + mCommands[functionName] = Cli::Command( + functionName, + functionDescription, + cliDescription, + function, + argsScheme + ); } // ----------------------------------------------------------------------------- @@ -274,6 +284,104 @@ void Cli::executeCommand (const QString &command, CommandFormat *format) const { mCommands[functionName].executeUri(address); } +QString splitWord(QString word, int &curPos, const int lineLength, const QString &padding) { + QString out; + out += word.mid(0,lineLength - curPos) + "\n" + padding; + curPos = padding.length(); + word = word.mid(lineLength - curPos); + while(word.length() > lineLength - curPos) { + out += word.mid(0,lineLength - curPos); + word = word.mid(lineLength - curPos); + out += "\n" + padding; + } + out += word; + curPos = word.length() + padding.length(); + return out; +} + +QString indentedWord(QString word, int &curPos, const int lineLength, const QString &padding){ + QString out; + if (curPos + word.length() > lineLength ) { + if (padding.length() + word.length() > lineLength) { + out += splitWord(word, curPos, lineLength, padding); + } else { + out += QStringLiteral("\n"); + out += padding + word; + curPos = padding.length(); + } + } else { + out += word; + curPos += word.length(); + } + return out; +} + +static string multilineIndent (const QString &str, int indentationNumber = 0) { + + static const int lineLength(80); + static const QRegExp spaceRegexp("(\\s)"); + const QString padding(indentationNumber * 2, ' '); + + QString out = padding; + + int indentedTextCurPos = padding.length(); + + int spacePos = 0; + int wordPos = spacePos; + QString word; + + while ((spacePos = spaceRegexp.indexIn(str, spacePos)) != -1) { + word = str.mid(wordPos,spacePos-wordPos); + out += indentedWord(word, indentedTextCurPos, lineLength, padding); + switch (str[spacePos].unicode()) { + case '\n': + out += "\n" + padding; + indentedTextCurPos = padding.length(); + break; + case '\t': //tabulated as a space + case ' ': + if (indentedTextCurPos == lineLength) { + out += "\n" + padding; + indentedTextCurPos = padding.length(); + } else { + out += " "; + indentedTextCurPos += 1; + } + break; + + case '\r': + case '\f': + break; + + default : + break; + } + spacePos += 1; + wordPos = spacePos; + } + word = str.mid(wordPos); + out += indentedWord(word, indentedTextCurPos,lineLength, padding); + out += "\n"; + + return ::Utils::appStringToCoreString(out); +} + +void Cli::showHelp() { + cout << multilineIndent(tr("linphoneCliDescription"),0); + cout << "\n" << "Usage : " << "\n"; + cout << multilineIndent(tr("uriCommandLineSyntax"),0); + cout < &argsScheme ); @@ -66,9 +67,19 @@ class Cli : public QObject { void execute (QHash &args) const; void executeUri (const std::shared_ptr &address) const; + QString getFunctionDescription() { + return mFunctionDescription; + } + + QString getCliDescription() { + return mCliDescription; + } + + private: + QString mFunctionDescription; + QString mCliDescription; QString mFunctionName; - QString mDescription; Function mFunction = nullptr; QHash mArgsScheme; }; @@ -85,10 +96,13 @@ public: void executeCommand (const QString &command, CommandFormat *format = nullptr) const; + void showHelp(); + private: void addCommand ( const QString &functionName, - const QString &description, + const QString &functionDescription, + const QString &cliDescription, Function function, const QHash &argsScheme = QHash() );