[libcalamares] Add "raw" support for extracting data from GeoIP

- This is prep-work for getting something other than the
   timezone (e.g. most extended formats also support Country).
This commit is contained in:
Adriaan de Groot 2019-05-09 10:15:53 -04:00
parent 8774b605fa
commit 9931b2df44
6 changed files with 67 additions and 17 deletions

View File

@ -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 static QString
selectMap( const QVariantMap& m, const QStringList& l, int index) selectMap( const QVariantMap& m, const QStringList& l, int index)
{ {
@ -51,8 +57,8 @@ selectMap( const QVariantMap& m, const QStringList& l, int index)
} }
} }
GeoIP::RegionZonePair QString
GeoIPJSON::processReply( const QByteArray& data ) GeoIPJSON::rawReply( const QByteArray& data )
{ {
try try
{ {
@ -63,7 +69,7 @@ GeoIPJSON::processReply( const QByteArray& data )
var.isValid() && var.isValid() &&
var.type() == QVariant::Map ) var.type() == QVariant::Map )
{ {
return splitTZString( selectMap( var.toMap(), m_element.split('.'), 0 ) ); return selectMap( var.toMap(), m_element.split('.'), 0 );
} }
else else
cWarning() << "Invalid YAML data for GeoIPJSON"; cWarning() << "Invalid YAML data for GeoIPJSON";
@ -73,7 +79,15 @@ GeoIPJSON::processReply( const QByteArray& data )
CalamaresUtils::explainYamlException( e, data, "GeoIP 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 } // namespace

View File

@ -42,7 +42,8 @@ public:
*/ */
explicit GeoIPJSON( const QString& attribute = QString() ); explicit GeoIPJSON( const QString& attribute = QString() );
virtual RegionZonePair processReply( const QByteArray& ); virtual RegionZonePair processReply( const QByteArray& ) override;
virtual QString rawReply(const QByteArray & ) override;
} ; } ;
} // namespace } // namespace

View File

@ -31,35 +31,60 @@ GeoIPXML::GeoIPXML( const QString& element )
{ {
} }
GeoIP::RegionZonePair static QStringList
GeoIPXML::processReply( const QByteArray& data ) getElementTexts( const QByteArray& data, const QString& tag )
{ {
QStringList elements;
QString domError; QString domError;
int errorLine, errorColumn; int errorLine, errorColumn;
QDomDocument doc; QDomDocument doc;
if ( doc.setContent( data, false, &domError, &errorLine, &errorColumn ) ) 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"; cDebug() << "GeoIP found" << tzElements.length() << "elements";
for ( int it = 0; it < tzElements.length(); ++it ) for ( int it = 0; it < tzElements.length(); ++it )
{ {
auto e = tzElements.at(it).toElement(); auto e = tzElements.at(it).toElement();
auto tz = splitTZString( e.text() ); auto e_text = e.text();
if ( !tz.first.isEmpty() ) if ( !e_text.isEmpty() )
return tz; elements.append( e_text );
} }
// None of them valid
cWarning() << "GeopIP XML had no recognizable timezone";
return RegionZonePair( QString(), QString() );
} }
else else
{ {
cWarning() << "GeoIP XML data error:" << domError << "(line" << errorLine << errorColumn << ')'; 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 } // namespace

View File

@ -42,7 +42,8 @@ public:
*/ */
explicit GeoIPXML( const QString& element = QString() ); explicit GeoIPXML( const QString& element = QString() );
virtual RegionZonePair processReply( const QByteArray& ); virtual RegionZonePair processReply( const QByteArray& ) override;
virtual QString rawReply(const QByteArray & ) override;
} ; } ;
} // namespace } // namespace

View File

@ -66,12 +66,18 @@ public:
* invalid (empty) result. * invalid (empty) result.
*/ */
RegionZonePair get() const; RegionZonePair get() const;
/// @brief Like get, but don't interpret the contents
QString getRaw() const;
/** @brief Asynchronously get the GeoIP result. /** @brief Asynchronously get the GeoIP result.
* *
* See get() for the return value. * See get() for the return value.
*/ */
QFuture< RegionZonePair > query() const; 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; } bool isValid() const { return m_type != Type::None; }
Type type() const { return m_type; } Type type() const { return m_type; }

View File

@ -85,6 +85,9 @@ public:
*/ */
virtual RegionZonePair processReply( const QByteArray& ) = 0; virtual RegionZonePair processReply( const QByteArray& ) = 0;
/** @brief Get the raw reply data. */
virtual QString rawReply( const QByteArray& ) = 0;
protected: protected:
Interface( const QString& e = QString() ); Interface( const QString& e = QString() );