[locale] Make the selector configurable

- GeoIP gets a string selector; the interpretation is up to derived classes.
 - GeoIPXML and GeoIPJSON use the selector to select an element by tag
   or an attribute, respectively.
This commit is contained in:
Adriaan de Groot 2018-04-16 04:55:37 -04:00
parent 79a6d7ccbd
commit fe20416a54
7 changed files with 55 additions and 7 deletions

View File

@ -20,6 +20,11 @@
#include "utils/Logger.h"
GeoIP::GeoIP(const QString& e)
: m_element( e )
{
}
GeoIP::~GeoIP()
{
}

View File

@ -32,8 +32,9 @@ class QByteArray;
* and can handle the data returned from its interpretation of that
* configured URL, returning a region and zone.
*/
struct GeoIP
class GeoIP
{
public:
using RegionZonePair = QPair<QString, QString>;
virtual ~GeoIP();
@ -51,6 +52,11 @@ struct GeoIP
/** @brief Splits a region/zone string into a pair. */
static RegionZonePair splitTZString( const QString& s );
protected:
GeoIP( const QString& e = QString() );
QString m_element; // string for selecting from data
} ;
#endif

View File

@ -26,6 +26,17 @@
#include <yaml-cpp/yaml.h>
GeoIPJSON::GeoIPJSON(const QString& attribute)
: GeoIP( attribute )
{
}
GeoIPJSON::GeoIPJSON()
: GeoIPJSON( QLatin1Literal( "time_zone" ) )
{
}
GeoIP::RegionZonePair
GeoIPJSON::processReply( const QByteArray& data )
{
@ -39,12 +50,14 @@ GeoIPJSON::processReply( const QByteArray& data )
var.type() == QVariant::Map )
{
QVariantMap map = var.toMap();
if ( map.contains( "time_zone" ) &&
!map.value( "time_zone" ).toString().isEmpty() )
if ( map.contains( m_element ) &&
!map.value( m_element ).toString().isEmpty() )
{
return splitTZString( map.value( "time_zone" ).toString() );
return splitTZString( map.value( m_element ).toString() );
}
}
else
cWarning() << "Invalid YAML data for GeoIPJSON";
}
catch ( YAML::Exception& e )
{

View File

@ -28,8 +28,12 @@
*
* The data is assumed to be in JSON format with a time_zone attribute.
*/
struct GeoIPJSON : public GeoIP
class GeoIPJSON : public GeoIP
{
public:
explicit GeoIPJSON( const QString& attribute );
explicit GeoIPJSON();
virtual RegionZonePair processReply( const QByteArray& );
} ;

View File

@ -76,6 +76,9 @@ GeoIPTests::testJSONbad()
tz = handler.processReply( "<html><body>404 Forbidden</body></html>" );
QCOMPARE( tz.first, QString() );
tz = handler.processReply( "{ time zone = 'America/LosAngeles'}" );
QCOMPARE( tz.first, QString() );
}

View File

@ -23,6 +23,17 @@
#include <QNetworkReply>
#include <QtXml/QDomDocument>
GeoIPXML::GeoIPXML( const QString& element )
: GeoIP( element )
{
}
GeoIPXML::GeoIPXML()
: GeoIPXML( QLatin1Literal( "TimeZone" ) )
{
}
GeoIP::RegionZonePair
GeoIPXML::processReply( const QByteArray& data )
{
@ -32,7 +43,7 @@ GeoIPXML::processReply( const QByteArray& data )
QDomDocument doc;
if ( doc.setContent( data, false, &domError, &errorLine, &errorColumn ) )
{
const auto tzElements = doc.elementsByTagName( "TimeZone" );
const auto tzElements = doc.elementsByTagName( m_element );
cDebug() << "GeoIP found" << tzElements.length() << "elements";
for ( int it = 0; it < tzElements.length(); ++it )
{

View File

@ -28,8 +28,14 @@
* element, which contains the text (string) for the region/zone. This
* format is expected by, e.g. the Ubiquity installer.
*/
struct GeoIPXML : public GeoIP
class GeoIPXML : public GeoIP
{
public:
/** @brief Configure the element name which is selected. */
explicit GeoIPXML( const QString& element );
/** @brief Use default TimeZone element. */
explicit GeoIPXML();
virtual RegionZonePair processReply( const QByteArray& );
} ;