1 /* === This file is part of Calamares - <https://calamares.io> ===
2  *
3  *   SPDX-FileCopyrightText: 2014-2016 Teo Mrnjavac <teo@kde.org>
4  *   SPDX-FileCopyrightText: 2018 Adriaan de Groot <groot@kde.org>
5  *   SPDX-License-Identifier: GPL-3.0-or-later
6  *
7  *   Calamares is Free Software: see the License-Identifier above.
8  *
9  */
10 
11 #include "GeoIPJSON.h"
12 
13 #include "utils/Logger.h"
14 #include "utils/Variant.h"
15 #include "utils/Yaml.h"
16 
17 #include <QByteArray>
18 
19 namespace CalamaresUtils
20 {
21 namespace GeoIP
22 {
23 
GeoIPJSON(const QString & attribute)24 GeoIPJSON::GeoIPJSON( const QString& attribute )
25     : Interface( attribute.isEmpty() ? QStringLiteral( "time_zone" ) : attribute )
26 {
27 }
28 
29 /** @brief Indexes into a map @m by selectors @p l
30  *
31  * Each element of @p l is an index into map @m or a sub-map thereof,
32  * so that "foo.bar.baz" looks up "baz" in the sub-map "bar" of sub-map
33  * "foo" of @p m, like a regular JSON lookup would.
34  */
35 static QString
selectMap(const QVariantMap & m,const QStringList & l,int index)36 selectMap( const QVariantMap& m, const QStringList& l, int index )
37 {
38     if ( index >= l.count() )
39     {
40         return QString();
41     }
42 
43     QString attributeName = l[ index ];
44     if ( index == l.count() - 1 )
45     {
46         return CalamaresUtils::getString( m, attributeName );
47     }
48     else
49     {
50         bool success = false;  // bogus
51         if ( m.contains( attributeName ) )
52         {
53             return selectMap( CalamaresUtils::getSubMap( m, attributeName, success ), l, index + 1 );
54         }
55         return QString();
56     }
57 }
58 
59 QString
rawReply(const QByteArray & data)60 GeoIPJSON::rawReply( const QByteArray& data )
61 {
62     try
63     {
64         YAML::Node doc = YAML::Load( data );
65 
66         QVariant var = CalamaresUtils::yamlToVariant( doc );
67         if ( !var.isNull() && var.isValid() && var.type() == QVariant::Map )
68         {
69             return selectMap( var.toMap(), m_element.split( '.' ), 0 );
70         }
71         else
72         {
73             cWarning() << "Invalid YAML data for GeoIPJSON";
74         }
75     }
76     catch ( YAML::Exception& e )
77     {
78         CalamaresUtils::explainYamlException( e, data, "GeoIP data" );
79     }
80 
81     return QString();
82 }
83 
84 GeoIP::RegionZonePair
processReply(const QByteArray & data)85 GeoIPJSON::processReply( const QByteArray& data )
86 {
87     return splitTZString( rawReply( data ) );
88 }
89 
90 }  // namespace GeoIP
91 }  // namespace CalamaresUtils
92