##// END OF EJS Templates
Amda provider (3)...
Alexandre Leroux -
r351:7ff7615687bf
parent child
Show More
@@ -0,0 +1,19
1 #ifndef SCIQLOP_AMDARESULTPARSER_H
2 #define SCIQLOP_AMDARESULTPARSER_H
3
4 #include "AmdaGlobal.h"
5
6 #include <QLoggingCategory>
7
8 #include <memory>
9
10 class IDataSeries;
11
12 Q_DECLARE_LOGGING_CATEGORY(LOG_AmdaResultParser)
13
14 struct SCIQLOP_AMDA_EXPORT AmdaResultParser {
15
16 static std::shared_ptr<IDataSeries> readTxt(const QString &filePath) noexcept;
17 };
18
19 #endif // SCIQLOP_AMDARESULTPARSER_H
@@ -0,0 +1,70
1 #include "AmdaResultParser.h"
2
3 #include <Data/ScalarSeries.h>
4
5 #include <QDateTime>
6 #include <QFile>
7
8 Q_LOGGING_CATEGORY(LOG_AmdaResultParser, "AmdaResultParser")
9
10 namespace {
11
12 /// Format for dates in result files
13 const auto DATE_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss.zzz");
14
15 /// @todo ALX
16 double doubleDate(const QString &stringDate) noexcept
17 {
18 auto dateTime = QDateTime::fromString(stringDate, DATE_FORMAT);
19 return dateTime.toMSecsSinceEpoch() / 1000.;
20 }
21
22 } // namespace
23
24 std::shared_ptr<IDataSeries> AmdaResultParser::readTxt(const QString &filePath) noexcept
25 {
26 QFile file{filePath};
27
28 if (!file.open(QFile::ReadOnly | QIODevice::Text)) {
29 qCCritical(LOG_AmdaResultParser())
30 << QObject::tr("Can't retrieve AMDA data from file %1: %2")
31 .arg(filePath, file.errorString());
32 return nullptr;
33 }
34
35 auto xData = QVector<double>{};
36 auto valuesData = QVector<double>{};
37
38 QTextStream stream{&file};
39
40 // Ignore comment lines (3 lines)
41 stream.readLine();
42 stream.readLine();
43 stream.readLine();
44
45 QString line{};
46 auto lineRegex = QRegExp{QStringLiteral("\\s+")};
47 while (stream.readLineInto(&line)) {
48 auto lineData = line.split(lineRegex, QString::SkipEmptyParts);
49 if (lineData.size() == 2) {
50 // X : the data is converted from date to double (in secs)
51 xData.push_back(doubleDate(lineData.at(0)));
52
53 // Value
54 valuesData.push_back(lineData.at(1).toDouble());
55 }
56 else {
57 /// @todo ALX : log
58 }
59 }
60
61 /// @todo ALX : handle units
62 auto scalarSeries = std::make_shared<ScalarSeries>(xData.size(), Unit{"nT", true}, Unit{});
63
64 const auto count = xData.size();
65 for (auto i = 0; i < count; ++i) {
66 scalarSeries->setData(i, xData.at(i), valuesData.at(i));
67 }
68
69 return scalarSeries;
70 }
@@ -1,123 +1,134
1 #include "AmdaProvider.h"
1 #include "AmdaProvider.h"
2 #include "AmdaResultParser.h"
3
2 #include <Data/DataProviderParameters.h>
4 #include <Data/DataProviderParameters.h>
3
5
4 #include <QNetworkAccessManager>
6 #include <QNetworkAccessManager>
5 #include <QNetworkReply>
7 #include <QNetworkReply>
6 #include <QTemporaryFile>
8 #include <QTemporaryFile>
7
9
8 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
10 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
9
11
10 namespace {
12 namespace {
11
13
12 /// URL format for a request on AMDA server. The parameters are as follows:
14 /// URL format for a request on AMDA server. The parameters are as follows:
13 /// - %1: start date
15 /// - %1: start date
14 /// - %2: end date
16 /// - %2: end date
15 /// - %3: parameter id
17 /// - %3: parameter id
16 const auto AMDA_URL_FORMAT = QStringLiteral(
18 const auto AMDA_URL_FORMAT = QStringLiteral(
17 "http://amda.irap.omp.eu/php/rest/"
19 "http://amda.irap.omp.eu/php/rest/"
18 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&sampling=60&outputFormat=ASCII&"
20 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&sampling=60&outputFormat=ASCII&"
19 "timeFormat=ISO8601&gzip=0");
21 "timeFormat=ISO8601&gzip=0");
20
22
21 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
23 /// Dates format passed in the URL (e.g 2013-09-23T09:00)
22 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:ss");
24 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:ss");
23
25
24 /// Formats a time to a date that can be passed in URL
26 /// Formats a time to a date that can be passed in URL
25 QString dateFormat(double sqpDateTime) noexcept
27 QString dateFormat(double sqpDateTime) noexcept
26 {
28 {
27 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
29 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
28 return dateTime.toString(AMDA_TIME_FORMAT);
30 return dateTime.toString(AMDA_TIME_FORMAT);
29 }
31 }
30
32
31 } // namespace
33 } // namespace
32
34
33 struct AmdaProvider::AmdaProviderPrivate {
35 struct AmdaProvider::AmdaProviderPrivate {
34 DataProviderParameters m_Params{};
36 DataProviderParameters m_Params{};
35 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
37 std::unique_ptr<QNetworkAccessManager> m_AccessManager{nullptr};
36 QNetworkReply *m_Reply{nullptr};
38 QNetworkReply *m_Reply{nullptr};
37 std::unique_ptr<QTemporaryFile> m_File{nullptr};
39 std::unique_ptr<QTemporaryFile> m_File{nullptr};
38 QUuid m_Token;
40 QUuid m_Token;
39 };
41 };
40
42
41 AmdaProvider::AmdaProvider() : impl{spimpl::make_unique_impl<AmdaProviderPrivate>()}
43 AmdaProvider::AmdaProvider() : impl{spimpl::make_unique_impl<AmdaProviderPrivate>()}
42 {
44 {
43 }
45 }
44
46
45 void AmdaProvider::requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList)
47 void AmdaProvider::requestDataLoading(QUuid token, const QVector<SqpDateTime> &dateTimeList)
46 {
48 {
47 // NOTE: Try to use multithread if possible
49 // NOTE: Try to use multithread if possible
48 for (const auto &dateTime : dateTimeList) {
50 for (const auto &dateTime : dateTimeList) {
49 retrieveData(token, DataProviderParameters{dateTime});
51 retrieveData(token, DataProviderParameters{dateTime});
50 }
52 }
51 }
53 }
52
54
53 void AmdaProvider::retrieveData(QUuid token, const DataProviderParameters &parameters) const
55 void AmdaProvider::retrieveData(QUuid token, const DataProviderParameters &parameters) const
54 {
56 {
55 // /////////// //
57 // /////////// //
56 // Creates URL //
58 // Creates URL //
57 // /////////// //
59 // /////////// //
58
60
59 auto startDate = dateFormat(parameters.m_Time.m_TStart);
61 auto startDate = dateFormat(parameters.m_Time.m_TStart);
60 auto endDate = dateFormat(parameters.m_Time.m_TEnd);
62 auto endDate = dateFormat(parameters.m_Time.m_TEnd);
61 auto productId = QStringLiteral("imf(0)");
63 auto productId = QStringLiteral("imf(0)");
62
64
63 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
65 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
64
66
65 // //////////////// //
67 // //////////////// //
66 // Executes request //
68 // Executes request //
67 // //////////////// //
69 // //////////////// //
68
70
69 impl->m_Token = token;
71 impl->m_Token = token;
70 impl->m_Params = parameters;
72 impl->m_Params = parameters;
71 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
73 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
72 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{url});
74 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{url});
73 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpFinished);
75 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpFinished);
74 }
76 }
75
77
76 void AmdaProvider::httpFinished() noexcept
78 void AmdaProvider::httpFinished() noexcept
77 {
79 {
78 // ////////////////////// //
80 // ////////////////////// //
79 // Gets download file url //
81 // Gets download file url //
80 // ////////////////////// //
82 // ////////////////////// //
81
83
82 auto downloadFileUrl = QUrl{QString{impl->m_Reply->readAll()}};
84 auto downloadFileUrl = QUrl{QString{impl->m_Reply->readAll()}};
83
85
84 // ///////////////////////////////////// //
86 // ///////////////////////////////////// //
85 // Executes request for downloading file //
87 // Executes request for downloading file //
86 // ///////////////////////////////////// //
88 // ///////////////////////////////////// //
87
89
88 // Deletes old reply
90 // Deletes old reply
89 impl->m_Reply->deleteLater();
91 impl->m_Reply->deleteLater();
90 impl->m_Reply = nullptr;
92 impl->m_Reply = nullptr;
91
93
92 // Creates destination file
94 // Creates destination file
93 impl->m_File = std::make_unique<QTemporaryFile>();
95 impl->m_File = std::make_unique<QTemporaryFile>();
94 if (impl->m_File->open()) {
96 if (impl->m_File->open()) {
95 qCDebug(LOG_AmdaProvider()) << "Temp file: " << impl->m_File->fileName();
97 qCDebug(LOG_AmdaProvider()) << "Temp file: " << impl->m_File->fileName();
96
98
97 // Executes request
99 // Executes request
98 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
100 impl->m_AccessManager = std::make_unique<QNetworkAccessManager>();
99 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{downloadFileUrl});
101 impl->m_Reply = impl->m_AccessManager->get(QNetworkRequest{downloadFileUrl});
100 connect(impl->m_Reply, &QNetworkReply::finished, this,
102 connect(impl->m_Reply, &QNetworkReply::finished, this,
101 &AmdaProvider::httpDownloadReadyRead);
103 &AmdaProvider::httpDownloadReadyRead);
102 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpDownloadFinished);
104 connect(impl->m_Reply, &QNetworkReply::finished, this, &AmdaProvider::httpDownloadFinished);
103 }
105 }
104 }
106 }
105
107
106 void AmdaProvider::httpDownloadFinished() noexcept
108 void AmdaProvider::httpDownloadFinished() noexcept
107 {
109 {
108 if (impl->m_File) {
110 if (impl->m_File) {
109 impl->m_File->close();
111 impl->m_File->close();
112
113 // Parse results file
114 if (auto dataSeries = AmdaResultParser::readTxt(impl->m_File->fileName())) {
115 emit dataProvided(impl->m_Token, dataSeries, impl->m_Params.m_Time);
116 }
117 else {
118 /// @todo ALX : debug
119 }
120
110 impl->m_File = nullptr;
121 impl->m_File = nullptr;
111 }
122 }
112
123
113 // Deletes reply
124 // Deletes reply
114 impl->m_Reply->deleteLater();
125 impl->m_Reply->deleteLater();
115 impl->m_Reply = nullptr;
126 impl->m_Reply = nullptr;
116 }
127 }
117
128
118 void AmdaProvider::httpDownloadReadyRead() noexcept
129 void AmdaProvider::httpDownloadReadyRead() noexcept
119 {
130 {
120 if (impl->m_File) {
131 if (impl->m_File) {
121 impl->m_File->write(impl->m_Reply->readAll());
132 impl->m_File->write(impl->m_Reply->readAll());
122 }
133 }
123 }
134 }
General Comments 0
You need to be logged in to leave comments. Login now