summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2015-11-13 17:21:43 -0800
committerGravatar Dirk Hohndel <dirk@hohndel.org>2015-11-13 17:21:43 -0800
commit7afed04520900906107774bb0d06f68dd142602e (patch)
tree3ab622544f5f7b9c7694c9f123f9d5ab6ccb8967
parent577da54454e83e448b3a9ba912b4ba58fa64d3ab (diff)
downloadsubsurface-7afed04520900906107774bb0d06f68dd142602e.tar.gz
Location service: upload GPS fixes to webservice
With this Subsurface-mobile should be able to mostly replace the companion app. This needs some more testing and fine tuning (for example the minimum time / distance should be configurable, there should be a location name), but I think the hard part is done now. Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--qt-mobile/gpslocation.cpp71
-rw-r--r--qt-mobile/gpslocation.h5
-rw-r--r--qt-mobile/qml/main.qml7
-rw-r--r--qt-mobile/qmlmanager.cpp5
4 files changed, 85 insertions, 3 deletions
diff --git a/qt-mobile/gpslocation.cpp b/qt-mobile/gpslocation.cpp
index f2bde130d..fc9767c65 100644
--- a/qt-mobile/gpslocation.cpp
+++ b/qt-mobile/gpslocation.cpp
@@ -4,8 +4,12 @@
#include "dive.h"
#include "helpers.h"
#include <time.h>
+#include <unistd.h>
#include <QDebug>
#include <QVariant>
+#include <QUrlQuery>
+#include <QApplication>
+#include <QTimer>
GpsLocation::GpsLocation(QObject *parent)
{
@@ -121,7 +125,7 @@ bool GpsLocation::applyLocations()
for (int j = last; j < cnt; j++) {
if (time_during_dive_with_offset(d, gpsTable[j].when, SAME_GROUP)) {
if (verbose)
- qDebug() << "processing gpsfix @" << get_dive_date_string(gpsTable[j].when) <<
+ qDebug() << "processing gpsFix @" << get_dive_date_string(gpsTable[j].when) <<
"which is withing six hours of dive from" <<
get_dive_date_string(d->when) << "until" <<
get_dive_date_string(d->when + d->duration.seconds);
@@ -131,7 +135,7 @@ bool GpsLocation::applyLocations()
*/
if (time_during_dive_with_offset(d, gpsTable[j].when, 0)) {
if (verbose)
- qDebug() << "gpsfix is during the dive, pick that one";
+ qDebug() << "gpsFix is during the dive, pick that one";
copy_gps_location(gpsTable + j, d);
changed = true;
last = j;
@@ -167,7 +171,7 @@ bool GpsLocation::applyLocations()
last = j;
break;
} else {
- /* ok, gpsfix is before, nextgpsfix is after */
+ /* ok, gpsFix is before, nextgpsFix is after */
if (d->when - gpsTable[j].when <= gpsTable[j+1].when - (d->when + d->duration.seconds)) {
if (verbose)
qDebug() << "pick the one before as it's closer to the start";
@@ -215,3 +219,64 @@ void GpsLocation::clearGpsData()
geoSettings->clear();
geoSettings->sync();
}
+
+void GpsLocation::postError(QNetworkReply::NetworkError error)
+{
+ status(QString("error when sending a GPS fix: %1").arg(reply->errorString()));
+}
+
+void GpsLocation::uploadToServer()
+{
+ // we want to do this one at a time (the server prefers that)
+ QEventLoop loop;
+ QTimer timer;
+ timer.setSingleShot(true);
+
+ QNetworkAccessManager *manager = new QNetworkAccessManager(qApp);
+ QUrl url("http://api.subsurface-divelog.org/api/dive/add/");
+ int count = geoSettings->value("count", 0).toInt();
+ for (int i = 0; i < count; i++) {
+ QDateTime dt;
+ QUrlQuery data;
+ if (geoSettings->contains(QString("gpsFix%1_uploaded").arg(i)))
+ continue;
+ time_t when = geoSettings->value(QString("gpsFix%1_time").arg(i), 0).toULongLong();
+ dt.setTime_t(when);
+ qDebug() << dt.toString() << get_dive_date_string(when);
+ data.addQueryItem("login", prefs.userid);
+ data.addQueryItem("dive_date", dt.toString("yyyy-MM-dd"));
+ data.addQueryItem("dive_time", dt.toString("hh:mm"));
+ data.addQueryItem("dive_latitude", QString::number(geoSettings->value(QString("gpsFix%1_lat").arg(i)).toInt() / 1000000.0));
+ data.addQueryItem("dive_longitude", QString::number(geoSettings->value(QString("gpsFix%1_lon").arg(i)).toInt() / 1000000.0));
+ status(data.toString(QUrl::FullyEncoded).toUtf8());
+ QNetworkRequest request;
+ request.setUrl(url);
+ request.setRawHeader("Accept", "text/json");
+ request.setRawHeader("Content-type", "application/x-www-form-urlencoded");
+ reply = manager->post(request, data.toString(QUrl::FullyEncoded).toUtf8());
+ connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit);
+ connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
+ // somehoe I cannot get this to work with the new connect syntax:
+ // connect(reply, &QNetworkReply::error, this, &GpsLocation::postError);
+ connect(reply, SIGNAL(error(QNetworkReply::NetworkError)),
+ this, SLOT(postError(QNetworkReply::NetworkError)));
+ timer.start(10000);
+ loop.exec();
+ if (timer.isActive()) {
+ timer.stop();
+ if (reply->error() != QNetworkReply::NoError) {
+ QString response = reply->readAll();
+ if (!response.contains("Duplicate entry")) {
+ status(QString("Server response:") + reply->readAll());
+ break;
+ }
+ }
+ } else {
+ status("Uploading to server timed out");
+ break;
+ }
+ reply->deleteLater();
+ status(QString("completed sending gps fix %1 - response: ").arg(i) + reply->readAll());
+ geoSettings->setValue(QString("gpsFix%1_uploaded").arg(i), 1);
+ }
+}
diff --git a/qt-mobile/gpslocation.h b/qt-mobile/gpslocation.h
index a8437cca2..ff7aa1ea4 100644
--- a/qt-mobile/gpslocation.h
+++ b/qt-mobile/gpslocation.h
@@ -7,6 +7,7 @@
#include <QGeoPositionInfoSource>
#include <QGeoPositionInfo>
#include <QSettings>
+#include <QNetworkReply>
class GpsLocation : QObject
{
@@ -21,6 +22,7 @@ private:
QGeoPositionInfoSource *gpsSource;
void status(QString msg);
QSettings *geoSettings;
+ QNetworkReply *reply;
signals:
@@ -28,7 +30,10 @@ public slots:
void serviceEnable(bool toggle);
void newPosition(QGeoPositionInfo pos);
void updateTimeout();
+ void uploadToServer();
+ void postError(QNetworkReply::NetworkError error);
void clearGpsData();
+
};
#endif // GPSLOCATION_H
diff --git a/qt-mobile/qml/main.qml b/qt-mobile/qml/main.qml
index d4b01cb33..f28a5795f 100644
--- a/qt-mobile/qml/main.qml
+++ b/qt-mobile/qml/main.qml
@@ -87,6 +87,13 @@ ApplicationWindow {
}
MenuItem {
+ text: "Send GPS data to server"
+ onTriggered: {
+ manager.sendGpsData();
+ }
+ }
+
+ MenuItem {
text: "Clear stored GPS data"
onTriggered: {
manager.clearGpsData();
diff --git a/qt-mobile/qmlmanager.cpp b/qt-mobile/qmlmanager.cpp
index 63de7d6e8..24a5fd8aa 100644
--- a/qt-mobile/qmlmanager.cpp
+++ b/qt-mobile/qmlmanager.cpp
@@ -158,6 +158,11 @@ void QMLManager::applyGpsData()
locationProvider->applyLocations();
}
+void QMLManager::sendGpsData()
+{
+ locationProvider->uploadToServer();
+}
+
void QMLManager::clearGpsData()
{
locationProvider->clearGpsData();