LatitudeUpdater 0.1, fix the previous commit
authorDeveloper <developer@virtu.(none)>
Wed, 27 Jul 2011 16:16:38 +0000 (18:16 +0200)
committerDeveloper <developer@virtu.(none)>
Wed, 27 Jul 2011 16:16:38 +0000 (18:16 +0200)
61 files changed:
LatitudeUpdater-common.pri [new file with mode: 0644]
LatitudeUpdater-daemon.pro [new file with mode: 0644]
LatitudeUpdater-qml.pro [new file with mode: 0644]
LatitudeUpdater-widget.pro [new file with mode: 0644]
LatitudeUpdater.pro [new file with mode: 0644]
LatitudeUpdaterDaemon.desktop [new file with mode: 0644]
LatitudeUpdaterDaemon.png [new file with mode: 0644]
LatitudeUpdaterQML.desktop [new file with mode: 0644]
LatitudeUpdaterQML.png [new file with mode: 0644]
LatitudeUpdaterWidget.desktop [new file with mode: 0644]
LatitudeUpdaterWidget.png [new file with mode: 0644]
deployment.pri [new file with mode: 0644]
googlelatitude.cpp [new file with mode: 0644]
googlelatitude.h [new file with mode: 0644]
gpscontrol.cpp [new file with mode: 0644]
gpscontrol.h [new file with mode: 0644]
latitudedaemon.cpp [new file with mode: 0644]
latitudedaemon.h [new file with mode: 0644]
latitudeqml.cpp [new file with mode: 0644]
latitudeqml.h [new file with mode: 0644]
latitudewidget.cpp [new file with mode: 0644]
latitudewidget.h [new file with mode: 0644]
libkqoauth/QtKOAuth [new file with mode: 0644]
libkqoauth/kqoauthauthreplyserver.cpp [new file with mode: 0644]
libkqoauth/kqoauthauthreplyserver.h [new file with mode: 0644]
libkqoauth/kqoauthauthreplyserver_p.h [new file with mode: 0644]
libkqoauth/kqoauthglobals.h [new file with mode: 0644]
libkqoauth/kqoauthmanager.cpp [new file with mode: 0644]
libkqoauth/kqoauthmanager.h [new file with mode: 0644]
libkqoauth/kqoauthmanager_p.h [new file with mode: 0644]
libkqoauth/kqoauthrequest.cpp [new file with mode: 0644]
libkqoauth/kqoauthrequest.h [new file with mode: 0644]
libkqoauth/kqoauthrequest_1.cpp [new file with mode: 0644]
libkqoauth/kqoauthrequest_1.h [new file with mode: 0644]
libkqoauth/kqoauthrequest_p.h [new file with mode: 0644]
libkqoauth/kqoauthrequest_xauth.cpp [new file with mode: 0644]
libkqoauth/kqoauthrequest_xauth.h [new file with mode: 0644]
libkqoauth/kqoauthrequest_xauth_p.h [new file with mode: 0644]
libkqoauth/kqoauthutils.cpp [new file with mode: 0644]
libkqoauth/kqoauthutils.h [new file with mode: 0644]
main-daemon.cpp [new file with mode: 0644]
main-qml.cpp [new file with mode: 0644]
main-widget.cpp [new file with mode: 0644]
not_used/glupdater [new file with mode: 0644]
not_used/gpsmaemo5.cpp [new file with mode: 0644]
not_used/gpsmaemo5.h [new file with mode: 0644]
qml/MainPage.qml [new file with mode: 0644]
qml/main.qml [new file with mode: 0644]
qtc_packaging/debian_fremantle/README [new file with mode: 0644]
qtc_packaging/debian_fremantle/changelog [new file with mode: 0644]
qtc_packaging/debian_fremantle/compat [new file with mode: 0644]
qtc_packaging/debian_fremantle/control [new file with mode: 0644]
qtc_packaging/debian_fremantle/copyright [new file with mode: 0644]
qtc_packaging/debian_fremantle/rules [new file with mode: 0755]
qtc_packaging/debian_harmattan/README [new file with mode: 0644]
qtc_packaging/debian_harmattan/changelog [new file with mode: 0644]
qtc_packaging/debian_harmattan/compat [new file with mode: 0644]
qtc_packaging/debian_harmattan/control [new file with mode: 0644]
qtc_packaging/debian_harmattan/copyright [new file with mode: 0644]
qtc_packaging/debian_harmattan/rules [new file with mode: 0755]
resouses.qrc [new file with mode: 0644]

diff --git a/LatitudeUpdater-common.pri b/LatitudeUpdater-common.pri
new file mode 100644 (file)
index 0000000..08adb36
--- /dev/null
@@ -0,0 +1,53 @@
+QT += network
+CONFIG += mobility
+MOBILITY += location
+
+SOURCES += gpscontrol.cpp googlelatitude.cpp
+HEADERS += gpscontrol.h   googlelatitude.h
+
+contains(QT_CONFIG, maemo5) {
+    QT          += maemo5
+    CONFIG      += link_pkgconfig
+    PKGCONFIG   += glib-2.0 liblocation
+}
+
+INCLUDEPATH += libkqoauth
+SOURCES += libkqoauth/kqoauthauthreplyserver.cpp \
+libkqoauth/kqoauthrequest.cpp \
+libkqoauth/kqoauthmanager.cpp \
+libkqoauth/kqoauthrequest_xauth.cpp \
+libkqoauth/kqoauthrequest_1.cpp \
+libkqoauth/kqoauthutils.cpp
+
+PUBLIC_HEADERS += libkqoauth/kqoauthmanager.h \
+libkqoauth/kqoauthrequest.h \
+libkqoauth/kqoauthrequest_1.h \
+libkqoauth/kqoauthrequest_xauth.h \
+libkqoauth/kqoauthglobals.h
+
+PRIVATE_HEADERS += libkqoauth/kqoauthrequest_p.h \
+libkqoauth/kqoauthmanager_p.h \
+libkqoauth/kqoauthauthreplyserver.h \
+libkqoauth/kqoauthauthreplyserver_p.h \
+libkqoauth/kqoauthutils.h \
+libkqoauth/kqoauthrequest_xauth_p.h
+
+HEADERS += $$PUBLIC_HEADERS $$PRIVATE_HEADERS
+
+# Please do not modify the following two lines. Required for deployment.
+include(deployment.pri)
+qtcAddDeployment()
+
+OTHER_FILES += \
+    qtc_packaging/debian_harmattan/rules \
+    qtc_packaging/debian_harmattan/README \
+    qtc_packaging/debian_harmattan/copyright \
+    qtc_packaging/debian_harmattan/control \
+    qtc_packaging/debian_harmattan/compat \
+    qtc_packaging/debian_harmattan/changelog \
+    qtc_packaging/debian_fremantle/rules \
+    qtc_packaging/debian_fremantle/README \
+    qtc_packaging/debian_fremantle/copyright \
+    qtc_packaging/debian_fremantle/control \
+    qtc_packaging/debian_fremantle/compat \
+    qtc_packaging/debian_fremantle/changelog
diff --git a/LatitudeUpdater-daemon.pro b/LatitudeUpdater-daemon.pro
new file mode 100644 (file)
index 0000000..3550b2a
--- /dev/null
@@ -0,0 +1,7 @@
+TARGET = LatitudeUpdaterDaemon
+QT -= gui
+
+SOURCES += latitudedaemon.cpp main-daemon.cpp
+HEADERS += latitudedaemon.h
+
+include(LatitudeUpdater-common.pri)
diff --git a/LatitudeUpdater-qml.pro b/LatitudeUpdater-qml.pro
new file mode 100644 (file)
index 0000000..02e624e
--- /dev/null
@@ -0,0 +1,10 @@
+TARGET = LatitudeUpdaterQML
+QT += declarative
+
+SOURCES += latitudeqml.cpp main-qml.cpp
+HEADERS += latitudeqml.h
+
+RESOURCES += resouses.qrc
+OTHER_FILES += qml/main.qml qml/MainPage.qml
+
+include(LatitudeUpdater-common.pri)
diff --git a/LatitudeUpdater-widget.pro b/LatitudeUpdater-widget.pro
new file mode 100644 (file)
index 0000000..129419c
--- /dev/null
@@ -0,0 +1,7 @@
+TARGET = LatitudeUpdaterWidget
+
+SOURCES += latitudewidget.cpp main-widget.cpp
+HEADERS += latitudewidget.h
+
+include(LatitudeUpdater-common.pri)
+
diff --git a/LatitudeUpdater.pro b/LatitudeUpdater.pro
new file mode 100644 (file)
index 0000000..e104265
--- /dev/null
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS += LatitudeUpdater-daemon.pro
+SUBDIRS += LatitudeUpdater-qml.pro
+SUBDIRS += LatitudeUpdater-widget.pro
diff --git a/LatitudeUpdaterDaemon.desktop b/LatitudeUpdaterDaemon.desktop
new file mode 100644 (file)
index 0000000..901b786
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=true
+Name=LatitudeDaemon
+Exec=/opt/LatitudeUpdaterDaemon/bin/LatitudeUpdaterDaemon
+Icon=LatitudeUpdaterDaDaemon
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/LatitudeUpdaterDaemon.png b/LatitudeUpdaterDaemon.png
new file mode 100644 (file)
index 0000000..d98268f
Binary files /dev/null and b/LatitudeUpdaterDaemon.png differ
diff --git a/LatitudeUpdaterQML.desktop b/LatitudeUpdaterQML.desktop
new file mode 100644 (file)
index 0000000..5b1a295
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=LatitudeQML
+Exec=/opt/LatitudeUpdaterQML/bin/LatitudeUpdaterQML
+Icon=LatitudeUpdaterQML
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/LatitudeUpdaterQML.png b/LatitudeUpdaterQML.png
new file mode 100644 (file)
index 0000000..d98268f
Binary files /dev/null and b/LatitudeUpdaterQML.png differ
diff --git a/LatitudeUpdaterWidget.desktop b/LatitudeUpdaterWidget.desktop
new file mode 100644 (file)
index 0000000..85e2deb
--- /dev/null
@@ -0,0 +1,11 @@
+[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Application
+Terminal=false
+Name=LatitudeWidget
+Exec=/opt/LatitudeUpdaterWidget/bin/LatitudeUpdaterWidget
+Icon=LatitudeUpdaterWidget
+X-Window-Icon=
+X-HildonDesk-ShowInToolbar=true
+X-Osso-Type=application/x-executable
diff --git a/LatitudeUpdaterWidget.png b/LatitudeUpdaterWidget.png
new file mode 100644 (file)
index 0000000..d98268f
Binary files /dev/null and b/LatitudeUpdaterWidget.png differ
diff --git a/deployment.pri b/deployment.pri
new file mode 100644 (file)
index 0000000..f147e99
--- /dev/null
@@ -0,0 +1,114 @@
+# This file was generated by an application wizard of Qt Creator.
+# The code below handles deployment to Symbian and Maemo, aswell as copying
+# of the application data to shadow build directories on desktop.
+# It is recommended not to modify this file, since newer versions of Qt Creator
+# may offer an updated version of it.
+
+defineTest(qtcAddDeployment) {
+for(deploymentfolder, DEPLOYMENTFOLDERS) {
+    item = item$${deploymentfolder}
+    itemsources = $${item}.sources
+    $$itemsources = $$eval($${deploymentfolder}.source)
+    itempath = $${item}.path
+    $$itempath= $$eval($${deploymentfolder}.target)
+    export($$itemsources)
+    export($$itempath)
+    DEPLOYMENT += $$item
+}
+
+MAINPROFILEPWD = $$PWD
+
+symbian {
+    isEmpty(ICON):exists($${TARGET}.svg):ICON = $${TARGET}.svg
+    isEmpty(TARGET.EPOCHEAPSIZE):TARGET.EPOCHEAPSIZE = 0x20000 0x2000000
+} else:win32 {
+    copyCommand =
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
+        source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+        source = $$replace(source, /, \\)
+        sourcePathSegments = $$split(source, \\)
+        target = $$OUT_PWD/$$eval($${deploymentfolder}.target)/$$last(sourcePathSegments)
+        target = $$replace(target, /, \\)
+        !isEqual(source,$$target) {
+            !isEmpty(copyCommand):copyCommand += &&
+            isEqual(QMAKE_DIR_SEP, \\) {
+                copyCommand += $(COPY_DIR) \"$$source\" \"$$target\"
+            } else {
+                source = $$replace(source, \\\\, /)
+                target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+                target = $$replace(target, \\\\, /)
+                copyCommand += test -d \"$$target\" || mkdir -p \"$$target\" && cp -r \"$$source\" \"$$target\"
+            }
+        }
+    }
+    !isEmpty(copyCommand) {
+        copyCommand = @echo Copying application data... && $$copyCommand
+        copydeploymentfolders.commands = $$copyCommand
+        first.depends = $(first) copydeploymentfolders
+        export(first.depends)
+        export(copydeploymentfolders.commands)
+        QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+    }
+} else:unix {
+    maemo5 {
+        desktopfile.path = /usr/share/applications/hildon
+    } else {
+        desktopfile.path = /usr/share/applications
+        copyCommand =
+        for(deploymentfolder, DEPLOYMENTFOLDERS) {
+            source = $$MAINPROFILEPWD/$$eval($${deploymentfolder}.source)
+            source = $$replace(source, \\\\, /)
+            macx {
+                target = $$OUT_PWD/$${TARGET}.app/Contents/Resources/$$eval($${deploymentfolder}.target)
+            } else {
+                target = $$OUT_PWD/$$eval($${deploymentfolder}.target)
+            }
+            target = $$replace(target, \\\\, /)
+            sourcePathSegments = $$split(source, /)
+            targetFullPath = $$target/$$last(sourcePathSegments)
+            !isEqual(source,$$targetFullPath) {
+                !isEmpty(copyCommand):copyCommand += &&
+                copyCommand += $(MKDIR) \"$$target\"
+                copyCommand += && $(COPY_DIR) \"$$source\" \"$$target\"
+            }
+        }
+        !isEmpty(copyCommand) {
+            copyCommand = @echo Copying application data... && $$copyCommand
+            copydeploymentfolders.commands = $$copyCommand
+            first.depends = $(first) copydeploymentfolders
+            export(first.depends)
+            export(copydeploymentfolders.commands)
+            QMAKE_EXTRA_TARGETS += first copydeploymentfolders
+        }
+    }
+    installPrefix = /opt/$${TARGET}
+    for(deploymentfolder, DEPLOYMENTFOLDERS) {
+        item = item$${deploymentfolder}
+        itemfiles = $${item}.files
+        $$itemfiles = $$eval($${deploymentfolder}.source)
+        itempath = $${item}.path
+        $$itempath = $${installPrefix}/$$eval($${deploymentfolder}.target)
+        export($$itemfiles)
+        export($$itempath)
+        INSTALLS += $$item
+    }
+    icon.files = $${TARGET}.png
+    icon.path = /usr/share/icons/hicolor/64x64/apps
+    desktopfile.files = $${TARGET}.desktop
+    target.path = $${installPrefix}/bin
+    export(icon.files)
+    export(icon.path)
+    export(desktopfile.files)
+    export(desktopfile.path)
+    export(target.path)
+    INSTALLS += desktopfile icon target
+}
+
+export (ICON)
+export (INSTALLS)
+export (DEPLOYMENT)
+export (TARGET.EPOCHEAPSIZE)
+export (TARGET.CAPABILITY)
+export (LIBS)
+export (QMAKE_EXTRA_TARGETS)
+}
diff --git a/googlelatitude.cpp b/googlelatitude.cpp
new file mode 100644 (file)
index 0000000..81b1d5b
--- /dev/null
@@ -0,0 +1,180 @@
+#include "googlelatitude.h"
+#include <QtNetwork/QNetworkConfigurationManager>
+
+GoogleLatitude::GoogleLatitude(QObject *parent) :
+    QObject(parent),
+    OauthSettings(this),
+    OAuthGetRequestToken("https://www.google.com/accounts/OAuthGetRequestToken"),
+    OAuthAuthorizeToken("https://www.google.com/accounts/OAuthAuthorizeToken"),
+    OAuthGetAccessToken("https://www.google.com/accounts/OAuthGetAccessToken"),
+    CurrentLocation("https://www.googleapis.com/latitude/v1/currentLocation"),
+    UserAuthorization(""),
+    ConsumerKey("1062862865804.apps.googleusercontent.com"),
+    ConsumerSecretKey("EYQaRaUJ9Fznw8mPMor660Kx"),
+    CurrentLatitude(0),
+    CurrentLongitude(0),
+    CurrentAccuracy(0) {
+    qDebug() << "* GoogleLatitude::GoogleLatitude";
+    OauthRequest = new KQOAuthRequest(this);
+    OauthManager = new KQOAuthManager(this);
+    GoogleOauthAdditional.insert("scope", "https://www.googleapis.com/auth/latitude");
+    GoogleOauthAdditional.insert("xoauth_displayname", "LatitudeUpdater");
+
+    connect(OauthManager, SIGNAL(temporaryTokenReceived(QString,QString)),
+            this, SLOT(onTemporaryTokenReceived(QString, QString)));
+
+    connect(OauthManager, SIGNAL(authorizationReceived(QString,QString)),
+            this, SLOT(onAuthorizationReceived(QString, QString)));
+
+    connect(OauthManager, SIGNAL(accessTokenReceived(QString,QString)),
+            this, SLOT(onAccessTokenReceived(QString,QString)));
+
+    connect(OauthManager, SIGNAL(requestReady(QByteArray)),
+            this, SLOT(onRequestReady(QByteArray)));
+
+    connect(OauthManager, SIGNAL(authorizedRequestDone()),
+            this, SLOT(onAuthorizedRequestDone()));
+
+    connect(this, SIGNAL(gotToken()),
+            this, SLOT(getCurrentLocation()));
+
+    connect(this, SIGNAL(notToken()),
+            this, SLOT(onNotToken()));
+
+    connect(this, SIGNAL(gotToken()),
+            this, SLOT(onGotToken()));
+
+    connect(this, SIGNAL(needAuth()),
+            this, SLOT(onNeedAuth()));
+}
+
+GoogleLatitude::~GoogleLatitude() {
+    qDebug() << "* GoogleLatitude::~GoogleLatitude";
+    delete OauthManager;
+    delete OauthRequest;
+}
+
+void GoogleLatitude::getAccess() {
+    qDebug() << "* GoogleLatitude::getAccess";
+    if ( OauthSettings.value("oauth_token").isNull() || OauthSettings.value("oauth_token_secret").isNull() ) {
+        OauthRequest->clearRequest();
+        OauthRequest->initRequest(KQOAuthRequest::TemporaryCredentials, OAuthGetRequestToken);
+        OauthRequest->setConsumerKey(ConsumerKey);
+        OauthRequest->setConsumerSecretKey(ConsumerSecretKey);
+        OauthRequest->setAdditionalParameters(GoogleOauthAdditional);
+        OauthManager->setHandleUserAuthorization(true);
+        OauthRequest->setHttpMethod(KQOAuthRequest::POST);
+        OauthManager->executeRequest(OauthRequest);
+    } else {
+        emit gotToken();
+    }
+}
+
+void GoogleLatitude::getCurrentLocation() {
+    qDebug() << "* GoogleLatitude::getCurrentLocation";
+    if ( OauthSettings.value("oauth_token").isNull() || OauthSettings.value("oauth_token_secret").isNull() ) {
+        emit notToken();
+    } else {
+        OauthRequest->clearRequest();
+        OauthRequest->initRequest(KQOAuthRequest::AuthorizedRequest, CurrentLocation);
+        OauthRequest->setToken(OauthSettings.value("oauth_token").toString());
+        OauthRequest->setTokenSecret(OauthSettings.value("oauth_token_secret").toString());
+        OauthRequest->setConsumerKey(ConsumerKey);
+        OauthRequest->setConsumerSecretKey(ConsumerSecretKey);
+        OauthRequest->setHttpMethod(KQOAuthRequest::GET);
+        OauthManager->executeRequest(OauthRequest);
+    }
+}
+
+void GoogleLatitude::sendCurrentLocation() {
+    qDebug() << "* GoogleLatitude::sendCurrentLocation";
+    if (OauthSettings.value("oauth_token").isNull() || OauthSettings.value("oauth_token_secret").isNull()) {
+        emit notToken();
+    } else {
+        if (abs(CurrentLatitude) <= 0.01) return;
+        if (abs(CurrentLongitude) <= 0.01) return;
+        if (abs(CurrentAccuracy) <= 0.01) return;
+
+        if (!OauthSettings.value("net_auto").toBool()) {
+            QNetworkConfigurationManager mgr;
+            if (!mgr.isOnline()) {
+                qDebug() << "* GoogleLatitude::sendCurrentLocation" << "offline";
+                return;
+            }
+        }
+
+        QByteArray json_location;
+        json_location = "{\"data\": {\"kind\":\"latitude#location\",";
+        json_location += QString("\"latitude\":%1,").arg(CurrentLatitude);
+        json_location += QString("\"longitude\":%1,").arg(CurrentLongitude);
+        json_location += QString("\"accuracy\":%1").arg(CurrentAccuracy);
+        json_location += "}}";
+        qDebug() << "json_location" <<  json_location;
+
+        OauthRequest->clearRequest();
+        OauthRequest->initRequest(KQOAuthRequest::AuthorizedRequest, CurrentLocation);
+        OauthRequest->setToken(OauthSettings.value("oauth_token").toString());
+        OauthRequest->setTokenSecret(OauthSettings.value("oauth_token_secret").toString());
+        OauthRequest->setConsumerKey(ConsumerKey);
+        OauthRequest->setConsumerSecretKey(ConsumerSecretKey);
+        OauthRequest->setHttpMethod(KQOAuthRequest::POST);
+        OauthRequest->setContentType("application/json");
+        OauthRequest->setRawData(json_location);
+        OauthManager->executeRequest(OauthRequest);
+    }
+}
+
+void GoogleLatitude::setCurrentLocation(double lat, double lon, double acc) {
+    qDebug() << "* GoogleLatitude::setCurrentLocation" << lat << lon << acc;
+    CurrentLatitude = lat;
+    CurrentLongitude = lon;
+    CurrentAccuracy = acc;
+}
+
+QUrl GoogleLatitude::getUserAuthorization() {
+    qDebug() << "* GoogleLatitude::getUserAuthorization";
+    return UserAuthorization;
+}
+
+void GoogleLatitude::setAutoConnect(bool status) {
+    qDebug() << "* GoogleLatitude::setAutoConnect" << status;
+    OauthSettings.setValue("net_auto", status);
+}
+
+bool GoogleLatitude::getAutoConnect() {
+    qDebug() << "* GoogleLatitude::getAutoConnect";
+    return OauthSettings.value("net_auto").toBool();
+}
+
+void GoogleLatitude::onTemporaryTokenReceived(QString temporaryToken, QString temporaryTokenSecret) {
+    qDebug() << "* GoogleLatitude::onTemporaryTokenReceived" << temporaryToken << temporaryTokenSecret;
+    if( OauthManager->lastError() == KQOAuthManager::NoError) {
+        UserAuthorization = OauthManager->getUserAuthorization(OAuthAuthorizeToken);
+        qDebug() << "* GoogleLatitude::onTemporaryTokenReceived" << "UserAuthorization" << UserAuthorization;
+        emit needAuth();
+    }
+}
+
+void GoogleLatitude::onAuthorizationReceived(QString token, QString verifier) {
+    qDebug() << "* GoogleLatitude::onAuthorizationReceived" << token << verifier;
+    OauthManager->getUserAccessTokens(OAuthGetAccessToken);
+    if(OauthManager->lastError() != KQOAuthManager::NoError) {
+        emit notToken();
+    }
+}
+
+void GoogleLatitude::onAccessTokenReceived(QString token, QString tokenSecret) {
+    qDebug() << "* GoogleLatitude::onAccessTokenReceived" << token << tokenSecret;
+    OauthSettings.setValue("oauth_token", token);
+    OauthSettings.setValue("oauth_token_secret", tokenSecret);
+    emit gotToken();
+}
+
+void GoogleLatitude::onRequestReady(QByteArray response) {
+    qDebug() << "* GoogleLatitude::onRequestReady" << response;
+    if (response.contains("Invalid Credentials") ) {
+        OauthSettings.remove("oauth_token");
+        OauthSettings.remove("oauth_token_secret");
+        emit notToken();
+    }
+}
diff --git a/googlelatitude.h b/googlelatitude.h
new file mode 100644 (file)
index 0000000..1f99a24
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef GOOGLELATITUDE_H
+#define GOOGLELATITUDE_H
+
+#include <QtCore/QObject>
+#include <QtCore/QSettings>
+#include <QtCore/QtDebug>
+#include <QtKOAuth>
+
+class GoogleLatitude : public QObject {
+    Q_OBJECT
+
+public:
+    GoogleLatitude(QObject *parent = 0);
+    ~GoogleLatitude();
+
+public slots:
+    void getAccess();
+    void getCurrentLocation();
+    void sendCurrentLocation();
+    void setCurrentLocation(double la, double lo, double ac);
+    QUrl getUserAuthorization();
+    void setAutoConnect(bool status);
+    bool getAutoConnect();
+
+private slots:
+    void onTemporaryTokenReceived(QString temporaryToken, QString temporaryTokenSecret);
+    void onAuthorizationReceived(QString token, QString verifier);
+    void onAccessTokenReceived(QString token, QString tokenSecret);
+    void onRequestReady(QByteArray response);
+    void onAuthorizedRequestDone() { qDebug() << "* GoogleLatitude::onAuthorizedRequestDone"; }
+    void onNotToken() { qDebug() << "* GoogleLatitude::onNotToken"; }
+    void onGotToken() { qDebug() << "* GoogleLatitude::onGotToken"; }
+    void onNeedAuth() { qDebug() << "* GoogleLatitude::onNeedAuth"; }
+
+signals:
+    void notToken();
+    void gotToken();
+    void needAuth();
+
+private:
+    QSettings OauthSettings;
+    QUrl OAuthGetRequestToken;
+    QUrl OAuthAuthorizeToken;
+    QUrl OAuthGetAccessToken;
+    QUrl CurrentLocation;
+    QUrl UserAuthorization;
+    KQOAuthParameters GoogleOauthAdditional;
+    QString ConsumerKey;
+    QString ConsumerSecretKey;
+    double CurrentLatitude;
+    double CurrentLongitude;
+    double CurrentAccuracy;
+    KQOAuthManager *OauthManager;
+    KQOAuthRequest *OauthRequest;
+};
+
+#endif // GOOGLELATITUDE_H
diff --git a/gpscontrol.cpp b/gpscontrol.cpp
new file mode 100644 (file)
index 0000000..8df1cc1
--- /dev/null
@@ -0,0 +1,127 @@
+#include "gpscontrol.h"
+#include <QtNetwork/QNetworkConfigurationManager>
+
+GpsControl::GpsControl(QObject *parent) :
+    QObject(parent),
+    GpsSettings(this),
+    GpsSource(QGeoPositionInfoSource::createDefaultSource(this)),
+    GpsPosition(),
+    GpsTimeout(this),
+    GpsInterval(this) {
+    qDebug() << "* GpsControl::GpsControl";
+
+    GpsTimeout.setSingleShot(true);
+    GpsInterval.setSingleShot(true);
+
+    setPositioningMethod(GpsSettings.value("gps_method", "cell").toString());
+    setTimeOut(GpsSettings.value("gps_timeout", 60).toInt());
+    setInterval(GpsSettings.value("gps_interval", 15*60).toInt());
+
+    if (!GpsSource) qDebug() << "* GpsControl::GpsControl" << "Not GpsSource";
+
+    connect(GpsSource, SIGNAL(positionUpdated(QGeoPositionInfo)),
+            this, SLOT(setCurrentLocation(QGeoPositionInfo)));
+
+    connect(this, SIGNAL(gotUpdate()),
+            this, SLOT(onGotUpdate()));
+
+    connect(this, SIGNAL(gotFix()),
+            this, SLOT(onGotFix()));
+
+}
+
+void GpsControl::setTimeOut(int sec) {
+    qDebug() << "* GpsControl::setTimeOut" << sec;
+    GpsSettings.setValue("gps_timeout", sec);
+}
+
+int GpsControl::getTimeOut() {
+    qDebug() << "* GpsControl::getTimeOut";
+    return GpsSettings.value("gps_timeout").toInt();
+}
+
+void GpsControl::setInterval(int sec) {
+    qDebug() << "* GpsControl::setInterval" << sec;
+    GpsSettings.setValue("gps_interval", sec);
+}
+
+int GpsControl::getInterval() {
+    qDebug() << "* GpsControl::getInterval";
+    return GpsSettings.value("gps_interval").toInt();
+}
+
+void GpsControl::setPositioningMethod(QString method) {
+    qDebug() << "* GpsControl::setPositioningMethod" << method;
+    if (method == "gps") {
+        GpsSettings.setValue("gps_method", method);
+        if (GpsSource) GpsSource->setPreferredPositioningMethods(QGeoPositionInfoSource::SatellitePositioningMethods);
+    }
+    if (method == "cell") {
+        GpsSettings.setValue("gps_method", method);
+        if (GpsSource) GpsSource->setPreferredPositioningMethods(QGeoPositionInfoSource::NonSatellitePositioningMethods);
+    }
+    if (method == "all") {
+        GpsSettings.setValue("gps_method", method);
+        if (GpsSource) GpsSource->setPreferredPositioningMethods(QGeoPositionInfoSource::AllPositioningMethods);
+    }
+}
+
+void GpsControl::startUpdates() {
+    qDebug() << "* GpsControl::start";
+    if (!GpsSettings.value("net_auto").toBool()) {
+        QNetworkConfigurationManager mgr;
+        if (!mgr.isOnline()) {
+            qDebug() << "* GpsControl::start" << "offline";
+            return;
+        }
+    }
+
+    if (!GpsSource) return;
+
+    GpsTimeout.singleShot(GpsSettings.value("gps_timeout").toInt()*1000, this, SLOT(stopUpdates()));
+    GpsInterval.singleShot(GpsSettings.value("gps_interval").toInt()*1000, this, SLOT(startUpdates()));
+    GpsSource->startUpdates();
+}
+
+void GpsControl::stopUpdates(bool force) {
+    qDebug() << "* GpsControl::stopUpdates" << force;
+    if (!GpsSource) return;
+    GpsSource->stopUpdates();
+
+    if (force) {
+        GpsTimeout.stop();
+        GpsInterval.stop();
+    } else {
+        if (GpsSource->lastKnownPosition(GpsSettings.value("gps_method") == "gps"?true:false).isValid() ) {
+            emit gotFix();
+        }
+    }
+}
+
+double GpsControl::getCurrentLatitude() {
+    qDebug() << "* GpsControl::getCurrentLatitude";
+    return GpsPosition.coordinate().latitude();
+}
+
+double GpsControl::getCurrentLongitude() {
+    qDebug() << "* GpsControl::getCurrentLongitude";
+    return GpsPosition.coordinate().longitude();
+}
+
+double GpsControl::getCurrentAccuracy() {
+    qDebug() << "* GpsControl::getCurrentAccuracy";
+    return GpsPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
+}
+
+unsigned int GpsControl::getCurrentTimestamp() {
+    qDebug() << "* GpsControl::getCurrentTimestamp";
+    return GpsPosition.timestamp().toTime_t();
+}
+
+void GpsControl::setCurrentLocation(QGeoPositionInfo pos) {
+    qDebug() << "* GpsControl::setCurrentLocation" << pos;
+    if (pos.isValid()) {
+        GpsPosition = pos;
+        emit gotUpdate();
+    }
+}
diff --git a/gpscontrol.h b/gpscontrol.h
new file mode 100644 (file)
index 0000000..7a7f6f5
--- /dev/null
@@ -0,0 +1,49 @@
+#ifndef GPSCONTROL_H
+#define GPSCONTROL_H
+
+#include <QObject>
+#include <QtCore/QDebug>
+#include <QtCore/QSettings>
+#include <QtCore/QTimer>
+#include <QtLocation/QGeoPositionInfo>
+#include <QtLocation/QGeoPositionInfoSource>
+
+using namespace QtMobility;
+
+class GpsControl : public QObject {
+    Q_OBJECT
+public:
+    GpsControl(QObject *parent = 0);
+
+signals:
+    void gotUpdate();
+    void gotFix();
+
+public slots:
+    void setTimeOut(int sec);
+    int getTimeOut();
+    void setInterval(int sec);
+    int getInterval();
+    void setPositioningMethod(QString method);
+    QString getPositioningMethod() {return GpsSettings.value("gps_method").toString();}
+    void startUpdates();
+    void stopUpdates(bool force = false);
+    double getCurrentLatitude();
+    double getCurrentLongitude();
+    double getCurrentAccuracy();
+    unsigned int getCurrentTimestamp();
+
+private slots:
+    void setCurrentLocation(QGeoPositionInfo pos);
+    void onGotUpdate() { qDebug() << "* GpsControl::ongotUpdate"; }
+    void onGotFix() { qDebug() << "* GpsControl::ongotFix"; }
+
+private:
+    QSettings GpsSettings;
+    QGeoPositionInfoSource *GpsSource;
+    QGeoPositionInfo GpsPosition;
+    QTimer GpsTimeout;
+    QTimer GpsInterval;
+};
+
+#endif // GPSCONTROL_H
diff --git a/latitudedaemon.cpp b/latitudedaemon.cpp
new file mode 100644 (file)
index 0000000..35a31e6
--- /dev/null
@@ -0,0 +1,17 @@
+#include "latitudedaemon.h"
+
+LatitudeDaemon::LatitudeDaemon(QObject *parent) :
+    QObject(parent),
+    latitude(this),
+    gps(this) {
+    qDebug() << "* LatitudeDaemon::LatitudeDaemon";
+
+    connect(&latitude, SIGNAL(gotToken()), this, SLOT(gl_GotToken()) );
+    connect(&latitude, SIGNAL(notToken()), this, SLOT(gl_NotToken()) );
+    connect(&latitude, SIGNAL(needAuth()), this, SLOT(gl_needAuth()) );
+
+    connect(&gps, SIGNAL(gotUpdate()), this, SLOT(get_gps()) );
+    connect(&gps, SIGNAL(gotFix()), this, SLOT(set_latitude()) );
+
+    latitude.getAccess();
+}
diff --git a/latitudedaemon.h b/latitudedaemon.h
new file mode 100644 (file)
index 0000000..d18a673
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef LATITUDEDAEMON_H
+#define LATITUDEDAEMON_H
+
+#include <QObject>
+#include <QtCore/QCoreApplication>
+#include "googlelatitude.h"
+#include "gpscontrol.h"
+
+class LatitudeDaemon : public QObject {
+    Q_OBJECT
+public:
+    LatitudeDaemon(QObject *parent = 0);
+signals:
+
+public slots:
+
+private slots:
+    void gl_GotToken() {
+        qDebug() << "LatitudeDaemon::gl_GotToken()";
+        gps.startUpdates();
+    }
+    void gl_NotToken() {
+        qDebug() << "LatitudeDaemon::gl_NotToken()";
+        QCoreApplication::exit();
+    }
+    void gl_needAuth() {
+        qDebug() << "LatitudeDaemon::gl_needAuth()";
+        QCoreApplication::exit();
+    }
+    void get_gps() {
+        qDebug() << "LatitudeDaemon::get_gps()"
+                 << gps.getCurrentLatitude()
+                 << gps.getCurrentLongitude()
+                 << gps.getCurrentAccuracy()
+                 << gps.getCurrentTimestamp();
+    }
+    void set_latitude() {
+        qDebug() << "LatitudeDaemon::set_latitude()"
+                 << gps.getCurrentLatitude()
+                 << gps.getCurrentLongitude()
+                 << gps.getCurrentAccuracy()
+                 << gps.getCurrentTimestamp();
+        latitude.setCurrentLocation(gps.getCurrentLatitude(),
+                                    gps.getCurrentLongitude(),
+                                    gps.getCurrentAccuracy());
+        latitude.sendCurrentLocation();
+    }
+
+private:
+    GoogleLatitude latitude;
+    GpsControl gps;
+};
+
+#endif // LATITUDEDAEMON_H
diff --git a/latitudeqml.cpp b/latitudeqml.cpp
new file mode 100644 (file)
index 0000000..0dd7af1
--- /dev/null
@@ -0,0 +1,15 @@
+#include "latitudeqml.h"
+#include <QtDeclarative/QDeclarativeContext>
+
+LatitudeQML::LatitudeQML(QDeclarativeView *parent) :
+    QDeclarativeView(parent),
+    latitude(this),
+    gps(this) {
+    qDebug() << "* LatitudeQML::LatitudeQML";
+
+    rootContext()->setContextProperty("latitude", &latitude);
+    rootContext()->setContextProperty("gps", &gps);
+    setSource(QUrl("qrc:/qml/main.qml"));
+
+    latitude.getAccess();
+}
diff --git a/latitudeqml.h b/latitudeqml.h
new file mode 100644 (file)
index 0000000..13c8b27
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef LatitudeQML_H
+#define LatitudeQML_H
+
+#include <QObject>
+#include <QtDeclarative/QDeclarativeView>
+#include "googlelatitude.h"
+#include "gpscontrol.h"
+
+class LatitudeQML : public QDeclarativeView {
+    Q_OBJECT
+public:
+    LatitudeQML(QDeclarativeView *parent = 0);
+
+signals:
+
+public slots:
+
+private slots:
+
+private:
+    GoogleLatitude latitude;
+    GpsControl gps;
+};
+
+#endif // LatitudeQML_H
diff --git a/latitudewidget.cpp b/latitudewidget.cpp
new file mode 100644 (file)
index 0000000..f81b786
--- /dev/null
@@ -0,0 +1,136 @@
+#include "latitudewidget.h"
+
+LatitudeGUI::LatitudeGUI(QWidget *parent) :
+    QWidget(parent),
+    latitude(this),
+    gps(this) {
+    qDebug() << "* LatitudeGUI::LatitudeGUI";
+    setWindowTitle(tr("LatitudeUpdater"));
+
+    // row 1
+    layout_row1 = new QHBoxLayout();
+    do_oauth = new QPushButton("Auth");
+    do_start = new QPushButton("Start");
+    do_stop = new QPushButton("Stop");
+    layout_row1->addWidget(do_oauth);
+    layout_row1->addWidget(do_start);
+    layout_row1->addWidget(do_stop);
+
+    do_oauth->setDisabled(true);
+    do_start->setDisabled(true);
+    do_stop->setDisabled(true);
+
+    connect(do_oauth, SIGNAL(clicked()), this, SLOT(gl_webauth()) );
+    connect(do_start, SIGNAL(clicked()), this, SLOT(gps_start()) );
+    connect(do_stop, SIGNAL(clicked()), this, SLOT(gps_stop()) );
+
+    connect(&latitude, SIGNAL(gotToken()), this, SLOT(gl_GotToken()) );
+    connect(&latitude, SIGNAL(notToken()), this, SLOT(gl_NotToken()) );
+    connect(&latitude, SIGNAL(needAuth()), this, SLOT(gl_needAuth()) );
+
+    latitude.getAccess();
+
+    // row 2
+    layout_row2 = new QHBoxLayout();
+    pos_label = new QLabel("Position");
+    pos_lat = new QLineEdit("lat");
+    pos_lon = new QLineEdit("lon");
+    pos_acc = new QLineEdit("acc");
+    pos_tis = new QLineEdit("tis");
+
+    pos_lat->setReadOnly(true);
+    pos_lon->setReadOnly(true);
+    pos_acc->setReadOnly(true);
+    pos_tis->setReadOnly(true);
+
+    layout_row2->addWidget(pos_label);
+    layout_row2->addWidget(pos_lat);
+    layout_row2->addWidget(pos_lon);
+    layout_row2->addWidget(pos_acc);
+    layout_row2->addWidget(pos_tis);
+
+    connect(&gps, SIGNAL(gotUpdate()), this, SLOT(get_gps()) );
+    connect(&gps, SIGNAL(gotFix()), this, SLOT(set_latitude()) );
+
+    // row 3
+    layout_row3 = new QHBoxLayout();
+    gps_group = new QButtonGroup();
+    gps_method = new QLabel("Method");
+    gps_cell = new QRadioButton("Cell Tower");
+    gps_both = new QRadioButton("Both");
+    gps_agps = new QRadioButton("Only Gps");
+    gps_group->addButton(gps_cell);
+    gps_group->addButton(gps_both);
+    gps_group->addButton(gps_agps);
+    layout_row3->addWidget(gps_method);
+    layout_row3->addWidget(gps_cell);
+    layout_row3->addWidget(gps_both);
+    layout_row3->addWidget(gps_agps);
+
+    if ( gps.getPositioningMethod() == "gps" ) gps_agps->setChecked(true);
+    if ( gps.getPositioningMethod() == "cell" ) gps_cell->setChecked(true);
+    if ( gps.getPositioningMethod() == "all" ) gps_both->setChecked(true);
+
+    connect(gps_cell, SIGNAL(clicked()), this, SLOT(set_method()) );
+    connect(gps_both, SIGNAL(clicked()), this, SLOT(set_method()) );
+    connect(gps_agps, SIGNAL(clicked()), this, SLOT(set_method()) );
+
+    // row 4
+    layout_row4 = new QHBoxLayout();
+    gps_to_label = new QLabel("Time Out");
+    gps_to_slider = new QSlider(Qt::Horizontal);
+    gps_to_slider->setSingleStep(5);
+    gps_to_slider->setRange(5, 120);
+    gps_to_slider->setValue(gps.getTimeOut());
+    gps_to_slider_value = new QLabel(QString("%1 sec.").arg(gps_to_slider->value()));
+    layout_row4->addWidget(gps_to_label);
+    layout_row4->addWidget(gps_to_slider);
+    layout_row4->addWidget(gps_to_slider_value);
+
+    connect(gps_to_slider, SIGNAL(valueChanged(int)), this, SLOT(set_to(int)) );
+
+    // row 5
+    layout_row5 = new QHBoxLayout();
+    gps_i_label = new QLabel("Interval");
+
+    gps_i_slider = new QSlider(Qt::Horizontal);
+    gps_i_slider->setSingleStep(5);
+    gps_i_slider->setRange(5, 60);
+    gps_i_slider->setValue(gps.getInterval()/60);
+    gps_i_slider_value = new QLabel(QString("%1 min.").arg(gps_i_slider->value()));
+    layout_row5->addWidget(gps_i_label);
+    layout_row5->addWidget(gps_i_slider);
+    layout_row5->addWidget(gps_i_slider_value);
+
+    connect(gps_i_slider, SIGNAL(valueChanged(int)), this, SLOT(set_i(int)) );
+
+    // row 6
+    layout_row6 = new QHBoxLayout();
+    gps_ac_group = new QButtonGroup();
+    gps_ac_label = new QLabel("Auto Connect");
+    gps_ac_yes = new QRadioButton("Yes");
+    gps_ac_not = new QRadioButton("No");
+    gps_ac_group->addButton(gps_ac_yes);
+    gps_ac_group->addButton(gps_ac_not);
+    layout_row6->addWidget(gps_ac_label);
+    layout_row6->addWidget(gps_ac_yes);
+    layout_row6->addWidget(gps_ac_not);
+
+    if ( latitude.getAutoConnect() == true ) gps_ac_yes->setChecked(true);
+    if ( latitude.getAutoConnect() == false ) gps_ac_not->setChecked(true);
+
+    connect(gps_ac_yes, SIGNAL(clicked()), this, SLOT(set_ac_yes()) );
+    connect(gps_ac_not, SIGNAL(clicked()), this, SLOT(set_ac_not()) );
+
+    // gui
+    layout_gui = new QVBoxLayout();
+    layout_gui->addLayout(layout_row1);
+    layout_gui->addLayout(layout_row2);
+    layout_gui->addLayout(layout_row3);
+    layout_gui->addLayout(layout_row4);
+    layout_gui->addLayout(layout_row5);
+    layout_gui->addLayout(layout_row6);
+
+    setLayout(layout_gui);
+}
+
diff --git a/latitudewidget.h b/latitudewidget.h
new file mode 100644 (file)
index 0000000..26bb749
--- /dev/null
@@ -0,0 +1,142 @@
+#ifndef LATITUDEGUI_H
+#define LATITUDEGUI_H
+
+#include <QtGui/QWidget>
+#include <QtGui/QPushButton>
+#include <QtGui/QLineEdit>
+#include <QtGui/QLabel>
+#include <QtGui/QVBoxLayout>
+#include <QtGui/QHBoxLayout>
+#include <QtGui/QRadioButton>
+#include <QtGui/QButtonGroup>
+#include <QtGui/QSlider>
+#include <QtGui/QDesktopServices>
+#include "googlelatitude.h"
+#include "gpscontrol.h"
+
+class LatitudeGUI : public QWidget {
+    Q_OBJECT
+public:
+    LatitudeGUI(QWidget *parent = 0);
+
+signals:
+
+public slots:
+
+private slots:
+    void gl_GotToken() {
+        qDebug() << "LatitudeGUI::gl_GotToken";
+        do_oauth->setDisabled(true);
+        do_start->setEnabled(true);
+        do_stop->setDisabled(true);
+    }
+    void gl_NotToken() {
+        qDebug() << "LatitudeGUI::gl_NotToken";
+        do_oauth->setEnabled(true);
+        do_start->setDisabled(true);
+        do_stop->setDisabled(true);
+        gps.stopUpdates(true);
+    }
+    void gl_needAuth() {
+        qDebug() << "LatitudeGUI::gl_needAuth";
+        do_oauth->setEnabled(true);
+    }
+    void gl_webauth() {
+        qDebug() << "LatitudeGUI::gl_webauth";
+        QDesktopServices::openUrl(latitude.getUserAuthorization());
+    }
+    void gps_start() {
+        qDebug() << "LatitudeGUI::gps_start";
+        do_start->setDisabled(true);
+        do_stop->setEnabled(true);
+        gps.startUpdates();
+    }
+    void gps_stop() {
+        qDebug() << "LatitudeGUI::gps_stop";
+        do_start->setEnabled(true);
+        do_stop->setDisabled(true);
+        gps.stopUpdates(true);
+    }
+    void get_gps()  {
+        qDebug() << "LatitudeGUI::get_gps";
+        pos_lat->setText(QString("%1").arg(gps.getCurrentLatitude()));
+        pos_lon->setText(QString("%1").arg(gps.getCurrentLongitude()));
+        pos_acc->setText(QString("%1").arg(gps.getCurrentAccuracy()));
+        pos_tis->setText(QString("%1").arg(gps.getCurrentTimestamp()));
+    }
+    void set_latitude() {
+        qDebug() << "LatitudeGUI::set_latitude";
+        latitude.setCurrentLocation(pos_lat->text().toDouble(),
+                                    pos_lon->text().toDouble(),
+                                    pos_acc->text().toDouble());
+        latitude.sendCurrentLocation();
+    }
+    void set_method() {
+        qDebug() << "LatitudeGUI::set_method";
+        if (gps_cell->isChecked()) gps.setPositioningMethod("cell");
+        if (gps_both->isChecked()) gps.setPositioningMethod("all");
+        if (gps_agps->isChecked()) gps.setPositioningMethod("gps");
+    }
+    void set_to(int value) {
+        qDebug() << "LatitudeGUI::set_to()" << value;
+        gps.setTimeOut(value);
+        gps_to_slider_value->setText(QString("%1 sec.").arg(value));
+
+    }
+    void set_i(int value) {
+        qDebug() << "LatitudeGUI::set_i()" << value;
+        gps.setInterval(value*60);
+        gps_i_slider_value->setText(QString("%1 min.").arg(value));
+    }
+    void set_ac_yes() {
+        qDebug() << "LatitudeGUI::set_ac_yes";
+        latitude.setAutoConnect(true);
+    }
+    void set_ac_not() {
+        qDebug() << "LatitudeGUI::set_ac_not";
+        latitude.setAutoConnect(false);
+    }
+
+private:
+    GoogleLatitude latitude;
+    GpsControl gps;
+
+    QHBoxLayout *layout_row1;
+    QPushButton *do_oauth;
+    QPushButton *do_start;
+    QPushButton *do_stop;
+
+    QHBoxLayout *layout_row2;
+    QLabel *pos_label;
+    QLineEdit *pos_lat;
+    QLineEdit *pos_lon;
+    QLineEdit *pos_acc;
+    QLineEdit *pos_tis;
+
+    QHBoxLayout *layout_row3;
+    QLabel *gps_method;
+    QButtonGroup *gps_group;
+    QRadioButton *gps_cell;
+    QRadioButton *gps_both;
+    QRadioButton *gps_agps;
+
+    QHBoxLayout *layout_row4;
+    QLabel *gps_to_label;
+    QSlider *gps_to_slider;
+    QLabel *gps_to_slider_value;
+
+    QHBoxLayout *layout_row5;
+    QLabel *gps_i_label;
+    QSlider *gps_i_slider;
+    QLabel *gps_i_slider_value;
+
+    QHBoxLayout *layout_row6;
+    QLabel *gps_ac_label;
+    QButtonGroup *gps_ac_group;
+    QRadioButton *gps_ac_yes;
+    QRadioButton *gps_ac_not;
+
+    QVBoxLayout *layout_gui;
+};
+
+#endif // LATITUDEGUI_H
diff --git a/libkqoauth/QtKOAuth b/libkqoauth/QtKOAuth
new file mode 100644 (file)
index 0000000..ae370fd
--- /dev/null
@@ -0,0 +1,5 @@
+#include "kqoauthrequest.h"
+#include "kqoauthrequest_1.h"
+#include "kqoauthrequest_xauth.h"
+#include "kqoauthmanager.h"
+#include "kqoauthglobals.h"
diff --git a/libkqoauth/kqoauthauthreplyserver.cpp b/libkqoauth/kqoauthauthreplyserver.cpp
new file mode 100644 (file)
index 0000000..8612f5f
--- /dev/null
@@ -0,0 +1,104 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QTcpSocket>
+#include <QStringList>
+#include <QUrl>
+
+#include "kqoauthauthreplyserver.h"
+#include "kqoauthauthreplyserver_p.h"
+
+KQOAuthAuthReplyServerPrivate::KQOAuthAuthReplyServerPrivate(KQOAuthAuthReplyServer *parent):
+    q_ptr(parent)
+{
+
+}
+
+KQOAuthAuthReplyServerPrivate::~KQOAuthAuthReplyServerPrivate()
+{
+
+}
+
+void KQOAuthAuthReplyServerPrivate::onIncomingConnection() {
+    Q_Q(KQOAuthAuthReplyServer);
+
+    socket = q->nextPendingConnection();
+    connect(socket, SIGNAL(readyRead()),
+            this, SLOT(onBytesReady()), Qt::UniqueConnection);
+}
+
+void KQOAuthAuthReplyServerPrivate::onBytesReady() {
+    Q_Q(KQOAuthAuthReplyServer);
+    
+    QByteArray reply;
+    QByteArray content;
+    content.append("<html><head><title>OAuth Finished!</title></head><body bgcolor='white' text='black'><center><h1>OAuth finished, return to the application!</h1></center></body></html>");
+
+    reply.append("HTTP/1.0 200 OK \r\n");
+    reply.append("Content-Type: text/html; charset=\"utf-8\"\r\n");
+    reply.append(QString("Content-Length: %1\r\n").arg(content.size()));
+    reply.append("\r\n");
+    reply.append(content);
+    socket->write(reply);
+    
+    QByteArray data = socket->readAll();
+    QMultiMap<QString, QString> queryParams = parseQueryParams(&data);
+
+    socket->disconnectFromHost();
+    q->close();
+    emit q->verificationReceived(queryParams);
+}
+
+QMultiMap<QString, QString> KQOAuthAuthReplyServerPrivate::parseQueryParams(QByteArray *data) {
+    QString splitGetLine = QString(*data).split("\r\n").first();   // Retrieve the first line with query params.
+    splitGetLine.remove("GET ");                                   // Clean the line from GET
+    splitGetLine.remove("HTTP/1.1");                               // From HTTP
+    splitGetLine.remove("\r\n");                                   // And from rest.
+    splitGetLine.prepend("http://localhost");                      // Now, make it a URL
+
+    QUrl getTokenUrl(splitGetLine);
+    QList< QPair<QString, QString> > tokens = getTokenUrl.queryItems();  // Ask QUrl to do our work.
+
+    QMultiMap<QString, QString> queryParams;
+    QPair<QString, QString> tokenPair;
+    foreach (tokenPair, tokens) {
+        queryParams.insert(tokenPair.first.trimmed(), tokenPair.second.trimmed());
+    }
+
+    return queryParams;
+}
+
+
+
+KQOAuthAuthReplyServer::KQOAuthAuthReplyServer(QObject *parent) :
+    QTcpServer(parent),
+    d_ptr( new KQOAuthAuthReplyServerPrivate(this) )
+{
+    Q_D(KQOAuthAuthReplyServer);
+
+    connect(this, SIGNAL(newConnection()),
+            d, SLOT(onIncomingConnection()));
+}
+
+KQOAuthAuthReplyServer::~KQOAuthAuthReplyServer()
+{
+    delete d_ptr;
+}
+
+
diff --git a/libkqoauth/kqoauthauthreplyserver.h b/libkqoauth/kqoauthauthreplyserver.h
new file mode 100644 (file)
index 0000000..742de2a
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHAUTHREPLYSERVER_H
+#define KQOAUTHAUTHREPLYSERVER_H
+
+#include <QTcpServer>
+
+#include "kqoauthglobals.h"
+
+class KQOAuthAuthReplyServerPrivate;
+class KQOAUTH_EXPORT KQOAuthAuthReplyServer : public QTcpServer
+{
+    Q_OBJECT
+public:
+    explicit KQOAuthAuthReplyServer(QObject *parent);
+    ~KQOAuthAuthReplyServer();
+
+Q_SIGNALS:
+    void verificationReceived(QMultiMap<QString, QString>);
+
+
+private:
+    KQOAuthAuthReplyServerPrivate * const d_ptr;
+    Q_DECLARE_PRIVATE(KQOAuthAuthReplyServer);
+    Q_DISABLE_COPY(KQOAuthAuthReplyServer);
+
+
+};
+
+#endif // KQOAUTHAUTHREPLYSERVER_H
diff --git a/libkqoauth/kqoauthauthreplyserver_p.h b/libkqoauth/kqoauthauthreplyserver_p.h
new file mode 100644 (file)
index 0000000..ab0ca9f
--- /dev/null
@@ -0,0 +1,47 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+// Note this class shouldn't be copied or used and the implementation might change later.
+#ifndef KQOAUTHAUTHREPLYSERVER_P_H
+#define KQOAUTHAUTHREPLYSERVER_P_H
+
+#include "kqoauthauthreplyserver.h"
+#include <QMultiMap>
+#include <QString>
+
+class KQOAUTH_EXPORT KQOAuthAuthReplyServerPrivate: public QObject
+{
+    Q_OBJECT
+public:
+    KQOAuthAuthReplyServerPrivate( KQOAuthAuthReplyServer * parent );
+    ~KQOAuthAuthReplyServerPrivate();
+    QMultiMap<QString, QString> parseQueryParams(QByteArray *sdata);
+
+public Q_SLOTS:
+    void onIncomingConnection();
+    void onBytesReady();
+
+public:
+    KQOAuthAuthReplyServer * q_ptr;
+    Q_DECLARE_PUBLIC(KQOAuthAuthReplyServer);
+    QTcpSocket *socket;
+
+};
+
+#endif // KQOAUTHAUTHREPLYSERVER_P_H
diff --git a/libkqoauth/kqoauthglobals.h b/libkqoauth/kqoauthglobals.h
new file mode 100644 (file)
index 0000000..b48eccc
--- /dev/null
@@ -0,0 +1,44 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHGLOBALS_H
+#define KQOAUTHGLOBALS_H
+
+#include <QtCore/qglobal.h>
+
+#if defined(KQOAUTH)
+#  define KQOAUTH_EXPORT Q_DECL_EXPORT
+#else
+#  define KQOAUTH_EXPORT Q_DECL_IMPORT
+#endif
+
+//////////// Static constant definitions ///////////
+const QString OAUTH_KEY_CONSUMER("oauth_consumer");
+const QString OAUTH_KEY_CONSUMER_KEY("oauth_consumer_key");
+const QString OAUTH_KEY_TOKEN("oauth_token");
+const QString OAUTH_KEY_TOKEN_SECRET("oauth_token_secret");
+const QString OAUTH_KEY_SIGNATURE_METHOD("oauth_signature_method");
+const QString OAUTH_KEY_TIMESTAMP("oauth_timestamp");
+const QString OAUTH_KEY_NONCE("oauth_nonce");
+const QString OAUTH_KEY_SIGNATURE("oauth_signature");
+const QString OAUTH_KEY_CALLBACK("oauth_callback");
+const QString OAUTH_KEY_VERIFIER("oauth_verifier");
+const QString OAUTH_KEY_VERSION("oauth_version");
+
+#endif // KQOAUTHGLOBALS_H
diff --git a/libkqoauth/kqoauthmanager.cpp b/libkqoauth/kqoauthmanager.cpp
new file mode 100644 (file)
index 0000000..ddd768e
--- /dev/null
@@ -0,0 +1,492 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QtCore>
+// #include <QDesktopServices>
+
+#include "kqoauthmanager.h"
+#include "kqoauthmanager_p.h"
+
+
+////////////// Private d_ptr implementation ////////////////
+
+KQOAuthManagerPrivate::KQOAuthManagerPrivate(KQOAuthManager *parent) :
+    error(KQOAuthManager::NoError) ,
+    r(0) ,
+    opaqueRequest(new KQOAuthRequest) ,
+    q_ptr(parent) ,
+    callbackServer(new KQOAuthAuthReplyServer(parent)) ,
+    isVerified(false) ,
+    isAuthorized(false) ,
+    autoAuth(false),
+    networkManager(new QNetworkAccessManager),
+    managerUserSet(false)
+{
+
+}
+
+KQOAuthManagerPrivate::~KQOAuthManagerPrivate() {
+    delete opaqueRequest;
+    opaqueRequest = 0;
+
+    if (!managerUserSet) {
+        delete networkManager;
+        networkManager = 0;
+    }
+}
+
+QList< QPair<QString, QString> > KQOAuthManagerPrivate::createQueryParams(const KQOAuthParameters &requestParams) {
+    QList<QString> requestKeys = requestParams.keys();
+    QList<QString> requestValues = requestParams.values();
+
+    QList< QPair<QString, QString> > result;
+    for(int i=0; i<requestKeys.size(); i++) {
+        result.append( qMakePair(requestKeys.at(i),
+                                 requestValues.at(i))
+                      );
+    }
+
+    return result;
+}
+
+QMultiMap<QString, QString> KQOAuthManagerPrivate::createTokensFromResponse(QByteArray reply) {
+    QMultiMap<QString, QString> result;
+    QString replyString(reply);
+
+    QStringList parameterPairs = replyString.split('&', QString::SkipEmptyParts);
+    foreach (const QString &parameterPair, parameterPairs) {
+        QStringList parameter = parameterPair.split('=');
+        result.insert(parameter.value(0), parameter.value(1));
+    }
+
+    return result;
+}
+
+bool KQOAuthManagerPrivate::setSuccessfulRequestToken(const QMultiMap<QString, QString> &request) {
+    if (currentRequestType == KQOAuthRequest::TemporaryCredentials) {
+        hasTemporaryToken = (!QString(request.value("oauth_token")).isEmpty() && !QString(request.value("oauth_token_secret")).isEmpty());
+    } else {
+        return false;
+    }
+
+    if (hasTemporaryToken) {
+        requestToken = QUrl::fromPercentEncoding( QString(request.value("oauth_token")).toLocal8Bit() );
+        requestTokenSecret =  QUrl::fromPercentEncoding( QString(request.value("oauth_token_secret")).toLocal8Bit() );
+    }
+
+    return hasTemporaryToken;
+}
+
+bool KQOAuthManagerPrivate::setSuccessfulAuthorized(const QMultiMap<QString, QString> &request ) {
+    if (currentRequestType == KQOAuthRequest::AccessToken) {
+        isAuthorized = (!QString(request.value("oauth_token")).isEmpty() && !QString(request.value("oauth_token_secret")).isEmpty());
+    } else {
+        return false;
+    }
+
+    if (isAuthorized) {
+        requestToken = QUrl::fromPercentEncoding( QString(request.value("oauth_token")).toLocal8Bit() );
+        requestTokenSecret =  QUrl::fromPercentEncoding( QString(request.value("oauth_token_secret")).toLocal8Bit() );
+    }
+
+    return isAuthorized;
+}
+
+void KQOAuthManagerPrivate::emitTokens() {
+    Q_Q(KQOAuthManager);
+
+    if (this->requestToken.isEmpty() || this->requestTokenSecret.isEmpty()) {
+        error = KQOAuthManager::RequestUnauthorized;
+    }
+
+    if (currentRequestType == KQOAuthRequest::TemporaryCredentials) {
+        // Signal that we are ready to use the protected resources.
+        emit q->temporaryTokenReceived(this->requestToken, this->requestTokenSecret);
+    }
+
+    if (currentRequestType == KQOAuthRequest::AccessToken) {
+        // Signal that we are ready to use the protected resources.
+        emit q->accessTokenReceived(this->requestToken, this->requestTokenSecret);
+    }
+
+    emit q->receivedToken(this->requestToken, this->requestTokenSecret);
+}
+
+bool KQOAuthManagerPrivate::setupCallbackServer() {
+    return callbackServer->listen();
+}
+
+
+/////////////// Public implementation ////////////////
+
+KQOAuthManager::KQOAuthManager(QObject *parent) :
+    QObject(parent) ,
+    d_ptr(new KQOAuthManagerPrivate(this))
+{
+
+}
+
+KQOAuthManager::~KQOAuthManager()
+{
+    delete d_ptr;
+}
+
+void KQOAuthManager::executeRequest(KQOAuthRequest *request) {
+    Q_D(KQOAuthManager);
+
+    d->r = request;
+
+    if (request == 0) {
+        qWarning() << "Request is NULL. Cannot proceed.";
+        d->error = KQOAuthManager::RequestError;
+        return;
+    }
+
+    if (!request->requestEndpoint().isValid()) {
+        qWarning() << "Request endpoint URL is not valid. Cannot proceed.";
+        d->error = KQOAuthManager::RequestEndpointError;
+        return;
+    }
+
+    if (!request->isValid()) {
+        qWarning() << "Request is not valid. Cannot proceed.";
+        d->error = KQOAuthManager::RequestValidationError;
+        return;
+    }
+
+    d->currentRequestType = request->requestType();
+
+    QNetworkRequest networkRequest;
+    networkRequest.setUrl( request->requestEndpoint() );
+
+    if (d->autoAuth && d->currentRequestType == KQOAuthRequest::TemporaryCredentials) {
+        d->setupCallbackServer();
+        connect(d->callbackServer, SIGNAL(verificationReceived(QMultiMap<QString, QString>)),
+                this, SLOT( onVerificationReceived(QMultiMap<QString, QString>)));
+
+        QString serverString = "http://localhost:";
+        serverString.append(QString::number(d->callbackServer->serverPort()));
+        request->setCallbackUrl(QUrl(serverString));
+    }
+
+    // And now fill the request with "Authorization" header data.
+    QList<QByteArray> requestHeaders = request->requestParameters();
+    QByteArray authHeader;
+
+    bool first = true;
+    foreach (const QByteArray header, requestHeaders) {
+        if (!first) {
+            authHeader.append(", ");
+        } else {
+            authHeader.append("OAuth ");
+            first = false;
+        }
+
+        authHeader.append(header);
+    }
+    networkRequest.setRawHeader("Authorization", authHeader);
+
+    connect(d->networkManager, SIGNAL(finished(QNetworkReply *)),
+            this, SLOT(onRequestReplyReceived(QNetworkReply *)));
+
+    if (request->httpMethod() == KQOAuthRequest::GET) {
+        // Get the requested additional params as a list of pairs we can give QUrl
+        QList< QPair<QString, QString> > urlParams = d->createQueryParams(request->additionalParameters());
+
+        // Take the original URL and append the query params to it.
+        QUrl urlWithParams = networkRequest.url();
+        urlWithParams.setQueryItems(urlParams);
+        networkRequest.setUrl(urlWithParams);
+
+        // Submit the request including the params.
+        QNetworkReply *reply = d->networkManager->get(networkRequest);
+        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+                 this, SLOT(slotError(QNetworkReply::NetworkError)));
+
+    } else if (request->httpMethod() == KQOAuthRequest::POST) {
+
+        networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, request->contentType());
+
+        qDebug() << networkRequest.rawHeaderList();
+        qDebug() << networkRequest.rawHeader("Authorization");
+        qDebug() << networkRequest.rawHeader("Content-Type");
+
+        QNetworkReply *reply;
+        if (request->contentType() == "application/x-www-form-urlencoded") {
+          reply = d->networkManager->post(networkRequest, request->requestBody());
+        } else {
+          reply = d->networkManager->post(networkRequest, request->rawData());
+        }
+
+        connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+                 this, SLOT(slotError(QNetworkReply::NetworkError)));
+    }
+
+    d->r->requestTimerStart();
+}
+
+
+void KQOAuthManager::setHandleUserAuthorization(bool set) {
+    Q_D(KQOAuthManager);
+
+    d->autoAuth = set;
+}
+
+bool KQOAuthManager::hasTemporaryToken() {
+    Q_D(KQOAuthManager);
+
+    return d->hasTemporaryToken;
+}
+
+bool KQOAuthManager::isVerified() {
+    Q_D(KQOAuthManager);
+
+    return d->isVerified;
+}
+
+bool KQOAuthManager::isAuthorized() {
+    Q_D(KQOAuthManager);
+
+    return d->isAuthorized;
+}
+
+KQOAuthManager::KQOAuthError KQOAuthManager::lastError() {
+    Q_D(KQOAuthManager);
+
+    return d->error;
+}
+
+void KQOAuthManager::setNetworkManager(QNetworkAccessManager *manager) {
+    Q_D(KQOAuthManager);
+
+    if (manager == 0) {
+        d->error = KQOAuthManager::ManagerError;
+        return;
+    }
+
+    if (!d->managerUserSet) {
+        delete d->networkManager;
+    }
+
+    d->managerUserSet = true;
+    d->networkManager = manager;
+}
+
+QNetworkAccessManager * KQOAuthManager::networkManager() const {
+    Q_D(const KQOAuthManager);
+
+    if (d->managerUserSet) {
+        return d->networkManager;
+    } else {
+        return NULL;
+    }
+
+}
+
+
+//////////// Public convenience API /////////////
+
+QUrl KQOAuthManager::getUserAuthorization(QUrl authorizationEndpoint) {
+    Q_D(KQOAuthManager);
+
+    if (!d->hasTemporaryToken) {
+        qWarning() << "No temporary tokens retreieved. Cannot get user authorization.";
+        d->error = KQOAuthManager::RequestUnauthorized;
+        return QString();
+    }
+
+    if (!authorizationEndpoint.isValid()) {
+        qWarning() << "Authorization endpoint not valid. Cannot proceed.";
+        d->error = KQOAuthManager::RequestEndpointError;
+        return QString();
+    }
+
+    d->error = KQOAuthManager::NoError;
+
+    QPair<QString, QString> tokenParam = qMakePair(QString("oauth_token"), QString(d->requestToken));
+    QUrl openWebPageUrl(authorizationEndpoint.toString(), QUrl::StrictMode);
+    openWebPageUrl.addQueryItem(tokenParam.first, tokenParam.second);
+
+    // Open the user's default browser to the resource authorization page provided
+    // by the service.
+    // QDesktopServices::openUrl(openWebPageUrl);
+    qDebug() << "* KQOAuthManager::getUserAuthorization -> QDesktopServices::openUrl" << openWebPageUrl;
+    return openWebPageUrl;
+}
+
+void KQOAuthManager::getUserAccessTokens(QUrl accessTokenEndpoint) {
+    Q_D(KQOAuthManager);
+
+    if (!d->isVerified) {
+        qWarning() << "Not verified. Cannot get access tokens.";
+        d->error = KQOAuthManager::RequestUnauthorized;
+        return;
+    }
+
+    if (!accessTokenEndpoint.isValid()) {
+        qWarning() << "Endpoint for access token exchange is not valid. Cannot proceed.";
+        d->error = KQOAuthManager::RequestEndpointError;
+        return;
+    }
+
+    d->error = KQOAuthManager::NoError;
+
+    d->opaqueRequest->clearRequest();
+    d->opaqueRequest->initRequest(KQOAuthRequest::AccessToken, accessTokenEndpoint);
+    d->opaqueRequest->setToken(d->requestToken);
+    d->opaqueRequest->setTokenSecret(d->requestTokenSecret);
+    d->opaqueRequest->setVerifier(d->requestVerifier);
+    d->opaqueRequest->setConsumerKey(d->consumerKey);
+    d->opaqueRequest->setConsumerSecretKey(d->consumerKeySecret);
+
+    executeRequest(d->opaqueRequest);
+}
+
+void KQOAuthManager::sendAuthorizedRequest(QUrl requestEndpoint, const KQOAuthParameters &requestParameters) {
+    Q_D(KQOAuthManager);
+
+    if (!d->isAuthorized) {
+        qWarning() << "No access tokens retrieved. Cannot send authorized requests.";
+        d->error = KQOAuthManager::RequestUnauthorized;
+        return;
+    }
+
+    if (!requestEndpoint.isValid()) {
+        qWarning() << "Endpoint for authorized request is not valid. Cannot proceed.";
+        d->error = KQOAuthManager::RequestEndpointError;
+        return;
+    }
+
+    d->error = KQOAuthManager::NoError;
+
+    d->opaqueRequest->clearRequest();
+    d->opaqueRequest->initRequest(KQOAuthRequest::AuthorizedRequest, requestEndpoint);
+    d->opaqueRequest->setAdditionalParameters(requestParameters);
+    d->opaqueRequest->setToken(d->requestToken);
+    d->opaqueRequest->setTokenSecret(d->requestTokenSecret);
+    d->opaqueRequest->setConsumerKey(d->consumerKey);
+    d->opaqueRequest->setConsumerSecretKey(d->consumerKeySecret);
+
+    executeRequest(d->opaqueRequest);
+}
+
+
+/////////////// Private slots //////////////////
+
+void KQOAuthManager::onRequestReplyReceived( QNetworkReply *reply ) {
+    Q_D(KQOAuthManager);
+
+    QNetworkReply::NetworkError networkError = reply->error();
+    switch (networkError) {
+    case QNetworkReply::NoError:
+        d->error = KQOAuthManager::NoError;
+        break;
+
+    case QNetworkReply::ContentAccessDenied:
+    case QNetworkReply::AuthenticationRequiredError:
+        d->error = KQOAuthManager::RequestUnauthorized;
+        break;
+
+    default:
+        d->error = KQOAuthManager::NetworkError;
+        break;
+    }
+
+    // Read the content of the reply from the network.
+    QByteArray networkReply = reply->readAll();
+
+    // Stop any timer we have set on the request.
+    d->r->requestTimerStop();
+
+    // Just don't do anything if we didn't get anything useful.
+    if(networkReply.isEmpty()) {
+        reply->deleteLater();
+        return;
+    }
+    QMultiMap<QString, QString> responseTokens;
+
+    // We need to emit the signal even if we got an error.
+    if (d->error != KQOAuthManager::NoError) {
+        reply->deleteLater();
+        emit requestReady(networkReply);
+        d->emitTokens();
+        return;
+    }
+
+    responseTokens = d->createTokensFromResponse(networkReply);
+    d->opaqueRequest->clearRequest();
+    d->opaqueRequest->setHttpMethod(KQOAuthRequest::POST);   // XXX FIXME: Convenient API does not support GET
+    if (!d->isAuthorized || !d->isVerified) {
+        if (d->setSuccessfulRequestToken(responseTokens)) {
+            qDebug() << "Successfully got request tokens.";
+            d->consumerKey = d->r->consumerKeyForManager();
+            d->consumerKeySecret = d->r->consumerKeySecretForManager();
+            d->opaqueRequest->setSignatureMethod(KQOAuthRequest::HMAC_SHA1);
+            d->opaqueRequest->setCallbackUrl(d->r->callbackUrlForManager());
+
+            d->emitTokens();
+
+        } else if (d->setSuccessfulAuthorized(responseTokens)) {
+              qDebug() << "Successfully got access tokens.";
+              d->opaqueRequest->setSignatureMethod(KQOAuthRequest::HMAC_SHA1);
+
+              d->emitTokens();
+          } else if (d->currentRequestType == KQOAuthRequest::AuthorizedRequest) {
+                emit authorizedRequestDone();
+            }
+    }
+
+    emit requestReady(networkReply);
+
+    reply->deleteLater();           // We need to clean this up, after the event processing is done.
+}
+
+void KQOAuthManager::onVerificationReceived(QMultiMap<QString, QString> response) {
+    Q_D(KQOAuthManager);
+
+    QString token = response.value("oauth_token");
+    QString verifier = response.value("oauth_verifier");
+    if (verifier.isEmpty()) {
+        d->error = KQOAuthManager::RequestUnauthorized;
+    }
+
+    verifier = QUrl::fromPercentEncoding(verifier.toUtf8());     // We get the raw URL response here so we need to convert it back
+                                                                 // to plain string so we can percent encode it again later in requests.
+
+    if (d->error == KQOAuthManager::NoError) {
+        d->requestVerifier = verifier;
+        d->isVerified = true;
+    }
+
+    emit authorizationReceived(token, verifier);
+}
+
+void KQOAuthManager::slotError(QNetworkReply::NetworkError error) {
+    Q_UNUSED(error)
+    Q_D(KQOAuthManager);
+
+    d->error = KQOAuthManager::NetworkError;
+    QByteArray emptyResponse;
+    emit requestReady(emptyResponse);
+    emit authorizedRequestDone();
+
+    QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender());
+    reply->deleteLater();
+}
+
diff --git a/libkqoauth/kqoauthmanager.h b/libkqoauth/kqoauthmanager.h
new file mode 100644 (file)
index 0000000..cdd0f4e
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHMANAGER_H
+#define KQOAUTHMANAGER_H
+
+#include <QObject>
+#include <QMultiMap>
+#include <QNetworkReply>
+
+#include "kqoauthrequest.h"
+
+class KQOAuthRequest;
+class KQOAuthManagerThread;
+class KQOAuthManagerPrivate;
+class QNetworkAccessManager;
+class QUrl;
+class QByteArray;
+class KQOAUTH_EXPORT KQOAuthManager : public QObject
+{
+    Q_OBJECT
+public:
+
+    enum KQOAuthError {
+        NoError,                    // No error
+        NetworkError,               // Network error: timeout, cannot connect.
+        RequestEndpointError,       // Request endpoint is not valid.
+        RequestValidationError,     // Request is not valid: some parameter missing?
+        RequestUnauthorized,        // Authorization error: trying to access a resource without tokens.
+        RequestError,               // The given request to KQOAuthManager is invalid: NULL?,
+        ManagerError                // Manager error, cannot use for sending requests.
+    };
+
+    explicit KQOAuthManager(QObject *parent = 0);
+    ~KQOAuthManager();
+
+    KQOAuthError lastError();
+
+    /**
+     * The manager executes the given request. It takes the HTTP parameters from the
+     * request and uses QNetworkAccessManager to submit the HTTP request to the net.
+     * When the request is done it will emit signal requestReady(QByteArray networkReply).
+     * NOTE: At the moment there is no timeout for the request.
+     */
+    void executeRequest(KQOAuthRequest *request);
+    /**
+     * Indicates to the user that KQOAuthManager should handle user authorization by
+     * opening the user's default browser and parsing the reply from the service.
+     * By setting the parameter to true, KQOAuthManager will store intermediate results
+     * of the OAuth 1.0 process in its own opaque request. This information is used in
+     * the user authorization process and also when calling sendAuthorizedRequest().
+     * NOTE: You need to set this to true if you want to use getUserAccessTokens() or
+     *       sendAuthorizedRequest().
+     */
+    void setHandleUserAuthorization(bool set);
+
+    /**
+     * Returns true if the KQOAuthManager has retrieved the oauth_token value. Otherwise
+     * return false.
+     */
+    bool hasTemporaryToken();
+    /**
+     * Returns true if the user has authorized us to use the protected resources. Otherwise
+     * returns false.
+     * NOTE: In order for KQOAuthManager to know if the user has authorized us to use the
+     *       protected resources, KQOAuthManager must be in control of the user authorization
+     *       process. Hence, this returns true if setHandleUserAuthorization() is set to true
+     *       and the user is authorized with getUserAuthorization().
+     */
+    bool isVerified();
+    /**
+     * Returns true if KQOAuthManager has the access token and hence can access the protected
+     * resources. Otherwise returns false.
+     * NOTE: In order for KQOAuthManager to know if we have access to protected resource
+     *       KQOAuthManager must be in control of the user authorization process and requesting
+     *       the acess token. Hence, this returns true if setHandleUserAuthorization() is set to true
+     *       and the user is authorized with getUserAuthorization() and the access token must be retrieved
+     *       with getUserAccessTokens.
+     */
+    bool isAuthorized();
+
+    /**
+     * This is a convenience API for authorizing the user.
+     * The call will open the user's default browser, setup a local HTTP server and parse the reply from the
+     * service after the user has authorized us to access protected resources. If the user authorizes
+     * us to access protected resources, the verifier token is stored in KQOAuthManager for further use.
+     * In order to use this method, you must set setHandleUserAuthorization() to true.
+     */
+    QUrl getUserAuthorization(QUrl authorizationEndpoint);
+    /**
+     * This is a convenience API for retrieving the access token in exchange for the temporary token and the
+     * verifier.
+     * This call will create a KQOAuthRequest and use the previously stored temporary token and verifier to
+     * exchange for the access token, which will be used to access the protected resources.
+     * Note that in order to use this method, KQOAuthManager must be in control of the user authorization process.
+     * Set setHandleUserAuthorization() to true and retrieve user authorization with void getUserAuthorization.
+     */
+    void getUserAccessTokens(QUrl accessTokenEndpoint);
+    /**
+     * Sends a request to the protected resources. Parameters for the request are service specific and
+     * are given to the 'requestParameters' as parameters.
+     * Note that in order to use this method, KQOAuthManager must be in control of the user authorization process.
+     * Set setHandleUserAuthorization() to true and retrieve user authorization with void getUserAuthorization.
+     */
+    void sendAuthorizedRequest(QUrl requestEndpoint, const KQOAuthParameters &requestParameters);
+
+    /**
+     * Sets a custom QNetworkAccessManager to handle network requests. This method can be useful if the
+     * application is using some proxy settings for example.
+     * The application is responsible for deleting this manager. KQOAuthManager will not delete any
+     * previously given manager.
+     * If the manager is NULL, the manager will not be set and the KQOAuthManager::Error.
+     * If no manager is given, KQOAuthManager will use the default one it will create by itself.
+     */
+    void setNetworkManager(QNetworkAccessManager *manager);
+
+    /**
+     * Returns the given QNetworkAccessManager. Returns NULL if none is given.
+     */
+    QNetworkAccessManager* networkManager() const;
+
+Q_SIGNALS:
+    // This signal will be emitted after each request has got a reply.
+    // Parameter is the raw response from the service.
+    void requestReady(QByteArray networkReply);
+
+    // This signal will be emited when we have an request tokens available
+    // (either temporary resource tokens, or authorization tokens).
+    void receivedToken(QString oauth_token, QString oauth_token_secret);   // oauth_token, oauth_token_secret
+
+    // This signal is emited when temporary tokens are returned from the service.
+    // Note that this signal is also emited in case temporary tokens are not available.
+    void temporaryTokenReceived(QString oauth_token, QString oauth_token_secret);   // oauth_token, oauth_token_secret
+
+    // This signal is emited when the user has authenticated the application to
+    // communicate with the protected resources. Next we need to exchange the
+    // temporary tokens for access tokens.
+    // Note that this signal is also emited if user denies access.
+    void authorizationReceived(QString oauth_token, QString oauth_verifier); // oauth_token, oauth_verifier
+
+    // This signal is emited when access tokens are received from the service. We are
+    // ready to start communicating with the protected resources.
+    void accessTokenReceived(QString oauth_token, QString oauth_token_secret);  // oauth_token, oauth_token_secret
+
+    // This signal is emited when the authorized request is done.
+    // This ends the kQOAuth interactions.
+    void authorizedRequestDone();
+
+private Q_SLOTS:
+    void onRequestReplyReceived( QNetworkReply *reply );
+    void onVerificationReceived(QMultiMap<QString, QString> response);
+    void slotError(QNetworkReply::NetworkError error);
+
+private:
+    KQOAuthManagerPrivate *d_ptr;
+    Q_DECLARE_PRIVATE(KQOAuthManager);
+    Q_DISABLE_COPY(KQOAuthManager);
+
+};
+
+#endif // KQOAUTHMANAGER_H
diff --git a/libkqoauth/kqoauthmanager_p.h b/libkqoauth/kqoauthmanager_p.h
new file mode 100644 (file)
index 0000000..ecbbb7b
--- /dev/null
@@ -0,0 +1,71 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHMANAGER_P_H
+#define KQOAUTHMANAGER_P_H
+
+#include "kqoauthauthreplyserver.h"
+#include "kqoauthrequest.h"
+
+class KQOAUTH_EXPORT KQOAuthManagerPrivate {
+
+public:
+    KQOAuthManagerPrivate(KQOAuthManager *parent);
+    ~KQOAuthManagerPrivate();
+
+    QList< QPair<QString, QString> > createQueryParams(const KQOAuthParameters &requestParams);
+    QMultiMap<QString, QString> createTokensFromResponse(QByteArray reply);
+    bool setSuccessfulRequestToken(const QMultiMap<QString, QString> &request);
+    bool setSuccessfulAuthorized(const QMultiMap<QString, QString> &request);
+    void emitTokens();
+    bool setupCallbackServer();
+
+    KQOAuthManager::KQOAuthError error;
+    KQOAuthRequest *r;                  // This request is used to cache the user sent request.
+    KQOAuthRequest *opaqueRequest;       // This request is used to creating opaque convenience requests for the user.
+    KQOAuthManager * const q_ptr;
+
+    /**
+     * The items below are needed in order to store the state of the manager and
+     * by that be able to do convenience operations for the user.
+     */
+    KQOAuthRequest::RequestType currentRequestType;
+
+    // Variables we store here for opaque request handling.
+    // NOTE: The variables are labeled the same for both access token request
+    //       and protected resource access.
+    QString requestToken;
+    QString requestTokenSecret;
+    QString consumerKey;
+    QString consumerKeySecret;
+    QString requestVerifier;
+
+    KQOAuthAuthReplyServer *callbackServer;
+
+    bool hasTemporaryToken;
+    bool isVerified;
+    bool isAuthorized;
+    bool autoAuth;
+    QNetworkAccessManager *networkManager;
+    bool managerUserSet;
+
+    Q_DECLARE_PUBLIC(KQOAuthManager);
+};
+
+#endif // KQOAUTHMANAGER_P_H
diff --git a/libkqoauth/kqoauthrequest.cpp b/libkqoauth/kqoauthrequest.cpp
new file mode 100644 (file)
index 0000000..1a7b8ca
--- /dev/null
@@ -0,0 +1,589 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QByteArray>
+#include <QDateTime>
+#include <QCryptographicHash>
+#include <QPair>
+#include <QStringList>
+
+#include <QtDebug>
+#include <QtAlgorithms>
+
+#include "kqoauthrequest.h"
+#include "kqoauthrequest_p.h"
+#include "kqoauthutils.h"
+#include "kqoauthglobals.h"
+
+
+//////////// Private d_ptr implementation /////////
+
+KQOAuthRequestPrivate::KQOAuthRequestPrivate() :
+    timeout(0)
+{
+
+}
+
+KQOAuthRequestPrivate::~KQOAuthRequestPrivate()
+{
+
+}
+
+// This method will not include the "oauthSignature" paramater, since it is calculated from these parameters.
+void KQOAuthRequestPrivate::prepareRequest() {
+
+    // If parameter list is not empty, we don't want to insert these values by
+    // accident a second time. So giving up.
+    if( !requestParameters.isEmpty() ) {
+        return;
+    }
+
+    switch ( requestType ) {
+    case KQOAuthRequest::TemporaryCredentials:
+        requestParameters.append( qMakePair( OAUTH_KEY_CALLBACK, oauthCallbackUrl.toString()) );  // This is so ugly that it is almost beautiful.
+        requestParameters.append( qMakePair( OAUTH_KEY_SIGNATURE_METHOD, oauthSignatureMethod) );
+        requestParameters.append( qMakePair( OAUTH_KEY_CONSUMER_KEY, oauthConsumerKey ));
+        requestParameters.append( qMakePair( OAUTH_KEY_VERSION, oauthVersion ));
+        requestParameters.append( qMakePair( OAUTH_KEY_TIMESTAMP, this->oauthTimestamp() ));
+        requestParameters.append( qMakePair( OAUTH_KEY_NONCE, this->oauthNonce() ));
+        break;
+
+    case KQOAuthRequest::AccessToken:
+        requestParameters.append( qMakePair( OAUTH_KEY_SIGNATURE_METHOD, oauthSignatureMethod ));
+        requestParameters.append( qMakePair( OAUTH_KEY_CONSUMER_KEY, oauthConsumerKey ));
+        requestParameters.append( qMakePair( OAUTH_KEY_VERSION, oauthVersion ));
+        requestParameters.append( qMakePair( OAUTH_KEY_TIMESTAMP, this->oauthTimestamp() ));
+        requestParameters.append( qMakePair( OAUTH_KEY_NONCE, this->oauthNonce() ));
+        requestParameters.append( qMakePair( OAUTH_KEY_VERIFIER, oauthVerifier ));
+        requestParameters.append( qMakePair( OAUTH_KEY_TOKEN, oauthToken ));
+        break;
+
+    case KQOAuthRequest::AuthorizedRequest:
+        requestParameters.append( qMakePair( OAUTH_KEY_SIGNATURE_METHOD, oauthSignatureMethod ));
+        requestParameters.append( qMakePair( OAUTH_KEY_CONSUMER_KEY, oauthConsumerKey ));
+        requestParameters.append( qMakePair( OAUTH_KEY_VERSION, oauthVersion ));
+        requestParameters.append( qMakePair( OAUTH_KEY_TIMESTAMP, this->oauthTimestamp() ));
+        requestParameters.append( qMakePair( OAUTH_KEY_NONCE, this->oauthNonce() ));
+        requestParameters.append( qMakePair( OAUTH_KEY_TOKEN, oauthToken ));
+        break;
+
+    default:
+        break;
+    }
+}
+
+void KQOAuthRequestPrivate::signRequest() {
+    QString signature = this->oauthSignature();
+    requestParameters.append( qMakePair( OAUTH_KEY_SIGNATURE, signature) );
+}
+
+QString KQOAuthRequestPrivate::oauthSignature()  {
+    /**
+     * http://oauth.net/core/1.0/#anchor16
+     * The HMAC-SHA1 signature method uses the HMAC-SHA1 signature algorithm as defined in [RFC2104] where the
+     * Signature Base String is the text and the key is the concatenated values (each first encoded per Parameter
+     * Encoding) of the Consumer Secret and Token Secret, separated by an â€˜&’ character (ASCII code 38) even if empty.
+     **/
+    QByteArray baseString = this->requestBaseString();
+
+    QString secret = QString(QUrl::toPercentEncoding(oauthConsumerSecretKey)) + "&" + QString(QUrl::toPercentEncoding(oauthTokenSecret));
+    QString signature = KQOAuthUtils::hmac_sha1(baseString, secret);
+
+    if (debugOutput) {
+        qDebug() << "========== KQOAuthRequest has the following signature:";
+        qDebug() << " * Signature : " << QUrl::toPercentEncoding(signature) << "\n";
+    }
+    return QString( QUrl::toPercentEncoding(signature) );
+}
+
+bool normalizedParameterSort(const QPair<QString, QString> &left, const QPair<QString, QString> &right) {
+    QString keyLeft = left.first;
+    QString valueLeft = left.second;
+    QString keyRight = right.first;
+    QString valueRight = right.second;
+
+    if(keyLeft == keyRight) {
+        return (valueLeft < valueRight);
+    } else {
+        return (keyLeft < keyRight);
+    }
+}
+QByteArray KQOAuthRequestPrivate::requestBaseString() {
+    QByteArray baseString;
+
+    // Every request has these as the commont parameters.
+    baseString.append( oauthHttpMethodString.toUtf8() + "&");                                                     // HTTP method
+    baseString.append( QUrl::toPercentEncoding( oauthRequestEndpoint.toString(QUrl::RemoveQuery) ) + "&" ); // The path and query components
+
+    QList< QPair<QString, QString> > baseStringParameters;
+    baseStringParameters.append(requestParameters);
+    baseStringParameters.append(additionalParameters);
+
+    // Sort the request parameters. These parameters have been
+    // initialized earlier.
+    qSort(baseStringParameters.begin(),
+          baseStringParameters.end(),
+          normalizedParameterSort
+          );
+
+    // Last append the request parameters correctly encoded.
+    baseString.append( encodedParamaterList(baseStringParameters) );
+
+    if (debugOutput) {
+        qDebug() << "========== KQOAuthRequest has the following base string:";
+        qDebug() << baseString << "\n";
+    }
+
+    return baseString;
+}
+
+QByteArray KQOAuthRequestPrivate::encodedParamaterList(const QList< QPair<QString, QString> > &parameters) {
+    QByteArray resultList;
+
+    bool first = true;
+    QPair<QString, QString> parameter;
+
+    // Do the debug output.
+    if (debugOutput) {
+        qDebug() << "========== KQOAuthRequest has the following parameters:";
+    }
+    foreach (parameter, parameters) {
+        if(!first) {
+            resultList.append( "&" );
+        } else {
+            first = false;
+        }
+
+        // Here we don't need to explicitely encode the strings to UTF-8 since
+        // QUrl::toPercentEncoding() takes care of that for us.
+        resultList.append( QUrl::toPercentEncoding(parameter.first)     // Parameter key
+                           + "="
+                           + QUrl::toPercentEncoding(parameter.second)  // Parameter value
+                          );
+        if (debugOutput) {
+            qDebug() << " * "
+                     << parameter.first
+                     << " : "
+                     << parameter.second;
+        }
+    }
+    if (debugOutput) {
+        qDebug() << "\n";
+    }
+
+    return QUrl::toPercentEncoding(resultList);
+}
+
+QString KQOAuthRequestPrivate::oauthTimestamp() const {
+    // This is basically for unit tests only. In most cases we don't set the nonce beforehand.
+    if (!oauthTimestamp_.isEmpty()) {
+        return oauthTimestamp_;
+    }
+
+#if QT_VERSION >= 0x040700
+    return QString::number(QDateTime::currentDateTimeUtc().toTime_t());
+#else
+   return QString::number(QDateTime::currentDateTime().toUTC().toTime_t());
+#endif
+
+}
+
+QString KQOAuthRequestPrivate::oauthNonce() const {
+    // This is basically for unit tests only. In most cases we don't set the nonce beforehand.
+    if (!oauthNonce_.isEmpty()) {
+        return oauthNonce_;
+    }
+
+    return QString::number(qrand());
+}
+
+bool KQOAuthRequestPrivate::validateRequest() const {
+    switch ( requestType ) {
+    case KQOAuthRequest::TemporaryCredentials:
+        if (oauthRequestEndpoint.isEmpty()
+            || oauthConsumerKey.isEmpty()
+            || oauthNonce_.isEmpty()
+            || oauthSignatureMethod.isEmpty()
+            || oauthTimestamp_.isEmpty()
+            || oauthVersion.isEmpty())
+        {
+            return false;
+        }
+        return true;
+
+    case KQOAuthRequest::AccessToken:
+        if (oauthRequestEndpoint.isEmpty()
+            || oauthVerifier.isEmpty()
+            || oauthConsumerKey.isEmpty()
+            || oauthNonce_.isEmpty()
+            || oauthSignatureMethod.isEmpty()
+            || oauthTimestamp_.isEmpty()
+            || oauthToken.isEmpty()
+            || oauthTokenSecret.isEmpty()
+            || oauthVersion.isEmpty())
+        {
+            return false;
+        }
+        return true;
+
+    case KQOAuthRequest::AuthorizedRequest:
+        if (oauthRequestEndpoint.isEmpty()
+            || oauthConsumerKey.isEmpty()
+            || oauthNonce_.isEmpty()
+            || oauthSignatureMethod.isEmpty()
+            || oauthTimestamp_.isEmpty()
+            || oauthToken.isEmpty()
+            || oauthTokenSecret.isEmpty()
+            || oauthVersion.isEmpty())
+        {
+            return false;
+        }
+        return true;
+
+    default:
+        return false;
+    }
+
+    // We should not come here.
+    return false;
+}
+
+//////////// Public implementation ////////////////
+
+KQOAuthRequest::KQOAuthRequest(QObject *parent) :
+    QObject(parent),
+    d_ptr(new KQOAuthRequestPrivate)
+{
+    d_ptr->debugOutput = false;  // No debug output by default.
+    qsrand(QTime::currentTime().msec());  // We need to seed the nonce random number with something.
+                                          // However, we cannot do this while generating the nonce since
+                                          // we might get the same seed. So initializing here should be fine.
+}
+
+KQOAuthRequest::~KQOAuthRequest()
+{
+    delete d_ptr;
+}
+
+void KQOAuthRequest::initRequest(KQOAuthRequest::RequestType type, const QUrl &requestEndpoint) {
+    Q_D(KQOAuthRequest);
+
+    if (!requestEndpoint.isValid()) {
+        qWarning() << "Endpoint URL is not valid. Ignoring. This request might not work.";
+        return;
+    }
+
+    if (type < 0 || type > KQOAuthRequest::AuthorizedRequest) {
+        qWarning() << "Invalid request type. Ignoring. This request might not work.";
+        return;
+    }
+
+    // Clear the request
+    clearRequest();
+
+    // Set smart defaults.
+    d->requestType = type;
+    d->oauthRequestEndpoint = requestEndpoint;
+    d->oauthTimestamp_ = d->oauthTimestamp();
+    d->oauthNonce_ = d->oauthNonce();
+    this->setSignatureMethod(KQOAuthRequest::HMAC_SHA1);
+    this->setHttpMethod(KQOAuthRequest::POST);
+    d->oauthVersion = "1.0"; // Currently supports only version 1.0
+
+    d->contentType = "application/x-www-form-urlencoded";
+}
+
+void KQOAuthRequest::setConsumerKey(const QString &consumerKey) {
+    Q_D(KQOAuthRequest);
+    d->oauthConsumerKey = consumerKey;
+}
+
+void KQOAuthRequest::setConsumerSecretKey(const QString &consumerSecretKey) {
+    Q_D(KQOAuthRequest);
+    d->oauthConsumerSecretKey = consumerSecretKey;
+}
+
+void KQOAuthRequest::setCallbackUrl(const QUrl &callbackUrl) {
+    Q_D(KQOAuthRequest);
+
+    d->oauthCallbackUrl = callbackUrl;
+}
+
+void KQOAuthRequest::setSignatureMethod(KQOAuthRequest::RequestSignatureMethod requestMethod) {
+    Q_D(KQOAuthRequest);
+    QString requestMethodString;
+
+    switch (requestMethod) {
+    case KQOAuthRequest::PLAINTEXT:
+        requestMethodString = "PLAINTEXT";
+        break;
+    case KQOAuthRequest::HMAC_SHA1:
+        requestMethodString = "HMAC-SHA1";
+        break;
+    case KQOAuthRequest::RSA_SHA1:
+        requestMethodString = "RSA-SHA1";
+        break;
+    default:
+        // We should not come here
+        qWarning() << "Invalid signature method set.";
+        break;
+    }
+
+    d->oauthSignatureMethod = requestMethodString;
+}
+
+void KQOAuthRequest::setTokenSecret(const QString &tokenSecret) {
+    Q_D(KQOAuthRequest);
+
+    d->oauthTokenSecret = tokenSecret;
+}
+
+void KQOAuthRequest::setToken(const QString &token) {
+    Q_D(KQOAuthRequest);
+
+    d->oauthToken = token;
+}
+
+void KQOAuthRequest::setVerifier(const QString &verifier) {
+    Q_D(KQOAuthRequest);
+
+    d->oauthVerifier = verifier;
+}
+
+
+void KQOAuthRequest::setHttpMethod(KQOAuthRequest::RequestHttpMethod httpMethod) {
+    Q_D(KQOAuthRequest);
+
+    QString requestHttpMethodString;
+
+    switch (httpMethod) {
+    case KQOAuthRequest::GET:
+        requestHttpMethodString = "GET";
+        break;
+    case KQOAuthRequest::POST:
+        requestHttpMethodString = "POST";
+        break;
+    default:
+        qWarning() << "Invalid HTTP method set.";
+        break;
+    }
+
+    d->oauthHttpMethod = httpMethod;
+    d->oauthHttpMethodString = requestHttpMethodString;
+}
+
+KQOAuthRequest::RequestHttpMethod KQOAuthRequest::httpMethod() const {
+    Q_D(const KQOAuthRequest);
+
+    return d->oauthHttpMethod;
+}
+
+void KQOAuthRequest::setAdditionalParameters(const KQOAuthParameters &additionalParams) {
+    Q_D(KQOAuthRequest);
+
+    QList<QString> additionalKeys = additionalParams.keys();
+    QList<QString> additionalValues = additionalParams.values();
+
+    int i=0;
+    foreach(QString key, additionalKeys) {
+        QString value = additionalValues.at(i);
+        d->additionalParameters.append( qMakePair(key, value) );
+        i++;
+    }
+}
+
+KQOAuthParameters KQOAuthRequest::additionalParameters() const {
+    Q_D(const KQOAuthRequest);
+
+    QMultiMap<QString, QString> additionalParams;
+    for(int i=0; i<d->additionalParameters.size(); i++) {
+        additionalParams.insert(d->additionalParameters.at(i).first,
+                                d->additionalParameters.at(i).second);
+    }
+
+    return additionalParams;
+}
+
+KQOAuthRequest::RequestType KQOAuthRequest::requestType() const {
+    Q_D(const KQOAuthRequest);
+    return d->requestType;
+}
+
+QUrl KQOAuthRequest::requestEndpoint() const {
+    Q_D(const KQOAuthRequest);
+    return d->oauthRequestEndpoint;
+}
+
+QList<QByteArray> KQOAuthRequest::requestParameters() {
+    Q_D(KQOAuthRequest);
+
+    QList<QByteArray> requestParamList;
+
+    d->prepareRequest();
+    if (!isValid() ) {
+        qWarning() << "Request is not valid! I will still sign it, but it will probably not work.";
+    }
+    d->signRequest();
+
+    QPair<QString, QString> requestParam;
+    QString param;
+    QString value;
+    foreach (requestParam, d->requestParameters) {
+        param = requestParam.first;
+        value = requestParam.second;
+        requestParamList.append(QString(param + "=\"" + value +"\"").toUtf8());
+    }
+
+    return requestParamList;
+}
+
+QString KQOAuthRequest::contentType()
+{
+    Q_D(const KQOAuthRequest);
+    return d->contentType;
+}
+
+void KQOAuthRequest::setContentType(const QString &contentType)
+{
+    Q_D(KQOAuthRequest);
+    d->contentType = contentType;
+}
+
+QByteArray KQOAuthRequest::rawData()
+{
+    Q_D(const KQOAuthRequest);
+    return d->postRawData;
+}
+
+void KQOAuthRequest::setRawData(const QByteArray &rawData)
+{
+    Q_D(KQOAuthRequest);
+    d->postRawData = rawData;
+}
+
+QByteArray KQOAuthRequest::requestBody() const {
+    Q_D(const KQOAuthRequest);
+
+    QByteArray postBodyContent;
+    bool first = true;
+    for(int i=0; i < d->additionalParameters.size(); i++) {
+        if(!first) {
+            postBodyContent.append("&");
+        } else {
+            first = false;
+        }
+
+        QString key = d->additionalParameters.at(i).first;
+        QString value = d->additionalParameters.at(i).second;
+
+        postBodyContent.append(QUrl::toPercentEncoding(key) + QString("=").toUtf8() +
+                               QUrl::toPercentEncoding(value));
+    }
+    return postBodyContent;
+}
+
+bool KQOAuthRequest::isValid() const {
+    Q_D(const KQOAuthRequest);
+
+    return d->validateRequest();
+}
+
+void KQOAuthRequest::setTimeout(int timeoutMilliseconds) {
+    Q_D(KQOAuthRequest);
+    d->timeout = timeoutMilliseconds;
+}
+
+void KQOAuthRequest::clearRequest() {
+    Q_D(KQOAuthRequest);
+
+    d->oauthRequestEndpoint = "";
+    d->oauthHttpMethodString = "";
+    d->oauthConsumerKey = "";
+    d->oauthConsumerSecretKey = "";
+    d->oauthToken = "";
+    d->oauthTokenSecret = "";
+    d->oauthSignatureMethod = "";
+    d->oauthCallbackUrl = "";
+    d->oauthVerifier = "";
+    d->oauthTimestamp_ = "";
+    d->oauthNonce_ = "";
+    d->requestParameters.clear();
+    d->additionalParameters.clear();
+    d->timeout = 0;
+}
+
+void KQOAuthRequest::setEnableDebugOutput(bool enabled) {
+    Q_D(KQOAuthRequest);
+    d->debugOutput = enabled;
+}
+
+/**
+ * Protected implementations for inherited classes
+ */
+bool KQOAuthRequest::validateXAuthRequest() const {
+    Q_D(const KQOAuthRequest);
+
+    if (d->oauthRequestEndpoint.isEmpty()
+        || d->oauthConsumerKey.isEmpty()
+        || d->oauthNonce_.isEmpty()
+        || d->oauthSignatureMethod.isEmpty()
+        || d->oauthTimestamp_.isEmpty()
+        || d->oauthVersion.isEmpty())
+    {
+        return false;
+    }
+    return true;
+}
+
+
+/**
+ * Private implementations for friend classes
+ */
+QString KQOAuthRequest::consumerKeyForManager() const {
+    Q_D(const KQOAuthRequest);
+    return d->oauthConsumerKey;
+}
+
+QString KQOAuthRequest::consumerKeySecretForManager() const {
+    Q_D(const KQOAuthRequest);
+    return d->oauthConsumerSecretKey;
+}
+
+QUrl KQOAuthRequest::callbackUrlForManager() const {
+    Q_D(const KQOAuthRequest);
+    return d->oauthCallbackUrl;
+}
+
+void KQOAuthRequest::requestTimerStart()
+{
+    Q_D(KQOAuthRequest);
+    if (d->timeout > 0) {
+        connect(&(d->timer), SIGNAL(timeout()), this, SIGNAL(requestTimedout()));
+        d->timer.start(d->timeout);
+    }
+}
+
+void KQOAuthRequest::requestTimerStop()
+{
+    Q_D(KQOAuthRequest);
+    if (d->timeout > 0) {
+        disconnect(&(d->timer), SIGNAL(timeout()), this, SIGNAL(requestTimedout()));
+        d->timer.stop();
+    }
+}
diff --git a/libkqoauth/kqoauthrequest.h b/libkqoauth/kqoauthrequest.h
new file mode 100644 (file)
index 0000000..687daaf
--- /dev/null
@@ -0,0 +1,145 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHREQUEST_H
+#define KQOAUTHREQUEST_H
+
+#include <QObject>
+#include <QUrl>
+#include <QMultiMap>
+
+#include "kqoauthglobals.h"
+
+typedef QMultiMap<QString, QString> KQOAuthParameters;
+
+class KQOAuthRequestPrivate;
+class KQOAUTH_EXPORT KQOAuthRequest : public QObject
+{
+    Q_OBJECT
+public:
+    explicit KQOAuthRequest(QObject *parent = 0);
+    ~KQOAuthRequest();
+
+    enum RequestType {
+        TemporaryCredentials = 0,
+        AccessToken,
+        AuthorizedRequest
+    };
+
+    enum RequestSignatureMethod {
+        PLAINTEXT = 0,
+        HMAC_SHA1,
+        RSA_SHA1
+    };
+
+    enum RequestHttpMethod {
+        GET = 0,
+        POST
+    };
+
+    /**
+     * These methods can be overridden in child classes which are different types of
+     * OAuth requests.
+     */
+    // Validate the request of this type.
+    virtual bool isValid() const;
+
+    /**
+     * These methods are OAuth request type specific and not overridden in child
+     * classes.
+     * NOTE: Refactorting still a TODO
+     */
+    // Initialize the request of this type.
+    void initRequest(KQOAuthRequest::RequestType type, const QUrl &requestEndpoint);
+
+    void setConsumerKey(const QString &consumerKey);
+    void setConsumerSecretKey(const QString &consumerSecretKey);
+
+    // Mandatory methods for acquiring a request token
+    void setCallbackUrl(const QUrl &callbackUrl);
+
+    // Mandator methods for acquiring a access token
+    void setTokenSecret(const QString &tokenSecret);
+    void setToken(const QString &token);
+    void setVerifier(const QString &verifier);
+
+    // Request signature method to use - HMAC_SHA1 currently only supported
+    void setSignatureMethod(KQOAuthRequest::RequestSignatureMethod = KQOAuthRequest::HMAC_SHA1);
+
+    // Request's HTTP method.
+    void setHttpMethod(KQOAuthRequest::RequestHttpMethod = KQOAuthRequest::POST);
+    KQOAuthRequest::RequestHttpMethod httpMethod() const;
+
+    // Sets the timeout for this request. If the timeout expires, signal "requestTimedout" will be
+    // emitted from the manager.
+    // 0 = If set to zero, timeout is disabled.
+    // TODO: Do we need some request ID now?
+    void setTimeout(int timeoutMilliseconds);
+
+    // Additional optional parameters to the request.
+    void setAdditionalParameters(const KQOAuthParameters &additionalParams);
+    KQOAuthParameters additionalParameters() const;
+    QList<QByteArray> requestParameters();  // This will return all request's parameters in the raw format given
+                                            // to the QNetworkRequest.
+    QByteArray requestBody() const;         // This will return the POST body as given to the QNetworkRequest.
+
+    KQOAuthRequest::RequestType requestType() const;
+    QUrl requestEndpoint() const;
+
+    void setContentType(const QString &contentType);
+    QString contentType();
+
+    void setRawData(const QByteArray &rawData);
+    QByteArray rawData();
+
+    void clearRequest();
+
+    // Enable verbose debug output for request content.
+    void setEnableDebugOutput(bool enabled);
+
+Q_SIGNALS:
+    // This signal is emited if the request is not completed before the request's timeout
+    // value has expired.
+    void requestTimedout();
+
+protected:
+    bool validateXAuthRequest() const;
+
+private:
+    KQOAuthRequestPrivate * const d_ptr;
+    Q_DECLARE_PRIVATE(KQOAuthRequest);
+    Q_DISABLE_COPY(KQOAuthRequest);
+
+    // These classes are only for the internal use of KQOAuthManager so it can
+    // work with the opaque request.
+    QString consumerKeyForManager() const;
+    QString consumerKeySecretForManager() const;
+    QUrl callbackUrlForManager() const;
+
+    // This method is for timeout handling by the KQOAuthManager.
+    void requestTimerStart();
+    void requestTimerStop();
+
+    friend class KQOAuthManager;
+#ifdef UNIT_TEST
+    friend class Ut_KQOAuth;
+#endif
+};
+
+#endif // KQOAUTHREQUEST_H
diff --git a/libkqoauth/kqoauthrequest_1.cpp b/libkqoauth/kqoauthrequest_1.cpp
new file mode 100644 (file)
index 0000000..85449cf
--- /dev/null
@@ -0,0 +1,5 @@
+#include "kqoauthrequest_1.h"
+
+KQOAuthRequest_1::KQOAuthRequest_1()
+{
+}
diff --git a/libkqoauth/kqoauthrequest_1.h b/libkqoauth/kqoauthrequest_1.h
new file mode 100644 (file)
index 0000000..aecf90f
--- /dev/null
@@ -0,0 +1,12 @@
+#ifndef KQOAUTHREQUEST_1_H
+#define KQOAUTHREQUEST_1_H
+
+#include "kqoauthrequest.h"
+
+class KQOAUTH_EXPORT KQOAuthRequest_1 : public KQOAuthRequest
+{
+public:
+    KQOAuthRequest_1();
+};
+
+#endif // KQOAUTHREQUEST_1_H
diff --git a/libkqoauth/kqoauthrequest_p.h b/libkqoauth/kqoauthrequest_p.h
new file mode 100644 (file)
index 0000000..cfbf82e
--- /dev/null
@@ -0,0 +1,93 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHREQUEST_P_H
+#define KQOAUTHREQUEST_P_H
+#include "kqoauthglobals.h"
+#include "kqoauthrequest.h"
+
+#include <QString>
+#include <QUrl>
+#include <QMap>
+#include <QPair>
+#include <QMultiMap>
+#include <QTimer>
+
+class KQOAUTH_EXPORT KQOAuthRequestPrivate {
+
+public:
+    KQOAuthRequestPrivate();
+    ~KQOAuthRequestPrivate();
+
+    // Helper methods to get the values for the OAuth request parameters.
+    QString oauthTimestamp() const;
+    QString oauthNonce() const;
+    QString oauthSignature();
+
+    // Utility methods for making the request happen.
+    void prepareRequest();
+    void signRequest();
+    bool validateRequest() const;
+    QByteArray requestBaseString();
+    QByteArray encodedParamaterList(const QList< QPair<QString, QString> > &requestParameters);
+    void insertAdditionalParams();
+    void insertPostBody();
+
+    QUrl oauthRequestEndpoint;
+    KQOAuthRequest::RequestHttpMethod oauthHttpMethod;
+    QString oauthHttpMethodString;
+    QString oauthConsumerKey;
+    QString oauthConsumerSecretKey;
+    QString oauthToken;
+    QString oauthTokenSecret;
+    QString oauthSignatureMethod;
+    QUrl oauthCallbackUrl;
+    QString oauthVersion;
+    QString oauthVerifier;
+
+    // These will be generated by the helper methods
+    QString oauthTimestamp_;
+    QString oauthNonce_;
+
+    // User specified additional parameters needed for the request.
+    QList< QPair<QString, QString> > additionalParameters;
+
+     // The raw POST body content as given to the HTTP request.
+     QByteArray postBodyContent;
+
+    // Protocol parameters.
+    // These parameters are used in the "Authorized" header of the HTTP request.
+    QList< QPair<QString, QString> > requestParameters;
+
+    KQOAuthRequest::RequestType requestType;
+
+    //The Content-Type HTTP header
+    QString contentType;
+
+    //Raw data to post if type is not url-encoded
+    QByteArray postRawData;
+
+    // Timeout for this request in milliseconds.
+    int timeout;
+    QTimer timer;
+
+    bool debugOutput;
+
+};
+#endif // KQOAUTHREQUEST_P_H
diff --git a/libkqoauth/kqoauthrequest_xauth.cpp b/libkqoauth/kqoauthrequest_xauth.cpp
new file mode 100644 (file)
index 0000000..92aab5f
--- /dev/null
@@ -0,0 +1,89 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QtDebug>
+
+#include "kqoauthrequest_xauth_p.h"
+#include "kqoauthrequest_xauth.h"
+
+/**
+ * Private d_ptr implementations.
+ */
+KQOAuthRequest_XAuthPrivate::KQOAuthRequest_XAuthPrivate()
+{
+
+}
+
+KQOAuthRequest_XAuthPrivate::~KQOAuthRequest_XAuthPrivate()
+{
+}
+
+/**
+ * Public implementations.
+ */
+KQOAuthRequest_XAuth::KQOAuthRequest_XAuth(QObject *parent) :
+        KQOAuthRequest(parent),
+        d_ptr(new KQOAuthRequest_XAuthPrivate)
+{
+}
+
+bool KQOAuthRequest_XAuth::isValid() const {
+    // An xAuth can never request temporary credentials.
+    if (requestType() == KQOAuthRequest::TemporaryCredentials) {
+        qWarning() << "XAuth request cannot be of type KQOAuthRequest::TemporaryCredentials. Aborting.";
+        return false;
+    }
+
+    // Access token must always be retrieved using the POST HTTP method.
+    if (requestType() == KQOAuthRequest::AccessToken
+        && httpMethod() != KQOAuthRequest::POST) {
+
+        qWarning() << "Access tokens must be fetched using the POST HTTP method. Aborting.";
+
+        return false;
+    }
+
+    if (!xauth_parameters_set) {
+        qWarning() << "No XAuth parameters set. Aborting.";
+        return false;
+    }
+
+    // And then check the validity of the XAuth request.
+    // Provided by the base class as a protected method for us.
+    return validateXAuthRequest();
+}
+
+void KQOAuthRequest_XAuth::setXAuthLogin(const QString &username,
+                                         const QString &password) {
+
+    if (username.isEmpty() || password.isEmpty()) {
+        qWarning() << "Username or password cannot be empty. Aborting.";
+        return;
+    }
+
+    xauth_parameters_set = true;
+
+    KQOAuthParameters xauthParams;
+    xauthParams.insert("x_auth_username", username);
+    xauthParams.insert("x_auth_password", password);
+    xauthParams.insert("x_auth_mode", "client_auth");
+
+    setAdditionalParameters(xauthParams);
+}
+
diff --git a/libkqoauth/kqoauthrequest_xauth.h b/libkqoauth/kqoauthrequest_xauth.h
new file mode 100644 (file)
index 0000000..4b12b70
--- /dev/null
@@ -0,0 +1,49 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHREQUEST_XAUTH_H
+#define KQOAUTHREQUEST_XAUTH_H
+
+#include "kqoauthrequest.h"
+#include "kqoauthrequest_1.h"
+
+class KQOAuthRequest_XAuthPrivate;
+class KQOAUTH_EXPORT KQOAuthRequest_XAuth : public KQOAuthRequest
+{
+    Q_OBJECT
+public:
+    KQOAuthRequest_XAuth(QObject *parent = 0);
+
+    /**
+     * These methods can be overridden in child classes which are different types of
+     * OAuth requests.
+     */
+    // Validate the request of this type.
+    bool isValid() const;
+
+    // Give the xAuth specific parameters.
+    void setXAuthLogin(const QString &username = "",
+                       const QString &password = "");
+
+private:
+    KQOAuthRequest_XAuthPrivate * const d_ptr;
+    bool xauth_parameters_set;
+};
+
+#endif // KQOAUTHREQUEST_XAUTH_H
diff --git a/libkqoauth/kqoauthrequest_xauth_p.h b/libkqoauth/kqoauthrequest_xauth_p.h
new file mode 100644 (file)
index 0000000..bc3ac4f
--- /dev/null
@@ -0,0 +1,14 @@
+#ifndef KQOAUTHREQUEST_XAUTH_P_H
+#define KQOAUTHREQUEST_XAUTH_P_H
+
+#include "kqoauthglobals.h"
+
+class KQOAuthRequest;
+class KQOAUTH_EXPORT KQOAuthRequest_XAuthPrivate
+{
+public:
+    KQOAuthRequest_XAuthPrivate();
+    ~KQOAuthRequest_XAuthPrivate();
+};
+
+#endif // KQOAUTHREQUEST_XAUTH_P_H
diff --git a/libkqoauth/kqoauthutils.cpp b/libkqoauth/kqoauthutils.cpp
new file mode 100644 (file)
index 0000000..d6518a7
--- /dev/null
@@ -0,0 +1,79 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <QString>
+#include <QCryptographicHash>
+#include <QByteArray>
+
+#include <QtDebug>
+#include "kqoauthutils.h"
+
+QString KQOAuthUtils::hmac_sha1(const QString &message, const QString &key)
+{
+    QByteArray keyBytes = key.toAscii();
+    int keyLength;              // Lenght of key word
+    const int blockSize = 64;   // Both MD5 and SHA-1 have a block size of 64.
+
+    keyLength = keyBytes.size();
+    // If key is longer than block size, we need to hash the key
+    if (keyLength > blockSize) {
+        QCryptographicHash hash(QCryptographicHash::Sha1);
+        hash.addData(keyBytes);
+        keyBytes = hash.result();
+    }
+
+    /* http://tools.ietf.org/html/rfc2104  - (1) */
+    // Create the opad and ipad for the hash function.
+    QByteArray ipad;
+    QByteArray opad;
+
+    ipad.fill( 0, blockSize);
+    opad.fill( 0, blockSize);
+
+    ipad.replace(0, keyBytes.length(), keyBytes);
+    opad.replace(0, keyBytes.length(), keyBytes);
+
+    /* http://tools.ietf.org/html/rfc2104 - (2) & (5) */
+    for (int i=0; i<64; i++) {
+        ipad[i] = ipad[i] ^ 0x36;
+        opad[i] = opad[i] ^ 0x5c;
+    }
+
+    QByteArray workArray;
+    workArray.clear();
+
+    workArray.append(ipad, 64);
+    /* http://tools.ietf.org/html/rfc2104 - (3) */
+    workArray.append(message.toAscii());
+
+
+    /* http://tools.ietf.org/html/rfc2104 - (4) */
+    QByteArray sha1 = QCryptographicHash::hash(workArray, QCryptographicHash::Sha1);
+
+    /* http://tools.ietf.org/html/rfc2104 - (6) */
+    workArray.clear();
+    workArray.append(opad, 64);
+    workArray.append(sha1);
+
+    sha1.clear();
+
+    /* http://tools.ietf.org/html/rfc2104 - (7) */
+    sha1 = QCryptographicHash::hash(workArray, QCryptographicHash::Sha1);
+    return QString(sha1.toBase64());
+}
diff --git a/libkqoauth/kqoauthutils.h b/libkqoauth/kqoauthutils.h
new file mode 100644 (file)
index 0000000..bb9edbb
--- /dev/null
@@ -0,0 +1,33 @@
+/**
+ * KQOAuth - An OAuth authentication library for Qt.
+ *
+ * Author: Johan Paul (johan.paul@d-pointer.com)
+ *         http://www.d-pointer.com
+ *
+ *  KQOAuth is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU Lesser General Public License as published by
+ *  the Free Software Foundation, either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  KQOAuth 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 Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public License
+ *  along with KQOAuth.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef KQOAUTHUTILS_H
+#define KQOAUTHUTILS_H
+
+#include "kqoauthglobals.h"
+
+class QString;
+class KQOAUTH_EXPORT KQOAuthUtils
+{
+public:
+
+    static QString hmac_sha1(const QString &message, const QString &key);
+};
+
+#endif // KQOAUTHUTILS_H
diff --git a/main-daemon.cpp b/main-daemon.cpp
new file mode 100644 (file)
index 0000000..be44174
--- /dev/null
@@ -0,0 +1,16 @@
+#include <QtCore/QCoreApplication>
+#include "latitudedaemon.h"
+
+int main(int argc, char *argv[]) {
+    qDebug() << "* main";
+    QCoreApplication::setOrganizationName("linfati.com");
+    QCoreApplication::setOrganizationDomain("linfati.com");
+    QCoreApplication::setApplicationName("latitudeupdater");
+
+    QCoreApplication lu(argc, argv);
+
+    LatitudeDaemon mygui;
+    Q_UNUSED(mygui)
+
+    return lu.exec();
+}
diff --git a/main-qml.cpp b/main-qml.cpp
new file mode 100644 (file)
index 0000000..1b6b9eb
--- /dev/null
@@ -0,0 +1,15 @@
+#include <QtGui/QApplication>
+#include "latitudeqml.h"
+
+int main(int argc, char *argv[]) {
+    qDebug() << "* main";
+    QCoreApplication::setOrganizationName("linfati.com");
+    QCoreApplication::setOrganizationDomain("linfati.com");
+    QCoreApplication::setApplicationName("latitudeupdater");
+
+    QApplication lu(argc, argv);
+    LatitudeQML mygui;
+    mygui.show();
+
+    return lu.exec();
+}
diff --git a/main-widget.cpp b/main-widget.cpp
new file mode 100644 (file)
index 0000000..111498a
--- /dev/null
@@ -0,0 +1,15 @@
+#include <QtGui/QApplication>
+#include "latitudewidget.h"
+
+int main(int argc, char *argv[]) {
+    qDebug() << "* main";
+    QCoreApplication::setOrganizationName("linfati.com");
+    QCoreApplication::setOrganizationDomain("linfati.com");
+    QCoreApplication::setApplicationName("latitudeupdater");
+
+    QApplication lu(argc, argv);
+    LatitudeGUI mygui;
+    mygui.show();
+
+    return lu.exec();
+}
diff --git a/not_used/glupdater b/not_used/glupdater
new file mode 100644 (file)
index 0000000..62c9362
--- /dev/null
@@ -0,0 +1,13 @@
+author "Danilo Luvizotto <danilo.luvizotto@gmail.com>"
+description "Google Latitude Updater Daemon"
+
+start on started hildon-desktop
+
+console output
+
+post-stop script
+    killall -9 GoogleLatitudeDaemon
+end script
+
+exec /bin/su - user -c "/opt/linfati.com/GoogleLatitudeDaemon --init"
+
diff --git a/not_used/gpsmaemo5.cpp b/not_used/gpsmaemo5.cpp
new file mode 100644 (file)
index 0000000..e5c8869
--- /dev/null
@@ -0,0 +1,110 @@
+#include "gps.h"
+
+GpsMaemo5::GpsMaemo5(QObject *parent) :
+        QObject(parent),
+        latitude(0), longitude(0), accuracy(0),
+        interval(1800), wait(30), method("cell"),
+        emitfix(false), stopgps(true) {
+#ifdef Q_WS_MAEMO_5
+    control = location_gpsd_control_get_default();
+    device = (LocationGPSDevice*) g_object_new(LOCATION_TYPE_GPS_DEVICE, NULL);
+    g_signal_connect(device, "changed", G_CALLBACK(GpsMaemo5_changed), this);
+#else
+    urlloc = QUrl::fromEncoded("http://www.google.com/loc/json");
+    worker = new QNetworkAccessManager();
+    connect(worker, SIGNAL(finished(QNetworkReply *)), this, SLOT(gloc_reply(QNetworkReply *)));
+#endif // Q_WS_MAEMO_5
+}
+
+void GpsMaemo5::refresh() {
+    if ( stopgps ) return;
+    qDebug() << "GpsMaemo5: refresh";
+
+    QTimer::singleShot(interval*1000, this, SLOT(refresh()));
+    QTimer::singleShot(wait*1000, this, SLOT(stop()));
+
+#if QT_VERSION >= QT_VERSION_CHECK(4, 7, 0)
+    QNetworkConfigurationManager mgr;
+    if (!mgr.isOnline()) {
+        qDebug() << "GpsMaemo5: offline";
+        return;
+    }
+#endif
+
+#ifdef Q_WS_MAEMO_5
+    if ( method == QString("cell") ) {
+        g_object_set(G_OBJECT(control), "preferred-method", LOCATION_METHOD_ACWP, NULL);
+    } else if ( method == QString("both") ) {
+        g_object_set(G_OBJECT(control), "preferred-method", LOCATION_METHOD_USER_SELECTED, NULL);
+    } else if ( method == QString("agps") ) {
+        g_object_set(G_OBJECT(control), "preferred-method", LOCATION_METHOD_AGNSS, NULL);
+    } else {
+        g_object_set(G_OBJECT(control), "preferred-method", LOCATION_METHOD_ACWP, NULL);
+    }
+    location_gpsd_control_start(control);
+#else
+    worker->post(QNetworkRequest(urlloc), QByteArray("{version:\"1.1.0\"}"));
+#endif // Q_WS_MAEMO_5
+}
+
+void GpsMaemo5::stop() {
+    qDebug() << "GpsMaemo5: stop";
+#ifdef Q_WS_MAEMO_5
+    location_gpsd_control_stop(control);
+#else
+#endif // Q_WS_MAEMO_5
+    if (emitfix) {
+        emitfix = false;
+        emit fix();
+    }
+}
+
+void GpsMaemo5::forcestop() {
+    qDebug() << "GpsMaemo5: forcestop";
+    stopgps = true;
+    emitfix = false;
+    stop();
+}
+
+int GpsMaemo5::config(int i, int w, QString m) {
+    qDebug() << "GpsMaemo5: config";
+    stopgps = false;
+    interval = i;
+    wait = w;
+    method = m;
+    return 0;
+}
+
+#ifdef Q_WS_MAEMO_5
+void GpsMaemo5_changed(LocationGPSDevice *device, GpsMaemo5 *gps) {
+    if (device->fix) {
+        if (device->fix->fields) {
+            if ( isnan(gps->device->fix->eph) ) return;
+            g_print("GpsMaemo5 lat %f lon %f eph %f\n", gps->device->fix->latitude, gps->device->fix->longitude, gps->device->fix->eph/100.);
+            gps->latitude = gps->device->fix->latitude;
+            gps->longitude = gps->device->fix->longitude;
+            gps->accuracy = gps->device->fix->eph/100.;
+            gps->emitfix = true;
+        }
+    }
+}
+#else
+void GpsMaemo5::gloc_reply(QNetworkReply *r) {
+    if ( r->url() == urlloc ) {
+        QString loc = r->readAll();
+        QRegExp regexp ("\\{\"latitude\":(.*),\"longitude\":(.*),\"accuracy\":(.*)\\}");
+        regexp.setMinimal(1);
+        regexp.indexIn(loc, 1);
+        latitude = regexp.capturedTexts().at(1).toDouble();
+        longitude = regexp.capturedTexts().at(2).toDouble();
+        accuracy = regexp.capturedTexts().at(3).toDouble();
+        if ( accuracy > 100000 ) accuracy = 100000;
+        qDebug() << "GpsIP lat" << latitude << "lon" << longitude << "acc" << accuracy;
+        emitfix = true;
+    } else {
+        qDebug() << "GpsIP Error url" << r->url();
+        qDebug() << r->rawHeaderList();
+        qDebug() << r->readAll();
+    }
+}
+#endif // Q_WS_MAEMO_5
diff --git a/not_used/gpsmaemo5.h b/not_used/gpsmaemo5.h
new file mode 100644 (file)
index 0000000..c0ba709
--- /dev/null
@@ -0,0 +1,63 @@
+#ifndef GPS_H
+#define GPS_H
+
+#include <QtCore>
+#include <QtNetwork>
+
+#ifdef Q_WS_MAEMO_5
+extern "C" {
+#include <location/location-gps-device.h>
+#include <location/location-gpsd-control.h>
+}
+#else
+#include <QtNetwork>
+#endif // Q_WS_MAEMO_5
+
+class GpsMaemo5 : public QObject {
+    Q_OBJECT
+
+signals:
+    void fix();
+
+public:
+    GpsMaemo5(QObject *parent = 0);
+    double get_lat() { return latitude; }
+    double get_lon() { return longitude; }
+    double get_acc() { return accuracy; }
+
+public slots:
+    void refresh();
+    void stop();
+    void forcestop();
+    int config(int i, int w, QString m);
+
+private slots:
+#ifdef Q_WS_MAEMO_5
+    friend void GpsMaemo5_changed(LocationGPSDevice *device, GpsMaemo5 *gps);
+#else
+    void gloc_reply(QNetworkReply *r);
+#endif // Q_WS_MAEMO_5
+
+private:
+    double latitude;
+    double longitude;
+    double accuracy;
+    int interval;
+    int wait;
+    QString method;
+    bool emitfix;
+    bool stopgps;
+#ifdef Q_WS_MAEMO_5
+    LocationGPSDControl *control;
+    LocationGPSDevice *device;
+#else
+    QUrl urlloc;
+    QNetworkAccessManager *worker;
+#endif // Q_WS_MAEMO_5
+};
+
+#ifdef Q_WS_MAEMO_5
+void GpsMaemo5_changed(LocationGPSDevice *device, GpsMaemo5 *gps);
+#endif // Q_WS_MAEMO_5
+
+#endif // GPS_H
diff --git a/qml/MainPage.qml b/qml/MainPage.qml
new file mode 100644 (file)
index 0000000..17f9154
--- /dev/null
@@ -0,0 +1,238 @@
+import QtQuick 1.0
+import com.meego 1.0
+
+Page {
+    id: mainPage
+    Column {
+        spacing: 16
+        Row {
+            width: rootWindow.width
+            Button {
+                id: do_auth
+                width: rootWindow.width / 3
+                text: "Auth"
+                enabled: false
+                onClicked: {
+                    Qt.openUrlExternally(latitude.getUserAuthorization())
+                }
+            }
+            Button {
+                id: do_start
+                width: rootWindow.width / 3
+                text: "Start"
+                enabled: false
+                onClicked: {
+                    do_start.enabled = false;
+                    do_stop.enabled = true;
+                    gps.startUpdates()
+                }
+            }
+            Button {
+                id: do_stop
+                width: rootWindow.width / 3
+                text: "Stop"
+                enabled: false
+                onClicked: {
+                    do_start.enabled = true;
+                    do_stop.enabled = false;
+                    gps.stopUpdates(true)
+                }
+            }
+        }
+        Row {
+            width: rootWindow.width
+            Label {
+                id: pos_label
+                text: "Position"
+                width: rootWindow.width / 4
+                anchors.verticalCenter: position.verticalCenter
+            }
+            Row {
+                id: position
+                width: rootWindow.width * 3 / 4
+                TextField  {
+                    id: pos_lat
+                    width: parent / 4
+                    placeholderText: "pos_lat"
+                    readOnly: true
+                }
+                TextField {
+                    id: pos_lon
+                    width: parent / 4
+                    placeholderText: "pos_lon"
+                    readOnly: true
+                }
+                TextField {
+                    id: pos_acc
+                    width: parent / 4
+                    placeholderText: "pos_acc"
+                    readOnly: true
+                }
+                TextField {
+                    id: pos_tis
+                    width: parent / 4
+                    placeholderText: "pos_tis"
+                    readOnly: true
+                }
+            }
+        }
+        Row {
+            Label {
+                id: method_label
+                text: "Method"
+                width: rootWindow.width / 4
+                anchors.verticalCenter: method_button.verticalCenter
+            }
+            ButtonRow {
+                id: method_button
+                width: rootWindow.width * 2 / 3
+                Button {
+                    id: method_cell
+                    text: "Cell Tower"
+                    checked: gps.getPositioningMethod() == "cell" ? true : false
+                    onClicked: gps.setPositioningMethod("cell")
+                }
+                Button {
+                    id: method_all
+                    text: "Both"
+                    checked: gps.getPositioningMethod() == "all" ? true : false
+                    onClicked: gps.setPositioningMethod("all")
+                }
+                Button {
+                    id: method_agps
+                    text: "Only GPS"
+                    checked: gps.getPositioningMethod() == "gps" ? true : false
+                    onClicked: gps.setPositioningMethod("gps")
+                }
+            }
+        }
+        Row {
+            Label {
+                id: timeout_label
+                text: "Time Out"
+                width: rootWindow.width / 4
+                anchors.verticalCenter: timeout_slider.verticalCenter
+            }
+            Slider {
+                id: timeout_slider
+                width: rootWindow.width / 2
+                valueIndicatorVisible: true
+                minimumValue: 5
+                maximumValue: 120
+                stepSize: 5
+                value: gps.getTimeOut()
+            }
+            Label {
+                id: timeout_value
+                text: timeout_slider.value + " seg."
+                width: rootWindow.width / 4
+                anchors.verticalCenter: timeout_slider.verticalCenter
+            }
+            Connections {
+                target: timeout_slider
+                onValueChanged: {
+                    timeout_value.text = timeout_slider.value + " seg."
+                    gps.setTimeOut(timeout_slider.value)
+                }
+            }
+        }
+        Row {
+            Label {
+                id: interval_label
+                text: "Interval"
+                width: rootWindow.width / 4
+                anchors.verticalCenter: interval_slider.verticalCenter
+            }
+            Slider {
+                id: interval_slider
+                width: rootWindow.width / 2
+                valueIndicatorVisible: true
+                minimumValue: 5
+                maximumValue: 60
+                stepSize: 5
+                value: gps.getInterval() / 60
+            }
+            Label {
+                id: interval_value
+                text:  interval_slider.value + " min."
+                width: rootWindow.width / 4
+                anchors.verticalCenter: interval_slider.verticalCenter
+            }
+            Connections {
+                target: interval_slider
+                onValueChanged: {
+                    interval_value.text = interval_slider.value + " min."
+                    gps.setInterval(interval_slider.value*60)
+                }
+            }
+        }
+        Row {
+            Label {
+                id: connect_label
+                text: "Auto Connect"
+                width: rootWindow.width / 4
+                anchors.verticalCenter: connect_switch.verticalCenter
+            }
+            Switch {
+                id: connect_switch
+                width: rootWindow.width / 2
+                checked: latitude.getAutoConnect() ? true : false
+                onCheckedChanged: {
+                    connect_value.text = checked
+                    latitude.setAutoConnect(checked)
+                }
+            }
+            Label {
+                id: connect_value
+                text:  connect_switch.checked
+                width: rootWindow.width / 4
+                anchors.verticalCenter: connect_switch.verticalCenter
+            }
+        }
+
+        Connections {
+            target: latitude
+            onGotToken: {
+                do_auth.enabled = false;
+                do_start.enabled = true;
+                do_stop.enabled = false;
+            }
+        }
+        Connections {
+            target: latitude
+            onNotToken: {
+                do_auth.enabled = true;
+                do_start.enabled = false;
+                do_stop.enabled = false;
+                gps.stopUpdates(true)
+            }
+        }
+        Connections {
+            target: latitude
+            onNeedAuth: {
+                do_auth.enabled = true;
+            }
+        }
+
+        Connections {
+            target: gps
+            onGotUpdate: {
+                pos_lat.text = gps.getCurrentLatitude()
+                pos_lon.text = gps.getCurrentLongitude()
+                pos_acc.text = gps.getCurrentAccuracy()
+                pos_tis.text = gps.getCurrentTimestamp()
+            }
+        }
+        Connections {
+            target: gps
+            onGotFix: {
+                pos_lat.text = gps.getCurrentLatitude()
+                pos_lon.text = gps.getCurrentLongitude()
+                pos_acc.text = gps.getCurrentAccuracy()
+                pos_tis.text = gps.getCurrentTimestamp()
+                latitude.setCurrentLocation(pos_lat.text, pos_lon.text, pos_acc.text)
+                latitude.sendCurrentLocation()
+            }
+        }
+    }
+}
diff --git a/qml/main.qml b/qml/main.qml
new file mode 100644 (file)
index 0000000..b77d0f9
--- /dev/null
@@ -0,0 +1,12 @@
+import QtQuick 1.0
+import com.meego 1.0
+
+PageStackWindow {
+    id: rootWindow
+    initialPage: mainPage
+    MainPage {
+        id: mainPage
+    }
+    showStatusBar: false
+    showToolBar: false
+}
diff --git a/qtc_packaging/debian_fremantle/README b/qtc_packaging/debian_fremantle/README
new file mode 100644 (file)
index 0000000..e407bf5
--- /dev/null
@@ -0,0 +1,10 @@
+The Debian Package latitudeupdater
+----------------------------
+
+Comments regarding the Package
+
+ -- Rodrigo Linfati <rodrigo@linfati.cl>  sab, 02 gen 2010 22:12:52 +0100
+
+Thanks to:
+         Joppu http://talk.maemo.org/member.php?u=24013
+         http://talk.maemo.org/showpost.php?p=449435&postcount=83
diff --git a/qtc_packaging/debian_fremantle/changelog b/qtc_packaging/debian_fremantle/changelog
new file mode 100644 (file)
index 0000000..7423439
--- /dev/null
@@ -0,0 +1,5 @@
+latitudeupdater (0.1-0) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Rodrigo Linfati <rodrigo@linfati.cl>  Thu, 21 Jul 2011 21:58:20 +0200
diff --git a/qtc_packaging/debian_fremantle/compat b/qtc_packaging/debian_fremantle/compat
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/qtc_packaging/debian_fremantle/control b/qtc_packaging/debian_fremantle/control
new file mode 100644 (file)
index 0000000..f56e759
--- /dev/null
@@ -0,0 +1,20 @@
+Source: latitudeupdater
+Section: user/navigation
+Priority: optional
+Maintainer: Rodrigo Linfati <rodrigo@linfati.cl>
+Build-Depends: debhelper (>= 5), libqt4-dev, libqtm-dev
+Standards-Version: 3.7.3
+Homepage: http://googlelatitude.garage.maemo.org/
+XSBC-Bugtracker: mailto:rodrigo@linfati.cl
+
+Package: latitudeupdater
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Google Latitude Updater
+ Google Latitude Updater is written in QT4.
+ Features:
+  - Retrieve location using Cell Tower and/or Gps and send to Google Latitude
+  - Run as Daemon
+XB-Maemo-Display-Name: LatitudeUpdater
+XB-Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAABrRJREFUaIHNmX9oHGUaxz+T3U3StNvG5tqYNgRNkzMH8XKeyxXleqUgaPHAnnpWOTiItCdivKtFkYJ/+IcoRbQXTgmU07YgFUVoK/3jKtiUu6PkIGkttN2kadIYzk2TbLJJ92d2dt73/pjM/pzZ3dnZyn1gmJl33nfm+8z7vM/7vDMKpvy1D/gL0GF+/UfnJtAP7uPQF8m+oBTW/WgdpMI/ji67yHl4bXN2ibuwUuryEx88iW9HKwBCCKSU6WMAKWXOsbHZrW+1md1n2h/jX2//e1O+WhMD6Oj4VStSSm5FFAJxl403ZBMFUx/IZ2t0knt/tt70mpkBeD36m5hLKHSdPeBEYlVY2nUAt0hSVwcrK7nXTA1QkKiaJCX11zMwMHDXReajadDX9zIASenCI5K4TJyhxqxxti/+v2PaA07FaxrMzsLYGCST+haNQmMjdHTomx3yB3g2pgYIIVgNGmU+ACYnYXAQrl3TzwHi8SFUdQJFuYfa2m24XD/B7W7KbsmhQwrNzaUNEBaCTA2wy7ffwtCQJBjUx0wsdoGamhH279/Jgw8+ixCCiYkJQqHrXLw4z8zM7zBC0HvvafT0pHjhhTrq660NsMLShcr1okAAzp0TqKo+nCKRI7z44nYeeeQgipKJkd3d3QDs2AHvv3+O6elf43KtBVxcueJiYWGU11/vsnyOlREVu1A4DGfOwMiIRMoaUqlZHnjgNK+++lrxhsAbbzxOOAxHj8YZH/ezfftVenv/WFR89sSWjWUUKsU338DlywIpFUDicn3OSy/1lmxnEImAqqo8/PCVouINPbZ6oBwXunRJQ9P0wByNnuHNN39LbW1tGdJ1Wlrgscdu4POVNrqiMSCEdaOrVyEazcwqhw//ho0bN5YUko/P5yurXrEoZNuFpISRkdyySsTbodg8YGqA0ciMSARmZtTsmo4Fmj+/PD22o9DUFMzNZc41bQm4pwKJhcTj+pavVQiBYncQW+W5wSAI4UmfK4rHtF65aBqkUpBI6HsrqhaFPAV67a8XDNFGnlSKisJodhTSNH1fUwNbtgAkAH3eV5Q1SEl6M1xPCD13T6UKXcIuxSaysnpgaSlzvLwM58/HkbIeIXRxi4vOBJZCSmm5cLM9BrZuBa83TiiUGbizs4s0N5cOpdEoXLigJ39mHDoEmwpWvRW4kBACIRVTG1wuOHlyC7t3Z8qeeSbO4KDZ+MgwPLzExx//g+Hhf1JXp+LxSJLJV2hoeChdx0y8YYAtFzIaWfXbunW554qyld7eUT77zDqb9PkaOXbseeD5dNm+fTHGxiybFOoxoeJkTlXHc86//76LTz65VZ4amxTTY2qAPpEVz6eHhjrZufM/SKmly44fv5+BgViFMq2pKBcqpxfeeWc7nZ2ncspOnmxg794lgsHibYWg7GVrMT22c6F8jh17FlVdyCkLBBp5+ukEX32lr9jybxUIwNmzEAqVNwlWtKiXsoxPZqsMDTWxvLzE4cOfcv78H/B4mpGynv5+6O+3lEUs9h3btn3I3r1PsXv3U8BaSwOsZkPHa2KDDRsaeffdg5w+/SWnTg1z/XqcSKQdt3sLbnczoKCqN1HVMVpbA7S1eXj00V+yf/8XJe9dkQFlfbQ0Yc+e59iz5zkAwuE7zM/PMjc3y8LCPPfd56Ot7fd4vebfOYthPxeSNj4MWeD1rsfrXU97e6ej+zjOhd5662VHApxiex6QEpACpQq9UBVSydWXWujWZj1wc/p6pKO1aw2bw5PM7jwI5MZi4zixpgm1foMzceEgcvG/ADmTVfbztGiIOz8oCFH41cPMgP5Lf7/6N/e+n7Kp04uHuOVfk4ZklBhtjoyQAT8g05HG7G9NeDrJ1NfLpu2L/iNzu6VphimlpGlbA7/4Uzc1DR7CLT2VqQ8HUW98h//EOHemMx8K8n1e0+qMKwX/yCqLlQAc8YPS1dJVx0MHekg2tZNa01i2cBnwo4YTXHx7ApCj4NkFfbftqrBMJUrj2QVydGZ0hVRkBU9wAlesvKWZIX70xE2ciAdHBvTdNoy4cvTaqhGTpZuF59PiF28pOBEPjlwoG92dNne66Pnzz9E2dyDWNuVWCc8jfvCTiqw4dptsHPRANnpPzI1rqOEEyu0bKJHcfNoQ7z8+TrXEQ9UMyLjTtU9HSUVWUG7fSF+Vd+ZIRVYYPTFOaKqGaomHqrlQNro7NbVLul/pRkpZdbfJpko9kI3eEwuTCmo4sTpgq+s22dyFHgD46F5QBzfeL7uklISmXIC7pdri4a4ZYHDEr++r/+YN/gc9CxXyOCXFlQAAAABJRU5ErkJggg==
+
diff --git a/qtc_packaging/debian_fremantle/copyright b/qtc_packaging/debian_fremantle/copyright
new file mode 100644 (file)
index 0000000..73b9a6b
--- /dev/null
@@ -0,0 +1,34 @@
+This package was debianized by Rodrigo Linfati <rodrigo@linfati.cl> on
+sab, 02 gen 2010 22:12:52 +0100.
+
+It was downloaded from <http://googlelatitude.garage.maemo.org/>
+
+Upstream Author(s):
+
+    Rodrigo Linfati <rodrigo@linfati.cl>
+
+Copyright:
+
+    Copyright (C) 2009 Rodrigo Linfati
+
+License:
+
+    This package is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This package 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU Lesser General
+Public License can be found in `/usr/share/common-licenses/LGPL'.
+
+The Debian packaging is (C) 2010, Rodrigo Linfati <rodrigo@linfati.cl> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
diff --git a/qtc_packaging/debian_fremantle/rules b/qtc_packaging/debian_fremantle/rules
new file mode 100755 (executable)
index 0000000..501d645
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # qmake PREFIX=/usr# Uncomment this line for use without Qt Creator
+
+       touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp  
+       dh_testdir
+
+       # Add here commands to compile the package.
+       # $(MAKE) # Uncomment this line for use without Qt Creator
+       #docbook-to-man debian/latitudeupdater.sgml > latitudeupdater.1
+
+       touch $@
+
+clean: 
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       $(MAKE) clean
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/latitudeupdater.
+       $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/latitudeupdater install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+#      dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_makeshlibs
+       dh_installdeb
+       # dh_shlibdeps # Uncomment this line for use without Qt Creator
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/qtc_packaging/debian_harmattan/README b/qtc_packaging/debian_harmattan/README
new file mode 100644 (file)
index 0000000..56bc3c9
--- /dev/null
@@ -0,0 +1,10 @@
+The Debian Package latitudeupdater
+----------------------------
+
+Comments regarding the Package
+
+ -- Rodrigo Linfati <rodrigo@linfati.cl>  sab, 02 gen 2010 22:12:52 +0100
+
+Thanks to:
+        Joppu http://talk.maemo.org/member.php?u=24013
+        http://talk.maemo.org/showpost.php?p=449435&postcount=83
diff --git a/qtc_packaging/debian_harmattan/changelog b/qtc_packaging/debian_harmattan/changelog
new file mode 100644 (file)
index 0000000..7423439
--- /dev/null
@@ -0,0 +1,5 @@
+latitudeupdater (0.1-0) unstable; urgency=low
+
+  * Initial Release.
+
+ -- Rodrigo Linfati <rodrigo@linfati.cl>  Thu, 21 Jul 2011 21:58:20 +0200
diff --git a/qtc_packaging/debian_harmattan/compat b/qtc_packaging/debian_harmattan/compat
new file mode 100644 (file)
index 0000000..7f8f011
--- /dev/null
@@ -0,0 +1 @@
+7
diff --git a/qtc_packaging/debian_harmattan/control b/qtc_packaging/debian_harmattan/control
new file mode 100644 (file)
index 0000000..709b8e9
--- /dev/null
@@ -0,0 +1,20 @@
+Source: latitudeupdater
+Section: user/navigation
+Priority: optional
+Maintainer: Rodrigo Linfati <rodrigo@linfati.cl>
+Build-Depends: debhelper (>= 5), libqt4-dev, libqtm-dev
+Standards-Version: 3.7.3
+Homepage: http://googlelatitude.garage.maemo.org/
+XSBC-Bugtracker: mailto:rodrigo@linfati.cl
+
+Package: latitudeupdater
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends}
+Description: Google Latitude Updater
+ Google Latitude Updater is written in QT4.
+ Features:
+  - Retrieve location using Cell Tower and/or Gps and send to Google Latitude
+  - Run as Daemon
+XSBC-Maemo-Display-Name: LatitudeUpdater
+XB-Maemo-Icon-26: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAABrRJREFUaIHNmX9oHGUaxz+T3U3StNvG5tqYNgRNkzMH8XKeyxXleqUgaPHAnnpWOTiItCdivKtFkYJ/+IcoRbQXTgmU07YgFUVoK/3jKtiUu6PkIGkttN2kadIYzk2TbLJJ92d2dt73/pjM/pzZ3dnZyn1gmJl33nfm+8z7vM/7vDMKpvy1D/gL0GF+/UfnJtAP7uPQF8m+oBTW/WgdpMI/ji67yHl4bXN2ibuwUuryEx88iW9HKwBCCKSU6WMAKWXOsbHZrW+1md1n2h/jX2//e1O+WhMD6Oj4VStSSm5FFAJxl403ZBMFUx/IZ2t0knt/tt70mpkBeD36m5hLKHSdPeBEYlVY2nUAt0hSVwcrK7nXTA1QkKiaJCX11zMwMHDXReajadDX9zIASenCI5K4TJyhxqxxti/+v2PaA07FaxrMzsLYGCST+haNQmMjdHTomx3yB3g2pgYIIVgNGmU+ACYnYXAQrl3TzwHi8SFUdQJFuYfa2m24XD/B7W7KbsmhQwrNzaUNEBaCTA2wy7ffwtCQJBjUx0wsdoGamhH279/Jgw8+ixCCiYkJQqHrXLw4z8zM7zBC0HvvafT0pHjhhTrq660NsMLShcr1okAAzp0TqKo+nCKRI7z44nYeeeQgipKJkd3d3QDs2AHvv3+O6elf43KtBVxcueJiYWGU11/vsnyOlREVu1A4DGfOwMiIRMoaUqlZHnjgNK+++lrxhsAbbzxOOAxHj8YZH/ezfftVenv/WFR89sSWjWUUKsU338DlywIpFUDicn3OSy/1lmxnEImAqqo8/PCVouINPbZ6oBwXunRJQ9P0wByNnuHNN39LbW1tGdJ1Wlrgscdu4POVNrqiMSCEdaOrVyEazcwqhw//ho0bN5YUko/P5yurXrEoZNuFpISRkdyySsTbodg8YGqA0ciMSARmZtTsmo4Fmj+/PD22o9DUFMzNZc41bQm4pwKJhcTj+pavVQiBYncQW+W5wSAI4UmfK4rHtF65aBqkUpBI6HsrqhaFPAV67a8XDNFGnlSKisJodhTSNH1fUwNbtgAkAH3eV5Q1SEl6M1xPCD13T6UKXcIuxSaysnpgaSlzvLwM58/HkbIeIXRxi4vOBJZCSmm5cLM9BrZuBa83TiiUGbizs4s0N5cOpdEoXLigJ39mHDoEmwpWvRW4kBACIRVTG1wuOHlyC7t3Z8qeeSbO4KDZ+MgwPLzExx//g+Hhf1JXp+LxSJLJV2hoeChdx0y8YYAtFzIaWfXbunW554qyld7eUT77zDqb9PkaOXbseeD5dNm+fTHGxiybFOoxoeJkTlXHc86//76LTz65VZ4amxTTY2qAPpEVz6eHhjrZufM/SKmly44fv5+BgViFMq2pKBcqpxfeeWc7nZ2ncspOnmxg794lgsHibYWg7GVrMT22c6F8jh17FlVdyCkLBBp5+ukEX32lr9jybxUIwNmzEAqVNwlWtKiXsoxPZqsMDTWxvLzE4cOfcv78H/B4mpGynv5+6O+3lEUs9h3btn3I3r1PsXv3U8BaSwOsZkPHa2KDDRsaeffdg5w+/SWnTg1z/XqcSKQdt3sLbnczoKCqN1HVMVpbA7S1eXj00V+yf/8XJe9dkQFlfbQ0Yc+e59iz5zkAwuE7zM/PMjc3y8LCPPfd56Ot7fd4vebfOYthPxeSNj4MWeD1rsfrXU97e6ej+zjOhd5662VHApxiex6QEpACpQq9UBVSydWXWujWZj1wc/p6pKO1aw2bw5PM7jwI5MZi4zixpgm1foMzceEgcvG/ADmTVfbztGiIOz8oCFH41cPMgP5Lf7/6N/e+n7Kp04uHuOVfk4ZklBhtjoyQAT8g05HG7G9NeDrJ1NfLpu2L/iNzu6VphimlpGlbA7/4Uzc1DR7CLT2VqQ8HUW98h//EOHemMx8K8n1e0+qMKwX/yCqLlQAc8YPS1dJVx0MHekg2tZNa01i2cBnwo4YTXHx7ApCj4NkFfbftqrBMJUrj2QVydGZ0hVRkBU9wAlesvKWZIX70xE2ciAdHBvTdNoy4cvTaqhGTpZuF59PiF28pOBEPjlwoG92dNne66Pnzz9E2dyDWNuVWCc8jfvCTiqw4dptsHPRANnpPzI1rqOEEyu0bKJHcfNoQ7z8+TrXEQ9UMyLjTtU9HSUVWUG7fSF+Vd+ZIRVYYPTFOaKqGaomHqrlQNro7NbVLul/pRkpZdbfJpko9kI3eEwuTCmo4sTpgq+s22dyFHgD46F5QBzfeL7uklISmXIC7pdri4a4ZYHDEr++r/+YN/gc9CxXyOCXFlQAAAABJRU5ErkJggg==
+
diff --git a/qtc_packaging/debian_harmattan/copyright b/qtc_packaging/debian_harmattan/copyright
new file mode 100644 (file)
index 0000000..73b9a6b
--- /dev/null
@@ -0,0 +1,34 @@
+This package was debianized by Rodrigo Linfati <rodrigo@linfati.cl> on
+sab, 02 gen 2010 22:12:52 +0100.
+
+It was downloaded from <http://googlelatitude.garage.maemo.org/>
+
+Upstream Author(s):
+
+    Rodrigo Linfati <rodrigo@linfati.cl>
+
+Copyright:
+
+    Copyright (C) 2009 Rodrigo Linfati
+
+License:
+
+    This package is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This package 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
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this package; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
+
+On Debian systems, the complete text of the GNU Lesser General
+Public License can be found in `/usr/share/common-licenses/LGPL'.
+
+The Debian packaging is (C) 2010, Rodrigo Linfati <rodrigo@linfati.cl> and
+is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
diff --git a/qtc_packaging/debian_harmattan/rules b/qtc_packaging/debian_harmattan/rules
new file mode 100755 (executable)
index 0000000..501d645
--- /dev/null
@@ -0,0 +1,91 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # qmake PREFIX=/usr# Uncomment this line for use without Qt Creator
+
+       touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp  
+       dh_testdir
+
+       # Add here commands to compile the package.
+       # $(MAKE) # Uncomment this line for use without Qt Creator
+       #docbook-to-man debian/latitudeupdater.sgml > latitudeupdater.1
+
+       touch $@
+
+clean: 
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       $(MAKE) clean
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/latitudeupdater.
+       $(MAKE) INSTALL_ROOT="$(CURDIR)"/debian/latitudeupdater install
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+#      dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_python
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_makeshlibs
+       dh_installdeb
+       # dh_shlibdeps # Uncomment this line for use without Qt Creator
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/resouses.qrc b/resouses.qrc
new file mode 100644 (file)
index 0000000..3d7ed28
--- /dev/null
@@ -0,0 +1,6 @@
+<RCC>
+    <qresource prefix="/">
+        <file>qml/main.qml</file>
+        <file>qml/MainPage.qml</file>
+    </qresource>
+</RCC>