File indexing completed on 2024-04-28 03:50:20
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2011 Daniel Marth <danielmarth@gmx.at> 0004 // 0005 0006 #include "OpenCachingModel.h" 0007 #include "OpenCachingItem.h" 0008 0009 #include "MarbleGlobal.h" 0010 #include "MarbleModel.h" 0011 #include "GeoDataCoordinates.h" 0012 #include "GeoDataLatLonAltBox.h" 0013 #include "MarbleDebug.h" 0014 #include "OpenCachingCache.h" 0015 0016 #include <QDebug> 0017 #include <QString> 0018 #include <QUrl> 0019 #include <QXmlStreamReader> 0020 0021 namespace Marble { 0022 0023 class OpenCachingModelPrivate 0024 { 0025 public: 0026 QHash<QString, QVariant> parseCache( QXmlStreamReader& reader ); 0027 QHash<QString, QVariant> parseLogEntry( QXmlStreamReader& reader ); 0028 QHash<QString, QVariant> parseDescription( QXmlStreamReader& reader ); 0029 }; 0030 0031 QHash<QString, QVariant> OpenCachingModelPrivate::parseCache( QXmlStreamReader& reader ) 0032 { 0033 QHash<QString, QVariant> cache; 0034 while ( !reader.atEnd() ) { 0035 if (reader.isStartElement() && reader.name() != QLatin1String("cache")) { 0036 if (reader.name() == QLatin1String("id")) { 0037 cache["id"] = reader.attributes().value("id").toString(); 0038 } 0039 else if (reader.name() != QLatin1String("attributes") && reader.name() != QLatin1String("attribute")) { 0040 cache[reader.name().toString()] = reader.readElementText(); 0041 } 0042 } 0043 else if (reader.isEndElement() && reader.name() == QLatin1String("cache")) { 0044 return cache; 0045 } 0046 reader.readNext(); 0047 } 0048 return QHash<QString, QVariant>(); 0049 } 0050 0051 QHash<QString, QVariant> OpenCachingModelPrivate::parseLogEntry( QXmlStreamReader& reader ) 0052 { 0053 QHash<QString, QVariant> cacheLogEntry; 0054 while ( !reader.atEnd() ) { 0055 if (reader.isStartElement() && reader.name() != QLatin1String("cachelog")) { 0056 if (reader.name() == QLatin1String("cacheid")) { 0057 cacheLogEntry["cacheid"] = reader.attributes().value( "id" ).toString(); 0058 } 0059 else { 0060 cacheLogEntry[reader.name().toString()] = reader.readElementText(); 0061 } 0062 } 0063 else if (reader.isEndElement() && reader.name() == QLatin1String("cachelog")) { 0064 return cacheLogEntry; 0065 } 0066 reader.readNext(); 0067 } 0068 return QHash<QString, QVariant>(); 0069 } 0070 0071 QHash<QString, QVariant> OpenCachingModelPrivate::parseDescription( QXmlStreamReader& reader ) 0072 { 0073 QHash<QString, QVariant> cacheDesc; 0074 while ( !reader.atEnd() ) { 0075 if (reader.isStartElement() && reader.name() != QLatin1String("cachedesc")) { 0076 if (reader.name() == QLatin1String("cacheid")) { 0077 cacheDesc["cacheid"] = reader.attributes().value( "id" ).toString(); 0078 } 0079 else { 0080 cacheDesc[reader.name().toString()] = reader.readElementText(); 0081 } 0082 } 0083 else if (reader.isEndElement() && reader.name() == QLatin1String("cachedesc")) { 0084 return cacheDesc; 0085 } 0086 reader.readNext(); 0087 } 0088 return QHash<QString, QVariant>(); 0089 } 0090 0091 OpenCachingModel::OpenCachingModel( const PluginManager *pluginManager, QObject *parent ) 0092 : AbstractDataPluginModel( "opencaching", pluginManager, parent ), 0093 m_numResults( numberOfItemsOnScreen ), 0094 m_maxDistance( 20 ), 0095 m_minDifficulty( 0.0 ), 0096 m_maxDifficulty( 5.0 ), 0097 m_startDate( QDateTime::fromString( "2006-01-01", "yyyy-MM-dd" ) ), 0098 m_endDate( QDateTime::currentDateTime() ), 0099 d( new OpenCachingModelPrivate ) 0100 { 0101 } 0102 0103 OpenCachingModel::~OpenCachingModel() 0104 { 0105 } 0106 0107 void OpenCachingModel::setNumResults( int numResults ) 0108 { 0109 m_numResults = numResults; 0110 } 0111 0112 void OpenCachingModel::setMaxDistance( int maxDistance ) 0113 { 0114 m_maxDistance = maxDistance; 0115 } 0116 0117 void OpenCachingModel::setMinDifficulty( double minDifficulty ) 0118 { 0119 m_minDifficulty = minDifficulty; 0120 } 0121 0122 void OpenCachingModel::setMaxDifficulty( double maxDifficulty ) 0123 { 0124 m_maxDifficulty = maxDifficulty; 0125 } 0126 0127 void OpenCachingModel::setStartDate( const QDateTime& startDate ) 0128 { 0129 m_startDate = startDate; 0130 } 0131 0132 void OpenCachingModel::setEndDate( const QDateTime& endDate ) 0133 { 0134 m_endDate = endDate; 0135 } 0136 0137 void OpenCachingModel::getAdditionalItems( const GeoDataLatLonAltBox& box, const MarbleModel *model, qint32 number ) 0138 { 0139 Q_UNUSED( number ); 0140 0141 if (model->planetId() != QLatin1String("earth")) { 0142 return; 0143 } 0144 0145 // https://www.opencaching.de/doc/xml/xml11.htm 0146 const QString openCachingUrl(QLatin1String("http://www.opencaching.de/xml/ocxml11.php") + 0147 QLatin1String("?modifiedsince=") + m_startDate.toString("yyyyMMddhhmmss") + 0148 QLatin1String("&cache=1&cachedesc=1&picture=0&cachelog=1&removedobject=0") + 0149 QLatin1String("&lat=") + QString::number(box.center().latitude() * RAD2DEG) + 0150 QLatin1String("&lon=") + QString::number(box.center().longitude() * RAD2DEG) + 0151 QLatin1String("&distance=") + QString::number(m_maxDistance) + 0152 QLatin1String("&charset=utf-8&cdata=0&session=0&zip=0")); 0153 downloadDescriptionFile( QUrl( openCachingUrl ) ); 0154 } 0155 0156 void OpenCachingModel::parseFile( const QByteArray& file ) 0157 { 0158 QXmlStreamReader reader( file ); 0159 QXmlStreamReader::TokenType token; 0160 QHash<int, OpenCachingCache> caches; 0161 QHash<int, QHash<QString, OpenCachingCacheDescription> > descriptions; 0162 QHash<int, OpenCachingCacheLog> logs; 0163 0164 while( !reader.atEnd() && !reader.hasError() ) { 0165 token = reader.readNext(); 0166 if( token == QXmlStreamReader::StartDocument ) { 0167 continue; 0168 } 0169 if( token == QXmlStreamReader::StartElement ) { 0170 if (reader.name() == QLatin1String("cache")) { 0171 OpenCachingCache cache = d->parseCache( reader ); 0172 caches[cache.id()] = cache; 0173 } 0174 else if (reader.name() == QLatin1String("cachedesc")) { 0175 OpenCachingCacheDescription description = d->parseDescription( reader ); 0176 descriptions[description.cacheId()][description.language()] = description; 0177 } 0178 else if (reader.name() == QLatin1String("cachelog")) { 0179 OpenCachingCacheLogEntry logEntry = d->parseLogEntry( reader ); 0180 logs[logEntry.cacheId()].addLogEntry( logEntry ); 0181 } 0182 } 0183 } 0184 0185 QHash<int, OpenCachingCache>::iterator itpoint = caches.begin(); 0186 QHash<int, OpenCachingCache>::iterator const endpoint = caches.end(); 0187 for (; itpoint != endpoint; ++itpoint ) { 0188 if( caches[itpoint.key()].difficulty() >= m_minDifficulty && 0189 caches[itpoint.key()].difficulty() <= m_maxDifficulty ) 0190 { 0191 caches[itpoint.key()].setDescription( descriptions[itpoint.key()] ); 0192 caches[itpoint.key()].setLog( logs[itpoint.key()] ); 0193 addItemToList( new OpenCachingItem( caches[itpoint.key()], this ) ); 0194 } 0195 } 0196 } 0197 0198 } 0199 0200 #include "moc_OpenCachingModel.cpp"