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