mirror of
https://github.com/arcan1s/queued.git
synced 2025-04-24 15:37:19 +00:00
start on queuedctl realization
This commit is contained in:
parent
a2872e7c23
commit
80c6f977d7
@ -75,6 +75,7 @@ get_directory_property(CMAKE_DEFINITIONS COMPILE_DEFINITIONS)
|
||||
configure_file("${CMAKE_SOURCE_DIR}/version.h.in" "${CMAKE_CURRENT_BINARY_DIR}/version.h")
|
||||
add_subdirectory("queued")
|
||||
add_subdirectory("queued-daemon")
|
||||
add_subdirectory("queuedctl")
|
||||
if (BUILD_TESTING)
|
||||
enable_testing()
|
||||
add_subdirectory("test")
|
||||
|
@ -43,7 +43,7 @@ QueuedApplication::~QueuedApplication()
|
||||
qCDebug(LOG_APP) << __PRETTY_FUNCTION__;
|
||||
|
||||
QDBusConnection::sessionBus().unregisterObject(
|
||||
QueuedConfig::DBUS_APPLICATION_PATH);
|
||||
QueuedConfig::DBUS_APPLICATION_PATH);
|
||||
deinit();
|
||||
}
|
||||
|
||||
|
@ -48,12 +48,6 @@ bool QueuedApplicationInterface::Active() const
|
||||
}
|
||||
|
||||
|
||||
void QueuedApplicationInterface::Close() const
|
||||
{
|
||||
return QCoreApplication::exit(0);
|
||||
}
|
||||
|
||||
|
||||
QStringList QueuedApplicationInterface::UIDs() const
|
||||
{
|
||||
QStringList uids;
|
||||
|
@ -35,7 +35,6 @@ public:
|
||||
|
||||
public slots:
|
||||
bool Active() const;
|
||||
Q_NOREPLY void Close() const;
|
||||
QStringList UIDs() const;
|
||||
|
||||
private:
|
||||
|
@ -95,7 +95,7 @@ int main(int argc, char *argv[])
|
||||
auto metadata = QueuedDebug::getBuildData();
|
||||
for (auto &string : metadata)
|
||||
QDebug(QtMsgType::QtInfoMsg).noquote() << string;
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// check if exists
|
||||
@ -114,7 +114,7 @@ int main(int argc, char *argv[])
|
||||
// start application
|
||||
instance = new QueuedApplication(nullptr, arguments);
|
||||
// catch SIGHUP
|
||||
signal(SIGHUP, [](int sig) ->void {
|
||||
signal(SIGHUP, [](int sig) -> void {
|
||||
qCInfo(LOG_APP) << "Received SIGHUP signal, reinit components";
|
||||
instance->init();
|
||||
});
|
||||
|
@ -109,6 +109,13 @@ public:
|
||||
const QString &_password, const uint _permissions,
|
||||
const QueuedLimits::Limits &_limits,
|
||||
const QString &_token);
|
||||
/**
|
||||
* @brief try to authorize by given token
|
||||
* @param _token
|
||||
* token ID
|
||||
* @return true if token is valid
|
||||
*/
|
||||
bool authorization(const QString &_token);
|
||||
/**
|
||||
* @brief authorize and create new token for user
|
||||
* @param _name
|
||||
|
@ -38,6 +38,13 @@
|
||||
namespace QueuedCoreAdaptor
|
||||
{
|
||||
// specific methods for control interface
|
||||
/**
|
||||
* @brief send TryAuth
|
||||
* @param _token
|
||||
* token ID
|
||||
* @return true if token is valid
|
||||
*/
|
||||
bool auth(const QString &_token);
|
||||
/**
|
||||
* @brief send auth method
|
||||
* @param _name
|
||||
|
@ -178,6 +178,13 @@ public slots:
|
||||
* @return true on successful task stop
|
||||
*/
|
||||
bool TaskStop(const qlonglong id, const QString &token);
|
||||
/**
|
||||
* @brief try auth by token
|
||||
* @param token
|
||||
* token ID
|
||||
* @return true if token is valid
|
||||
*/
|
||||
bool TryAuth(const QString &token);
|
||||
/**
|
||||
* @brief add new user
|
||||
* @param name
|
||||
|
@ -67,6 +67,12 @@ public:
|
||||
* @return default path to configuration file
|
||||
*/
|
||||
static QString defaultPath();
|
||||
/**
|
||||
* @brief default path to cached token
|
||||
* @return default path to cached token file
|
||||
* @return
|
||||
*/
|
||||
static QString defaultTokenPath();
|
||||
/**
|
||||
* @brief path to database
|
||||
* @return path to used database
|
||||
|
@ -140,6 +140,18 @@ long long QueuedCore::addUser(const QString &_name, const QString &_email,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn authorization
|
||||
*/
|
||||
bool QueuedCore::authorization(const QString &_token)
|
||||
{
|
||||
bool status = false;
|
||||
m_users->checkToken(_token, &status);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn authorization
|
||||
*/
|
||||
|
@ -25,8 +25,20 @@
|
||||
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMessage>
|
||||
#include <queued/QueuedProcess.h>
|
||||
#include <queued/QueuedUser.h>
|
||||
|
||||
|
||||
/**
|
||||
* @fn auth
|
||||
*/
|
||||
bool QueuedCoreAdaptor::auth(const QString &_token)
|
||||
{
|
||||
QVariantList args = {_token};
|
||||
return toNativeType(sendRequest(QueuedConfig::DBUS_SERVICE,
|
||||
QueuedConfig::DBUS_OBJECT_PATH,
|
||||
QueuedConfig::DBUS_SERVICE, "/TryAuth",
|
||||
args))
|
||||
.toBool();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
|
@ -193,6 +193,15 @@ bool QueuedCoreInterface::TaskStop(const qlonglong id, const QString &token)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn TryAuth
|
||||
*/
|
||||
bool QueuedCoreInterface::TryAuth(const QString &token)
|
||||
{
|
||||
return m_core->authorization(token);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn UserAdd
|
||||
*/
|
||||
|
@ -88,6 +88,20 @@ QString QueuedSettings::defaultPath()
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn defaultTokenPath
|
||||
*/
|
||||
QString QueuedSettings::defaultTokenPath()
|
||||
{
|
||||
QString fileName = QString("%1/queued")
|
||||
.arg(QStandardPaths::writableLocation(
|
||||
QStandardPaths::GenericCacheLocation));
|
||||
qCInfo(LOG_LIB) << "Cache file location" << fileName;
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @fn path
|
||||
*/
|
||||
@ -106,24 +120,22 @@ void QueuedSettings::readConfiguration()
|
||||
qCInfo(LOG_LIB) << "Read configuration from" << settings.fileName();
|
||||
|
||||
// administrator related settings
|
||||
settings.beginGroup(QString("Administrator"));
|
||||
m_cfgAdmin.name
|
||||
= settings.value(QString("Username"), QString("root")).toString();
|
||||
m_cfgAdmin.password = settings.value(QString("Password")).toString();
|
||||
settings.beginGroup("Administrator");
|
||||
m_cfgAdmin.name = settings.value("Username", "root").toString();
|
||||
m_cfgAdmin.password = settings.value("Password").toString();
|
||||
settings.endGroup();
|
||||
|
||||
// database related settings
|
||||
settings.beginGroup(QString("Database"));
|
||||
m_cfgDB.driver
|
||||
= settings.value(QString("Driver"), QString("QSQLITE")).toString();
|
||||
m_cfgDB.hostname = settings.value(QString("Hostname")).toString();
|
||||
m_cfgDB.password = settings.value(QString("Password")).toString();
|
||||
settings.beginGroup("Database");
|
||||
m_cfgDB.driver = settings.value("Driver", "QSQLITE").toString();
|
||||
m_cfgDB.hostname = settings.value("Hostname").toString();
|
||||
m_cfgDB.password = settings.value("Password").toString();
|
||||
// get standard path for temporary files
|
||||
QString defaultDB = QString("%1/queued.db")
|
||||
.arg(QStandardPaths::writableLocation(
|
||||
QStandardPaths::TempLocation));
|
||||
m_cfgDB.path = settings.value(QString("Path"), defaultDB).toString();
|
||||
m_cfgDB.port = settings.value(QString("Port")).toInt();
|
||||
m_cfgDB.username = settings.value(QString("Username")).toString();
|
||||
m_cfgDB.path = settings.value("Path", defaultDB).toString();
|
||||
m_cfgDB.port = settings.value("Port").toInt();
|
||||
m_cfgDB.username = settings.value("Username").toString();
|
||||
settings.endGroup();
|
||||
}
|
||||
|
13
sources/queuedctl/CMakeLists.txt
Normal file
13
sources/queuedctl/CMakeLists.txt
Normal file
@ -0,0 +1,13 @@
|
||||
# set project name
|
||||
set (SUBPROJECT "queuedctl")
|
||||
message (STATUS "Subproject ${SUBPROJECT}")
|
||||
|
||||
add_subdirectory ("src")
|
||||
# build man
|
||||
file (GLOB SUBPROJECT_MAN_IN "*.1")
|
||||
file (RELATIVE_PATH SUBPROJECT_MAN "${CMAKE_SOURCE_DIR}" "${SUBPROJECT_MAN_IN}")
|
||||
configure_file ("${SUBPROJECT_MAN_IN}" "${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_MAN}")
|
||||
|
||||
install (FILES "${CMAKE_CURRENT_BINARY_DIR}/${SUBPROJECT_MAN}" DESTINATION "${DATA_INSTALL_DIR}/man/man1")
|
||||
install (FILES "bash-completions" DESTINATION "${DATA_INSTALL_DIR}/bash-completion/completions" RENAME "${SUBPROJECT}")
|
||||
install (FILES "zsh-completions" DESTINATION "${DATA_INSTALL_DIR}/zsh/site-functions" RENAME "_${SUBPROJECT}")
|
0
sources/queuedctl/bash-completions
Normal file
0
sources/queuedctl/bash-completions
Normal file
0
sources/queuedctl/queued-daemon.1
Normal file
0
sources/queuedctl/queued-daemon.1
Normal file
18
sources/queuedctl/src/CMakeLists.txt
Normal file
18
sources/queuedctl/src/CMakeLists.txt
Normal file
@ -0,0 +1,18 @@
|
||||
# set files
|
||||
file (GLOB_RECURSE SUBPROJECT_SOURCES "*.cpp")
|
||||
file (GLOB_RECURSE SUBPROJECT_HEADERS "*.h")
|
||||
|
||||
# include_path
|
||||
include_directories ("${PROJECT_LIBRARY_DIR}/include"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}"
|
||||
"${CMAKE_BINARY_DIR}"
|
||||
"${PROJECT_TRDPARTY_DIR}"
|
||||
"${Qt_INCLUDE}")
|
||||
|
||||
qt5_wrap_cpp (SUBPROJECT_MOC_SOURCES "${SUBPROJECT_HEADERS}")
|
||||
|
||||
add_executable ("${SUBPROJECT}" "${SUBPROJECT_HEADERS}" "${SUBPROJECT_SOURCES}"
|
||||
"${SUBPROJECT_MOC_SOURCES}")
|
||||
target_link_libraries ("${SUBPROJECT}" "${PROJECT_LIBRARY}" "${Qt_LIBRARIES}")
|
||||
# install properties
|
||||
install (TARGETS "${SUBPROJECT}" DESTINATION "${BIN_INSTALL_DIR}")
|
104
sources/queuedctl/src/QueuedctlAuth.cpp
Normal file
104
sources/queuedctl/src/QueuedctlAuth.cpp
Normal file
@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Evgeniy Alekseev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
*
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "QueuedctlAuth.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <queued/Queued.h>
|
||||
|
||||
extern "C" {
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
}
|
||||
|
||||
|
||||
QString QueuedctlAuth::auth(const QString &_user)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Auth as user" << _user;
|
||||
|
||||
// read password
|
||||
// do not show input characters
|
||||
struct termios tty;
|
||||
::tcgetattr(STDIN_FILENO, &tty);
|
||||
tty.c_lflag &= ~ECHO;
|
||||
tcsetattr(STDIN_FILENO, TCSANOW, &tty);
|
||||
|
||||
qInfo() << "Password for" << _user;
|
||||
QTextStream stream(stdin);
|
||||
QString password;
|
||||
stream >> password;
|
||||
|
||||
return QueuedCoreAdaptor::auth(_user, password);
|
||||
}
|
||||
|
||||
|
||||
QString QueuedctlAuth::getToken(const QString &_cache, const QString &_user)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Get token using cache" << _cache << "and user"
|
||||
<< _user;
|
||||
|
||||
QString tokenId = token(_cache);
|
||||
if (tryAuth(tokenId)) {
|
||||
return tokenId;
|
||||
} else {
|
||||
tokenId = auth(_user);
|
||||
setToken(tokenId, _cache);
|
||||
return getToken(_cache, _user);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QueuedctlAuth::parser(QCommandLineParser &_parser)
|
||||
{
|
||||
_parser.clearPositionalArguments();
|
||||
}
|
||||
|
||||
|
||||
void QueuedctlAuth::setToken(const QString &_token, const QString &_cache)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Save token to" << _cache;
|
||||
|
||||
QSettings settings(_cache, QSettings::IniFormat);
|
||||
settings.beginGroup("queuedctl");
|
||||
settings.setValue("Token", _token);
|
||||
settings.endGroup();
|
||||
|
||||
settings.sync();
|
||||
}
|
||||
|
||||
|
||||
QString QueuedctlAuth::token(const QString &_cache)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Load token from" << _cache;
|
||||
|
||||
QString token;
|
||||
|
||||
QSettings settings(_cache, QSettings::IniFormat);
|
||||
settings.beginGroup("queuedctl");
|
||||
token = settings.value("Token").toString();
|
||||
settings.endGroup();
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
|
||||
bool QueuedctlAuth::tryAuth(const QString &_token)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Try auth with" << _token;
|
||||
|
||||
return QueuedCoreAdaptor::auth(_token);
|
||||
}
|
34
sources/queuedctl/src/QueuedctlAuth.h
Normal file
34
sources/queuedctl/src/QueuedctlAuth.h
Normal file
@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Evgeniy Alekseev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
*
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QUEUEDCTLAUTH_H
|
||||
#define QUEUEDCTLAUTH_H
|
||||
|
||||
#include <QCommandLineParser>
|
||||
|
||||
|
||||
namespace QueuedctlAuth
|
||||
{
|
||||
QString auth(const QString &_user);
|
||||
QString getToken(const QString &_cache, const QString &_user);
|
||||
void parser(QCommandLineParser &_parser);
|
||||
void setToken(const QString &_token, const QString &_cache);
|
||||
QString token(const QString &_cache);
|
||||
bool tryAuth(const QString &_token);
|
||||
};
|
||||
|
||||
|
||||
#endif /* QUEUEDCTLAUTH_H */
|
39
sources/queuedctl/src/QueuedctlOption.cpp
Normal file
39
sources/queuedctl/src/QueuedctlOption.cpp
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Evgeniy Alekseev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
*
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include "QueuedctlOption.h"
|
||||
|
||||
#include <queued/Queued.h>
|
||||
|
||||
#include "QueuedctlAuth.h"
|
||||
|
||||
|
||||
bool QueuedctlOption::editOption(const QString &_option, const QVariant &_value,
|
||||
const QString &_cache, const QString &_user)
|
||||
{
|
||||
qCDebug(LOG_APP) << "Edit option" << _option << "to" << _value;
|
||||
|
||||
QString token = QueuedctlAuth::getToken(_cache, _user);
|
||||
return QueuedCoreAdaptor::sendOptionEdit(_option, _value, token);
|
||||
}
|
||||
|
||||
|
||||
void QueuedctlOption::parser(QCommandLineParser &_parser)
|
||||
{
|
||||
_parser.clearPositionalArguments();
|
||||
_parser.addPositionalArgument("option", "Option name.");
|
||||
_parser.addPositionalArgument("value", "Option value.");
|
||||
}
|
31
sources/queuedctl/src/QueuedctlOption.h
Normal file
31
sources/queuedctl/src/QueuedctlOption.h
Normal file
@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Evgeniy Alekseev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
*
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef QUEUEDCTLOPTION_H
|
||||
#define QUEUEDCTLOPTION_H
|
||||
|
||||
#include <QCommandLineParser>
|
||||
|
||||
|
||||
namespace QueuedctlOption
|
||||
{
|
||||
bool editOption(const QString &_option, const QVariant &_value,
|
||||
const QString &_cache, const QString &_user);
|
||||
void parser(QCommandLineParser &_parser);
|
||||
};
|
||||
|
||||
|
||||
#endif /* QUEUEDCTLOPTION_H */
|
107
sources/queuedctl/src/main.cpp
Normal file
107
sources/queuedctl/src/main.cpp
Normal file
@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (c) 2016 Evgeniy Alekseev
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
*
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*/
|
||||
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <queued/Queued.h>
|
||||
|
||||
#include "QueuedctlAuth.h"
|
||||
#include "QueuedctlOption.h"
|
||||
#include "version.h"
|
||||
|
||||
extern "C" {
|
||||
#include <unistd.h>
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
QCoreApplication app(argc, argv);
|
||||
app.setApplicationName(NAME);
|
||||
app.setApplicationVersion(VERSION);
|
||||
|
||||
// parser
|
||||
QCommandLineParser parser;
|
||||
parser.setApplicationDescription(
|
||||
"Daemon for starting jobs to queue of calculations");
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
// info
|
||||
QCommandLineOption infoOption(QStringList() << "i"
|
||||
<< "info",
|
||||
"Show additional info.");
|
||||
parser.addOption(infoOption);
|
||||
|
||||
// debug mode
|
||||
QCommandLineOption debugOption(QStringList() << "d"
|
||||
<< "debug",
|
||||
"Print debug information.");
|
||||
parser.addOption(debugOption);
|
||||
|
||||
// configuration option
|
||||
QCommandLineOption tokenOption(QStringList() << "t"
|
||||
<< "token",
|
||||
"Path to cached token.", "token",
|
||||
QueuedSettings::defaultTokenPath());
|
||||
parser.addOption(tokenOption);
|
||||
QCommandLineOption userOption(QStringList() << "u"
|
||||
<< "user",
|
||||
"User to login instead of current one.",
|
||||
"user", ::getlogin());
|
||||
parser.addOption(userOption);
|
||||
|
||||
parser.addPositionalArgument("command", "Command to execute.");
|
||||
|
||||
// pre-parse
|
||||
parser.parse(QCoreApplication::arguments());
|
||||
QStringList args = parser.positionalArguments();
|
||||
QString command = args.isEmpty() ? QString() : args.first();
|
||||
|
||||
if (command == "auth") {
|
||||
QueuedctlAuth::parser(parser);
|
||||
} else if (command == "option-edit") {
|
||||
QueuedctlOption::parser(parser);
|
||||
} else if (command == "task-add") {
|
||||
parser.clearPositionalArguments();
|
||||
} else if (command == "task-edit") {
|
||||
parser.clearPositionalArguments();
|
||||
} else if (command == "user-add") {
|
||||
parser.clearPositionalArguments();
|
||||
} else if (command == "user-edit") {
|
||||
parser.clearPositionalArguments();
|
||||
} else {
|
||||
parser.process(app);
|
||||
qWarning() << "Unknown command" << command;
|
||||
parser.showHelp(1);
|
||||
}
|
||||
|
||||
parser.process(app);
|
||||
|
||||
// show info and exit
|
||||
if (parser.isSet(infoOption)) {
|
||||
auto metadata = QueuedDebug::getBuildData();
|
||||
for (auto &string : metadata)
|
||||
QDebug(QtMsgType::QtInfoMsg).noquote() << string;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// enable debug
|
||||
if (parser.isSet(debugOption))
|
||||
QueuedDebug::enableDebug();
|
||||
|
||||
return 0;
|
||||
}
|
0
sources/queuedctl/zsh-completions
Normal file
0
sources/queuedctl/zsh-completions
Normal file
Loading…
Reference in New Issue
Block a user