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
114{
115 Q_D(const PendingWeatherForecast);
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.
WeatherForecast value() const
value pointer to the shared weather data the pointer is nullptr until finished() raised
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-2025 The KDE developers.
Generated on Fri Jan 24 2025 11:57:57 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.