Patronum
Loading...
Searching...
No Matches
PServiceBase.cpp
Go to the documentation of this file.
1/*
2 * Copyright (C) 2018-2025 QuasarApp.
3 * Distributed under the lgplv3 software license, see the accompanying
4 * Everyone is permitted to copy and distribute verbatim copies
5 * of this license document, but changing it is not allowed.
6*/
7
8#include "PServiceBase.h"
9#include <QCoreApplication>
10#include <QFile>
11#include <QLibraryInfo>
12#include <QProcess>
13#include <QStandardPaths>
14#include <QTimer>
15#include <pcommon.h>
16#include "PController.h"
17#include "serviceprivate.h"
18#include <chrono>
19#include <thread>
20#include "patronum.h"
21
22namespace Patronum {
23
24ServiceBase::ServiceBase(int argc, char *argv[]) {
25 QuasarAppUtils::Params::parseParams(argc, argv);
26 d_ptr = new ServicePrivate(this);
27
28 init();
29
30}
31
33 delete d_ptr;
34
35 qint64 pid = PCommon::instance()->getPidFromPidfile();
36 if (pid == QCoreApplication::applicationPid()) {
37 QFile pidFile(PCommon::instance()->getPidfile());
38 pidFile.remove();
39 }
40
41 if (_core) {
42 delete _core;
43 }
44
45 if (_controller) {
46 delete _controller;
47 }
48}
49
50void ServiceBase::handleReceiveData(const QSet<Feature> &data) {
51 auto list = supportedFeatures();
52
53 QString commandList;
54
55 for (const auto& i: data) {
56 if (list.contains(i)) {
57 if (!handleReceive(i)) {
58 sendResuylt(QString("The process of a command %0 with argumets: %1 is failed")
59 .arg(i.cmd(), i.arg()));
60 }
61 } else {
62 commandList += i.toString() + " ";
63 }
64 }
65
66 if (commandList.size()) {
67 QString stringList;
68
69 for (const auto&i : list) {
70 stringList += i.toString() + " ";
71 }
72
73 QVariantMap result;
74
75 result["Error"] = "Wrong command! The commands : " + commandList + " is not supported";
76 result["Available commands"] = stringList;
77
78 sendResuylt(result);
79 }
80}
81
83 return {};
84}
85
86bool ServiceBase::sendResuylt(const QVariantMap &result) {
87 return d_ptr->sendCmdResult(result);
88}
89
90bool ServiceBase::sendResuylt(const QString &result) {
91 return d_ptr->sendCmdResult({{"Result", result}});
92}
93
95 sendResuylt("Success! Use default stop function");
96
97 QTimer::singleShot(1000, nullptr, [](){
98 QCoreApplication::quit();
99 });
100}
101
103 sendResuylt("This function not supported");
104}
105
107 sendResuylt("This function not supported");
108}
109
111 if (_controller)
112 return _controller;
113
114 _controller = new Controller();
115
116 return _controller;
117}
118
119void ServiceBase::printDefaultHelp() {
120 auto serviceHelp = controller()->help();
121 serviceHelp.unite(QuasarAppUtils::Params::getHelp());
122
123 serviceHelp.unite({{QObject::tr("Options that available befor install"),{
124 {"start / s", QObject::tr("Start a service in console")},
125 {"daemon / d", QObject::tr("Start a service as a daemon")},
126 {"install / i / -install username", QObject::tr("Install a service. Add user name if you want to run service from custom user. Example: -install username")},
127 {"unistall / u", QObject::tr("unistall a service")},
128 }}});
129
130 const auto features = supportedFeatures();
131 QuasarAppUtils::Help::Options optionsList;
132 for (const auto& cmd : features) {
133 optionsList.insert(cmd.cmd(), cmd.description());
134 }
135
136 serviceHelp.unite({{"Available commands of the service:", optionsList}});
137
138 QuasarAppUtils::Help::print(serviceHelp);
139
140}
141
142QCoreApplication *ServiceBase::core() {
143 return _core;
144}
145
146void ServiceBase::setCore(QCoreApplication *core) {
147 if (_core)
148 delete _core;
149
150 _core = core;
151}
152
154 if (!core()) {
156 }
157
158
159 bool printHelp = !QuasarAppUtils::Params::size() ||
160 QuasarAppUtils::Params::isEndable("h") ||
161 QuasarAppUtils::Params::isEndable("help");
162
163 if (printHelp) {
164 printDefaultHelp();
165 return 0;
166 }
167
168 bool fStart = QuasarAppUtils::Params::isEndable("start") || QuasarAppUtils::Params::isEndable("s");
169 bool fDaemon = QuasarAppUtils::Params::isEndable("daemon") || QuasarAppUtils::Params::isEndable("d");
170
171 if (QuasarAppUtils::Params::isEndable("install") || QuasarAppUtils::Params::isEndable("i")) {
172 if (!d_ptr->install(QuasarAppUtils::Params::getArg("install")))
174 return 0;
175 }
176
177 if (QuasarAppUtils::Params::isEndable("uninstall") || QuasarAppUtils::Params::isEndable("u")) {
178 if (!d_ptr->uninstall())
180 return 0;
181 }
182
183 if (fStart || fDaemon) {
184
185 if (fDaemon) {
186 if (!d_ptr->startDeamon())
188 return 0;
189 }
190
191 QTimer::singleShot(0, nullptr, [this]() {
192 if (controller()->sendStop()) {
193 std::this_thread::sleep_for (std::chrono::milliseconds(1000));
194 }
195
196 if (!d_ptr->start()) {
197 QCoreApplication::exit(FailedToStart);
198 }
199
200 });
201 } else {
202 QTimer::singleShot(0, nullptr, [this]() {
203 if (!controller()->send()) {
204 core()->exit(static_cast<int>(PatronumError::ServiceUnavailable));
205 }
206 });
207 }
208
209 return core()->exec();
210}
211
212}
213
The Controller class provide control functionality for your service.
Definition PController.h:57
QuasarAppUtils::Help::Section help() const
help This method return help of the Controller.
virtual bool handleReceive(const Feature &data)=0
handleReceive This method invoked when service receive a request from terminal. Override this method ...
void setCore(QCoreApplication *core)
setCore This method sets new object of the core application.
virtual int exec()
exec This is main method of the service. Use this like a QCoreApplication::exec.
void onPause() override
onPause Called when get pause command from terminal. The Default implementation do nothing.
void onResume() override
onResume Called when get resume command from terminal. The Default implementation do nothing.
virtual void createApplication()=0
createApplication Default implementation create a Application object and parse arguments.
bool sendResuylt(const QVariantMap &result)
sendResuylt - Call this method for send responce from service to tour controller.
QSet< Feature > supportedFeatures() override
supportedFeatures
void onStop() override
onStop Called when get stop command from terminal. The default implementation of this method invoke a...
Controller * controller()
controller This method return the local controller object. If the controller object is not inited the...
void handleReceiveData(const QSet< Feature > &data) override final
handleReceiveData - This method invoice when service receive new command from terminal of controller ...
QCoreApplication * core()
core This method return a pointer to instance of the core application.
ServiceBase(int argc, char *argv[])
ServiceBase This is main constructor of the service.
The Patronum namespace - It is main name space of Patronum Library. The Patronum library support the ...
void init()
Definition patronum.cpp:17
@ FailedToStart
This error ocured when user srvice failed to start.
@ ServiceUnavailable
Service is unavailable. Try send start command or restart the service manually.
@ UnsupportedPlatform
This error ocured when service not supportded using platform.