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 
8 #include "weatherforecastsource.h"
9 #include "kweathercore_p.h"
10 #include "locationqueryresult.h"
11 #include "weatherforecast.h"
12 
13 #include <QFile>
14 #include <QJsonDocument>
15 #include <QNetworkAccessManager>
16 #include <QStandardPaths>
17 
18 #include <algorithm>
19 
20 namespace KWeatherCore
21 {
22 class WeatherForecastSourcePrivate
23 {
24 public:
25  QNetworkAccessManager *m_nam = nullptr;
26 };
27 
28 WeatherForecastSource::WeatherForecastSource(QObject *parent)
29  : QObject(parent)
30  , d(new WeatherForecastSourcePrivate)
31 {
32 }
33 
34 WeatherForecastSource::~WeatherForecastSource() = default;
35 
37 {
38  QFile cache(KWeatherCorePrivate::getCacheDirectory(latitude, longitude).path() + QStringLiteral("/cache.json"));
39  std::vector<Sunrise> sunriseCache;
40  QString timezone;
41  // valid cache
42  if (cache.exists() && cache.open(QIODevice::ReadOnly)) {
43  auto weatherforecast = WeatherForecast::fromJson(QJsonDocument::fromJson(cache.readAll()).object());
44  timezone = weatherforecast.timezone();
45  if (weatherforecast.createdTime().secsTo(QDateTime::currentDateTime()) <= 3600) {
46  return new PendingWeatherForecast(weatherforecast);
47  } else {
48  const auto &days = weatherforecast.dailyWeatherForecast();
49  auto it = std::lower_bound(days.begin(), days.end(), QDate::currentDate(), [](const DailyWeatherForecast &day, const QDate &date) {
50  return day.date() < date;
51  });
52 
53  auto size = std::distance(it, days.end());
54  if (size) {
55  sunriseCache.reserve(size);
56  while (it != days.end()) {
57  sunriseCache.push_back(it->sunrise());
58  it++;
59  }
60  }
61  }
62  }
63 
64  if (!d->m_nam) {
65  d->m_nam = new QNetworkAccessManager(this);
66  d->m_nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
67  d->m_nam->setStrictTransportSecurityEnabled(true);
68  d->m_nam->enableStrictTransportSecurityStore(true,
70  + QLatin1String("/org.kde.kweathercore/hsts/"));
71  }
72 
73  return new PendingWeatherForecast(latitude, longitude, timezone, sunriseCache, d->m_nam);
74 }
75 
77 {
78  return requestData(result.latitude(), result.longitude());
79 }
80 
82 {
83  if (d->m_nam == nam) {
84  return;
85  }
86 
87  if (d->m_nam->parent() == this) {
88  delete d->m_nam;
89  }
90  d->m_nam = nam;
91 }
92 }
QJsonObject object() const const
static WeatherForecast fromJson(QJsonObject obj)
construct from json
QJsonDocument fromJson(const QByteArray &json, QJsonParseError *error)
virtual bool open(QIODevice::OpenMode mode) override
QDateTime currentDateTime()
QString writableLocation(QStandardPaths::StandardLocation type)
bool exists() const const
Class represents weatherforecast in a day.
PendingWeatherForecast * requestData(double latitude, double longitude)
requestData
QDate currentDate()
void setNetworkAccessManager(QNetworkAccessManager *nam)
Set the network access manager to use for network operations.
Class represents location query result.
QByteArray readAll()
The PendingWeatherForecast class contains the reply to an asynchronous weather forecast request.
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Sun May 22 2022 03:55:44 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.