Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linphone-desktop
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
linphone-desktop
Commits
e90b2311
Commit
e90b2311
authored
Jun 06, 2017
by
Nicolas Follet
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat(app): provide a cli
parent
e26dcceb
Changes
9
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
326 additions
and
27 deletions
+326
-27
CMakeLists.txt
linphone-desktop/CMakeLists.txt
+2
-0
en.ts
linphone-desktop/assets/languages/en.ts
+23
-0
fr.ts
linphone-desktop/assets/languages/fr.ts
+23
-0
App.cpp
linphone-desktop/src/app/App.cpp
+35
-24
App.hpp
linphone-desktop/src/app/App.hpp
+6
-0
Cli.cpp
linphone-desktop/src/app/cli/Cli.cpp
+150
-0
Cli.hpp
linphone-desktop/src/app/cli/Cli.hpp
+84
-0
SingleApplication.cpp
...op/src/externals/single-application/SingleApplication.cpp
+1
-2
main.cpp
linphone-desktop/src/main.cpp
+2
-1
No files found.
linphone-desktop/CMakeLists.txt
View file @
e90b2311
...
...
@@ -93,6 +93,7 @@ endif ()
set
(
SOURCES
src/app/App.cpp
src/app/cli/Cli.cpp
src/app/logger/Logger.cpp
src/app/paths/Paths.cpp
src/app/providers/AvatarProvider.cpp
...
...
@@ -141,6 +142,7 @@ set(SOURCES
set
(
HEADERS
src/app/App.hpp
src/app/cli/Cli.hpp
src/app/logger/Logger.hpp
src/app/paths/Paths.hpp
src/app/providers/AvatarProvider.hpp
...
...
linphone-desktop/assets/languages/en.ts
View file @
e90b2311
...
...
@@ -64,6 +64,18 @@
<
source
>
commandLineOptionIconified
<
/source
>
<
translation
>
Start
in
the
system
tray
,
do
not
show
the
main
interface
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionConfigArg
<
/source
>
<
translation
>
file
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionCmd
<
/source
>
<
translation
>
Run
a
command
line
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionCmdArg
<
/source
>
<
translation
>
command
line
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
AssistantAbstractView
<
/name
>
...
...
@@ -387,6 +399,17 @@
Server
url
not
configured
.
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
Cli
<
/name
>
<
message
>
<
source
>
showFunctionDescription
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
message
>
<
source
>
showFunctionCall
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
CodecsViewer
<
/name
>
<
message
>
...
...
linphone-desktop/assets/languages/fr.ts
View file @
e90b2311
...
...
@@ -64,6 +64,18 @@
<
source
>
commandLineOptionIconified
<
/source
>
<
translation
>
Lancer
l
&
apos
;
application
dans
la
zone
de
notification
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionConfigArg
<
/source
>
<
translation
>
file
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionCmd
<
/source
>
<
translation
>
É
x
é
cuter
une
ligne
de
commande
.
<
/translation
>
<
/message
>
<
message
>
<
source
>
commandLineOptionCmdArg
<
/source
>
<
translation
>
ligne
de
commande
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
AssistantAbstractView
<
/name
>
...
...
@@ -387,6 +399,17 @@
Url
du
serveur
non
configur
é
e
.
<
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
Cli
<
/name
>
<
message
>
<
source
>
showFunctionDescription
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
message
>
<
source
>
showFunctionCall
<
/source
>
<
translation
type
=
"
unfinished
"
><
/translation
>
<
/message
>
<
/context
>
<
context
>
<
name
>
CodecsViewer
<
/name
>
<
message
>
...
...
linphone-desktop/src/app/App.cpp
View file @
e90b2311
...
...
@@ -37,6 +37,7 @@
#include "providers/AvatarProvider.hpp"
#include "providers/ThumbnailProvider.hpp"
#include "translator/DefaultTranslator.hpp"
#include "cli/Cli.hpp"
#include "App.hpp"
...
...
@@ -139,16 +140,13 @@ void App::initContentApp () {
// Don't quit if last window is closed!!!
setQuitOnLastWindowClosed
(
false
);
QObject
::
connect
(
this
,
&
App
::
receivedMessage
,
this
,
[
this
](
int
,
QByteArray
byteArray
)
{
QString
message
(
byteArray
);
QObject
::
connect
(
this
,
&
App
::
receivedMessage
,
this
,
[
this
](
int
,
const
QByteArray
&
byteArray
)
{
QString
command
(
byteArray
);
qInfo
()
<<
QStringLiteral
(
"Received command from other application: `%1`."
).
arg
(
command
);
executeCommand
(
command
);
});
qInfo
()
<<
QStringLiteral
(
"Received message from other application: `%1`."
).
arg
(
message
);
if
(
message
==
"show"
)
smartShowWindow
(
getMainWindow
());
}
);
mCli
=
new
Cli
(
this
);
}
// Init core.
...
...
@@ -207,12 +205,13 @@ void App::parseArgs () {
mParser
.
addHelpOption
();
mParser
.
addVersionOption
();
mParser
.
addOptions
({
{
"config"
,
tr
(
"commandLineOptionConfig"
),
"file"
},
{
"config"
,
tr
(
"commandLineOptionConfig"
),
tr
(
"commandLineOptionConfigArg"
)
},
#ifndef __APPLE__
{
"iconified"
,
tr
(
"commandLineOptionIconified"
)
},
#endif // ifndef __APPLE__
{
"self-test"
,
tr
(
"commandLineOptionSelfTest"
)
},
{
{
"V"
,
"verbose"
},
tr
(
"commandLineOptionVerbose"
)
}
{
{
"V"
,
"verbose"
},
tr
(
"commandLineOptionVerbose"
)
},
{
{
"c"
,
"cmd"
},
tr
(
"commandLineOptionCmd"
),
tr
(
"commandLineOptionCmdArg"
)
}
});
mParser
.
process
(
*
this
);
...
...
@@ -228,6 +227,18 @@ void App::parseArgs () {
// -----------------------------------------------------------------------------
QString
App
::
getCommandArgument
()
{
return
mParser
.
value
(
"cmd"
);
}
// -----------------------------------------------------------------------------
void
App
::
executeCommand
(
const
QString
&
command
)
{
mCli
->
executeCommand
(
command
);
}
// -----------------------------------------------------------------------------
void
App
::
tryToUsePreferredLocale
()
{
QString
locale
=
getConfigLocale
();
...
...
@@ -267,15 +278,13 @@ QQuickWindow *App::getMainWindow () const {
QQuickWindow
*
App
::
getSettingsWindow
()
{
if
(
!
mSettingsWindow
)
{
mSettingsWindow
=
createSubWindow
(
this
,
QML_VIEW_SETTINGS_WINDOW
);
QObject
::
connect
(
mSettingsWindow
,
&
QWindow
::
visibilityChanged
,
this
,
[](
QWindow
::
Visibility
visibility
)
{
QObject
::
connect
(
mSettingsWindow
,
&
QWindow
::
visibilityChanged
,
this
,
[](
QWindow
::
Visibility
visibility
)
{
if
(
visibility
==
QWindow
::
Hidden
)
{
qInfo
()
<<
QStringLiteral
(
"Update nat policy."
);
shared_ptr
<
linphone
::
Core
>
core
=
CoreManager
::
getInstance
()
->
getCore
();
core
->
setNatPolicy
(
core
->
getNatPolicy
());
}
}
);
});
}
return
mSettingsWindow
;
...
...
@@ -329,12 +338,9 @@ void registerMetaType (const char *name) {
template
<
class
T
>
void
registerSingletonType
(
const
char
*
name
)
{
qmlRegisterSingletonType
<
T
>
(
"Linphone"
,
1
,
0
,
name
,
[](
QQmlEngine
*
,
QJSEngine
*
)
->
QObject
*
{
qmlRegisterSingletonType
<
T
>
(
"Linphone"
,
1
,
0
,
name
,
[](
QQmlEngine
*
,
QJSEngine
*
)
->
QObject
*
{
return
new
T
();
}
);
});
}
template
<
class
T
>
...
...
@@ -408,8 +414,7 @@ void App::setTrayIcon () {
// trayIcon: Left click actions.
QMenu
*
menu
=
new
QMenu
();
root
->
connect
(
systemTrayIcon
,
&
QSystemTrayIcon
::
activated
,
[
root
](
root
->
connect
(
systemTrayIcon
,
&
QSystemTrayIcon
::
activated
,
[
root
](
QSystemTrayIcon
::
ActivationReason
reason
)
{
if
(
reason
==
QSystemTrayIcon
::
Trigger
)
{
...
...
@@ -418,8 +423,7 @@ void App::setTrayIcon () {
else
root
->
hide
();
}
}
);
});
// Build trayIcon menu.
menu
->
addAction
(
restoreAction
);
...
...
@@ -491,6 +495,13 @@ void App::openAppAfterInit () {
config
->
setInt
(
SettingsModel
::
UI_SECTION
,
"force_assistant_at_startup"
,
0
);
}
}
// Execute command argument if needed.
{
const
QString
&
commandArgument
=
getCommandArgument
();
if
(
!
commandArgument
.
isEmpty
())
executeCommand
(
commandArgument
);
}
}
// -----------------------------------------------------------------------------
...
...
linphone-desktop/src/app/App.hpp
View file @
e90b2311
...
...
@@ -34,6 +34,7 @@
// =============================================================================
class
Cli
;
class
DefaultTranslator
;
class
App
:
public
SingleApplication
{
...
...
@@ -51,6 +52,9 @@ public:
void
initContentApp
();
void
parseArgs
();
QString
getCommandArgument
();
void
executeCommand
(
const
QString
&
command
);
void
tryToUsePreferredLocale
();
QQmlEngine
*
getEngine
()
{
...
...
@@ -119,6 +123,8 @@ private:
QQuickWindow
*
mCallsWindow
=
nullptr
;
QQuickWindow
*
mSettingsWindow
=
nullptr
;
Cli
*
mCli
=
nullptr
;
};
#endif // APP_H_
linphone-desktop/src/app/cli/Cli.cpp
0 → 100644
View file @
e90b2311
/*
* Cli.cpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: June 6, 2017
* Author: Nicolas Follet
*/
#include <stdexcept>
#include <QObject>
#include "../../components/core/CoreManager.hpp"
#include "../../Utils.hpp"
#include "../App.hpp"
#include "Cli.hpp"
using
namespace
std
;
// =============================================================================
// API.
// =============================================================================
static
void
cliShow
(
const
QHash
<
QString
,
QString
>
&
)
{
App
*
app
=
App
::
getInstance
();
app
->
smartShowWindow
(
app
->
getMainWindow
());
}
static
void
cliCall
(
const
QHash
<
QString
,
QString
>
&
args
)
{
CoreManager
::
getInstance
()
->
getCallsListModel
()
->
launchAudioCall
(
args
[
"sipAddress"
]);
}
// =============================================================================
Cli
::
Command
::
Command
(
const
QString
&
functionName
,
const
QString
&
description
,
Cli
::
Function
function
,
const
QHash
<
QString
,
Cli
::
Argument
>
&
argsScheme
)
:
mFunctionName
(
functionName
),
mDescription
(
description
),
mFunction
(
function
),
mArgsScheme
(
argsScheme
)
{}
void
Cli
::
Command
::
execute
(
const
QHash
<
QString
,
QString
>
&
args
)
{
for
(
const
auto
&
argName
:
mArgsScheme
.
keys
())
{
if
(
!
args
.
contains
(
argName
)
&&
!
mArgsScheme
[
argName
].
isOptional
)
{
qWarning
()
<<
QStringLiteral
(
"Missing argument for command: `%1 (%2)`."
)
.
arg
(
mFunctionName
).
arg
(
argName
);
return
;
}
}
(
*
mFunction
)(
args
);
}
// =============================================================================
Cli
::
Cli
(
QObject
*
parent
)
:
QObject
(
parent
)
{
// FIXME: Do not accept args without value like: cmd toto.
// In the future `toto` could be a boolean argument.
mRegExpArgs
=
QRegExp
(
"(?:(?:(
\\
w+)
\\
s*)=
\\
s*(?:
\"
([^
\"\\\\
]*(?:
\\\\
.[^
\"\\\\
]*)*)
\"
|([^
\\
s]+)
\\
s*))"
);
mRegExpFunctionName
=
QRegExp
(
"^
\\
s*(
\\
w+)
\\
s*"
);
makeCommands
();
}
// -----------------------------------------------------------------------------
void
Cli
::
addCommand
(
const
QString
&
functionName
,
const
QString
&
description
,
Function
function
,
const
QHash
<
QString
,
Argument
>
&
argsScheme
)
noexcept
{
if
(
mCommands
.
contains
(
functionName
))
qWarning
()
<<
QStringLiteral
(
"Command already exists: `%1`."
).
arg
(
functionName
);
else
mCommands
[
functionName
]
=
Cli
::
Command
(
functionName
,
description
,
function
,
argsScheme
);
}
void
Cli
::
makeCommands
()
noexcept
{
addCommand
(
"show"
,
tr
(
"showFunctionDescription"
),
cliShow
);
addCommand
(
"call"
,
tr
(
"showFunctionCall"
),
cliCall
,
{
{
"sipAddress"
,
{}
}
});
}
// -----------------------------------------------------------------------------
void
Cli
::
executeCommand
(
const
QString
&
command
)
noexcept
{
const
QString
&
functionName
=
parseFunctionName
(
command
);
if
(
functionName
.
isEmpty
())
return
;
bool
soFarSoGood
;
const
QHash
<
QString
,
QString
>
&
args
=
parseArgs
(
command
,
functionName
,
soFarSoGood
);
if
(
!
soFarSoGood
)
return
;
mCommands
[
functionName
].
execute
(
args
);
}
// -----------------------------------------------------------------------------
const
QString
Cli
::
parseFunctionName
(
const
QString
&
command
)
noexcept
{
mRegExpFunctionName
.
indexIn
(
command
);
const
QStringList
&
texts
=
mRegExpFunctionName
.
capturedTexts
();
if
(
texts
.
size
()
<
2
)
{
qWarning
()
<<
QStringLiteral
(
"Unable to parse function name of command: `%1`."
).
arg
(
command
);
return
QStringLiteral
(
""
);
}
const
QString
functionName
=
texts
[
1
];
if
(
!
mCommands
.
contains
(
functionName
))
{
qWarning
()
<<
QStringLiteral
(
"This command doesn't exist: `%1`."
).
arg
(
functionName
);
return
QStringLiteral
(
""
);
}
return
functionName
;
}
const
QHash
<
QString
,
QString
>
Cli
::
parseArgs
(
const
QString
&
command
,
const
QString
functionName
,
bool
&
soFarSoGood
)
noexcept
{
QHash
<
QString
,
QString
>
args
;
int
pos
=
0
;
soFarSoGood
=
true
;
while
((
pos
=
mRegExpArgs
.
indexIn
(
command
,
pos
))
!=
-
1
)
{
pos
+=
mRegExpArgs
.
matchedLength
();
if
(
!
mCommands
[
functionName
].
argNameExists
(
mRegExpArgs
.
cap
(
1
)))
{
qWarning
()
<<
QStringLiteral
(
"Command with invalid argument(s): `%1 (%2)`."
)
.
arg
(
functionName
).
arg
(
mRegExpArgs
.
cap
(
1
));
soFarSoGood
=
false
;
return
args
;
}
args
[
mRegExpArgs
.
cap
(
1
)]
=
(
mRegExpArgs
.
cap
(
2
).
isEmpty
()
?
mRegExpArgs
.
cap
(
3
)
:
mRegExpArgs
.
cap
(
2
));
}
return
args
;
}
linphone-desktop/src/app/cli/Cli.hpp
0 → 100644
View file @
e90b2311
/*
* Cli.hpp
* Copyright (C) 2017 Belledonne Communications, Grenoble, France
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Created on: June 6, 2017
* Author: Nicolas Follet
*/
#ifndef CLI_H_
#define CLI_H_
#include <QHash>
#include <QObject>
// =============================================================================
class
Cli
:
public
QObject
{
typedef
void
(
*
Function
)(
const
QHash
<
QString
,
QString
>
&
);
enum
ArgumentType
{
STRING
};
struct
Argument
{
Argument
(
ArgumentType
type
=
STRING
,
bool
isOptional
=
false
)
{
this
->
type
=
type
;
this
->
isOptional
=
isOptional
;
}
ArgumentType
type
;
bool
isOptional
;
};
class
Command
{
public:
Command
()
=
default
;
Command
(
const
QString
&
functionName
,
const
QString
&
description
,
Function
function
,
const
QHash
<
QString
,
Argument
>
&
argsScheme
);
void
execute
(
const
QHash
<
QString
,
QString
>
&
args
);
bool
argNameExists
(
const
QString
&
argName
)
{
return
mArgsScheme
.
contains
(
argName
);
}
private:
QString
mFunctionName
;
QString
mDescription
;
Function
mFunction
=
nullptr
;
QHash
<
QString
,
Argument
>
mArgsScheme
;
};
public:
Cli
(
QObject
*
parent
=
Q_NULLPTR
);
~
Cli
()
=
default
;
void
executeCommand
(
const
QString
&
command
)
noexcept
;
const
QString
parseFunctionName
(
const
QString
&
command
)
noexcept
;
const
QHash
<
QString
,
QString
>
parseArgs
(
const
QString
&
command
,
const
QString
functionName
,
bool
&
soFarSoGood
)
noexcept
;
private:
void
addCommand
(
const
QString
&
functionName
,
const
QString
&
description
,
Function
function
,
const
QHash
<
QString
,
Argument
>
&
argsScheme
=
{})
noexcept
;
void
makeCommands
()
noexcept
;
QRegExp
mRegExpArgs
;
QRegExp
mRegExpFunctionName
;
QHash
<
QString
,
Command
>
mCommands
;
};
#endif // CLI_H_
linphone-desktop/src/externals/single-application/SingleApplication.cpp
View file @
e90b2311
...
...
@@ -453,10 +453,9 @@ bool SingleApplication::sendMessage (QByteArray message, int timeout) {
// Nobody to connect to
if
(
isPrimary
())
return
false
;
// Make sure the socket is connected
d
->
connectToPrimary
(
timeout
,
Reconnect
);
d
->
connectToPrimary
(
timeout
,
Reconnect
);
d
->
socket
->
write
(
message
);
bool
dataWritten
=
d
->
socket
->
flush
();
d
->
socket
->
waitForBytesWritten
(
timeout
);
...
...
linphone-desktop/src/main.cpp
View file @
e90b2311
...
...
@@ -72,7 +72,8 @@ int main (int argc, char *argv[]) {
app
.
parseArgs
();
if
(
app
.
isSecondary
())
{
app
.
sendMessage
(
"show"
,
0
);
QString
command
=
app
.
getCommandArgument
();
app
.
sendMessage
(
command
.
isEmpty
()
?
"show"
:
command
.
toLocal8Bit
(),
0
);
return
0
;
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment