Merge branch 'route_json'
authorlampehe-local <henri.lampela@ixonos.com>
Wed, 21 Jul 2010 12:22:39 +0000 (15:22 +0300)
committerlampehe-local <henri.lampela@ixonos.com>
Wed, 21 Jul 2010 12:22:39 +0000 (15:22 +0300)
Conflicts:
src/engine/engine.h
src/network/networkaccessmanager.cpp
src/network/networkaccessmanager.h

1  2 
src/engine/engine.cpp
src/map/mapengine.cpp
src/network/networkaccessmanager.cpp
src/network/networkaccessmanager.h
src/routing/routingservice.cpp

Simple merge
Simple merge
@@@ -127,6 -128,43 +127,33 @@@ QNetworkReply *NetworkAccessManager::ge
      }
  }
  
+ QNetworkReply *NetworkAccessManager::post(const QNetworkRequest &request, QByteArray &data,
+                                           bool onlineRequestsOnly)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     //Disconnected from network, queue request and return empty reply.
+     if (!m_networkHandler->isConnected()) {
+         m_requestQueue.append(request);
+         m_networkHandler->connect();
+         QNetworkReply *reply = new NetworkReply(request, this);
+         if (onlineRequestsOnly) {
+             ((NetworkReply*)reply)->setErrorCode(QNetworkReply::UnknownNetworkError);
+             emit finished(reply);
+         }
+         else {
+             m_offlineReplyQueue.insert(request.url().toString(), reply);
+         }
+         return reply;
+     }
+     //Connected, use normal post method.
+     else {
+         return m_networkAccessManagerPrivate->post(request, data);
+     }
+ }
 -NetworkAccessManager *NetworkAccessManager::instance()
 -{
 -    qDebug() << __PRETTY_FUNCTION__;
 -
 -    if (!m_instance)
 -        m_instance = new NetworkAccessManager();
 -
 -    return m_instance;
 -}
 -
  bool NetworkAccessManager::isConnected()
  {
      qDebug() << __PRETTY_FUNCTION__;
@@@ -61,10 -61,10 +61,10 @@@ public
      bool isConnected();
  
      /**
-     * @brief Makes request and return reply.
+     * @brief Makes get request and returns reply.
      *
      * @param request QNetworkRequest
 -    * @param onlineRequestOnly bool
 +    * @param onlineRequestsOnly true if does only requests when online, false otherwise
      * @return QNetworkReply
      */
      QNetworkReply *get(const QNetworkRequest &request, bool onlineRequestsOnly = false);
index 0000000,a613e35..8bedaf2
mode 000000,100644..100644
--- /dev/null
@@@ -1,0 -1,213 +1,213 @@@
+ /*
+    Situare - A location system for Facebook
+    Copyright (C) 2010  Ixonos Plc. Authors:
+       Henri Lampela - henri.lampela@ixonos.com
+       Sami Rämö - sami.ramo@ixonos.com
+    Situare is free software; you can redistribute it and/or
+    modify it under the terms of the GNU General Public License
+    version 2 as published by the Free Software Foundation.
+    Situare is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+    You should have received a copy of the GNU General Public License
+    along with Situare; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
+    USA.
+ */
+ #include <QDebug>
+ #include <QtGlobal>
+ #include <QStringList>
+ #include <QNetworkReply>
+ #include <QPointF>
+ #include <QCryptographicHash>
+ #if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+ #include <QDBusInterface>
+ #include <QDBusMessage>
+ #endif
+ #include "common.h"
+ #include "network/networkaccessmanager.h"
+ #include "parser.h"
+ #include "route.h"
+ #include "routesegment.h"
+ #include "routingservice.h"
+ // defines for IMEI retrieval via dbus
+ #define SIM_DBUS_SERVICE  "com.nokia.phone.SIM"
+ #define SIM_DBUS_PATH     "/com/nokia/phone/SIM/security"
+ #define SIM_DBUS_IFACE    "Phone.Sim.Security"
+ #define SIM_IMEI_REQ      "get_imei"
+ const int NO_ERROR = 0;
+ // cloudmade
+ const QString CLOUDMADE_AUTH_PART = "http://auth.cloudmade.com/token/";
+ const QString CLOUDMADE_API_KEY = "0cea0072adbf42ce823f4c78b974f12d";
+ RoutingService::RoutingService(QObject *parent)
+         : QObject(parent)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     m_pendingRequest.clear();
+     m_token.clear();
 -    m_networkManager = NetworkAccessManager::instance();
++    m_networkManager = new NetworkAccessManager(this);
+     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
+             this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
+ }
+ void RoutingService::parseRouteData(const QByteArray &jsonReply)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     QJson::Parser parser;
+     bool ok;
+     QVariantMap result = parser.parse (jsonReply, &ok).toMap();
+     if (!ok) {
+         emit error(ErrorContext::SITUARE, SituareError::INVALID_JSON);
+         return;
+     } else {
+         if(result.value("status").toInt() == NO_ERROR) {
+             QVariant routeSummary = result.value("route_summary");
+             QMap<QString, QVariant> routeSummaryMap = routeSummary.toMap();
+             Route route;
+             route.setEndPointName(routeSummaryMap["end_point"].toString());
+             route.setStartPointName(routeSummaryMap["start_point"].toString());
+             route.setTotalDistance(routeSummaryMap["total_distance"].toInt());
+             route.setTotalTime(routeSummaryMap["total_time"].toInt());
+             foreach(QVariant routeGeometry, result["route_geometry"].toList()) {
+                 QStringList list = routeGeometry.toStringList();
+                 route.appendGeometryPoint(QPointF(list.at(1).toDouble(), list.at(0).toDouble()));
+             }
+             foreach(QVariant routeInstructions, result["route_instructions"].toList()) {
+                 QStringList list = routeInstructions.toStringList();
+                 RouteSegment segment;
+                 segment.setInstruction(list.at(0));
+                 segment.setLength(list.at(1).toDouble());
+                 segment.setPositionIndex(list.at(2).toInt());
+                 segment.setTime(list.at(3).toInt());
+                 segment.setLengthCaption(list.at(4));
+                 segment.setEarthDirection(list.at(5));
+                 segment.setAzimuth(list.at(6).toDouble());
+                 if (list.count() == 8) {
+                     segment.setTurnType(list.at(7));
+                     segment.setTurnAngle(list.at(8).toDouble());
+                 }
+                 route.appendSegment(segment);
+             }
+             emit routeParsed(route);
+         }
+     }
+ }
+ void RoutingService::requestAuthorizationToken()
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     // create token request of format: http://auth.cloudmade.com/token/APIKEY?userid=UserID
+     // where APIKEY is our application specific key and userID is md5 hashed value of IMEI code
+     QString url = CLOUDMADE_AUTH_PART;
+     url.append(CLOUDMADE_API_KEY);
+     QString uidPart = "?userid=";
+     QByteArray rawData;
+ #ifdef Q_WS_MAEMO_5
+     // get the device IMEI code
+     QDBusInterface interface(SIM_DBUS_SERVICE, SIM_DBUS_PATH, SIM_DBUS_IFACE,
+                              QDBusConnection::systemBus());
+     QDBusMessage reply = interface.call(SIM_IMEI_REQ);
+     if (reply.type() == QDBusMessage::ErrorMessage)
+         qDebug() << reply.errorMessage();
+     else {
+         QList<QVariant> args = reply.arguments();
+         qDebug() << QString("Phone's IMEI: %1").arg(args.at(0).toString());
+         rawData = args.at(0).toByteArray();
+     }
+ #else
+     // for desktop we need to use login name
+     rawData.append(system("whoami"));
+ #endif
+     QCryptographicHash crypto(QCryptographicHash::Md5);
+     crypto.addData(rawData);
+     uidPart.append(crypto.result().toHex());
+     url.append(uidPart);
+     sendRequest(url);
+ }
+ void RoutingService::requestFinished(QNetworkReply *reply)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     if (m_currentRequests.contains(reply)) {
+         QByteArray replyArray = reply->readAll();
+         qDebug() << "Reply from: " << reply->url() << "reply " << replyArray;
+         if (reply->error()) {
+             emit error(ErrorContext::NETWORK, reply->error());
+         } else if(reply->url().toString().contains(CLOUDMADE_AUTH_PART)) {
+             m_token = replyArray;
+             m_pendingRequest.append(m_token);
+             sendRequest(m_pendingRequest);
+             m_pendingRequest.clear();
+         } else {
+             parseRouteData(replyArray);
+         }
+         m_currentRequests.removeAll(reply);
+         reply->deleteLater();
+     }
+ }
+ void RoutingService::requestRoute(QPointF from, QPointF to)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     QString url = "http://routes.cloudmade.com/";
+     url.append(CLOUDMADE_API_KEY);
+     url.append("/api/0.3/");
+     url.append(QString::number(from.x()) + "," + QString::number(from.y()) + ",");
+     url.append(QString::number(to.x()) + "," + QString::number(to.y()));
+     url.append("/car/fastest.js?lang=en&units=km&token=");
+     if(m_token.isEmpty()) {
+         m_pendingRequest.append(url);
+         requestAuthorizationToken();
+     } else {
+         url.append(m_token);
+         sendRequest(QUrl(url));
+     }
+ }
+ void RoutingService::sendRequest(const QUrl &url)
+ {
+     qDebug() << __PRETTY_FUNCTION__;
+     QNetworkRequest request;
+     request.setUrl(url);
+     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
+     QByteArray ba;
+     QNetworkReply *reply = m_networkManager->post(request, ba, false);
+     m_currentRequests.append(reply);
+ }