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 QHash<QString, 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
94bool ServiceBase::sendRawResuylt(const QByteArray &result) {
95 return d_ptr->sendCmdResult({{"", result}});
96}
97
99 sendResuylt("Success! Use default stop function");
100
101 QTimer::singleShot(1000, nullptr, [](){
102 QCoreApplication::quit();
103 });
104}
105
107 sendResuylt("This function not supported");
108}
109
111 sendResuylt("This function not supported");
112}
113
115 if (_controller)
116 return _controller;
117
118 _controller = new Controller();
119
120 return _controller;
121}
122
123void ServiceBase::printDefaultHelp() {
124 auto serviceHelp = controller()->help();
125 serviceHelp.unite(QuasarAppUtils::Params::getHelp());
126
127 serviceHelp.unite({{QObject::tr("Options that available befor install"),{
128 {"start / s", QObject::tr("Start a service in console")},
129 {"daemon / d", QObject::tr("Start a service as a daemon")},
130 {"install / i / -install username", QObject::tr("Install a service. Add user name if you want to run service from custom user. Example: -install username")},
131 {"unistall / u", QObject::tr("unistall a service")},
132 }}});
133
134 const auto features = supportedFeatures();
135 QuasarAppUtils::Help::Options optionsList;
136 for (const auto& cmd : features) {
137 optionsList.insert(cmd.cmd(), cmd.description());
138 }
139
140 serviceHelp.unite({{"Available commands of the service:", optionsList}});
141
142 QuasarAppUtils::Help::print(serviceHelp);
143
144}
145
146QCoreApplication *ServiceBase::core() {
147 return _core;
148}
149
150void ServiceBase::setCore(QCoreApplication *core) {
151 if (_core)
152 delete _core;
153
154 _core = core;
155}
156
158 if (!core()) {
160 }
161
162
163 bool printHelp = !QuasarAppUtils::Params::size() ||
164 QuasarAppUtils::Params::isEndable("h") ||
165 QuasarAppUtils::Params::isEndable("help");
166
167 if (printHelp) {
168 printDefaultHelp();
169 return 0;
170 }
171
172 bool fStart = QuasarAppUtils::Params::isEndable("start") || QuasarAppUtils::Params::isEndable("s");
173 bool fDaemon = QuasarAppUtils::Params::isEndable("daemon") || QuasarAppUtils::Params::isEndable("d");
174
175 if (QuasarAppUtils::Params::isEndable("install") || QuasarAppUtils::Params::isEndable("i")) {
176 if (!d_ptr->install(QuasarAppUtils::Params::getArg("install")))
178 return 0;
179 }
180
181 if (QuasarAppUtils::Params::isEndable("uninstall") || QuasarAppUtils::Params::isEndable("u")) {
182 if (!d_ptr->uninstall())
184 return 0;
185 }
186
187 if (fStart || fDaemon) {
188
189 if (fDaemon) {
190 if (!d_ptr->startDeamon())
192 return 0;
193 }
194
195 QTimer::singleShot(0, nullptr, [this]() {
196 if (controller()->sendStop()) {
197 std::this_thread::sleep_for (std::chrono::milliseconds(1000));
198 }
199
200 if (!d_ptr->start()) {
201 QCoreApplication::exit(FailedToStart);
202 }
203
204 });
205 } else {
206 QTimer::singleShot(0, nullptr, [this]() {
207 if (!controller()->send()) {
208 core()->exit(static_cast<int>(PatronumError::ServiceUnavailable));
209 }
210 });
211 }
212
213 return core()->exec();
214}
215
216}
217
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.
void handleReceiveData(const QHash< QString, Feature > &data) override
handleReceiveData - This method invoice when service receive new command from terminal of controller ...
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.
bool sendRawResuylt(const QByteArray &result)
sendRawResuylt This method send raw text responce to controller.
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...
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.