##// END OF EJS Templates
Uses DateUtils
Alexandre Leroux -
r450:5b65a4cc471b
parent child
Show More
@@ -1,44 +1,43
1 #ifndef SCIQLOP_SQPDATETIME_H
1 #ifndef SCIQLOP_SQPDATETIME_H
2 #define SCIQLOP_SQPDATETIME_H
2 #define SCIQLOP_SQPDATETIME_H
3
3
4 #include <QObject>
4 #include <QObject>
5
5
6 #include <QDateTime>
7 #include <QDebug>
6 #include <QDebug>
8
7
8 #include <Common/DateUtils.h>
9 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
10
10
11 /**
11 /**
12 * @brief The SqpDateTime struct holds the information of time parameters
12 * @brief The SqpDateTime struct holds the information of time parameters
13 */
13 */
14 struct SqpDateTime {
14 struct SqpDateTime {
15 /// Start time
15 /// Start time
16 double m_TStart;
16 double m_TStart;
17 /// End time
17 /// End time
18 double m_TEnd;
18 double m_TEnd;
19
19
20 bool contains(const SqpDateTime &dateTime) const noexcept
20 bool contains(const SqpDateTime &dateTime) const noexcept
21 {
21 {
22 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
22 return (m_TStart <= dateTime.m_TStart && m_TEnd >= dateTime.m_TEnd);
23 }
23 }
24
24
25 bool intersect(const SqpDateTime &dateTime) const noexcept
25 bool intersect(const SqpDateTime &dateTime) const noexcept
26 {
26 {
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
27 return (m_TEnd >= dateTime.m_TStart && m_TStart <= dateTime.m_TEnd);
28 }
28 }
29 };
29 };
30
30
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
31 inline QDebug operator<<(QDebug d, SqpDateTime obj)
32 {
32 {
33 auto tendDateTimeStart = QDateTime::fromMSecsSinceEpoch(obj.m_TStart * 1000);
33 auto tendDateTimeStart = DateUtils::dateTime(obj.m_TStart);
34 auto tendDateTimeEnd = QDateTime::fromMSecsSinceEpoch(obj.m_TEnd * 1000);
34 auto tendDateTimeEnd = DateUtils::dateTime(obj.m_TEnd);
35
35
36 // QDebug << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
37 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
36 d << "ts: " << tendDateTimeStart << " te: " << tendDateTimeEnd;
38 return d;
37 return d;
39 }
38 }
40
39
41 // Required for using shared_ptr in signals/slots
40 // Required for using shared_ptr in signals/slots
42 SCIQLOP_REGISTER_META_TYPE(SQPDATETIME_REGISTRY, SqpDateTime)
41 SCIQLOP_REGISTER_META_TYPE(SQPDATETIME_REGISTRY, SqpDateTime)
43
42
44 #endif // SCIQLOP_SQPDATETIME_H
43 #endif // SCIQLOP_SQPDATETIME_H
@@ -1,248 +1,249
1 #include <Variable/Variable.h>
1 #include <Variable/Variable.h>
2 #include <Variable/VariableModel.h>
2 #include <Variable/VariableModel.h>
3
3
4 #include <Common/DateUtils.h>
5
4 #include <Data/IDataSeries.h>
6 #include <Data/IDataSeries.h>
5
7
6 #include <QDateTime>
7 #include <QSize>
8 #include <QSize>
8 #include <unordered_map>
9 #include <unordered_map>
9
10
10 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11 Q_LOGGING_CATEGORY(LOG_VariableModel, "VariableModel")
11
12
12 namespace {
13 namespace {
13
14
14 // Column indexes
15 // Column indexes
15 const auto NAME_COLUMN = 0;
16 const auto NAME_COLUMN = 0;
16 const auto TSTART_COLUMN = 1;
17 const auto TSTART_COLUMN = 1;
17 const auto TEND_COLUMN = 2;
18 const auto TEND_COLUMN = 2;
18 const auto NB_COLUMNS = 3;
19 const auto NB_COLUMNS = 3;
19
20
20 // Column properties
21 // Column properties
21 const auto DEFAULT_HEIGHT = 25;
22 const auto DEFAULT_HEIGHT = 25;
22 const auto DEFAULT_WIDTH = 100;
23 const auto DEFAULT_WIDTH = 100;
23
24
24 struct ColumnProperties {
25 struct ColumnProperties {
25 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
26 ColumnProperties(const QString &name = {}, int width = DEFAULT_WIDTH,
26 int height = DEFAULT_HEIGHT)
27 int height = DEFAULT_HEIGHT)
27 : m_Name{name}, m_Width{width}, m_Height{height}
28 : m_Name{name}, m_Width{width}, m_Height{height}
28 {
29 {
29 }
30 }
30
31
31 QString m_Name;
32 QString m_Name;
32 int m_Width;
33 int m_Width;
33 int m_Height;
34 int m_Height;
34 };
35 };
35
36
36 const auto COLUMN_PROPERTIES
37 const auto COLUMN_PROPERTIES
37 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
38 = QHash<int, ColumnProperties>{{NAME_COLUMN, {QObject::tr("Name")}},
38 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
39 {TSTART_COLUMN, {QObject::tr("tStart"), 180}},
39 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
40 {TEND_COLUMN, {QObject::tr("tEnd"), 180}}};
40
41
41 /// Format for datetimes
42 /// Format for datetimes
42 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
43 const auto DATETIME_FORMAT = QStringLiteral("dd/MM/yyyy \nhh:mm:ss:zzz");
43
44
44
45
45 } // namespace
46 } // namespace
46
47
47 struct VariableModel::VariableModelPrivate {
48 struct VariableModel::VariableModelPrivate {
48 /// Variables created in SciQlop
49 /// Variables created in SciQlop
49 std::vector<std::shared_ptr<Variable> > m_Variables;
50 std::vector<std::shared_ptr<Variable> > m_Variables;
50 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
51 std::unordered_map<std::shared_ptr<Variable>, double> m_VariableToProgress;
51
52
52 /// Return the row index of the variable. -1 if it's not found
53 /// Return the row index of the variable. -1 if it's not found
53 int indexOfVariable(Variable *variable) const noexcept;
54 int indexOfVariable(Variable *variable) const noexcept;
54 };
55 };
55
56
56 VariableModel::VariableModel(QObject *parent)
57 VariableModel::VariableModel(QObject *parent)
57 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
58 : QAbstractTableModel{parent}, impl{spimpl::make_unique_impl<VariableModelPrivate>()}
58 {
59 {
59 }
60 }
60
61
61 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
62 std::shared_ptr<Variable> VariableModel::createVariable(const QString &name,
62 const SqpDateTime &dateTime,
63 const SqpDateTime &dateTime,
63 const QVariantHash &metadata) noexcept
64 const QVariantHash &metadata) noexcept
64 {
65 {
65 auto insertIndex = rowCount();
66 auto insertIndex = rowCount();
66 beginInsertRows({}, insertIndex, insertIndex);
67 beginInsertRows({}, insertIndex, insertIndex);
67
68
68 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
69 auto variable = std::make_shared<Variable>(name, dateTime, metadata);
69
70
70 impl->m_Variables.push_back(variable);
71 impl->m_Variables.push_back(variable);
71 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
72 connect(variable.get(), &Variable::updated, this, &VariableModel::onVariableUpdated);
72
73
73 endInsertRows();
74 endInsertRows();
74
75
75 return variable;
76 return variable;
76 }
77 }
77
78
78 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
79 void VariableModel::deleteVariable(std::shared_ptr<Variable> variable) noexcept
79 {
80 {
80 if (!variable) {
81 if (!variable) {
81 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
82 qCCritical(LOG_Variable()) << "Can't delete a null variable from the model";
82 return;
83 return;
83 }
84 }
84
85
85 // Finds variable in the model
86 // Finds variable in the model
86 auto begin = impl->m_Variables.cbegin();
87 auto begin = impl->m_Variables.cbegin();
87 auto end = impl->m_Variables.cend();
88 auto end = impl->m_Variables.cend();
88 auto it = std::find(begin, end, variable);
89 auto it = std::find(begin, end, variable);
89 if (it != end) {
90 if (it != end) {
90 auto removeIndex = std::distance(begin, it);
91 auto removeIndex = std::distance(begin, it);
91
92
92 // Deletes variable
93 // Deletes variable
93 beginRemoveRows({}, removeIndex, removeIndex);
94 beginRemoveRows({}, removeIndex, removeIndex);
94 impl->m_Variables.erase(it);
95 impl->m_Variables.erase(it);
95 endRemoveRows();
96 endRemoveRows();
96 }
97 }
97 else {
98 else {
98 qCritical(LOG_VariableModel())
99 qCritical(LOG_VariableModel())
99 << tr("Can't delete variable %1 from the model: the variable is not in the model")
100 << tr("Can't delete variable %1 from the model: the variable is not in the model")
100 .arg(variable->name());
101 .arg(variable->name());
101 }
102 }
102
103
103 // Removes variable from progress map
104 // Removes variable from progress map
104 impl->m_VariableToProgress.erase(variable);
105 impl->m_VariableToProgress.erase(variable);
105 }
106 }
106
107
107
108
108 std::shared_ptr<Variable> VariableModel::variable(int index) const
109 std::shared_ptr<Variable> VariableModel::variable(int index) const
109 {
110 {
110 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
111 return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr;
111 }
112 }
112
113
113 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
114 void VariableModel::setDataProgress(std::shared_ptr<Variable> variable, double progress)
114 {
115 {
115 if (progress > 0.0) {
116 if (progress > 0.0) {
116 impl->m_VariableToProgress[variable] = progress;
117 impl->m_VariableToProgress[variable] = progress;
117 }
118 }
118 else {
119 else {
119 impl->m_VariableToProgress.erase(variable);
120 impl->m_VariableToProgress.erase(variable);
120 }
121 }
121 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
122 auto modelIndex = createIndex(impl->indexOfVariable(variable.get()), NAME_COLUMN);
122
123
123 emit dataChanged(modelIndex, modelIndex);
124 emit dataChanged(modelIndex, modelIndex);
124 }
125 }
125
126
126 int VariableModel::columnCount(const QModelIndex &parent) const
127 int VariableModel::columnCount(const QModelIndex &parent) const
127 {
128 {
128 Q_UNUSED(parent);
129 Q_UNUSED(parent);
129
130
130 return NB_COLUMNS;
131 return NB_COLUMNS;
131 }
132 }
132
133
133 int VariableModel::rowCount(const QModelIndex &parent) const
134 int VariableModel::rowCount(const QModelIndex &parent) const
134 {
135 {
135 Q_UNUSED(parent);
136 Q_UNUSED(parent);
136
137
137 return impl->m_Variables.size();
138 return impl->m_Variables.size();
138 }
139 }
139
140
140 QVariant VariableModel::data(const QModelIndex &index, int role) const
141 QVariant VariableModel::data(const QModelIndex &index, int role) const
141 {
142 {
142 if (!index.isValid()) {
143 if (!index.isValid()) {
143 return QVariant{};
144 return QVariant{};
144 }
145 }
145
146
146 if (index.row() < 0 || index.row() >= rowCount()) {
147 if (index.row() < 0 || index.row() >= rowCount()) {
147 return QVariant{};
148 return QVariant{};
148 }
149 }
149
150
150 if (role == Qt::DisplayRole) {
151 if (role == Qt::DisplayRole) {
151 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 if (auto variable = impl->m_Variables.at(index.row()).get()) {
152 /// Lambda function that builds the variant to return for a time value
153 /// Lambda function that builds the variant to return for a time value
153 auto dateTimeVariant = [](double time) {
154 auto dateTimeVariant = [](double secs) {
154 auto dateTime = QDateTime::fromMSecsSinceEpoch(time * 1000.);
155 auto dateTime = DateUtils::dateTime(secs);
155 return dateTime.toString(DATETIME_FORMAT);
156 return dateTime.toString(DATETIME_FORMAT);
156 };
157 };
157
158
158 switch (index.column()) {
159 switch (index.column()) {
159 case NAME_COLUMN:
160 case NAME_COLUMN:
160 return variable->name();
161 return variable->name();
161 case TSTART_COLUMN:
162 case TSTART_COLUMN:
162 return dateTimeVariant(variable->dateTime().m_TStart);
163 return dateTimeVariant(variable->dateTime().m_TStart);
163 case TEND_COLUMN:
164 case TEND_COLUMN:
164 return dateTimeVariant(variable->dateTime().m_TEnd);
165 return dateTimeVariant(variable->dateTime().m_TEnd);
165 default:
166 default:
166 // No action
167 // No action
167 break;
168 break;
168 }
169 }
169
170
170 qWarning(LOG_VariableModel())
171 qWarning(LOG_VariableModel())
171 << tr("Can't get data (unknown column %1)").arg(index.column());
172 << tr("Can't get data (unknown column %1)").arg(index.column());
172 }
173 }
173 else {
174 else {
174 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
175 qWarning(LOG_VariableModel()) << tr("Can't get data (no variable)");
175 }
176 }
176 }
177 }
177 else if (role == VariableRoles::ProgressRole) {
178 else if (role == VariableRoles::ProgressRole) {
178 if (auto variable = impl->m_Variables.at(index.row())) {
179 if (auto variable = impl->m_Variables.at(index.row())) {
179
180
180 auto it = impl->m_VariableToProgress.find(variable);
181 auto it = impl->m_VariableToProgress.find(variable);
181 if (it != impl->m_VariableToProgress.cend()) {
182 if (it != impl->m_VariableToProgress.cend()) {
182 return it->second;
183 return it->second;
183 }
184 }
184 }
185 }
185 }
186 }
186
187
187 return QVariant{};
188 return QVariant{};
188 }
189 }
189
190
190 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
191 QVariant VariableModel::headerData(int section, Qt::Orientation orientation, int role) const
191 {
192 {
192 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
193 if (role != Qt::DisplayRole && role != Qt::SizeHintRole) {
193 return QVariant{};
194 return QVariant{};
194 }
195 }
195
196
196 if (orientation == Qt::Horizontal) {
197 if (orientation == Qt::Horizontal) {
197 auto propertiesIt = COLUMN_PROPERTIES.find(section);
198 auto propertiesIt = COLUMN_PROPERTIES.find(section);
198 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
199 if (propertiesIt != COLUMN_PROPERTIES.cend()) {
199 // Role is either DisplayRole or SizeHintRole
200 // Role is either DisplayRole or SizeHintRole
200 return (role == Qt::DisplayRole)
201 return (role == Qt::DisplayRole)
201 ? QVariant{propertiesIt->m_Name}
202 ? QVariant{propertiesIt->m_Name}
202 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
203 : QVariant{QSize{propertiesIt->m_Width, propertiesIt->m_Height}};
203 }
204 }
204 else {
205 else {
205 qWarning(LOG_VariableModel())
206 qWarning(LOG_VariableModel())
206 << tr("Can't get header data (unknown column %1)").arg(section);
207 << tr("Can't get header data (unknown column %1)").arg(section);
207 }
208 }
208 }
209 }
209
210
210 return QVariant{};
211 return QVariant{};
211 }
212 }
212
213
213 void VariableModel::abortProgress(const QModelIndex &index)
214 void VariableModel::abortProgress(const QModelIndex &index)
214 {
215 {
215 if (auto variable = impl->m_Variables.at(index.row())) {
216 if (auto variable = impl->m_Variables.at(index.row())) {
216 emit abortProgessRequested(variable);
217 emit abortProgessRequested(variable);
217 }
218 }
218 }
219 }
219
220
220 void VariableModel::onVariableUpdated() noexcept
221 void VariableModel::onVariableUpdated() noexcept
221 {
222 {
222 // Finds variable that has been updated in the model
223 // Finds variable that has been updated in the model
223 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
224 if (auto updatedVariable = dynamic_cast<Variable *>(sender())) {
224 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
225 auto updatedVariableIndex = impl->indexOfVariable(updatedVariable);
225
226
226 if (updatedVariableIndex > -1) {
227 if (updatedVariableIndex > -1) {
227 emit dataChanged(createIndex(updatedVariableIndex, 0),
228 emit dataChanged(createIndex(updatedVariableIndex, 0),
228 createIndex(updatedVariableIndex, columnCount() - 1));
229 createIndex(updatedVariableIndex, columnCount() - 1));
229 }
230 }
230 }
231 }
231 }
232 }
232
233
233 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
234 int VariableModel::VariableModelPrivate::indexOfVariable(Variable *variable) const noexcept
234 {
235 {
235 auto begin = std::cbegin(m_Variables);
236 auto begin = std::cbegin(m_Variables);
236 auto end = std::cend(m_Variables);
237 auto end = std::cend(m_Variables);
237 auto it
238 auto it
238 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
239 = std::find_if(begin, end, [variable](const auto &var) { return var.get() == variable; });
239
240
240 if (it != end) {
241 if (it != end) {
241 // Gets the index of the variable in the model: we assume here that views have the same
242 // Gets the index of the variable in the model: we assume here that views have the same
242 // order as the model
243 // order as the model
243 return std::distance(begin, it);
244 return std::distance(begin, it);
244 }
245 }
245 else {
246 else {
246 return -1;
247 return -1;
247 }
248 }
248 }
249 }
@@ -1,48 +1,47
1 #include "TimeWidget/TimeWidget.h"
1 #include "TimeWidget/TimeWidget.h"
2 #include "ui_TimeWidget.h"
2 #include "ui_TimeWidget.h"
3
3
4 #include <SqpApplication.h>
4 #include <SqpApplication.h>
5 #include <Time/TimeController.h>
5 #include <Time/TimeController.h>
6
6
7 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget}
7 TimeWidget::TimeWidget(QWidget *parent) : QWidget{parent}, ui{new Ui::TimeWidget}
8 {
8 {
9 ui->setupUi(this);
9 ui->setupUi(this);
10
10
11 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
11 ui->applyToolButton->setIcon(sqpApp->style()->standardIcon(QStyle::SP_DialogApplyButton));
12
12
13 // Connection
13 // Connection
14 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
14 connect(ui->startDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
15 &TimeWidget::onTimeUpdateRequested);
15 &TimeWidget::onTimeUpdateRequested);
16
16
17 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
17 connect(ui->endDateTimeEdit, &QDateTimeEdit::dateTimeChanged, this,
18 &TimeWidget::onTimeUpdateRequested);
18 &TimeWidget::onTimeUpdateRequested);
19
19
20
20
21 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
21 connect(ui->applyToolButton, &QToolButton::clicked, &sqpApp->timeController(),
22 &TimeController::onTimeNotify);
22 &TimeController::onTimeNotify);
23
23
24 // Initialisation
24 // Initialisation
25 ui->startDateTimeEdit->setDateTime(
25 ui->startDateTimeEdit->setDateTime(
26 QDateTime::currentDateTime().addSecs(-3600)); // one hour berefore
26 QDateTime::currentDateTime().addSecs(-3600)); // one hour berefore
27 ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());
27 ui->endDateTimeEdit->setDateTime(QDateTime::currentDateTime());
28
28
29 auto dateTime
29 auto dateTime
30 = SqpDateTime{QDateTime::currentDateTime().addSecs(-3600).toMSecsSinceEpoch() / 1000.0,
30 = SqpDateTime{QDateTime::currentDateTime().addSecs(-3600).toMSecsSinceEpoch() / 1000.0,
31 QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0};
31 QDateTime::currentDateTime().toMSecsSinceEpoch() / 1000.0};
32 sqpApp->timeController().onTimeToUpdate(dateTime);
32 sqpApp->timeController().onTimeToUpdate(dateTime);
33 }
33 }
34
34
35
35
36 TimeWidget::~TimeWidget()
36 TimeWidget::~TimeWidget()
37 {
37 {
38 delete ui;
38 delete ui;
39 }
39 }
40
40
41 void TimeWidget::onTimeUpdateRequested()
41 void TimeWidget::onTimeUpdateRequested()
42 {
42 {
43 auto dateTime = SqpDateTime{
43 auto dateTime = SqpDateTime{DateUtils::secondsSinceEpoch(ui->startDateTimeEdit->dateTime()),
44 static_cast<double>(ui->startDateTimeEdit->dateTime().toMSecsSinceEpoch() / 1000.),
44 DateUtils::secondsSinceEpoch(ui->endDateTimeEdit->dateTime())};
45 static_cast<double>(ui->endDateTimeEdit->dateTime().toMSecsSinceEpoch()) / 1000.};
46
45
47 emit timeUpdated(std::move(dateTime));
46 emit timeUpdated(std::move(dateTime));
48 }
47 }
@@ -1,147 +1,148
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 <Data/DataProviderParameters.h>
6 #include <Data/DataProviderParameters.h>
6 #include <Network/NetworkController.h>
7 #include <Network/NetworkController.h>
7 #include <SqpApplication.h>
8 #include <SqpApplication.h>
8 #include <Variable/Variable.h>
9 #include <Variable/Variable.h>
9
10
10 #include <QNetworkAccessManager>
11 #include <QNetworkAccessManager>
11 #include <QNetworkReply>
12 #include <QNetworkReply>
12 #include <QTemporaryFile>
13 #include <QTemporaryFile>
13 #include <QThread>
14 #include <QThread>
14
15
15 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16 Q_LOGGING_CATEGORY(LOG_AmdaProvider, "AmdaProvider")
16
17
17 namespace {
18 namespace {
18
19
19 /// 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:
20 /// - %1: start date
21 /// - %1: start date
21 /// - %2: end date
22 /// - %2: end date
22 /// - %3: parameter id
23 /// - %3: parameter id
23 const auto AMDA_URL_FORMAT = QStringLiteral(
24 const auto AMDA_URL_FORMAT = QStringLiteral(
24 "http://amda.irap.omp.eu/php/rest/"
25 "http://amda.irap.omp.eu/php/rest/"
25 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "getParameter.php?startTime=%1&stopTime=%2&parameterID=%3&outputFormat=ASCII&"
26 "timeFormat=ISO8601&gzip=0");
27 "timeFormat=ISO8601&gzip=0");
27
28
28 /// 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)
29 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30 const auto AMDA_TIME_FORMAT = QStringLiteral("yyyy-MM-ddThh:mm:ss");
30
31
31 /// 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
32 QString dateFormat(double sqpDateTime) noexcept
33 QString dateFormat(double sqpDateTime) noexcept
33 {
34 {
34 auto dateTime = QDateTime::fromMSecsSinceEpoch(sqpDateTime * 1000.);
35 auto dateTime = DateUtils::dateTime(sqpDateTime);
35 return dateTime.toString(AMDA_TIME_FORMAT);
36 return dateTime.toString(AMDA_TIME_FORMAT);
36 }
37 }
37
38
38 } // namespace
39 } // namespace
39
40
40 AmdaProvider::AmdaProvider()
41 AmdaProvider::AmdaProvider()
41 {
42 {
42 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
43 qCDebug(LOG_AmdaProvider()) << tr("AmdaProvider::AmdaProvider") << QThread::currentThread();
43 if (auto app = sqpApp) {
44 if (auto app = sqpApp) {
44 auto &networkController = app->networkController();
45 auto &networkController = app->networkController();
45 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
46 connect(this, SIGNAL(requestConstructed(QNetworkRequest, QUuid,
46 std::function<void(QNetworkReply *, QUuid)>)),
47 std::function<void(QNetworkReply *, QUuid)>)),
47 &networkController,
48 &networkController,
48 SLOT(onProcessRequested(QNetworkRequest, QUuid,
49 SLOT(onProcessRequested(QNetworkRequest, QUuid,
49 std::function<void(QNetworkReply *, QUuid)>)));
50 std::function<void(QNetworkReply *, QUuid)>)));
50
51
51
52
52 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
53 connect(&sqpApp->networkController(), SIGNAL(replyDownloadProgress(QUuid, double)), this,
53 SIGNAL(dataProvidedProgress(QUuid, double)));
54 SIGNAL(dataProvidedProgress(QUuid, double)));
54 }
55 }
55 }
56 }
56
57
57 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
58 void AmdaProvider::requestDataLoading(QUuid token, const DataProviderParameters &parameters)
58 {
59 {
59 // NOTE: Try to use multithread if possible
60 // NOTE: Try to use multithread if possible
60 const auto times = parameters.m_Times;
61 const auto times = parameters.m_Times;
61 const auto data = parameters.m_Data;
62 const auto data = parameters.m_Data;
62 for (const auto &dateTime : qAsConst(times)) {
63 for (const auto &dateTime : qAsConst(times)) {
63 retrieveData(token, dateTime, data);
64 retrieveData(token, dateTime, data);
64 }
65 }
65 }
66 }
66
67
67 void AmdaProvider::requestDataAborting(QUuid identifier)
68 void AmdaProvider::requestDataAborting(QUuid identifier)
68 {
69 {
69 if (auto app = sqpApp) {
70 if (auto app = sqpApp) {
70 auto &networkController = app->networkController();
71 auto &networkController = app->networkController();
71 networkController.onReplyCanceled(identifier);
72 networkController.onReplyCanceled(identifier);
72 }
73 }
73 }
74 }
74
75
75 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data)
76 void AmdaProvider::retrieveData(QUuid token, const SqpDateTime &dateTime, const QVariantHash &data)
76 {
77 {
77 // Retrieves product ID from data: if the value is invalid, no request is made
78 // Retrieves product ID from data: if the value is invalid, no request is made
78 auto productId = data.value(AMDA_XML_ID_KEY).toString();
79 auto productId = data.value(AMDA_XML_ID_KEY).toString();
79 if (productId.isNull()) {
80 if (productId.isNull()) {
80 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
81 qCCritical(LOG_AmdaProvider()) << tr("Can't retrieve data: unknown product id");
81 return;
82 return;
82 }
83 }
83 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
84 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData") << dateTime;
84
85
85 // /////////// //
86 // /////////// //
86 // Creates URL //
87 // Creates URL //
87 // /////////// //
88 // /////////// //
88
89
89 auto startDate = dateFormat(dateTime.m_TStart);
90 auto startDate = dateFormat(dateTime.m_TStart);
90 auto endDate = dateFormat(dateTime.m_TEnd);
91 auto endDate = dateFormat(dateTime.m_TEnd);
91
92
92 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
93 auto url = QUrl{QString{AMDA_URL_FORMAT}.arg(startDate, endDate, productId)};
93 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
94 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData url:") << url;
94 auto tempFile = std::make_shared<QTemporaryFile>();
95 auto tempFile = std::make_shared<QTemporaryFile>();
95
96
96 // LAMBDA
97 // LAMBDA
97 auto httpDownloadFinished
98 auto httpDownloadFinished
98 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
99 = [this, dateTime, tempFile, token](QNetworkReply *reply, QUuid dataId) noexcept {
99 Q_UNUSED(dataId);
100 Q_UNUSED(dataId);
100
101
101 // Don't do anything if the reply was abort
102 // Don't do anything if the reply was abort
102 if (reply->error() != QNetworkReply::OperationCanceledError) {
103 if (reply->error() != QNetworkReply::OperationCanceledError) {
103
104
104 if (tempFile) {
105 if (tempFile) {
105 auto replyReadAll = reply->readAll();
106 auto replyReadAll = reply->readAll();
106 if (!replyReadAll.isEmpty()) {
107 if (!replyReadAll.isEmpty()) {
107 tempFile->write(replyReadAll);
108 tempFile->write(replyReadAll);
108 }
109 }
109 tempFile->close();
110 tempFile->close();
110
111
111 // Parse results file
112 // Parse results file
112 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
113 if (auto dataSeries = AmdaResultParser::readTxt(tempFile->fileName())) {
113 emit dataProvided(token, dataSeries, dateTime);
114 emit dataProvided(token, dataSeries, dateTime);
114 }
115 }
115 else {
116 else {
116 /// @todo ALX : debug
117 /// @todo ALX : debug
117 }
118 }
118 }
119 }
119 }
120 }
120
121
121 };
122 };
122 auto httpFinishedLambda
123 auto httpFinishedLambda
123 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
124 = [this, httpDownloadFinished, tempFile](QNetworkReply *reply, QUuid dataId) noexcept {
124
125
125 // Don't do anything if the reply was abort
126 // Don't do anything if the reply was abort
126 if (reply->error() != QNetworkReply::OperationCanceledError) {
127 if (reply->error() != QNetworkReply::OperationCanceledError) {
127 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
128 auto downloadFileUrl = QUrl{QString{reply->readAll()}};
128
129
129
130
130 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
131 qCInfo(LOG_AmdaProvider()) << tr("AmdaProvider::retrieveData downloadFileUrl:")
131 << downloadFileUrl;
132 << downloadFileUrl;
132 // Executes request for downloading file //
133 // Executes request for downloading file //
133
134
134 // Creates destination file
135 // Creates destination file
135 if (tempFile->open()) {
136 if (tempFile->open()) {
136 // Executes request
137 // Executes request
137 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
138 emit requestConstructed(QNetworkRequest{downloadFileUrl}, dataId,
138 httpDownloadFinished);
139 httpDownloadFinished);
139 }
140 }
140 }
141 }
141 };
142 };
142
143
143 // //////////////// //
144 // //////////////// //
144 // Executes request //
145 // Executes request //
145 // //////////////// //
146 // //////////////// //
146 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
147 emit requestConstructed(QNetworkRequest{url}, token, httpFinishedLambda);
147 }
148 }
General Comments 0
You need to be logged in to leave comments. Login now