File indexing completed on 2024-04-28 04:42:43

0001 /*
0002  * SPDX-FileCopyrightText: 2020-2021 Han Young <hanyoung@protonmail.com>
0003  * SPDX-FileCopyrightText: 2020 Devin Lin <espidev@gmail.com>
0004  *
0005  * SPDX-License-Identifier: LGPL-2.0-or-later
0006  */
0007 
0008 #include "weatherforecastsource.h"
0009 #include "kweathercore_p.h"
0010 #include "locationqueryresult.h"
0011 #include "weatherforecast.h"
0012 
0013 #include <KTimeZone>
0014 
0015 #include <QFile>
0016 #include <QJsonDocument>
0017 #include <QNetworkAccessManager>
0018 #include <QStandardPaths>
0019 
0020 #include <algorithm>
0021 
0022 namespace KWeatherCore
0023 {
0024 class WeatherForecastSourcePrivate
0025 {
0026 public:
0027     QNetworkAccessManager *m_nam = nullptr;
0028 };
0029 
0030 WeatherForecastSource::WeatherForecastSource(QObject *parent)
0031     : QObject(parent)
0032     , d(new WeatherForecastSourcePrivate)
0033 {
0034 }
0035 
0036 WeatherForecastSource::~WeatherForecastSource() = default;
0037 
0038 PendingWeatherForecast *WeatherForecastSource::requestData(double latitude, double longitude)
0039 {
0040     QFile cache(KWeatherCorePrivate::getCacheDirectory(latitude, longitude).path() + QStringLiteral("/cache.json"));
0041     QString timezone;
0042     // valid cache
0043     if (cache.exists() && cache.open(QIODevice::ReadOnly)) {
0044         auto weatherforecast = WeatherForecast::fromJson(QJsonDocument::fromJson(cache.readAll()).object());
0045         timezone = weatherforecast.timezone();
0046         if (weatherforecast.createdTime().secsTo(QDateTime::currentDateTime()) <= 3600) {
0047             return new PendingWeatherForecast(weatherforecast);
0048         }
0049     }
0050 
0051     if (timezone.isEmpty()) {
0052         timezone = QString::fromUtf8(KTimeZone::fromLocation(latitude, longitude));
0053     }
0054 
0055     if (!d->m_nam) {
0056         d->m_nam = new QNetworkAccessManager(this);
0057         d->m_nam->setRedirectPolicy(QNetworkRequest::NoLessSafeRedirectPolicy);
0058         d->m_nam->setStrictTransportSecurityEnabled(true);
0059         d->m_nam->enableStrictTransportSecurityStore(true,
0060                                                      QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation)
0061                                                          + QLatin1String("/org.kde.kweathercore/hsts/"));
0062     }
0063 
0064     return new PendingWeatherForecast(latitude, longitude, timezone, d->m_nam);
0065 }
0066 
0067 PendingWeatherForecast *WeatherForecastSource::requestData(const KWeatherCore::LocationQueryResult &result)
0068 {
0069     return requestData(result.latitude(), result.longitude());
0070 }
0071 
0072 void WeatherForecastSource::setNetworkAccessManager(QNetworkAccessManager *nam)
0073 {
0074     if (d->m_nam == nam) {
0075         return;
0076     }
0077 
0078     if (d->m_nam->parent() == this) {
0079         delete d->m_nam;
0080     }
0081     d->m_nam = nam;
0082 }
0083 }
0084 
0085 #include "moc_weatherforecastsource.cpp"