KWeatherCore

pendingweatherforecast.cpp
1/*
2 * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com>
3 * SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
4 *
5 * SPDX-License-Identifier: LGPL-2.0-or-later
6 */
7
8#include "pendingweatherforecast.h"
9#include "geotimezone.h"
10#include "kweathercore_p.h"
11#include "kweathercore_version.h"
12#include "pendingweatherforecast_p.h"
13
14#include <QDir>
15#include <QFile>
16#include <QJsonArray>
17#include <QJsonDocument>
18#include <QJsonObject>
19#include <QNetworkAccessManager>
20#include <QNetworkReply>
21#include <QStandardPaths>
22#include <QTimeZone>
23#include <QUrlQuery>
24
25namespace KWeatherCore
26{
27
28PendingWeatherForecastPrivate::PendingWeatherForecastPrivate(PendingWeatherForecast *qq)
29 : q(qq)
30{
31}
32
33void PendingWeatherForecastPrivate::getTimezone(double latitude, double longitude)
34{
35 auto timezoneSource = new GeoTimezone(m_manager, latitude, longitude, q);
36 QObject::connect(timezoneSource, &GeoTimezone::finished, q, [this, timezoneSource]() {
37 timezoneSource->deleteLater();
38 parseTimezoneResult(timezoneSource->timezone());
39 });
40}
41void PendingWeatherForecastPrivate::parseTimezoneResult(const QString &result)
42{
43 hasTimezone = true;
44 parser.forecast.setTimezone(result);
45 m_timezone = result;
46 if (parser.hasData()) {
47 parser.applySunriseToForecast(QTimeZone(m_timezone.toUtf8()));
48 Q_EMIT q->finished();
49 }
50}
51
52void PendingWeatherForecastPrivate::parseWeatherForecastResults(QNetworkReply *reply)
53{
54 reply->deleteLater();
55 if (reply->error() != QNetworkReply::NoError) {
56 qWarning() << "network error when fetching forecast:" << reply->errorString();
57 setError(PendingWeatherForecast::NetworkError, reply->errorString());
58 Q_EMIT q->finished();
59 return;
60 }
61
62 parser.parseLocationForecast(reply->readAll());
63 if (hasTimezone) {
64 parser.applySunriseToForecast(QTimeZone(m_timezone.toUtf8()));
65 Q_EMIT q->finished();
66 }
67}
68
69PendingWeatherForecast::PendingWeatherForecast(double latitude,
70 double longitude,
71 const QString &timezone,
73 QObject *parent)
74 : Reply(new PendingWeatherForecastPrivate(this), parent)
75{
76 Q_D(PendingWeatherForecast);
77 d->m_manager = nam;
78
79 // query weather api
80 QUrl url(QStringLiteral("https://api.met.no/weatherapi/locationforecast/2.0/complete"));
82 query.addQueryItem(QStringLiteral("lat"), KWeatherCorePrivate::toFixedString(latitude));
83 query.addQueryItem(QStringLiteral("lon"), KWeatherCorePrivate::toFixedString(longitude));
84 url.setQuery(query);
85 QNetworkRequest req(url);
87
88 // see ┬žIdentification on https://api.met.no/conditions_service.html
89 req.setHeader(QNetworkRequest::UserAgentHeader, QStringLiteral("KWeatherCore/" KWEATHERCORE_VERSION_STRING " kde-frameworks-devel@kde.org"));
90 auto reply = d->m_manager->get(req);
91 connect(reply, &QNetworkReply::finished, this, [reply, this]() {
92 Q_D(PendingWeatherForecast);
93 d->parseWeatherForecastResults(reply);
94 });
95
96 d->parser.forecast.setCoordinate(latitude, longitude);
97
98 if (timezone.isEmpty()) {
99 d->hasTimezone = false;
100 d->getTimezone(latitude, longitude);
101 } else {
102 d->hasTimezone = true;
103 d->parser.forecast.setTimezone(timezone);
104 d->m_timezone = timezone;
105 }
106}
107PendingWeatherForecast::PendingWeatherForecast(WeatherForecast data, QObject *parent)
108 : Reply(new PendingWeatherForecastPrivate(this), parent)
109{
110 Q_D(PendingWeatherForecast);
111 d->parser.forecast = data;
112 QMetaObject::invokeMethod(this, &PendingWeatherForecast::finished, Qt::QueuedConnection);
113}
114
115PendingWeatherForecast::~PendingWeatherForecast() = default;
116
117WeatherForecast PendingWeatherForecast::value() const
118{
120 return d->parser.forecast;
121}
122}
123
124#include "moc_pendingweatherforecast.cpp"
The PendingWeatherForecast class contains the reply to an asynchronous weather forecast request.
The WeatherForecast class contains the weather information of one location for days.
std::optional< QSqlQuery > query(const QString &queryStatement)
QString errorString() const const
QByteArray readAll()
bool invokeMethod(QObject *context, Functor &&function, FunctorReturnType *ret)
NetworkError error() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
void deleteLater()
bool isEmpty() const const
QueuedConnection
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
Q_D(Todo)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:31 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.