10#include "qstandardpaths.h"
12#include <QNetworkReply>
18 _manager =
new QNetworkAccessManager();
19 _manager->setAutoDeleteReplies(
true);
20 _requestExecutor =
new QTimer(
this);
21 _requestExecutor->setInterval(1000 / 20);
23 connect(_requestExecutor, &QTimer::timeout,
this , &IBot::handleEcxecuteRequest);
40 _startTime = QDateTime::currentDateTime();
45 if (!message->isValid())
48 auto id = message->updateId();
50 if (!_processed.contains(
id)) {
52 _processed.insert(
id);
53 _notProcessedUpdates[id] = message;
59QNetworkReply* IBot::sendRquestImpl(
const QSharedPointer<iRequest> &rquest) {
65#ifdef QTBOT_PRINT_RQUESTS
69 QNetworkReply* networkReplay =
nullptr;
70 QSharedPointer<QHttpMultiPart> httpData;
72 switch (rquest->method()) {
74 networkReplay = _manager->get(QNetworkRequest(url));
85 QNetworkRequest netRequest(url);
87 httpData = rquest->argsToMultipartFormData();
89 networkReplay = _manager->post(netRequest, httpData.data());
106 return _totalRequest;
110 return _parallelActiveNetworkThreads;
114 _parallelActiveNetworkThreads = newParallelActiveNetworkThreads;
117void IBot::setCurrentParallelActiveNetworkThreads(
int newParallelActiveNetworkThreads) {
118 _currentParallelActiveNetworkThreads = newParallelActiveNetworkThreads;
119 qDebug () <<
"current network active requests count : " << _currentParallelActiveNetworkThreads;
123 return _requestExecutor->interval() * 1000;
127 _requestExecutor->setInterval(1000 / newReqestLimitPerSecond);
132 auto&& responce = QSharedPointer<QPromise<QByteArray>>::create();
136 _requestQueue.insert(makeKey(rquest->priority()),
139 _requestExecutor->start();
141 return responce->future();
146 const QString &pathToResult) {
147 auto&& responce = QSharedPointer<QPromise<QByteArray>>::create();
149 _requestQueue.insert(makeKey(rquest->priority()),
152 _requestExecutor->start();
154 return responce->future();
159 _notProcessedUpdates.remove(message->updateId());
167 _processed.remove(messageID);
171 return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation);
178void IBot::handleEcxecuteRequest() {
179 if (!_requestQueue.size()) {
180 _requestExecutor->stop();
184 if (_currentParallelActiveNetworkThreads > _parallelActiveNetworkThreads) {
188 auto&& requestData = _requestQueue.take(_requestQueue.firstKey());
190 if (requestData.responceFilePath.size()) {
191 sendRequestPrivate(requestData.request, requestData.responceFilePath, requestData.responce);
195 sendRequestPrivate(requestData.request, requestData.responce);
199 unsigned long long key = _totalRequest;
205void IBot::sendRequestPrivate(
const QSharedPointer<iRequest> &rquest,
206 const QSharedPointer<QPromise<QByteArray> > &promise) {
208 QNetworkReply* networkReplay = sendRquestImpl(rquest);
209 if (!networkReplay) {
213 setCurrentParallelActiveNetworkThreads(_currentParallelActiveNetworkThreads + 1);
215 connect(networkReplay, &QNetworkReply::finished, [
this, networkReplay, promise](){
216 if (networkReplay->error() == QNetworkReply::NoError) {
217 promise->addResult(networkReplay->readAll());
221 promise->setException(HttpException(networkReplay->error(), networkReplay->errorString().toLatin1() + networkReplay->readAll()));
224 setCurrentParallelActiveNetworkThreads(_currentParallelActiveNetworkThreads - 1);
228 auto && setProggress = [promise](qint64 bytesCurrent, qint64 bytesTotal){
230 if (promise->future().progressMaximum() != bytesTotal)
231 promise->setProgressRange(0, bytesTotal);
233 promise->setProgressValue(bytesCurrent);
236 connect(networkReplay, &QNetworkReply::downloadProgress, setProggress);
237 connect(networkReplay, &QNetworkReply::uploadProgress, setProggress);
240void IBot::sendRequestPrivate(
const QSharedPointer<iRequest> &rquest,
241 const QString &pathToResult,
242 const QSharedPointer<QPromise<QByteArray>> & promise) {
243 auto&& file = QSharedPointer<QFile>::create(pathToResult);
245 if (!file->open(QIODeviceBase::WriteOnly | QIODevice::Truncate)) {
246 qCritical() <<
"Fail to wrote data into " << pathToResult;
250 QNetworkReply* networkReplay = sendRquestImpl(rquest);
251 if (!networkReplay) {
255 setCurrentParallelActiveNetworkThreads(_currentParallelActiveNetworkThreads + 1);
256 connect(networkReplay, &QNetworkReply::finished, [
this, promise, networkReplay, pathToResult](){
258 if (networkReplay->error() == QNetworkReply::NoError) {
259 promise->setException(HttpException(networkReplay->error(), networkReplay->errorString().toLatin1()));
261 promise->addResult(pathToResult.toUtf8());
264 setCurrentParallelActiveNetworkThreads(_currentParallelActiveNetworkThreads - 1);
267 connect(networkReplay, &QNetworkReply::readyRead, [networkReplay, promise, pathToResult, file](){
268 if (networkReplay->error() == QNetworkReply::NoError) {
269 file->write(networkReplay->readAll());
274 auto && setProggress = [promise](qint64 bytesCurrent, qint64 bytesTotal){
276 if (promise->future().progressMaximum() != bytesTotal)
277 promise->setProgressRange(0, bytesTotal);
279 promise->setProgressValue(bytesCurrent);
282 connect(networkReplay, &QNetworkReply::downloadProgress, setProggress);
283 connect(networkReplay, &QNetworkReply::uploadProgress, setProggress);
292 _processed = newProcessed;
304 if (_notProcessedUpdates.size()) {
305 auto toRemove = std::move(*_notProcessedUpdates.begin());
306 _notProcessedUpdates.erase(_notProcessedUpdates.cbegin());
virtual QString makeUrl(const QSharedPointer< iRequest > &request) const =0
makeUrl This method prepare a prefix url for http requests.
void setName(const QString &newName)
setName This method sets new value for the IBot::name field.
const QString & name() const
name This is name of the bot. usualy it fields will be received from the server after autication.
unsigned long long totalSentRequests() const
totalSentRequests This is total prepared requests count of bot from the start.
void markUpdateAsUnprocessed(const QSharedPointer< iUpdate > &message)
markMessageAsUnprocessed This method add the message into a not processed messages store.
void markUpdateAsProcessed(const QSharedPointer< iUpdate > &message)
markMessageAsProcessed This method remove message from the not processed messages store.
const QByteArray & token() const
token This is token value for authication on the remote server (bot)
int parallelActiveNetworkThreads() const
parallelActiveNetworkThreads
virtual void handleIncomeNewUpdate(const QSharedPointer< iUpdate > &)
handleIncomeNewUpdate This method just emit the sigReceiveUpdate signal.
int reqestLimitPerSecond() const
reqestLimitPerSecond this is request performence limitation. by default is 20 requests per second
void setReqestLimitPerSecond(int newReqestLimitPerSecond)
setReqestLimitPerSecond this method sets new limitation of bot performance.
virtual QString defaultFileStorageLocation() const
defaultFileStorageLocation This method return default file storage location.
void incomeNewUpdate(const QSharedPointer< iUpdate > &message)
incomeNewUpdate This method save incomed messages into store.
void setParallelActiveNetworkThreads(int newParallelActiveNetworkThreads)
setParallelActiveNetworkThreads
QSet< unsigned long long > processed() const
processed This method return list of processed mesages.
QFuture< QByteArray > sendRequest(const QSharedPointer< iRequest > &rquest)
sendRequest This method sent custom requests to the server.
virtual void setProcessed(const QSet< unsigned long long > &newProcessed)
setProcessed This method sets new list of processed mesages.
void setToken(const QByteArray &newToken)
setToken This is setter of the IBot::token value.
virtual void logout()
login This method remove login token of bot.
void sigReceiveUpdate(const QSharedPointer< iUpdate > &)
sigReceiveUpdate emit when but receive any updates from users.
QDateTime startTime() const
startTime this is time when bol wil started.
QSharedPointer< iUpdate > takeNextUnreadUpdate()
takeNextUnreadUpdate This method take a unread update and mark them as read.
@ Post
general post request
@ Upload
this is post request to upload a big data to telegram
@ Get
general ger request, all request data sent as a url line
RequestPriority
The RequestPriority enum.
The RequestData class is simple wrapper of request object with path of responce. If Path of responce ...