[locale] Support multi-level selection from JSON data
- Some providers don't provide a single flat JSON object (e.g. "{time_zone: foo}") but a nested structure (e.g. "{location: {time_zone: foo}}"), so allow dots in the selector to do multi-level selection.
This commit is contained in:
parent
6545d5d022
commit
0f5e061c4a
@ -19,6 +19,7 @@
|
||||
|
||||
#include "GeoIPJSON.h"
|
||||
|
||||
#include "utils/CalamaresUtils.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/YamlUtils.h"
|
||||
|
||||
@ -31,6 +32,24 @@ GeoIPJSON::GeoIPJSON(const QString& attribute)
|
||||
{
|
||||
}
|
||||
|
||||
static QString
|
||||
selectMap( const QVariantMap& m, const QStringList& l, int index)
|
||||
{
|
||||
if ( index >= l.count() )
|
||||
return QString();
|
||||
|
||||
QString attributeName = l[index];
|
||||
if ( index == l.count() - 1 )
|
||||
return CalamaresUtils::getString( m, attributeName );
|
||||
else
|
||||
{
|
||||
bool success = false; // bogus
|
||||
if ( m.contains( attributeName ) )
|
||||
return selectMap( CalamaresUtils::getSubMap( m, attributeName, success ), l, index+1 );
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
|
||||
GeoIP::RegionZonePair
|
||||
GeoIPJSON::processReply( const QByteArray& data )
|
||||
{
|
||||
@ -43,12 +62,7 @@ GeoIPJSON::processReply( const QByteArray& data )
|
||||
var.isValid() &&
|
||||
var.type() == QVariant::Map )
|
||||
{
|
||||
QVariantMap map = var.toMap();
|
||||
if ( map.contains( m_element ) &&
|
||||
!map.value( m_element ).toString().isEmpty() )
|
||||
{
|
||||
return splitTZString( map.value( m_element ).toString() );
|
||||
}
|
||||
return splitTZString( selectMap( var.toMap(), m_element.split('.'), 0 ) );
|
||||
}
|
||||
else
|
||||
cWarning() << "Invalid YAML data for GeoIPJSON";
|
||||
|
@ -78,4 +78,15 @@ zone: "New_York"
|
||||
# a different attribute name (e.g. "timezone") in JSON or a
|
||||
# different element tag (e.g. "<Time_Zone>") in XML, set this
|
||||
# string to the name or tag to be used.
|
||||
#
|
||||
# In JSON:
|
||||
# - if the string contains "." characters, this is used as a
|
||||
# multi-level selector, e.g. "a.b" will select the timezone
|
||||
# from data "{a: {b: "Europe/Amsterdam" } }".
|
||||
# - each part of the string split by "." characters is used as
|
||||
# a key into the JSON data.
|
||||
# In XML:
|
||||
# - all elements with the named tag (e.g. all TimeZone) elements
|
||||
# from the document are checked; the first one with non-empty
|
||||
# text value is used.
|
||||
#geoipSelector: ""
|
||||
|
Loading…
Reference in New Issue
Block a user