From 1da580f43d6cf8fc20f07fa1d7d11e28afe40871 Mon Sep 17 00:00:00 2001 From: Adriaan de Groot Date: Thu, 2 May 2019 08:33:29 -0400 Subject: [PATCH] [libcalamares] Implement Handler's synchronous query() - Steal code from existing tests for a synchronous HTTP get, then hand it off to the handler. - Extend tests with Handler interpreting the same data. --- src/libcalamares/geoip/GeoIPTests.cpp | 7 ++- src/libcalamares/geoip/Handler.cpp | 61 ++++++++++++++++++++++++++- src/libcalamares/geoip/Handler.h | 29 +++++++++++++ 3 files changed, 94 insertions(+), 3 deletions(-) diff --git a/src/libcalamares/geoip/GeoIPTests.cpp b/src/libcalamares/geoip/GeoIPTests.cpp index f72388892..d4f40a251 100644 --- a/src/libcalamares/geoip/GeoIPTests.cpp +++ b/src/libcalamares/geoip/GeoIPTests.cpp @@ -22,6 +22,7 @@ #ifdef QT_XML_LIB #include "GeoIPXML.h" #endif +#include "Handler.h" #include #include @@ -219,14 +220,18 @@ synchronous_get( const char* urlstring ) #define CHECK_GET(t, selector, url) \ { \ auto tz = GeoIP##t( selector ).processReply( synchronous_get( url ) ); \ + qDebug() << tz; \ QCOMPARE( default_tz, tz ); \ + auto tz2 = CalamaresUtils::GeoIP::Handler( ""#t, url, selector ).query(); \ + qDebug() << tz2; \ + QCOMPARE( default_tz, tz2 ); \ } void GeoIPTests::testGet() { if ( !QProcessEnvironment::systemEnvironment().contains( QStringLiteral("TEST_HTTP_GET") ) ) { - qDebug() << "Skipping HTTP GET tests"; + qDebug() << "Skipping HTTP GET tests, set TEST_HTTP_GET environment variable to enable"; return; } diff --git a/src/libcalamares/geoip/Handler.cpp b/src/libcalamares/geoip/Handler.cpp index 22643d9ac..f5f8efd11 100644 --- a/src/libcalamares/geoip/Handler.cpp +++ b/src/libcalamares/geoip/Handler.cpp @@ -18,23 +18,80 @@ #include "Handler.h" +#include "GeoIPJSON.h" +#if defined(QT_XML_LIB) +#include "GeoIPXML.h" +#endif + +#include "utils/Logger.h" + +#include +#include +#include + namespace CalamaresUtils::GeoIP { Handler::Handler() + : m_interface( nullptr ) { } +Handler::Handler( const QString& implementation, const QString& url, const QString& selector ) + : m_interface( nullptr ) + , m_url( url ) +{ + if ( implementation.compare( "json", Qt::CaseInsensitive ) == 0 ) + { + m_interface = new GeoIPJSON( selector ); + } +#if defined(QT_XML_LIB) + else if ( implementation.compare( "xml", Qt::CaseInsensitive ) == 0 ) + { + m_interface = new GeoIPXML( selector ); + } +#endif + else + { + cWarning() << "GeoIP Style" << implementation << "is not recognized."; + } +} + +Handler::~Handler() +{ + delete m_interface; +} + bool Handler::isValid() const { - return false; + return m_interface; } +static QByteArray +synchronous_get( const QString& urlstring ) +{ + QUrl url( urlstring ); + QNetworkAccessManager manager; + QEventLoop loop; + + QObject::connect( &manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit ); + + QNetworkRequest request( url ); + QNetworkReply* reply = manager.get( request ); + loop.exec(); + reply->deleteLater(); + return reply->readAll(); +} + + RegionZonePair Handler::query() const { - return RegionZonePair(); + if ( !isValid() ) + return RegionZonePair(); + + return m_interface->processReply( synchronous_get( m_url ) ); } } // namespace diff --git a/src/libcalamares/geoip/Handler.h b/src/libcalamares/geoip/Handler.h index 2e7bed888..e31e1d7df 100644 --- a/src/libcalamares/geoip/Handler.h +++ b/src/libcalamares/geoip/Handler.h @@ -21,6 +21,9 @@ #include "Interface.h" +#include +#include + namespace CalamaresUtils {} namespace CalamaresUtils::GeoIP { @@ -37,10 +40,36 @@ class DLLEXPORT Handler public: /** @brief An unconfigured handler; this always returns errors. */ Handler(); + /** @brief A handler for a specific GeoIP source. + * + * The @p implementation name selects an implementation; currently JSON and XML + * are supported. The @p url is retrieved by query() and then the @p selector + * is used to select something from the data returned by the @url. + */ + Handler( const QString& implementation, const QString& url, const QString& selector ); + /** @brief A handler for a specific GeoIP source. + * + * This is like the 3-QString Handler constructor, except the strings + * are extracted from the map, which is typically part of the configuration + * of a Calamares module. The strings are fetched from these keys: + * - implementation from "style" or "geoipStyle" (if the first does not exist) + * - url from "url" or "geoipUrl" (if the first does not exist) + * - selector from "selector" or "geoipSelector" (if the first does not exist) + * Unlike the 3-QString Handler constructor, this also understands implementations + * "legacy" and blank, which are interpreted as "JSON", except that the url is extended + * by "/json/" before fetching. + */ + Handler( const QVariantMap& config ); + + ~Handler(); RegionZonePair query() const; bool isValid() const; + +private: + Interface* m_interface; + const QString m_url; }; } // namespace