diff --git a/src/libcalamares/geoip/GeoIPJSON.cpp b/src/libcalamares/geoip/GeoIPJSON.cpp index 801031c9e..61b9fd8d6 100644 --- a/src/libcalamares/geoip/GeoIPJSON.cpp +++ b/src/libcalamares/geoip/GeoIPJSON.cpp @@ -33,6 +33,12 @@ GeoIPJSON::GeoIPJSON(const QString& attribute) { } +/** @brief Indexes into a map @m by selectors @p l + * + * Each element of @p l is an index into map @m or a sub-map thereof, + * so that "foo.bar.baz" looks up "baz" in the sub-map "bar" of sub-map + * "foo" of @p m, like a regular JSON lookup would. + */ static QString selectMap( const QVariantMap& m, const QStringList& l, int index) { @@ -51,8 +57,8 @@ selectMap( const QVariantMap& m, const QStringList& l, int index) } } -GeoIP::RegionZonePair -GeoIPJSON::processReply( const QByteArray& data ) +QString +GeoIPJSON::rawReply( const QByteArray& data ) { try { @@ -63,7 +69,7 @@ GeoIPJSON::processReply( const QByteArray& data ) var.isValid() && var.type() == QVariant::Map ) { - return splitTZString( selectMap( var.toMap(), m_element.split('.'), 0 ) ); + return selectMap( var.toMap(), m_element.split('.'), 0 ); } else cWarning() << "Invalid YAML data for GeoIPJSON"; @@ -73,7 +79,15 @@ GeoIPJSON::processReply( const QByteArray& data ) CalamaresUtils::explainYamlException( e, data, "GeoIP data"); } - return RegionZonePair( QString(), QString() ); + return QString(); } +GeoIP::RegionZonePair +GeoIPJSON::processReply( const QByteArray& data ) +{ + return splitTZString( rawReply( data ) ); +} + + + } // namespace diff --git a/src/libcalamares/geoip/GeoIPJSON.h b/src/libcalamares/geoip/GeoIPJSON.h index 355fa0739..584825d70 100644 --- a/src/libcalamares/geoip/GeoIPJSON.h +++ b/src/libcalamares/geoip/GeoIPJSON.h @@ -42,7 +42,8 @@ public: */ explicit GeoIPJSON( const QString& attribute = QString() ); - virtual RegionZonePair processReply( const QByteArray& ); + virtual RegionZonePair processReply( const QByteArray& ) override; + virtual QString rawReply(const QByteArray & ) override; } ; } // namespace diff --git a/src/libcalamares/geoip/GeoIPXML.cpp b/src/libcalamares/geoip/GeoIPXML.cpp index e67354e1d..a4b9bb146 100644 --- a/src/libcalamares/geoip/GeoIPXML.cpp +++ b/src/libcalamares/geoip/GeoIPXML.cpp @@ -31,35 +31,60 @@ GeoIPXML::GeoIPXML( const QString& element ) { } -GeoIP::RegionZonePair -GeoIPXML::processReply( const QByteArray& data ) +static QStringList +getElementTexts( const QByteArray& data, const QString& tag ) { + QStringList elements; + QString domError; int errorLine, errorColumn; QDomDocument doc; if ( doc.setContent( data, false, &domError, &errorLine, &errorColumn ) ) { - const auto tzElements = doc.elementsByTagName( m_element ); + const auto tzElements = doc.elementsByTagName( tag ); cDebug() << "GeoIP found" << tzElements.length() << "elements"; for ( int it = 0; it < tzElements.length(); ++it ) { auto e = tzElements.at(it).toElement(); - auto tz = splitTZString( e.text() ); - if ( !tz.first.isEmpty() ) - return tz; + auto e_text = e.text(); + if ( !e_text.isEmpty() ) + elements.append( e_text ); } - - // None of them valid - cWarning() << "GeopIP XML had no recognizable timezone"; - return RegionZonePair( QString(), QString() ); } else { cWarning() << "GeoIP XML data error:" << domError << "(line" << errorLine << errorColumn << ')'; } - return RegionZonePair( QString(), QString() ); + if ( elements.count() < 1 ) + cWarning() << "GeopIP XML had no non-empty elements" << tag; + + return elements; +} + + +QString +GeoIPXML::rawReply( const QByteArray& data ) +{ + for ( const auto& e : getElementTexts( data, m_element ) ) + if ( !e.isEmpty() ) + return e; + + return QString(); +} + +GeoIP::RegionZonePair +GeoIPXML::processReply( const QByteArray& data ) +{ + for ( const auto& e : getElementTexts( data, m_element ) ) + { + auto tz = splitTZString( e ); + if ( !tz.first.isEmpty() ) + return tz; + } + + return RegionZonePair(); } } // namespace diff --git a/src/libcalamares/geoip/GeoIPXML.h b/src/libcalamares/geoip/GeoIPXML.h index 367c307f8..7dee2ecbe 100644 --- a/src/libcalamares/geoip/GeoIPXML.h +++ b/src/libcalamares/geoip/GeoIPXML.h @@ -42,7 +42,8 @@ public: */ explicit GeoIPXML( const QString& element = QString() ); - virtual RegionZonePair processReply( const QByteArray& ); + virtual RegionZonePair processReply( const QByteArray& ) override; + virtual QString rawReply(const QByteArray & ) override; } ; } // namespace diff --git a/src/libcalamares/geoip/Handler.h b/src/libcalamares/geoip/Handler.h index 533188a0d..b095c59ac 100644 --- a/src/libcalamares/geoip/Handler.h +++ b/src/libcalamares/geoip/Handler.h @@ -66,12 +66,18 @@ public: * invalid (empty) result. */ RegionZonePair get() const; + /// @brief Like get, but don't interpret the contents + QString getRaw() const; /** @brief Asynchronously get the GeoIP result. * * See get() for the return value. */ QFuture< RegionZonePair > query() const; + /// @brief Like query, but don't interpret the contents + QFuture< QString > queryRaw() const; + + bool isValid() const { return m_type != Type::None; } Type type() const { return m_type; } diff --git a/src/libcalamares/geoip/Interface.h b/src/libcalamares/geoip/Interface.h index 94c6b3c20..4b2ff3a5a 100644 --- a/src/libcalamares/geoip/Interface.h +++ b/src/libcalamares/geoip/Interface.h @@ -85,6 +85,9 @@ public: */ virtual RegionZonePair processReply( const QByteArray& ) = 0; + /** @brief Get the raw reply data. */ + virtual QString rawReply( const QByteArray& ) = 0; + protected: Interface( const QString& e = QString() );