mirror of
https://github.com/Qortal/Brooklyn.git
synced 2025-02-15 11:45:54 +00:00
196 lines
6.2 KiB
C++
196 lines
6.2 KiB
C++
/*
|
|
SPDX-FileCopyrightText: 2009 Petri Damstén <damu@iki.fi>
|
|
|
|
Original Implementation:
|
|
SPDX-FileCopyrightText: 2009 Andrew Coles <andrew.coles@yahoo.co.uk>
|
|
|
|
Extension to iplocationtools engine:
|
|
SPDX-FileCopyrightText: 2015 Martin Gräßlin <mgraesslin@kde.org>
|
|
|
|
SPDX-License-Identifier: GPL-2.0-or-later
|
|
*/
|
|
|
|
#include "location_ip.h"
|
|
#include "geolocdebug.h"
|
|
#include <KIO/Job>
|
|
#include <KIO/TransferJob>
|
|
#include <KJob>
|
|
#include <KSharedConfig>
|
|
#include <NetworkManagerQt/Manager>
|
|
#include <NetworkManagerQt/WirelessDevice>
|
|
#include <QJsonArray>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QUrl>
|
|
|
|
class Ip::Private : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
Private(Ip *q)
|
|
: q(q)
|
|
{
|
|
}
|
|
|
|
void readGeoLocation(KJob *job)
|
|
{
|
|
m_geoLocationResolved = true;
|
|
if (job && job->error()) {
|
|
qCCritical(DATAENGINE_GEOLOCATION) << "error: " << job->errorString();
|
|
m_geoLocationPayload.clear();
|
|
checkUpdateData();
|
|
return;
|
|
}
|
|
const QJsonObject json = QJsonDocument::fromJson(m_geoLocationPayload).object();
|
|
m_geoLocationPayload.clear();
|
|
|
|
auto accuracyIt = json.find(QStringLiteral("accuracy"));
|
|
if (accuracyIt != json.end()) {
|
|
m_data[QStringLiteral("accuracy")] = (*accuracyIt).toDouble();
|
|
} else {
|
|
m_data[QStringLiteral("accuracy")] = 40000;
|
|
}
|
|
|
|
auto locationIt = json.find(QStringLiteral("location"));
|
|
if (locationIt != json.end()) {
|
|
QJsonObject location = (*locationIt).toObject();
|
|
m_data[QStringLiteral("latitude")] = location.value(QStringLiteral("lat")).toDouble();
|
|
m_data[QStringLiteral("longitude")] = location.value(QStringLiteral("lng")).toDouble();
|
|
}
|
|
checkUpdateData();
|
|
}
|
|
|
|
void clear()
|
|
{
|
|
m_geoLocationPayload.clear();
|
|
m_countryPayload.clear();
|
|
m_countryResolved = false;
|
|
m_geoLocationResolved = false;
|
|
m_data.clear();
|
|
}
|
|
|
|
void geoLocationData(KIO::Job *job, const QByteArray &data)
|
|
{
|
|
Q_UNUSED(job)
|
|
|
|
if (data.isEmpty()) {
|
|
return;
|
|
}
|
|
m_geoLocationPayload.append(data);
|
|
}
|
|
|
|
void countryData(KIO::Job *job, const QByteArray &data)
|
|
{
|
|
Q_UNUSED(job)
|
|
|
|
if (data.isEmpty()) {
|
|
return;
|
|
}
|
|
m_countryPayload.append(data);
|
|
}
|
|
|
|
void readCountry(KJob *job)
|
|
{
|
|
m_countryResolved = true;
|
|
if (job && job->error()) {
|
|
qCCritical(DATAENGINE_GEOLOCATION) << "error: " << job->errorString();
|
|
m_countryPayload.clear();
|
|
checkUpdateData();
|
|
return;
|
|
}
|
|
|
|
const QJsonObject json = QJsonDocument::fromJson(m_countryPayload).object();
|
|
m_countryPayload.clear();
|
|
|
|
m_data[QStringLiteral("country")] = json.value(QStringLiteral("country_name")).toString();
|
|
m_data[QStringLiteral("country code")] = json.value(QStringLiteral("country_code")).toString();
|
|
checkUpdateData();
|
|
}
|
|
|
|
private:
|
|
void checkUpdateData()
|
|
{
|
|
if (!m_countryResolved || !m_geoLocationResolved) {
|
|
return;
|
|
}
|
|
q->setData(m_data);
|
|
}
|
|
|
|
Ip *q;
|
|
QByteArray m_geoLocationPayload;
|
|
QByteArray m_countryPayload;
|
|
bool m_countryResolved = false;
|
|
bool m_geoLocationResolved = false;
|
|
Plasma::DataEngine::Data m_data;
|
|
};
|
|
|
|
Ip::Ip(QObject *parent, const QVariantList &args)
|
|
: GeolocationProvider(parent, args)
|
|
, d(new Private(this))
|
|
{
|
|
setUpdateTriggers(SourceEvent | NetworkConnected);
|
|
}
|
|
|
|
Ip::~Ip()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
static QJsonArray accessPoints()
|
|
{
|
|
QJsonArray wifiAccessPoints;
|
|
const KConfigGroup config = KSharedConfig::openConfig()->group(QStringLiteral("org.kde.plasma.geolocation.ip"));
|
|
if (!NetworkManager::isWirelessEnabled() || !config.readEntry("Wifi", false)) {
|
|
return wifiAccessPoints;
|
|
}
|
|
for (const auto &device : NetworkManager::networkInterfaces()) {
|
|
QSharedPointer<NetworkManager::WirelessDevice> wifi = qSharedPointerDynamicCast<NetworkManager::WirelessDevice>(device);
|
|
if (!wifi) {
|
|
continue;
|
|
}
|
|
for (const auto &network : wifi->networks()) {
|
|
const QString &ssid = network->ssid();
|
|
if (ssid.isEmpty() || ssid.endsWith(QLatin1String("_nomap"))) {
|
|
// skip hidden SSID and networks with "_nomap"
|
|
continue;
|
|
}
|
|
for (const auto &accessPoint : network->accessPoints()) {
|
|
wifiAccessPoints.append(QJsonObject{{QStringLiteral("macAddress"), accessPoint->hardwareAddress()}});
|
|
}
|
|
}
|
|
}
|
|
return wifiAccessPoints;
|
|
}
|
|
|
|
void Ip::update()
|
|
{
|
|
d->clear();
|
|
if (!NetworkManager::isNetworkingEnabled()) {
|
|
setData(Plasma::DataEngine::Data());
|
|
return;
|
|
}
|
|
const QJsonArray wifiAccessPoints = accessPoints();
|
|
QJsonObject request;
|
|
if (wifiAccessPoints.count() >= 2) {
|
|
request.insert(QStringLiteral("wifiAccessPoints"), wifiAccessPoints);
|
|
}
|
|
const QByteArray postData = QJsonDocument(request).toJson(QJsonDocument::Compact);
|
|
const QString apiKey = QStringLiteral("60e8eae6-3988-4ada-ad48-2cfddddf216b");
|
|
KIO::TransferJob *datajob =
|
|
KIO::http_post(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/geolocate?key=%1").arg(apiKey)), postData, KIO::HideProgressInfo);
|
|
datajob->addMetaData(QStringLiteral("content-type"), QStringLiteral("application/json"));
|
|
|
|
qCDebug(DATAENGINE_GEOLOCATION) << "Fetching https://location.services.mozilla.com/v1/geolocate";
|
|
connect(datajob, &KIO::TransferJob::data, d, &Ip::Private::geoLocationData);
|
|
connect(datajob, &KIO::TransferJob::result, d, &Ip::Private::readGeoLocation);
|
|
|
|
datajob = KIO::http_post(QUrl(QStringLiteral("https://location.services.mozilla.com/v1/country?key=%1").arg(apiKey)), postData, KIO::HideProgressInfo);
|
|
datajob->addMetaData(QStringLiteral("content-type"), QStringLiteral("application/json"));
|
|
connect(datajob, &KIO::TransferJob::data, d, &Ip::Private::countryData);
|
|
connect(datajob, &KIO::TransferJob::result, d, &Ip::Private::readCountry);
|
|
}
|
|
|
|
K_PLUGIN_CLASS_WITH_JSON(Ip, "plasma-geolocation-ip.json")
|
|
|
|
#include "location_ip.moc"
|