|
@@
-1,150
+1,168
|
|
1
|
#include "AmdaProvider.h"
|
|
1
|
#include "AmdaProvider.h"
|
|
2
|
#include "AmdaDefs.h"
|
|
2
|
#include "AmdaDefs.h"
|
|
3
|
#include "AmdaResultParser.h"
|
|
3
|
#include "AmdaResultParser.h"
|
|
4
|
|
|
4
|
|
|
5
|
#include <Common/DateUtils.h>
|
|
5
|
#include <Common/DateUtils.h>
|
|
6
|
#include <Data/DataProviderParameters.h>
|
|
6
|
#include <Data/DataProviderParameters.h>
|
|
7
|
#include <Network/NetworkController.h>
|
|
7
|
#include <Network/NetworkController.h>
|
|
8
|
#include <SqpApplication.h>
|
|
8
|
#include <SqpApplication.h>
|
|
9
|
#include <Variable/Variable.h>
|
|
9
|
#include <Variable/Variable.h>
|
|
10
|
|
|
10
|
|
|
11
|
#include <QNetworkAccessManager>
|
|
11
|
#include <QNetworkAccessManager>
|
|
12
|
#include <QNetworkReply>
|
|
12
|
#include <QNetworkReply>
|
|
13
|
#include <QTemporaryFile>
|
|
13
|
#include <QTemporaryFile>
|
|
14
|
#include <QThread>
|
|
14
|
#include <QThread>
|
|
15
|
|
|
15
|
|
|
16
|
Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
|
|
16
|
Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
|
|
17
|
|
|
17
|
|
|
18
|
namespace {
|
|
18
|
namespace {
|
|
19
|
|
|
19
|
|
|
20
|
/// URL format for a request on AMDA server. The parameters are as follows:
|
|
20
|
/// URL format for a request on AMDA server. The parameters are as follows:
|
|
21
|
/// - %1: start date
|
|
21
|
/// - %1: start date
|
|
22
|
/// - %2: end date
|
|
22
|
/// - %2: end date
|
|
23
|
/// - %3: parameter id
|
|
23
|
/// - %3: parameter id
|
|
24
|
const auto AMDA_URL_FORMAT = QStringLiteral(
|
|
24
|
const auto AMDA_URL_FORMAT = QStringLiteral(
|
|
25
|
"http://amda.irap.omp.eu/php/rest/"
|
|
25
|
"http://amda.irap.omp.eu/php/rest/"
|
|
26
|
"getParameter.php?startTime=%1&stopTime=%2¶meterID=%3&outputFormat=ASCII&"
|
|
26
|
"getParameter.php?startTime=%1&stopTime=%2¶meterID=%3&outputFormat=ASCII&"
|
|
27
|
"timeFormat=ISO8601&gzip=0");
|
|
27
|
"timeFormat=ISO8601&gzip=0");
|
|
28
|
|
|
28
|
|
|
29
|
/// Dates format passed in the URL (e.g 2013-09-23T09:00)
|
|
29
|
/// Dates format passed in the URL (e.g 2013-09-23T09:00)
|
|
30
|
const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
|
|
30
|
const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
|
|
31
|
|
|
31
|
|
|
32
|
/// Formats a time to a date that can be passed in URL
|
|
32
|
/// Formats a time to a date that can be passed in URL
|
|
33
|
QString dateFormat(double sqpRange) noexcept
|
|
33
|
QString dateFormat(double sqpRange) noexcept
|
|
34
|
{
|
|
34
|
{
|
|
35
|
auto dateTime = DateUtils::dateTime(sqpRange);
|
|
35
|
auto dateTime = DateUtils::dateTime(sqpRange);
|
|
36
|
return dateTime.toString(AMDA_TIME_FORMAT);
|
|
36
|
return dateTime.toString(AMDA_TIME_FORMAT);
|
|
37
|
}
|
|
37
|
}
|
|
38
|
|
|
38
|
|
|
|
|
|
39
|
AmdaResultParser::ValueType valueType(const QString &valueType)
|
|
|
|
|
40
|
{
|
|
|
|
|
41
|
if (valueType == QStringLiteral("scalar")) {
|
|
|
|
|
42
|
return AmdaResultParser::ValueType::SCALAR;
|
|
|
|
|
43
|
}
|
|
|
|
|
44
|
else if (valueType == QStringLiteral("vector")) {
|
|
|
|
|
45
|
return AmdaResultParser::ValueType::VECTOR;
|
|
|
|
|
46
|
}
|
|
|
|
|
47
|
else {
|
|
|
|
|
48
|
return AmdaResultParser::ValueType::UNKNOWN;
|
|
|
|
|
49
|
}
|
|
|
|
|
50
|
}
|
|
|
|
|
51
|
|
|
39
|
} // namespace
|
|
52
|
} // namespace
|
|
40
|
|
|
53
|
|
|
41
|
AmdaProvider::AmdaProvider()
|
|
54
|
AmdaProvider::AmdaProvider()
|
|
42
|
{
|
|
55
|
{
|
|
43
|
qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
|
|
56
|
qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
|
|
44
|
if (auto app = sqpApp) {
|
|
57
|
if (auto app = sqpApp) {
|
|
45
|
auto &networkController = app->networkController();
|
|
58
|
auto &networkController = app->networkController();
|
|
46
|
connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
|
|
59
|
connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
|
|
47
|
std::function<void(QNetworkReply *, QUuid)>)),
|
|
60
|
std::function<void(QNetworkReply *, QUuid)>)),
|
|
48
|
&networkController,
|
|
61
|
&networkController,
|
|
49
|
SLOT(onProcessRequested(QNetworkRequest, QUuid,
|
|
62
|
SLOT(onProcessRequested(QNetworkRequest, QUuid,
|
|
50
|
std::function<void(QNetworkReply *, QUuid)>)));
|
|
63
|
std::function<void(QNetworkReply *, QUuid)>)));
|
|
51
|
|
|
64
|
|
|
52
|
|
|
65
|
|
|
53
|
connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
|
|
66
|
connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
|
|
54
|
SIGNAL(dataProvidedProgress(QUuid, double)));
|
|
67
|
SIGNAL(dataProvidedProgress(QUuid, double)));
|
|
55
|
}
|
|
68
|
}
|
|
56
|
}
|
|
69
|
}
|
|
57
|
|
|
70
|
|
|
58
|
void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters ¶meters)
|
|
71
|
void AmdaProvider::requestDataLoading(QUuid acqIdentifier, const DataProviderParameters ¶meters)
|
|
59
|
{
|
|
72
|
{
|
|
60
|
// NOTE: Try to use multithread if possible
|
|
73
|
// NOTE: Try to use multithread if possible
|
|
61
|
const auto times = parameters.m_Times;
|
|
74
|
const auto times = parameters.m_Times;
|
|
62
|
const auto data = parameters.m_Data;
|
|
75
|
const auto data = parameters.m_Data;
|
|
63
|
for (const auto &dateTime : qAsConst(times)) {
|
|
76
|
for (const auto &dateTime : qAsConst(times)) {
|
|
64
|
this->retrieveData(acqIdentifier, dateTime, data);
|
|
77
|
this->retrieveData(acqIdentifier, dateTime, data);
|
|
65
|
|
|
78
|
|
|
66
|
// TORM
|
|
79
|
// TORM
|
|
67
|
// QThread::msleep(200);
|
|
80
|
// QThread::msleep(200);
|
|
68
|
}
|
|
81
|
}
|
|
69
|
}
|
|
82
|
}
|
|
70
|
|
|
83
|
|
|
71
|
void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
|
|
84
|
void AmdaProvider::requestDataAborting(QUuid acqIdentifier)
|
|
72
|
{
|
|
85
|
{
|
|
73
|
if (auto app = sqpApp) {
|
|
86
|
if (auto app = sqpApp) {
|
|
74
|
auto &networkController = app->networkController();
|
|
87
|
auto &networkController = app->networkController();
|
|
75
|
networkController.onReplyCanceled(acqIdentifier);
|
|
88
|
networkController.onReplyCanceled(acqIdentifier);
|
|
76
|
}
|
|
89
|
}
|
|
77
|
}
|
|
90
|
}
|
|
78
|
|
|
91
|
|
|
79
|
void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
|
|
92
|
void AmdaProvider::retrieveData(QUuid token, const SqpRange &dateTime, const QVariantHash &data)
|
|
80
|
{
|
|
93
|
{
|
|
81
|
// Retrieves product ID from data: if the value is invalid, no request is made
|
|
94
|
// Retrieves product ID from data: if the value is invalid, no request is made
|
|
82
|
auto productId = data.value(AMDA_XML_ID_KEY).toString();
|
|
95
|
auto productId = data.value(AMDA_XML_ID_KEY).toString();
|
|
83
|
if (productId.isNull()) {
|
|
96
|
if (productId.isNull()) {
|
|
84
|
qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
|
|
97
|
qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
|
|
85
|
return;
|
|
98
|
return;
|
|
86
|
}
|
|
99
|
}
|
|
87
|
qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
|
|
100
|
qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
|
|
88
|
|
|
101
|
|
|
|
|
|
102
|
// Retrieves the data type that determines whether the expected format for the result file is
|
|
|
|
|
103
|
// scalar, vector...
|
|
|
|
|
104
|
auto productValueType = valueType(data.value(AMDA_DATA_TYPE_KEY).toString());
|
|
|
|
|
105
|
|
|
89
|
// /////////// //
|
|
106
|
// /////////// //
|
|
90
|
// Creates URL //
|
|
107
|
// Creates URL //
|
|
91
|
// /////////// //
|
|
108
|
// /////////// //
|
|
92
|
|
|
109
|
|
|
93
|
auto startDate = dateFormat(dateTime.m_TStart);
|
|
110
|
auto startDate = dateFormat(dateTime.m_TStart);
|
|
94
|
auto endDate = dateFormat(dateTime.m_TEnd);
|
|
111
|
auto endDate = dateFormat(dateTime.m_TEnd);
|
|
95
|
|
|
112
|
|
|
96
|
auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
|
|
113
|
auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
|
|
97
|
qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
|
|
114
|
qCInfo(LOG_AmdaProvider()) << tr("TORM AmdaProvider::retrieveData url:") << url;
|
|
98
|
auto tempFile = std::make_shared<QTemporaryFile>();
|
|
115
|
auto tempFile = std::make_shared<QTemporaryFile>();
|
|
99
|
|
|
116
|
|
|
100
|
// LAMBDA
|
|
117
|
// LAMBDA
|
|
101
|
auto httpDownloadFinished
|
|
118
|
auto httpDownloadFinished = [this, dateTime, tempFile,
|
|
102
|
= [this, dateTime, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
|
|
119
|
productValueType](QNetworkReply *reply, QUuid dataId) noexcept {
|
|
103
|
|
|
120
|
|
|
104
|
// Don't do anything if the reply was abort
|
|
121
|
// Don't do anything if the reply was abort
|
|
105
|
if (reply->error() != QNetworkReply::OperationCanceledError) {
|
|
122
|
if (reply->error() != QNetworkReply::OperationCanceledError) {
|
|
106
|
|
|
123
|
|
|
107
|
if (tempFile) {
|
|
124
|
if (tempFile) {
|
|
108
|
auto replyReadAll = reply->readAll();
|
|
125
|
auto replyReadAll = reply->readAll();
|
|
109
|
if (!replyReadAll.isEmpty()) {
|
|
126
|
if (!replyReadAll.isEmpty()) {
|
|
110
|
tempFile->write(replyReadAll);
|
|
127
|
tempFile->write(replyReadAll);
|
|
111
|
}
|
|
128
|
}
|
|
112
|
tempFile->close();
|
|
129
|
tempFile->close();
|
|
113
|
|
|
130
|
|
|
114
|
// Parse results file
|
|
131
|
// Parse results file
|
|
115
|
if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
|
|
132
|
if (auto dataSeries
|
|
116
|
emit dataProvided(dataId, dataSeries, dateTime);
|
|
133
|
= AmdaResultParser::readTxt(tempFile->fileName(), productValueType)) {
|
|
117
|
}
|
|
134
|
emit dataProvided(dataId, dataSeries, dateTime);
|
|
118
|
else {
|
|
135
|
}
|
|
119
|
/// @todo ALX : debug
|
|
136
|
else {
|
|
120
|
}
|
|
137
|
/// @todo ALX : debug
|
|
121
|
}
|
|
138
|
}
|
|
122
|
}
|
|
139
|
}
|
|
123
|
|
|
140
|
}
|
|
124
|
};
|
|
141
|
|
|
|
|
|
142
|
};
|
|
125
|
auto httpFinishedLambda
|
|
143
|
auto httpFinishedLambda
|
|
126
|
= [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
|
|
144
|
= [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
|
|
127
|
|
|
145
|
|
|
128
|
// Don't do anything if the reply was abort
|
|
146
|
// Don't do anything if the reply was abort
|
|
129
|
if (reply->error() != QNetworkReply::OperationCanceledError) {
|
|
147
|
if (reply->error() != QNetworkReply::OperationCanceledError) {
|
|
130
|
auto downloadFileUrl = QUrl{QString{reply->readAll()}};
|
|
148
|
auto downloadFileUrl = QUrl{QString{reply->readAll()}};
|
|
131
|
|
|
149
|
|
|
132
|
|
|
150
|
|
|
133
|
qCInfo(LOG_AmdaProvider())
|
|
151
|
qCInfo(LOG_AmdaProvider())
|
|
134
|
<< tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
|
|
152
|
<< tr("TORM AmdaProvider::retrieveData downloadFileUrl:") << downloadFileUrl;
|
|
135
|
// Executes request for downloading file //
|
|
153
|
// Executes request for downloading file //
|
|
136
|
|
|
154
|
|
|
137
|
// Creates destination file
|
|
155
|
// Creates destination file
|
|
138
|
if (tempFile->open()) {
|
|
156
|
if (tempFile->open()) {
|
|
139
|
// Executes request
|
|
157
|
// Executes request
|
|
140
|
emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
|
|
158
|
emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
|
|
141
|
httpDownloadFinished);
|
|
159
|
httpDownloadFinished);
|
|
142
|
}
|
|
160
|
}
|
|
143
|
}
|
|
161
|
}
|
|
144
|
};
|
|
162
|
};
|
|
145
|
|
|
163
|
|
|
146
|
// //////////////// //
|
|
164
|
// //////////////// //
|
|
147
|
// Executes request //
|
|
165
|
// Executes request //
|
|
148
|
// //////////////// //
|
|
166
|
// //////////////// //
|
|
149
|
emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
|
|
167
|
emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
|
|
150
|
}
|
|
168
|
}
|