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"