File indexing completed on 2024-04-28 03:50:31
0001 // SPDX-License-Identifier: LGPL-2.1-or-later 0002 // 0003 // SPDX-FileCopyrightText: 2010 Dennis Nienhüser <nienhueser@kde.org> 0004 0005 #include "HostipRunner.h" 0006 0007 #include "MarbleDebug.h" 0008 #include "GeoDataPlacemark.h" 0009 0010 #include <QTimer> 0011 #include <QVector> 0012 #include <QUrl> 0013 #include <QNetworkReply> 0014 0015 namespace Marble 0016 { 0017 0018 HostipRunner::HostipRunner( QObject *parent ) : 0019 SearchRunner( parent ), 0020 m_networkAccessManager() 0021 { 0022 connect( &m_networkAccessManager, SIGNAL(finished(QNetworkReply*)), 0023 this, SLOT(slotRequestFinished(QNetworkReply*)), Qt::DirectConnection ); 0024 } 0025 0026 HostipRunner::~HostipRunner() 0027 { 0028 } 0029 0030 void HostipRunner::slotNoResults() 0031 { 0032 emit searchFinished( QVector<GeoDataPlacemark*>() ); 0033 } 0034 0035 void HostipRunner::search( const QString &searchTerm, const GeoDataLatLonBox & ) 0036 { 0037 if (!searchTerm.contains(QLatin1Char('.'))) { 0038 // Simple IP/hostname heuristic to avoid requests not needed: 0039 // String must contain at least one dot. 0040 slotNoResults(); 0041 } 0042 else { 0043 QEventLoop eventLoop; 0044 0045 QTimer timer; 0046 timer.setSingleShot( true ); 0047 timer.setInterval( 15000 ); 0048 0049 connect( &timer, SIGNAL(timeout()), 0050 &eventLoop, SLOT(quit())); 0051 connect( this, SIGNAL(searchFinished(QVector<GeoDataPlacemark*>)), 0052 &eventLoop, SLOT(quit()) ); 0053 0054 // Lookup the IP address for a hostname, or the hostname if an IP address was given 0055 QHostInfo ::lookupHost( searchTerm, this, SLOT(slotLookupFinished(QHostInfo))); 0056 timer.start(); 0057 0058 eventLoop.exec(); 0059 } 0060 } 0061 0062 void HostipRunner::slotLookupFinished(const QHostInfo &info) 0063 { 0064 if ( !info.addresses().isEmpty() ) { 0065 m_hostInfo = info; 0066 QString hostAddress = info.addresses().first().toString(); 0067 QString query = QString( "http://api.hostip.info/get_html.php?ip=%1&position=true" ).arg( hostAddress ); 0068 m_request.setUrl( QUrl( query ) ); 0069 0070 // @todo FIXME Must currently be done in the main thread, see bug 257376 0071 QTimer::singleShot( 0, this, SLOT(get()) ); 0072 } 0073 else 0074 slotNoResults(); 0075 } 0076 0077 void HostipRunner::get() 0078 { 0079 QNetworkReply *reply = m_networkAccessManager.get( m_request ); 0080 connect( reply, SIGNAL(error(QNetworkReply::NetworkError)), 0081 this, SLOT(slotNoResults()), Qt::DirectConnection ); 0082 } 0083 0084 void HostipRunner::slotRequestFinished( QNetworkReply* reply ) 0085 { 0086 double lon(0.0), lat(0.0); 0087 for ( QString line = reply->readLine(); !line.isEmpty(); line = reply->readLine() ) { 0088 QString lonInd = "Longitude: "; 0089 if ( line.startsWith(lonInd) ) { 0090 lon = line.mid( lonInd.length() ).toDouble(); 0091 } 0092 0093 QString latInd = "Latitude: "; 0094 if (line.startsWith( latInd) ) { 0095 lat = line.mid( latInd.length() ).toDouble(); 0096 } 0097 } 0098 0099 QVector<GeoDataPlacemark*> placemarks; 0100 0101 if (lon != 0.0 && lat != 0.0) { 0102 GeoDataPlacemark *placemark = new GeoDataPlacemark; 0103 0104 placemark->setName( m_hostInfo.hostName() ); 0105 0106 QString description("%1 (%2)"); 0107 placemark->setDescription( description. 0108 arg( m_hostInfo.hostName() ). 0109 arg( m_hostInfo.addresses().first().toString() ) ); 0110 0111 placemark->setCoordinate( lon * DEG2RAD, lat * DEG2RAD ); 0112 placemark->setVisualCategory(GeoDataPlacemark::Coordinate); 0113 placemarks << placemark; 0114 } 0115 0116 emit searchFinished( placemarks ); 0117 } 0118 0119 } // namespace Marble 0120 0121 #include "moc_HostipRunner.cpp"