Manually merged freebsd fork from git.floating-in.space/isabell/labcontrol into github.com/markuspg/Labcontrol.

master
Isabell Pflug 3 years ago
parent f5d7d1af7e
commit 78b2af6947

@ -26,6 +26,7 @@ HEADERS += src/localzleafstarter.h \
src/Lib/client.h \
src/Lib/clienthelpnotificationserver.h \
src/Lib/clientpinger.h \
src/Lib/global.h \
src/Lib/lablib.h \
src/Lib/netstatagent.h \
src/Lib/receipts_handler.h \
@ -51,3 +52,5 @@ OTHER_FILES += \
data/scripts/kill_zLeaf_labcontrol2.sh \
data/scripts/start_zLeaf_labcontrol2.sh \
doc/manual.tex
INCLUDEPATH += /usr/local/include/

@ -4,7 +4,7 @@
The easiest way to build and install _Labcontrol_ is to open the `labcontrol.pro` file with _Qt Creator_ and build the project. Afterwards _Labcontrol_ can be started by running the created executable file. To build correctly _Qt5_ has to be available and must be know to _Qt Creator_.
To work properly _Labcontrol_ requires a file named `labcontrol.conf` in `/etc/xdg/Economic\ Laboratory`. This directory must be created, the existing dummy file be copied there and afterwards be modified according to the laboratory's needs. All _z-Tree_ executables should reside in sub-directories of `/opt/z-Leaves` following the naming scheme `zTree_X.Y.ZZ`.
To work properly _Labcontrol_ requires a file named `labcontrol.json` + the folder named `icons` (inside of `data`) in either `/usr/local/etc/Labcontrol` or `/etc/Labcontrol` or next to the Labcontrol binary. This directory must be created, the existing dummy file be copied there and afterwards be modified according to the laboratory's needs. All _z-Tree_ executables should reside in sub-directories of `/opt/z-Leaves` following the naming scheme `zTree_X.Y.ZZ`.
Receipt creation requires at least one receipt template in `/usr/local/share/labcontrol`. The name of the header file should match the pattern `NAMETHEHEADERSHALLHAVE_header.tex` to be recognized.

@ -1,98 +0,0 @@
[General]
### Server settings
# The IP of the server running zTree
server_ip=192.168.1.200
# Network broadcast address
network_broadcast_address=192.168.1.255
# The port which shall be used by zTree by default
initial_port=8000
# The port the client help server shall listen on
client_help_server_port=XXXX
# User names of all users which shall be able to conduct administrative tasks with Labcontrol
admin_users="UserA|UserB|UserC"
# The public keys to access the clients as root
pkey_path_root=/usr/local/share/labcontrol/id_labclient_root
# The public keys to access the clients as unprivileged user
pkey_path_user=/usr/local/share/labcontrol/id_labclient_dsa
# The default name for locally started zLeaves
local_zLeaf_name=local
# Default dimension for locally started zLeaves
local_zLeaf_size=1280x1024
# If multiple receipts are availabe, this indicates, which one will be shown by default (the index counting from 0 following an alphabetical ordering)
default_receipt_index=0
# The URL address of your lab's ORSEE
orsee_url=http://yourORSEEserver.tld
# URLs to available webcams
webcams=http://user:pass@webcam_right|http://user:pass@webcam_left
# Display names for the webcams
webcams_names="Webcam right|Webcam left"
### Client settings
# The client settings are represented as an array. So the info of the first client stands in the first field in every section and the same is valid for the other clients with other indices each.
client_ips=192.168.1.1|192.168.1.2|192.168.1.3|192.168.1.4|192.168.1.5|192.168.1.6|192.168.1.7|192.168.1.8|192.168.1.9|192.168.1.10|192.168.1.11|192.168.1.12|192.168.1.13|192.168.1.14|192.168.1.15|192.168.1.16|192.168.1.17|192.168.1.18|192.168.1.19|192.168.1.20|192.168.1.21|192.168.1.22|192.168.1.23|192.168.1.24
client_macs=00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00|00:00:00:00:00:00
# These are the names which show up in the interface. They should match the hostnames of the clients
client_names=client01|client02|client03|client04|client05|client06|client07|client08|client09|client10|client11|client12|client13|client14|client15|client16|client17|client18|backupclient01|backupclient02|backupclient03|backupclient04|backupclient05|backupclient06
# This is just a hash to control the correct length of the other client attributes
client_quantity=24
# The following two coordinates specify where the client will be shown in the coordinate grid at the bottom of the Labcontrol screen
client_xpos=1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16|17|18|19|20|21|22|23|24
client_ypos=1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1|1
# The name of the user of the clients which is used to conduct experiments
user_name_on_clients=user
### Binary paths
# Path to your lpr binary
lpr_command=/usr/bin/lpr
# Path to your netstat binary
netstat_command=/bin/netstat
# The command used to kill 'zleaf.exe' instances (part of the 'psmisc' package)
killall_command=/usr/bin/killall
# Where all Labcontrol data got installed
#DOTO: REMOVE VAGUE NAME WHEN NOT NEEDED ANYMORE (AFTER 2.1.4 MIRGRATION)
labcontrol_data_directory=/usr/local/share/labcontrol
labcontrol_data_directory=/usr/local/share/labcontrol
# Path to your latex binary
latex_command=/usr/bin/latex
# Path to your dvips binary
dvips_command=/usr/bin/dvips
# Path to your filemanager binary
file_manager=/usr/bin/dolphin
# Path to your ping binary
ping_command=/bin/ping
# Path to PDF/Postscript viewer binary
postscript_viewer=/usr/bin/okular
# Path to ps2pdf binary
ps2pdf_command=/usr/bin/ps2pdf
# Path to rm binary
rm_command=/bin/rm
# Path to SCP binary
scp_command=/usr/bin/scp
# The browser in which ORSEE shall be displayed
browser_command=/usr/bin/firefox
# Path to wmctrl binary
ssh_command=/usr/bin/ssh
# Path to taskset binary
taskset_command=/usr/bin/taskset
# Path to terminal-emulator binary
terminal_emulator_command=/usr/bin/gnome-terminal
# Path to wine binary
wine_command=/usr/bin/wine
# Path to wmctrl binary
wmctrl_command=/usr/bin/wmctrl
# Path to xset binary
xset_command=/usr/bin/xset
# Path to VNC viewer binary
vnc_viewer=/usr/bin/vinagre
# Path to wakeonlan binary
wakeonlan_command=/usr/bin/wakeonlan
# The program used to view the laboratory's webcams
webcam_command=/usr/local/bin/WebcamDisplay
# The folder were all zTree versions are installed (in subfolders matching the scheme zTree_X.Y.Z)
ztree_installation_directory=/opt/z-Leaves
# Script to be called after session crash
restart_crashed_session_script=/home/scripts/start_zTree_after_crash.sh
# Client default browser cmd (firefox) - need to be quoted!
client_browser_command="firefox-esr"
# Client cromium cmd- need to be quoted!
client_chromium_command="chromium"

@ -0,0 +1,79 @@
{
"server": {
"server_ip": "192.168.53.100",
"network_broadcast_address": "192.168.53.255",
"initial_port": 7000,
"client_help_server_port": 19871,
"admin_users": ["okirchkamp", "weiss", "isabell"],
"pkey_path_root": "/usr/share/labcontrol/id_clients_root",
"pkey_path_root_comment": "The public keys to access the clients as root",
"pkey_path_user": "/usr/share/labcontrol/id_clients_ewfuser",
"pkey_path_user_comment": "The public keys to access the clients as unprivileged user",
"local_zLeaf_def_name": "local",
"local_zLeaf_def_size": "1280x1024",
"default_receipt_index": 0,
"default_receipt_index_comment": "If multiple receipts are availabe, this indicates, which one will be shown by default (the index counting from 0 following an alphabetical ordering)",
"orsee_url": "http://yourORSEEserver.tld",
"webcams": { "Webcam right": "http://user:pass@webcam_right", "Webcam left": "http://user:pass@webcam_left"},
"vnc_view_only_argument": "-ViewOnly"
},
"client": {
"clients": { "client01": {"ip": "192.168.53.1", "mac": "4c:72:b9:21:ea:7e", "xpos": "3", "ypos": "4"},
"client02": {"ip": "192.168.53.2", "mac": "4c:72:b9:24:86:60", "xpos": "4", "ypos": "4"},
"client03": {"ip": "192.168.53.3", "mac": "00:1e:8c:f2:5b:7a", "xpos": "5", "ypos": "4"},
"client04": {"ip": "192.168.53.4", "mac": "4c:72:b9:24:85:a6", "xpos": "6", "ypos": "4"},
"client05": {"ip": "192.168.53.5", "mac": "4c:72:b9:24:85:b9", "xpos": "6", "ypos": "3"},
"client06": {"ip": "192.168.53.6", "mac": "00:1e:8c:f2:ac:b9", "xpos": "5", "ypos": "3"},
"client07": {"ip": "192.168.53.7", "mac": "4c:72:b9:24:84:ea", "xpos": "4", "ypos": "3"},
"client08": {"ip": "192.168.53.8", "mac": "4c:72:b9:24:86:d0", "xpos": "4", "ypos": "2"},
"client09": {"ip": "192.168.53.9", "mac": "4c:72:b9:24:80:b1", "xpos": "5", "ypos": "2"},
"client10": {"ip": "192.168.53.10", "mac": "4c:72:b9:21:e8:ba", "xpos": "6", "ypos": "2"},
"client11": {"ip": "192.168.53.11", "mac": "4c:72:b9:24:83:ae", "xpos": "6", "ypos": "1"},
"client12": {"ip": "192.168.53.12", "mac": "4c:72:b9:24:83:81", "xpos": "5", "ypos": "1"},
"client13": {"ip": "192.168.53.13", "mac": "4c:72:b9:21:a3:25", "xpos": "4", "ypos": "1"},
"client14": {"ip": "192.168.53.14", "mac": "4c:72:b9:24:85:10", "xpos": "3", "ypos": "1"},
"client15": {"ip": "192.168.53.15", "mac": "4c:72:b9:24:86:39", "xpos": "2", "ypos": "1"},
"client16": {"ip": "192.168.53.16", "mac": "4c:72:b9:24:83:73", "xpos": "1", "ypos": "1"},
"client17": {"ip": "192.168.53.17", "mac": "4c:72:b9:24:85:df", "xpos": "1", "ypos": "2"},
"client18": {"ip": "192.168.53.18", "mac": "4c:72:b9:24:85:fd", "xpos": "2", "ypos": "2"},
"backupclient01": {"ip": "192.168.53.19", "mac": "00:17:31:5f:7e:21", "xpos": "1", "ypos": "7"},
"backupclient02": {"ip": "192.168.53.20", "mac": "00:17:31:5f:7e:21", "xpos": "2", "ypos": "7"},
"backupclient04": {"ip": "192.168.53.22", "mac": "00:17:31:5f:84:c6", "xpos": "4", "ypos": "7"},
"backupclient05": {"ip": "192.168.53.23", "mac": "00:17:31:5f:84:c6", "xpos": "5", "ypos": "7"},
"backupclient06": {"ip": "192.168.53.24", "mac": "00:17:31:5c:68:89", "xpos": "6", "ypos": "7"},
"server": {"ip": "192.168.53.100", "mac": "4c:72:b9:21:bb:0c", "xpos": "1", "ypos": "5"},
"testclient": {"ip": "192.168.53.48", "mac": "00:27:0e:34:3f:5d", "xpos": "3", "ypos": "2"}},
"user_name_on_clients": "ewfuser"
},
"binary_paths": {
"lpr_command": "lpr",
"netstat_command": "netstat",
"killall_command": "pkill -f",
"zleaf_exe_name": "zleaf.exe",
"ztree_exe_name": "ztree.exe",
"labcontrol_data_directory": ".",
"latex_command": "latex",
"dvips_command": "dvips",
"file_manager": "thunar",
"ping_command": "ping",
"postscript_viewer": "okular",
"ps2pdf_command": "ps2pdf",
"rm_command": "rm",
"scp_command": "scp",
"browser_command": "firefox",
"client_browser_command": "firefox",
"client_chromium_command": "chrome",
"ssh_command": "ssh",
"taskset_command": "LANG=en_US.UTF-8 cpuset -l 1",
"terminal_emulator_command": "gnome-terminal",
"wine_command": "wine",
"wmctrl_command": "wmctrl",
"xset_command": "xset",
"vnc_viewer": "vncviewer",
"wakeonlan_command": "wakeonlan",
"webcam_command": "WebcamDisplay",
"ztree_installation_directory": "/opt/zTree",
"ztree_installation_directory_comment": "The folder where all zTree versions are installed (in subfolders matching the scheme zTree_X.Y.Z)",
"restart_crashed_session_script": "/home/scripts/start_zTree_after_crash.sh"
}
}

@ -49,6 +49,9 @@ lc::Client::Client(const QString &argIP, const QString &argMAC,
pingTimer = new QTimer{this};
connect(pingTimer, &QTimer::timeout, this, &Client::RequestAPing);
pingTimer->start(3000);
} else {
qDebug() << "ClientPingerArg not found: " << argPingCmd;
exit(127);
}
qDebug() << "Created client" << name << "with MAC" << mac << "and IP" << ip
@ -125,9 +128,7 @@ void lc::Client::KillZLeaf() {
QStringList arguments;
arguments << "-i" << settings->pkeyPathUser
<< QString{settings->userNameOnClients + "@" + ip}
<< settings->killallCmd << "-I"
<< "-q"
<< "zleaf.exe";
<< settings->killallCmd << " " << settings->zleafExeName;
// Start the process
QProcess killZLeafProcess;
@ -210,7 +211,11 @@ void lc::Client::SetStateToZLEAF_RUNNING(QString argClientIP) {
void lc::Client::ShowDesktopViewOnly() {
QStringList arguments;
#ifdef Q_OS_FREEBSD
arguments << " " << settings->vncViewOnlyArguments << " " << ip;
#else
arguments << ip;
#endif
QProcess showDesktopProcess;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@ -223,8 +228,11 @@ void lc::Client::ShowDesktopViewOnly() {
void lc::Client::ShowDesktopFullControl() {
QStringList arguments;
arguments << ip + ":5901";
#ifdef Q_OS_FREEBSD
arguments << ip;
#else
arguments << ip + ":5901"; // TODO: command arguments (port, etc.) into config
#endif
QProcess showDesktopProcess;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
showDesktopProcess.setProcessEnvironment(env);
@ -264,6 +272,7 @@ void lc::Client::Shutdown() {
void lc::Client::StartZLeaf(const QString *argFakeName, QString cmd) {
if (state < State::RESPONDING || zLeafVersion.isEmpty() ||
GetSessionPort() < 7000) {
qDebug() << "zleaf could not be started.";
return;
}
@ -308,7 +317,7 @@ void lc::Client::StartZLeaf(const QString *argFakeName, QString cmd) {
void lc::Client::StartClientBrowser(const QString *const argURL,
const bool *const argFullscreen,
const QString *const argBrowser) {
QString const argBrowser) {
// Declarations
QStringList arguments;
@ -335,13 +344,14 @@ void lc::Client::StartClientBrowser(const QString *const argURL,
<< "DISPLAY=:0.0" << settings->clientChromiumCmd
<< "--noerrdialogs --kiosk"
<< "--app='" + processedArgUrl + "'"
<< "> /dev/null 2>&1 &disown";
<< "> /dev/null 2>&1";
}
// Start the process
QProcess startClientBrowserProcess;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
startClientBrowserProcess.setProcessEnvironment(env);
qDebug() << "arguments: " << arguments << "\nargBrowser: " << argBrowser;
startClientBrowserProcess.startDetached(settings->sshCmd, arguments);
// Output message via the debug messages tab
@ -378,12 +388,12 @@ void lc::Client::ControlRMB(bool enable) {
arguments << "-i" << settings->pkeyPathUser
<< QString{settings->userNameOnClients + "@" + ip}
<< "DISPLAY=:0 xinput set-button-map 'Microsoft Basic Optical "
"Mouse' 1 2 3 4 5 6 7 8 9 10 11 12 > /dev/null 2>&1 &disown;";
"Mouse' 1 2 3 4 5 6 7 8 9 10 11 12 > /dev/null 2>&1;";
} else {
arguments << "-i" << settings->pkeyPathUser
<< QString{settings->userNameOnClients + "@" + ip}
<< "DISPLAY=:0 xinput set-button-map 'Microsoft Basic Optical "
"Mouse' 1 2 0 4 5 6 7 8 9 10 11 12 > /dev/null 2>&1 &disown;";
"Mouse' 1 2 0 4 5 6 7 8 9 10 11 12 > /dev/null 2>&1;";
}
// Start the process

@ -148,7 +148,7 @@ public:
*/
void StartClientBrowser(const QString *argURL = nullptr,
const bool *argFullscreen = nullptr,
const QString *argBrowser = nullptr);
QString argBrowser = nullptr);
/*!
* \brief Closes all browser instances

@ -24,6 +24,7 @@
#include <QNetworkSession>
#include <QTcpServer>
#include <QTcpSocket>
#include <QSettings>
extern std::unique_ptr<lc::Settings> settings;

@ -16,7 +16,6 @@
* You should have received a copy of the GNU General Public License
* along with Labcontrol. If not, see <http://www.gnu.org/licenses/>.
*/
#include "clientpinger.h"
/*!
@ -32,7 +31,11 @@ lc::ClientPinger::ClientPinger(const QString &argIP,
: QObject{argParent},
// Arguments: -c 1 (send 1 ECHO_REQUEST packet) -w 1 (timeout after 1
// second) -q (quiet output)
pingArguments{"-c", "1", "-w", "1", "-q", argIP},
#ifdef Q_OS_FREEBSD
pingArguments{ QStringList{} << "-c" << "1" << "-W" << "1" << "-q" << argIP },
#else
pingArguments{ QStringList{} << "-c" << "1" << "-w" << "1" << "-q" << argIP },
#endif
pingCommand{argPingCommand}, pingProcess{new QProcess{this}} {
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
pingProcess->setProcessEnvironment(env);

@ -175,19 +175,15 @@ void lc::Lablib::SetLocalZLeafDefaultName(const QString &argName) {
// Returns the commandline that is issued on the client when zleaf is started
QStringList lc::Lablib::getzLeafArgs(int sessionPort, QString zleafVersion) {
QStringList arguments;
if (sessionPort == 7000) {
arguments << "DISPLAY=:0.0" << settings->tasksetCmd << "0x00000001"
<< settings->wineCmd
<< QString{settings->zTreeInstDir + "/zTree_" + zleafVersion +
"/zleaf.exe"}
if ( sessionPort == 7000 ) {
arguments << "sleep 5 && DISPLAY=:0.0" << settings->tasksetCmd << settings->wineCmd
<< QString{ settings->zTreeInstDir + "/zTree_" + zleafVersion + "/zleaf.exe" }
<< "/server" << settings->serverIP;
} else {
arguments << "DISPLAY=:0.0" << settings->tasksetCmd << "0x00000001"
<< settings->wineCmd
<< QString{settings->zTreeInstDir + "/zTree_" + zleafVersion +
"/zleaf.exe"}
arguments << "sleep 5 && DISPLAY=:0.0" << settings->tasksetCmd << settings->wineCmd
<< QString{ settings->zTreeInstDir + "/zTree_" + zleafVersion + "/zleaf.exe" }
<< "/server" << settings->serverIP << "/channel"
<< QString::number(sessionPort - 7000);
<< QString::number( sessionPort- 7000 );
}
// Return the crafted QStringList

@ -22,11 +22,12 @@
lc::NetstatAgent::NetstatAgent(const QString &argNetstatCommand,
QObject *argParent)
: QObject{argParent}, extractionRegexp{"\\d+\\.\\d+\\.\\d+\\.\\d+"},
netstatArguments{QStringList{} << "-anp"
<< "--tcp"},
//netstatArguments{QStringList{} << "-anp" << "--tcp"},
netstatArguments{QStringList{} << "-4v"},
netstatCommand{argNetstatCommand}, netstatQueryProcess{this},
searchRegexp{"\\W(ESTABLISHED|VERBUNDEN)( +)(\\d+)(/ztree.exe)\\W",
QRegularExpression::CaseInsensitiveOption} {
//searchRegexp{"\\W(ESTABLISHED|VERBUNDEN)( +)(\\d+)(/ztree.exe)\\W", QRegularExpression::CaseInsensitiveOption} {
searchRegexp{ ".*(wine ).*", QRegularExpression::CaseInsensitiveOption }
{
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
netstatQueryProcess.setProcessEnvironment(env);
}

@ -20,160 +20,108 @@
#include <QDebug>
#include <QDir>
#include <QFile>
#include <QProcessEnvironment>
#include <QProcessEnvironment>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include "client.h"
#include "settings.h"
lc::Settings::Settings(const QSettings &argSettings, QObject *argParent)
: QObject{argParent}, defaultReceiptIndex{GetDefaultReceiptIndex(
argSettings)},
browserCmd{ReadSettingsItem("browser_command",
"Opening ORSEE in a browser will not work.",
argSettings, true)},
clientBrowserCmd{
ReadSettingsItem("client_browser_command",
"Opening a browser window on clients will not work.",
argSettings, false)},
clientChromiumCmd{ReadSettingsItem(
"client_chromium_command",
"Opening a chromium window on clients will not work.", argSettings,
false)},
dvipsCmd{ReadSettingsItem("dvips_command",
"Receipts creation will not work.", argSettings,
true)},
fileMngr{ReadSettingsItem("file_manager",
"The display of preprints will not work.",
argSettings, true)},
killallCmd{ReadSettingsItem(
"killall_command", "Killing 'zleaf.exe' instances will not work.",
argSettings, true)},
latexCmd{ReadSettingsItem("latex_command",
"Receipts creation will not work.", argSettings,
true)},
lcDataDir{ReadSettingsItem(
"labcontrol_data_directory",
"Datapath not set. Labcontrol will missbehave with high propability.",
argSettings, true)},
localUserName{GetLocalUserName()}, localzLeafSize{ReadSettingsItem(
"local_zLeaf_size",
"Resolution of local zLeaf window",
argSettings, false)},
lprCmd{ReadSettingsItem("lpr_command", "Receipts printing will not work.",
argSettings, true)},
netstatCmd{ReadSettingsItem(
"netstat_command",
"Detection of active zLeaf connections will not work.", argSettings,
true)},
netwBrdAddr{ReadSettingsItem("network_broadcast_address",
"Booting the clients will not work.",
argSettings, false)},
orseeUrl{ReadSettingsItem("orsee_url",
"Opening ORSEE in a browser will not work.",
argSettings, false)},
pingCmd{ReadSettingsItem("ping_command",
"Status updates for the clients will not work.",
argSettings, true)},
postscriptViewer{ReadSettingsItem(
"postscript_viewer",
"Viewing the generated receipts postscript file will not work.",
argSettings, true)},
ps2pdfCmd{ReadSettingsItem(
"ps2pdf_command",
"Converting and viewing the generated receipts file will not work.",
argSettings, true)},
pkeyPathRoot{ReadSettingsItem("pkey_path_root",
"Administration actions concerning the "
"clients will not be available.",
argSettings, true)},
pkeyPathUser{ReadSettingsItem(
"pkey_path_user",
"Many actions concerning the clients will not be available.",
argSettings, true)},
rmCmd{ReadSettingsItem(
"rm_command", "Cleanup of the zTree data target path will not work.",
argSettings, true)},
scpCmd{ReadSettingsItem(
"scp_command", "Beaming files to the clients will not be possible.",
argSettings, true)},
serverIP{ReadSettingsItem(
"server_ip",
"Starting zLeaves and retrieving client help messages will not work.",
argSettings, false)},
sshCmd{ReadSettingsItem(
"ssh_command",
"All actions concerning the clients will not be possible.",
argSettings, true)},
tasksetCmd{ReadSettingsItem(
"taskset_command", "Running z-Leaves or z-Tree will be possible.",
argSettings, true)},
termEmulCmd{ReadSettingsItem(
"terminal_emulator_command",
"Conducting administrative tasks will not be possible.", argSettings,
true)},
userNameOnClients{
ReadSettingsItem("user_name_on_clients",
"All actions concerning the clients performed by "
"the experiment user will not work.",
argSettings, false)},
vncViewer{ReadSettingsItem("vnc_viewer",
"Viewing the clients' screens will not work.",
argSettings, true)},
wakeonlanCmd{ReadSettingsItem("wakeonlan_command",
"Booting the clients will not work.",
argSettings, true)},
webcamDisplayCmd{
ReadSettingsItem("webcam_command",
"Displaying the laboratory's webcams will not work.",
argSettings, true)},
webcams{argSettings.value("webcams", "")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseInsensitive)},
webcams_names{
argSettings.value("webcams_names", "")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseInsensitive)},
wineCmd{ReadSettingsItem("wine_command",
"Running z-Leaves or z-Tree will be possible.",
argSettings, true)},
wmctrlCmd{ReadSettingsItem(
"wmctrl_command",
"Setting zTree's window title to its port number will not work.",
argSettings, true)},
xsetCmd{ReadSettingsItem(
"xset_command",
"Deactivating the screen saver on the clients will not be possible.",
argSettings, true)},
zTreeInstDir{ReadSettingsItem("ztree_installation_directory",
"zTree will not be available.", argSettings,
true)},
restartCrashedSessionScript{ReadSettingsItem(
"restart_crashed_session_script",
"Script to be called after session crash", argSettings, false)},
adminUsers{GetAdminUsers(argSettings)},
installedLaTeXHeaders{DetectInstalledLaTeXHeaders()},
installedZTreeVersions{DetectInstalledzTreeVersions()},
clientHelpNotificationServerPort{
GetClientHelpNotificationServerPort(argSettings)},
chosenzTreePort{GetInitialPort(argSettings)}, clients{CreateClients(
argSettings, pingCmd)},
localzLeafName{ReadSettingsItem(
"local_zLeaf_name",
"The local zLeaf default name will default to 'local'.", argSettings,
false)},
clIPsToClMap{CreateClIPsToClMap(clients)} {
// Let the local zLeaf name default to 'local' if none was given in the
// settings
if (localzLeafName.isEmpty()) {
lc::Settings::Settings( pt::ptree root ) :
//defaultReceiptIndex{ GetDefaultReceiptIndex( argSettings ) },
binary_paths(root.get_child("binary_paths")),
client(root.get_child("client")),
server(root.get_child("server")),
webcams_root(server.get_child("webcams")),
clientBrowserCmd(QString::fromStdString(binary_paths.get<std::string>("client_browser_command",
"Opening a browser window on clients will not work."))),
clientChromiumCmd(QString::fromStdString(binary_paths.get<std::string>("client_chromium_command",
"Opening a chromium window on clients will not work."))),
dvipsCmd(QString::fromStdString(binary_paths.get<std::string>("dvips_command",
"Receipts creation will not work."))),
fileMngr(QString::fromStdString(binary_paths.get<std::string>("file_manager",
"The display of preprints will not work."))),
killallCmd(QString::fromStdString(binary_paths.get<std::string>("killall_command",
"Killing 'zleaf.exe' or 'ztree.exe' instances will not work."))),
zleafExeName(QString::fromStdString(binary_paths.get<std::string>("zleaf_exe_name"))),
ztreeExeName(QString::fromStdString(binary_paths.get<std::string>("ztree_exe_name"))),
latexCmd(QString::fromStdString(binary_paths.get<std::string>("latex_command",
"Receipts creation will not work."))),
lcDataDir(QString::fromStdString(binary_paths.get<std::string>("labcontrol_data_directory",
"Datapath not set. Labcontrol will missbehave with high propability."))),
localUserName{ GetLocalUserName() },
lprCmd(QString::fromStdString(binary_paths.get<std::string>("lpr_command",
"Receipts printing will not work."))),
netstatCmd(QString::fromStdString(binary_paths.get<std::string>("netstat_command",
"Detection of active zLeaf connections will not work."))),
netwBrdAddr(QString::fromStdString(server.get<std::string>( "network_broadcast_address",
"Booting the clients will not work."))),
orseeUrl(QString::fromStdString(server.get<std::string>("orsee_url",
"Opening ORSEE in a browser will not work."))),
pingCmd(QString::fromStdString(binary_paths.get<std::string>("ping_command",
"Status updates for the clients will not work."))),
postscriptViewer(QString::fromStdString(binary_paths.get<std::string>("postscript_viewer",
"Viewing the generated receipts postscript file will not work."))),
ps2pdfCmd(QString::fromStdString(binary_paths.get<std::string>("ps2pdf_command",
"Converting and viewing the generated receipts file will not work."))),
pkeyPathRoot(QString::fromStdString(server.get<std::string>("pkey_path_root",
"Administration actions concerning the clients will not be available."))),
pkeyPathUser(QString::fromStdString(server.get<std::string>("pkey_path_user",
"Many actions concerning the clients will not be available."))),
rmCmd(QString::fromStdString(binary_paths.get<std::string>("rm_command",
"Cleanup of the zTree data target path will not work."))),
scpCmd(QString::fromStdString(binary_paths.get<std::string>("scp_command", "Beaming files to the clients will not be possible."))),
serverIP(QString::fromStdString(server.get<std::string>("server_ip",
"Starting zLeaves and retrieving client help messages will not work."))),
sshCmd(QString::fromStdString(binary_paths.get<std::string>("ssh_command",
"All actions concerning the clients will not be possible."))),
tasksetCmd(QString::fromStdString(binary_paths.get<std::string>("taskset_command",
"Running z-Leaves or z-Tree will be possible."))),
termEmulCmd(QString::fromStdString(binary_paths.get<std::string>("terminal_emulator_command",
"Conducting administrative tasks will not be possible."))),
userNameOnClients(QString::fromStdString(client.get<std::string>("user_name_on_clients",
"All actions concerning the clients performed by the experiment user will not work."))),
vncViewer(QString::fromStdString(binary_paths.get<std::string>("vnc_viewer",
"Viewing the clients' screens will not work."))),
wakeonlanCmd(QString::fromStdString(binary_paths.get<std::string>("wakeonlan_command",
"Booting the clients will not work."))),
webcamDisplayCmd(QString::fromStdString(binary_paths.get<std::string>("webcam_command",
"Displaying the laboratory's webcams will not work."))),
webcams{ GetWebcams(server) },
webcams_names{ GetWebcamsNames(server) },
wineCmd(QString::fromStdString(binary_paths.get<std::string>("wine_command",
"Running z-Leaves or z-Tree will be possible."))),
wmctrlCmd(QString::fromStdString(binary_paths.get<std::string>("wmctrl_command",
"Setting zTree's window title to its port number will not work."))),
xsetCmd(QString::fromStdString(binary_paths.get<std::string>("xset_command",
"Deactivating the screen saver on the clients will not be possible."))),
zTreeInstDir(QString::fromStdString(binary_paths.get<std::string>("ztree_installation_directory",
"zTree will not be available."))),
restartCrashedSessionScript(QString::fromStdString(binary_paths.get<std::string>("restart_crashed_session_script",
"Script to be called after session crash"))),
//adminUsers(server.get<QStringList>("admin_users")),
adminUsers{ GetAdminUsers(server) },
installedLaTeXHeaders{ DetectInstalledLaTeXHeaders() },
installedZTreeVersions{ DetectInstalledzTreeVersions() },
//clientHelpNotificationServerPort(server.get<unsigned short>("client_help_server_port")),
clientHelpNotificationServerPort{ GetClientHelpNotificationServerPort(server) },
vncViewOnlyArguments( QString::fromStdString(server.get<std::string>("vnc_view_only_argument",
"vnc view only mode won't work.")) ),
chosenzTreePort(server.get<int>("initial_port")),
clients{ CreateClients( client, pingCmd ) },
localzLeafName(QString::fromStdString(server.get<std::string>("local_zLeaf_def_name",
"The local zLeaf default name will default to 'local'."))),
localzLeafSize(QString::fromStdString(server.get<std::string>("local_zLeaf_size",
"Resolution of local zLeaf window"))),
clIPsToClMap{ CreateClIPsToClMap( clients ) }
{
// Let the local zLeaf name default to 'local' if none was given in the settings
if ( localzLeafName.isEmpty() ) {
qDebug() << "'local_zLeaf_name' was not set, defaulting to 'local'";
localzLeafName = "local";
}
if (webcams.isEmpty()) {
qDebug() << "'webcams' was not properly set. No stationary webcams will be "
"available.";
} else {
qDebug() << "The following webcams where loaded:" << webcams;
}
qDebug() << "Detected z-Tree versions" << installedZTreeVersions;
}
@ -196,105 +144,70 @@ bool lc::Settings::CheckPathAndComplain(const QString &argPath,
return true;
}
QVector<lc::Client *> lc::Settings::CreateClients(const QSettings &argSettings,
const QString &argPingCmd) {
QVector<Client *> tempClientVec;
// Get the client quantity to check the value lists for clients creation for
// correct length
int clientQuantity = 0;
if (!argSettings.contains("client_quantity")) {
qWarning()
<< "'client_quantity' was not set. The client quantity will be guessed"
" by the amount of client IPs set in 'client_ips'.";
clientQuantity = argSettings.value("client_ips", "")
.toString()
.split('/', QString::SkipEmptyParts, Qt::CaseSensitive)
.length();
qDebug() << "'clientQuantity':" << clientQuantity;
} else {
bool ok = true;
clientQuantity = argSettings.value("client_quantity").toInt(&ok);
if (!ok) {
qWarning() << "The variable 'client_quantity' was not convertible to int";
QVector< lc::Client* > lc::Settings::CreateClients( const pt::ptree &clients,
const QString &argPingCmd ) { // TO DO
QVector< Client* > tempClientVec;
// Get the client quantity to check the value lists for clients creation for correct length
int clientQuantity = 0;
BOOST_FOREACH(const pt::ptree::value_type &v, clients.get_child("clients")) {
clientQuantity++;
}
qDebug() << "'clientQuantity':" << clientQuantity;
}
// Create all the clients in the lab
QStringList clientIPs =
argSettings.value("client_ips")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseSensitive);
if (clientIPs.length() != clientQuantity) {
qWarning()
<< "The quantity of client ips does not match the client quantity. "
"Client"
" creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "Client IPs:" << clientIPs.join(" / ");
QStringList clientMACs =
argSettings.value("client_macs")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseSensitive);
if (clientMACs.length() != clientQuantity) {
qWarning()
<< "The quantity of client macs does not match the client quantity. "
"Client"
" creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "Client MACs:" << clientMACs.join(" / ");
QStringList clientNames =
argSettings.value("client_names")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseSensitive);
if (clientNames.length() != clientQuantity) {
qWarning()
<< "The quantity of client names does not match the client quantity. "
"Client"
" creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "Client names:" << clientNames.join(" / ");
QStringList clientXPositions =
argSettings.value("client_xpos")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseSensitive);
if (clientXPositions.length() != clientQuantity) {
qWarning() << "The quantity of client x positions does not match the "
"client quantity."
" Client creation will fail. No clients will be available "
"for interaction.";
return tempClientVec;
}
qDebug() << "clientXPositions:" << clientXPositions.join(" / ");
QStringList clientYPositions =
argSettings.value("client_ypos")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseSensitive);
if (clientYPositions.length() != clientQuantity) {
qWarning() << "The quantity of client y positions does not match the "
"client quantity."
" Client creation will fail. No clients will be available "
"for interaction.";
return tempClientVec;
}
qDebug() << "clientYPositions:" << clientYPositions.join(" / ");
QStringList clientIPs;
QStringList clientMACs;
QStringList clientNames;
QStringList clientXPositions;
QStringList clientYPositions;
for (int i = 0; i < clientQuantity; i++) {
tempClientVec.append(new Client{clientIPs[i], clientMACs[i], clientNames[i],
clientXPositions[i].toUShort(),
clientYPositions[i].toUShort(),
argPingCmd});
}
pt::ptree clients_dict = clients.get_child("clients");
BOOST_FOREACH(const pt::ptree::value_type &v, clients_dict) {
clientNames += QString::fromStdString(v.first);
clientIPs += QString::fromStdString(clients_dict.get_child(v.first).get<std::string>("ip"));
clientMACs += QString::fromStdString(clients_dict.get_child(v.first).get<std::string>("mac"));
clientXPositions += QString::fromStdString(clients_dict.get_child(v.first).get<std::string>("xpos"));
clientYPositions += QString::fromStdString(clients_dict.get_child(v.first).get<std::string>("ypos"));
}
qDebug() << "Client IPs:" << clientIPs.join( " / " );
if ( clientMACs.length() != clientQuantity ) {
qWarning() << "The quantity of client macs does not match the client quantity. Client"
" creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "Client MACs:" << clientMACs.join( " / " );
return tempClientVec;
if ( clientNames.length() != clientQuantity ) {
qWarning() << "The quantity of client names does not match the client quantity. Client"
" creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "Client names:" << clientNames.join( " / " );
if ( clientXPositions.length() != clientQuantity ) {
qWarning() << "The quantity of client x positions does not match the client quantity."
" Client creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "clientXPositions:" << clientXPositions.join( " / " );
if ( clientYPositions.length() != clientQuantity ) {
qWarning() << "The quantity of client y positions does not match the client quantity."
" Client creation will fail. No clients will be available for interaction.";
return tempClientVec;
}
qDebug() << "clientYPositions:" << clientYPositions.join( " / " );
for ( int i = 0; i < clientQuantity; i++ ) {
tempClientVec.append( new Client{ clientIPs[ i ], clientMACs[ i ], clientNames[ i ],
clientXPositions[ i ].toUShort(),
clientYPositions[ i ].toUShort(), argPingCmd } );
}
return tempClientVec;
}
QMap<QString, lc::Client *>
@ -347,63 +260,44 @@ QStringList lc::Settings::DetectInstalledzTreeVersions() const {
return tempInstzTreeVersions;
}
QStringList lc::Settings::GetAdminUsers(const QSettings &argSettings) {
// Read the list of users with administrative rights
if (!argSettings.contains("admin_users")) {
qDebug() << "The 'admin_users' variable was not set."
" No users will be able to conduct administrative tasks.";
return QStringList{};
} else {
QStringList adminUsers{
argSettings.value("admin_users", "")
.toString()
.split('|', QString::SkipEmptyParts, Qt::CaseInsensitive)};
qDebug() << "'adminUsers':" << adminUsers.join(" / ");
return adminUsers;
}
return QStringList{};
template <typename T>
std::vector<T> as_vector(pt::ptree const& pt, pt::ptree::key_type const& key) {
std::vector<T> r;
for (auto& item : pt.get_child(key))
r.push_back(item.second.get_value<T>());
return r;
}
quint16 lc::Settings::GetClientHelpNotificationServerPort(
const QSettings &argSettings) {
// Read the port the ClientHelpNotificationServer shall listen on
quint16 clientHelpNotificationServerPort =
argSettings.value("client_help_server_port", 0).toUInt();
if (!clientHelpNotificationServerPort) {
qDebug()
<< "The 'client_help_server_port' variable was not set or set to zero."
" The ClientHelpNotificationServer will be deactivated therefore."
" Clients' help requests will be ignored by the server.";
return 0;
} else {
qDebug() << "'clientHelpNotificationServerPort':"
<< clientHelpNotificationServerPort;
return clientHelpNotificationServerPort;
}
return 0;
}
QStringList lc::Settings::GetAdminUsers( const pt::ptree server ) {
// Read the list of users with administrative rights
int lc::Settings::GetDefaultReceiptIndex(const QSettings &argSettings) {
// Read the default receipt index for the 'CBReceipts' combobox
if (!argSettings.contains("default_receipt_index")) {
qDebug() << "'default_receipt_index' was not set. It will default to '0'.";
return 0;
}
int tempIndex = argSettings.value("default_receipt_index", 0).toInt();
qDebug() << "'defaultReceiptIndex':" << tempIndex;
return tempIndex;
QStringList adminUsers;
for (auto adminUser : as_vector<std::string>(server, "admin_users")) {
adminUsers << QString::fromStdString(adminUser);
}
if ( !adminUsers.length() ) {
qDebug() << "The 'admin_users' variable was not set."
" No users will be able to conduct administrative tasks.";
return QStringList{};
} else {
qDebug() << "'adminUsers':" << adminUsers.join( " / " );
return adminUsers;
}
}
int lc::Settings::GetInitialPort(const QSettings &argSettings) {
// Read the initial port number
if (!argSettings.contains("initial_port")) {
qDebug()
<< "The 'initial_port' variable was not set."
" Labcontrol will default to port 7000 for new zTree instances.";
}
int initialPort = argSettings.value("initial_port", 7000).toInt();
qDebug() << "'initial_port':" << initialPort;
return initialPort;
quint16 lc::Settings::GetClientHelpNotificationServerPort( const pt::ptree server ) {
// Read the port the ClientHelpNotificationServer shall listen on
quint16 clientHelpNotificationServerPort = server.get<unsigned short>( "client_help_server_port", 0 );
if ( !clientHelpNotificationServerPort ) {
qDebug() << "The 'client_help_server_port' variable was not set or set to zero."
" The ClientHelpNotificationServer will be deactivated therefore."
" Clients' help requests will be ignored by the server.";
return 0;
} else {
qDebug() << "'clientHelpNotificationServerPort':" << clientHelpNotificationServerPort;
return clientHelpNotificationServerPort;
}
}
QString lc::Settings::GetLocalUserName() {
@ -422,26 +316,38 @@ QString lc::Settings::GetLocalUserName() {
return userName;
}
QString lc::Settings::ReadSettingsItem(const QString &argVariableName,
const QString &argMessage,
const QSettings &argSettings,
bool argItemIsFile) {
if (!argSettings.contains(argVariableName)) {
qDebug() << argVariableName << "was not set." << argMessage;
return QString{};
} else {
QString tempString{argSettings.value(argVariableName).toString()};
if (argItemIsFile &&
!CheckPathAndComplain(tempString, argVariableName, argMessage)) {
tempString.clear();
}
return tempString;
}
return QString{};
}
void lc::Settings::SetLocalzLeafSize(QString arg) { localzLeafSize = arg; }
void lc::Settings::SetChosenZTreePort(const int argPort) {
chosenzTreePort = argPort;
}
QStringList lc::Settings::GetWebcams(const pt::ptree server) {
if ( !server.count("webcams") ) {
qDebug() << "'webcams' was not properly set. No stationary webcams will be available.";
return QStringList{};
} else {
std::stringstream webcam_stream;
QStringList webcams;
BOOST_FOREACH(const pt::ptree::value_type &v, server.get_child("webcams")) {
webcam_stream << v.first << ": " << &v.second << ", ";
webcams << QString::fromStdString(v.second.get_value<std::string>());
}
qDebug() << "The following webcams where loaded:" << qPrintable(QString::fromStdString(webcam_stream.str()));
return webcams;
}
}
QStringList lc::Settings::GetWebcamsNames(const pt::ptree server) {
if ( !server.count("webcams") ) {
qDebug() << "'webcams' was not properly set. No stationary webcams will be available.";
return QStringList{};
} else {
std::stringstream webcam_stream;
QStringList webcam_names;
BOOST_FOREACH(const pt::ptree::value_type &v, server.get_child("webcams")) {
webcam_names << QString::fromStdString(v.first);
}
return webcam_names;
}
}

@ -22,111 +22,115 @@
#include <QDebug>
#include <QObject>
#include <QSettings>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/foreach.hpp>
#include "client.h"
namespace pt = boost::property_tree;
namespace lc {
class Settings : public QObject {
Q_OBJECT
Q_OBJECT
public:
Settings() = delete;
explicit Settings(const QSettings &argSettings, QObject *argParent = nullptr);
Settings(const Settings &argSettings) = delete;
Settings &operator=(const Settings &argSettings) = delete;
Settings(Settings &&argSettings) = delete;
Settings &operator=(Settings &&argSettings) = delete;
~Settings();
int GetChosenZTreePort() const { return chosenzTreePort; }
QVector<Client *> &GetClients() { return clients; }
QString GetLocalzLeafName() const;
void SetChosenZTreePort(const int argPort);
void SetLocalzLeafName(const QString &argLocalzLeafName);
const int defaultReceiptIndex = 0;
const QString browserCmd;
const QString clientBrowserCmd;
const QString clientChromiumCmd;
const QString dvipsCmd;
const QString fileMngr;
const QString killallCmd;
const QString latexCmd;
const QString lcDataDir;
const QString localUserName;
QString localzLeafSize;
void SetLocalzLeafSize(QString arg);
QString GetLocalzLeafSize() const { return localzLeafSize; }
const QString lprCmd;
const QString netstatCmd;
const QString netwBrdAddr;
const QString orseeUrl;
const QString pingCmd;
const QString postscriptViewer;
const QString ps2pdfCmd;
const QString pkeyPathRoot;
const QString pkeyPathUser;
const QString rmCmd;
const QString scpCmd;
const QString serverIP;
const QString sshCmd;
const QString tasksetCmd;
const QString termEmulCmd;
const QString userNameOnClients;
const QString vncViewer;
const QString wakeonlanCmd;
const QString webcamDisplayCmd;
const QStringList webcams;
const QStringList webcams_names;
const QString wineCmd;
const QString wmctrlCmd;
const QString xsetCmd;
const QString zTreeInstDir;
const QString restartCrashedSessionScript;
const QStringList adminUsers;
const QStringList installedLaTeXHeaders;
const QStringList installedZTreeVersions;
const quint16 clientHelpNotificationServerPort = 0;
Settings() = delete;
explicit Settings( pt::ptree root );
Settings( const Settings &argSettings ) = delete;
Settings& operator=( const Settings &argSettings ) = delete;
Settings( Settings &&argSettings ) = delete;
Settings& operator=( Settings &&argSettings ) = delete;
~Settings();
QVector< Client* > &GetClients() { return clients; }
// get and set functions
int GetChosenZTreePort() const { return chosenzTreePort; }
void SetChosenZTreePort( const int argPort );
QString GetLocalzLeafName() const { return localzLeafName; }
void SetLocalzLeafName( const QString &argLocalzLeafName ) { localzLeafName = argLocalzLeafName; }
QString GetLocalzLeafSize() const { return localzLeafSize; }
void SetLocalzLeafSize( QString arg);
// ptree childs
const pt::ptree root;
const pt::ptree binary_paths;
const pt::ptree client;
const pt::ptree server;
const pt::ptree webcams_root;
// constants
const int defaultReceiptIndex = 0;
const QString browserCmd;
const QString clientBrowserCmd;
const QString clientChromiumCmd;
const QString dvipsCmd;
const QString fileMngr;
const QString killallCmd;
const QString zleafExeName;
const QString ztreeExeName;
const QString latexCmd;
const QString lcDataDir;
const QString localUserName;
const QString lprCmd;
const QString netstatCmd;
const QString netwBrdAddr;
const QString orseeUrl;
const QString pingCmd;
const QString postscriptViewer;
const QString ps2pdfCmd;
const QString pkeyPathRoot;
const QString pkeyPathUser;
const QString rmCmd;
const QString scpCmd;
const QString serverIP;
const QString sshCmd;
const QString tasksetCmd;
const QString termEmulCmd;
const QString userNameOnClients;
const QString vncViewer;
const QString wakeonlanCmd;
const QString webcamDisplayCmd;
const QStringList webcams;
const QStringList webcams_names;
const QString wineCmd;
const QString wmctrlCmd;
const QString xsetCmd;
const QString zTreeInstDir;
const QString restartCrashedSessionScript;
const QStringList adminUsers;
const QStringList installedLaTeXHeaders;
const QStringList installedZTreeVersions;
const quint16 clientHelpNotificationServerPort = 0;
const QString vncViewOnlyArguments;
private:
static bool CheckPathAndComplain(const QString &argPath,
const QString &argVariableName,
const QString &argMessage);
static QVector<Client *> CreateClients(const QSettings &argSettings,
const QString &argPingCmd);
static QMap<QString, Client *>
CreateClIPsToClMap(const QVector<Client *> &argClients);
QStringList DetectInstalledLaTeXHeaders() const;
QStringList DetectInstalledzTreeVersions() const;
static QStringList GetAdminUsers(const QSettings &argSettings);
static quint16
GetClientHelpNotificationServerPort(const QSettings &argSettings);
static int GetDefaultReceiptIndex(const QSettings &argSettings);
static int GetInitialPort(const QSettings &argSettings);
static QString GetLocalUserName();
static QString ReadSettingsItem(const QString &argVariableName,
const QString &argMessage,
const QSettings &argSettings,
bool argItemIsFile);
int chosenzTreePort = 0;
QVector<Client *> clients;
QString localzLeafName;
static bool CheckPathAndComplain( const QString &argPath, const QString &argVariableName,
const QString &argMessage );
static QVector< Client* > CreateClients( const pt::ptree &clients,
const QString &argPingCmd);
static QMap< QString, Client* > CreateClIPsToClMap( const QVector< Client* > &argClients );
QStringList DetectInstalledLaTeXHeaders() const;
QStringList DetectInstalledzTreeVersions() const;
static QStringList GetAdminUsers( const pt::ptree server );
static quint16 GetClientHelpNotificationServerPort( const pt::ptree server );
static QString GetLocalUserName();
static QStringList GetWebcams(const pt::ptree server);
static QStringList GetWebcamsNames(const pt::ptree server);
int chosenzTreePort = 0;
QVector< Client* > clients;
QString localzLeafName;
QString localzLeafSize;
public:
const QMap<QString, Client *> clIPsToClMap;
const QMap< QString, Client* > clIPsToClMap;
};
} // namespace lc
inline QString lc::Settings::GetLocalzLeafName() const {
return localzLeafName;
}
inline void lc::Settings::SetLocalzLeafName(const QString &argLocalzLeafName) {
localzLeafName = argLocalzLeafName;
}
#endif // SETTINGS_H

@ -38,30 +38,21 @@ extern std::unique_ptr<lc::Settings> settings;
* \param[in] argParent The instance's parent QObject
*/
lc::ZTree::ZTree(const QString &argZTreeDataTargetPath, const int &argZTreePort,
const QString &argZTreeVersion, QObject *const argParent)
const QString &argZTreeVersionPath, QObject *const argParent)
: QObject{argParent}, zTreeInstance{new QProcess{this}} {
const QStringList arguments{"-c",
"0",
settings->wineCmd,
QString{settings->zTreeInstDir + "/zTree_" +
argZTreeVersion + "/ztree.exe"},
"/datadir",
QString{"Z:/" + argZTreeDataTargetPath},
"/privdir",
QString{"Z:/" + argZTreeDataTargetPath},
"/gsfdir",
QString{"Z:/" + argZTreeDataTargetPath},
"/tempdir",
QString{"Z:/" + argZTreeDataTargetPath},
"/leafdir",
QString{"Z:/" + argZTreeDataTargetPath},
"/channel",
QString::number(argZTreePort - 7000)};
const QStringList arguments{ QStringList{} << QString{ settings->zTreeInstDir + "/zTree_" // first line before: << settings->wineCmd
+ argZTreeVersionPath + "/ztree.exe" }
<< "/datadir" << QString{ "Z:/" + argZTreeDataTargetPath }
<< "/privdir" << QString{ "Z:/" + argZTreeDataTargetPath }
<< "/gsfdir" << QString{ "Z:/" + argZTreeDataTargetPath }
<< "/tempdir" << QString{ "Z:/" + argZTreeDataTargetPath }
<< "/leafdir" << QString{ "Z:/" + argZTreeDataTargetPath }
<< "/channel" << QString::number( argZTreePort - 7000 ) };
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
zTreeInstance->setProcessEnvironment(env);
zTreeInstance->setWorkingDirectory(QDir::homePath());
zTreeInstance->start(settings->tasksetCmd, arguments, QIODevice::NotOpen);
//zTreeInstance->start( settings->tasksetCmd, arguments, QIODevice::NotOpen ); // old
zTreeInstance->start( settings->wineCmd, arguments, QIODevice::NotOpen );
connect(zTreeInstance,
static_cast<void (QProcess::*)(int)>(&QProcess::finished), this,
&ZTree::ZTreeClosed);

@ -20,6 +20,7 @@
#include <memory>
#include <QApplication>
#include <QDebug>
#include "Lib/settings.h"
#include "mainwindow.h"
@ -33,9 +34,23 @@ int main(int argc, char *argv[]) {
qRegisterMetaType<lc::Client::State>("Client::State");
qRegisterMetaType<lc::Client::State>("lc::Client::State");
settings.reset(new lc::Settings{QSettings{"Labcontrol", "Labcontrol"}});
lc::MainWindow w;
w.show();
return a.exec();
unsigned long i = 0;
// hard coded, you can edit here, if you prefer a different location for your config file:
std::vector<std::string> filenames = {"/usr/local/etc/Labcontrol/Labcontrol.json", "/etc/Labcontrol/Labcontrol.json", "./Labcontrol.json"};
for (i; i < filenames.size(); i++) { // if a configuration file was found, the loop breaks
std::ifstream f(filenames[i].c_str());
pt::ptree root;
if (f.good()) {
pt::read_json(f, root);
settings.reset( new lc::Settings{root} );
// clients?
lc::MainWindow w;
w.show();
return a.exec();
break;
}
}
if (i == filenames.size()) QMessageBox::critical(NULL, QString("Error"), QString("No configuration file found."));
}

@ -285,22 +285,23 @@ void lc::MainWindow::LoadIconPixmaps() {
}
void lc::MainWindow::on_PBKillLocalzLeaf_clicked() {
QString program{settings->killallCmd};
QStringList arguments;
QString program{ settings->killallCmd + " " + settings->zleafExeName};
/*QStringList arguments;
arguments << "-I"
<< "-q"
<< "zleaf.exe";
<< "zleaf.exe";*/
// ps aux | grep zleaf.exe | cut -f 5 -d " "
// Start the process
QProcess killLocalzLeafProc;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
killLocalzLeafProc.setProcessEnvironment(env);
killLocalzLeafProc.startDetached(program, arguments);
killLocalzLeafProc.startDetached(program);
localzLeavesAreRunning = false;
// Output message via the debug messages tab
qDebug() << program << arguments;
qDebug() << program;
}
void lc::MainWindow::on_PBPrintPaymentFileManually_clicked() {
@ -338,6 +339,7 @@ void lc::MainWindow::on_PBRunzLeaf_clicked() {
for (QModelIndexList::ConstIterator it = activatedItems.cbegin();
it != activatedItems.cend(); ++it) {
if ((*it).data(Qt::DisplayRole).type() != 0) {
qDebug() << "chosen fakename: " << fakeName;
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StartZLeaf(fakeName);
@ -455,7 +457,7 @@ void lc::MainWindow::SetupWidgets() {
// DisableDisfunctionalWidgets();
// Set the info text in LInfo on the TInfo tab
ui->LInfo->setText(
/*ui->LInfo->setText(
"This is Labcontrol version 2.1.6\n\n\n\n\n\n"
"Developers\n\n"
"0day-2016 Henning Prömpers\n"
@ -472,7 +474,7 @@ void lc::MainWindow::SetupWidgets() {
"See the GNU General Public License for more details.\n\n"
"You should have received a copy of the GNU General Public License\n"
"along with Labcontrol. If not, see "
"<http://www.gnu.org/licenses/>.\n\n\n");
"<http://www.gnu.org/licenses/>.\n\n\n");*/
}
void lc::MainWindow::StartReceiptsHandler(
@ -513,7 +515,7 @@ void lc::MainWindow::UpdateClientsTableView() {
s->setIcon(icons[(int)icons_t::DOWN]);
break;
case Client::State::ZLEAF_RUNNING:
s->setBackground(QBrush(QColor(0, 255, 0, 255)));
s->setBackground(QBrush(QColor(0, 255, 0, 255))); // overthink this color, thx
s->setIcon(icons[(int)icons_t::ZLEAF]);
break;
case Client::State::UNINITIALIZED:
@ -644,7 +646,7 @@ void lc::MainWindow::on_PBstartBrowser_clicked() {
if ((*it).data(Qt::DisplayRole).type() != 0) {
Client *client =
static_cast<Client *>((*it).data(Qt::UserRole).value<void *>());
client->StartClientBrowser(&argURL, &argFullscreen);
client->StartClientBrowser( &argURL, &argFullscreen, ui->CB_BrowserSelection->currentText() );
}
}
}
@ -741,20 +743,20 @@ void lc::MainWindow::StartLocalzLeaf(const QString &argzLeafName,
<< "127.0.0.1"
<< "/channel" << QString::number(argzTreePort - 7000) << "/name"
<< argzLeafName;
if (!settings->localzLeafSize.isEmpty()) {
arguments << "/size" << QString{settings->localzLeafSize};
if (!settings->GetLocalzLeafSize().isEmpty()) {
arguments << "/size" << QString{settings->GetLocalzLeafSize()};
}
qDebug() << "Start local zLeaf:" << arguments;
startProc.startDetached(settings->tasksetCmd, arguments);
startProc.startDetached(settings->wineCmd, arguments ); // before: settings->tasksetCmd
}
void lc::MainWindow::on_PBStopZtree_clicked() {
QString program{settings->killallCmd};
QStringList arguments;
QString program{settings->killallCmd + " " + settings->ztreeExeName };
/*QStringList arguments;
arguments << "-I"
<< "-q"
<< "ztree.exe";
<< "ztree.exe";*/
// Confirmation dialog
QMessageBox::StandardButton reply;
reply = QMessageBox::question(this, "Confirm",
@ -765,9 +767,9 @@ void lc::MainWindow::on_PBStopZtree_clicked() {
QProcess killLocalzLeafProc;
QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
killLocalzLeafProc.setProcessEnvironment(env);
killLocalzLeafProc.startDetached(program, arguments);
killLocalzLeafProc.startDetached(program);
// Output message via the debug messages tab
qDebug() << program << arguments;
qDebug() << program;
} else {
qDebug() << "Canceled stopping all z-Tree processes";
}
@ -812,7 +814,7 @@ void lc::MainWindow::on_CBReceiptsHeader_activated(int argIndex) {
}
// Anonymous receipients header check box
void lc::MainWindow::on_ChBPrintanonymousreceipts_clicked() {
void lc::MainWindow::on_ChBPrintAnonymousReceipts_clicked() {
ui->LReplaceParticipantNames->setEnabled(true);
ui->CBReplaceParticipantNames->setEnabled(true);
}

@ -150,10 +150,10 @@ private slots:
void GetNewDataTargetPath();
void on_CBDataTargetPath_activated(int argIndex);
void on_CBReceiptsHeader_activated(int argIndex);
void on_ChBPrintanonymousreceipts_clicked();
void on_PBKillzLeaf_clicked();
void on_PBEnableRMB_clicked();
void on_PBDisableRMB_clicked();
void on_ChBPrintAnonymousReceipts_clicked();
};
} // namespace lc

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>730</width>
<height>900</height>
<height>850</height>
</rect>
</property>
<property name="sizePolicy">
@ -16,6 +16,18 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>850</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>850</height>
</size>
</property>
<property name="windowTitle">
<string>Labcontrol</string>
</property>
@ -48,7 +60,13 @@
<property name="minimumSize">
<size>
<width>640</width>
<height>580</height>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>800</height>
</size>
</property>
<property name="baseSize">
@ -176,7 +194,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@ -214,24 +232,28 @@
</widget>
</item>
<item>
<widget class="QPushButton" name="PBBoot">
<property name="toolTip">
<string>Boots the selected clients.</string>
</property>
<property name="text">
<string>Boot</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PBShutdown">
<property name="toolTip">
<string>Turns off the selected clients.</string>
</property>
<property name="text">
<string>Shutdown</string>
</property>
</widget>
<layout class="QHBoxLayout" name="HLBootShutdown">
<item>
<widget class="QPushButton" name="PBShutdown">
<property name="toolTip">
<string>Turn off the selected clients.</string>
</property>
<property name="text">
<string>Shutdown</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PBBoot">
<property name="toolTip">
<string>Boot the selected clients.</string>
</property>
<property name="text">
<string>Boot</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="Line" name="line_bootActions">
@ -243,30 +265,33 @@
<item>
<widget class="QLabel" name="L_VNC">
<property name="text">
<string>Remote control the selected clients</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PBViewDesktopViewOnly">
<property name="toolTip">
<string>Shows the desktop of the selected clients.</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="L_VNC">
<property name="text">
<string>View desktop (view only)</string>
<string>Remote Control selected clients</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PBViewDesktopFullControl">
<property name="text">
<string>Control desktop (mouse and keyboard)</string>
</property>
</widget>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QPushButton" name="PBViewDesktopFullControl">
<property name="toolTip">
<string>Control mouse and keyboard</string>
</property>
<property name="text">
<string>Control desktop</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PBViewDesktopViewOnly">
<property name="toolTip">
<string>View only</string>
</property>
<property name="text">
<string>Show desktop</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label">
@ -357,13 +382,6 @@
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="L_ClientPlaceholder">
<property name="text">
<string>%CLIENT% is a placeholder for hostname in URL</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="HLURL">
<item>
@ -375,6 +393,12 @@
</item>
<item>
<widget class="QLineEdit" name="LEURL">
<property name="toolTip">
<string>%CLIENT% is a placeholder for the hostname in the URL</string>
</property>
<property name="toolTipDuration">
<number>-1</number>
</property>
<property name="text">
<string>http://localhost:8000/%CLIENT%</string>
</property>
@ -383,25 +407,35 @@
</layout>
</item>
<item>
<widget class="QLabel" name="L_BrowserSelection">
<property name="text">
<string>Use the following browser</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="CB_BrowserSelection">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<property name="text">
<string>chromium</string>
</property>
<widget class="QLabel" name="L_BrowserSelection">
<property name="text">
<string>Use browser:</string>
</property>
</widget>
</item>
<item>
<property name="text">
<string>firefox</string>
</property>
<widget class="QComboBox" name="CB_BrowserSelection">
<property name="minimumSize">
<size>
<width>240</width>
<height>0</height>
</size>
</property>
<item>
<property name="text">
<string>chromium</string>
</property>
</item>
<item>
<property name="text">
<string>firefox</string>
</property>
</item>
</widget>
</item>
</widget>
</layout>
</item>
<item>
<widget class="QCheckBox" name="CBFullscreen">
@ -439,7 +473,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@ -537,7 +571,7 @@
<x>10</x>
<y>88</y>
<width>691</width>
<height>468</height>
<height>539</height>
</rect>
</property>
<layout class="QVBoxLayout" name="VLNewSession">
@ -738,7 +772,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@ -878,7 +912,7 @@
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
<height>0</height>
</size>
</property>
</spacer>
@ -941,7 +975,7 @@
<item>
<widget class="QRadioButton" name="RBUseUserRoot">
<property name="text">
<string>root</string>
<string>roo&amp;t</string>
</property>
</widget>
</item>
@ -1007,26 +1041,6 @@
</item>
</layout>
</widget>
<widget class="QWidget" name="TInfo">
<property name="layoutDirection">
<enum>Qt::RightToLeft</enum>
</property>
<attribute name="title">
<string>Info</string>
</attribute>
<layout class="QVBoxLayout" name="VLInfo">
<item>
<widget class="QLabel" name="LInfo">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
<item>
@ -1043,7 +1057,13 @@
<property name="minimumSize">
<size>
<width>0</width>
<height>256</height>
<height>200</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>200</height>
</size>
</property>
<property name="font">
@ -1081,24 +1101,24 @@
<attribute name="horizontalHeaderCascadingSectionResizes">
<bool>true</bool>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>115</number>
</attribute>
<attribute name="horizontalHeaderMinimumSectionSize">
<number>30</number>
</attribute>
<attribute name="horizontalHeaderDefaultSectionSize">
<number>115</number>
</attribute>
<attribute name="horizontalHeaderStretchLastSection">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>false</bool>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>35</number>
</attribute>
<attribute name="verticalHeaderMinimumSectionSize">
<number>25</number>
</attribute>
<attribute name="verticalHeaderDefaultSectionSize">
<number>35</number>
</attribute>
<attribute name="verticalHeaderStretchLastSection">
<bool>false</bool>
</attribute>

Loading…
Cancel
Save