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, double longitude, const QString &timezone, QNetworkAccessManager *nam, QObject *parent)
70 : Reply(new PendingWeatherForecastPrivate(this), parent)
71{
72 Q_D(PendingWeatherForecast);
73 d->m_manager = nam;
74
75 // query weather api
76 QUrl url(QStringLiteral("https://api.met.no/weatherapi/locationforecast/2.0/complete"));
78 query.addQueryItem(QStringLiteral("lat"), KWeatherCorePrivate::toFixedString(latitude));
79 query.addQueryItem(QStringLiteral("lon"), KWeatherCorePrivate::toFixedString(longitude));
80 url.setQuery(query);
81 QNetworkRequest req(url);
83
84 // see §Identification on https://api.met.no/conditions_service.html
85 req.setHeader(QNetworkRequest::UserAgentHeader, QStringLiteral("KWeatherCore/" KWEATHERCORE_VERSION_STRING " kde-frameworks-devel@kde.org"));
86 auto reply = d->m_manager->get(req);
87 connect(reply, &QNetworkReply::finished, this, [reply, this]() {
88 Q_D(PendingWeatherForecast);
89 d->parseWeatherForecastResults(reply);
90 });
91
92 d->parser.forecast.setCoordinate(latitude, longitude);
93
94 if (timezone.isEmpty()) {
95 d->hasTimezone = false;
96 d->getTimezone(latitude, longitude);
97 } else {
98 d->hasTimezone = true;
99 d->parser.forecast.setTimezone(timezone);
100 d->m_timezone = timezone;
101 }
102}
103PendingWeatherForecast::PendingWeatherForecast(WeatherForecast data, QObject *parent)
104 : Reply(new PendingWeatherForecastPrivate(this), parent)
105{
106 Q_D(PendingWeatherForecast);
107 d->parser.forecast = data;
108 QMetaObject::invokeMethod(this, &PendingWeatherForecast::finished, Qt::QueuedConnection);
109}
110
111PendingWeatherForecast::~PendingWeatherForecast() = default;
112
113WeatherForecast PendingWeatherForecast::value() const
114{
116 return d->parser.forecast;
117}
118}
119
120#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.
KSERVICE_EXPORT KService::List query(FilterFunc filterFunc)
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 Dec 20 2024 12:00:07 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.