KWeatherCore

weatherforecastsource.cpp
1 /*
2  * SPDX-FileCopyrightText: 2020-2021 Han Young <[email protected]>
3  * SPDX-FileCopyrightText: 2020 Devin Lin <[email protected]>
4  *
5  * SPDX-License-Identifier: LGPL-2.0-or-later
6  */
7 #include "weatherforecastsource.h"
8 #include "geotimezone.h"
9 #include "kweathercore_p.h"
10 #include "pendingweatherforecast_p.h"
11 #include "weatherforecast.h"
12 #include <QCoreApplication>
13 #include <QDir>
14 #include <QFile>
15 #include <QJsonDocument>
16 #include <QNetworkReply>
17 #include <QStandardPaths>
18 #include <QUrlQuery>
19 #include <algorithm>
20 namespace KWeatherCore
21 {
22 class WeatherForecastSourcePrivate : public QObject
23 {
24  Q_OBJECT
25 public:
26  WeatherForecastSourcePrivate(QObject *parent = nullptr);
27  PendingWeatherForecast *requestData(double latitude, double longitude);
28 
29 private:
30 };
31 WeatherForecastSourcePrivate::WeatherForecastSourcePrivate(QObject *parent)
32  : QObject(parent)
33 {
34 }
35 PendingWeatherForecast *WeatherForecastSourcePrivate::requestData(double latitude, double longitude)
36 {
37  QFile cache(self()->getCacheDirectory(latitude, longitude).path() + QStringLiteral("/cache.json"));
38  std::vector<Sunrise> sunriseCache;
40  // valid cache
41  if (cache.exists() && cache.open(QIODevice::ReadOnly)) {
42  auto weatherforecast = WeatherForecast::fromJson(QJsonDocument::fromJson(cache.readAll()).object());
43  timezone = weatherforecast.timezone();
44  if (weatherforecast.createdTime().secsTo(QDateTime::currentDateTime()) <= 3600) {
45  return new PendingWeatherForecast(weatherforecast);
46  } else {
47  const auto &days = weatherforecast.dailyWeatherForecast();
48  auto it = std::lower_bound(days.begin(), days.end(), QDate::currentDate(), [](const DailyWeatherForecast &day, const QDate &date) {
49  return day.date() < date;
50  });
51 
52  auto size = std::distance(it, days.end());
53  if (size) {
54  sunriseCache.reserve(size);
55  while (it != days.end()) {
56  sunriseCache.push_back(it->sunrise());
57  it++;
58  }
59  }
60  }
61  }
62 
63  // query weather api
64  QUrl url(QStringLiteral("https://api.met.no/weatherapi/locationforecast/2.0/complete"));
66  query.addQueryItem(QStringLiteral("lat"), self()->toFixedString(latitude));
67  query.addQueryItem(QStringLiteral("lon"), self()->toFixedString(longitude));
68 
69  url.setQuery(query);
70 
71  return new PendingWeatherForecast(latitude, longitude, url, timezone, sunriseCache);
72 }
73 WeatherForecastSource::WeatherForecastSource(QObject *parent)
74  : QObject(parent)
75  , d(new WeatherForecastSourcePrivate(this))
76 {
77 }
79 {
80  return d->requestData(latitude, longitude);
81 }
83 {
84  return requestData(result.latitude(), result.longitude());
85 }
86 }
87 #include "weatherforecastsource.moc"
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
Class represents location query result.
std::optional< QSqlQuery > query(const QString &queryStatement)
const QString & timezone() const
IANA Time Zone ID.
void addQueryItem(const QString &key, const QString &value)
Q_OBJECTQ_OBJECT
PendingWeatherForecast * requestData(double latitude, double longitude)
requestData
The PendingWeatherForecast class contains the reply to an asynchronous weather forecast request...
static WeatherForecast fromJson(QJsonObject obj)
construct from json
QDateTime currentDateTime()
QDate currentDate()
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Thu Oct 21 2021 23:05:33 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.