summaryrefslogtreecommitdiffstats
path: root/qt-ui
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-12-09 17:22:33 +0100
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-12-09 17:22:33 +0100
commit8ac58181f75e494a242126751646285d4db672bc (patch)
tree10ec814fc20f3ce53a46b1df767eff56422e64b7 /qt-ui
parent4675ab0617ed4536ad0196c7a09035b9c586dff7 (diff)
parent04b62a46e9f28f0e3b4a4f2e3c3aa9c18445df2f (diff)
downloadsubsurface-8ac58181f75e494a242126751646285d4db672bc.tar.gz
Merge branch 'web' of github.com:neolit123/subsurface
Diffstat (limited to 'qt-ui')
-rw-r--r--qt-ui/divelistview.cpp8
-rw-r--r--qt-ui/divelistview.h1
-rw-r--r--qt-ui/subsurfacewebservices.cpp194
-rw-r--r--qt-ui/subsurfacewebservices.h3
4 files changed, 186 insertions, 20 deletions
diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp
index a1c4cf7fc..06b691c17 100644
--- a/qt-ui/divelistview.cpp
+++ b/qt-ui/divelistview.cpp
@@ -8,6 +8,7 @@
#include "models.h"
#include "modeldelegates.h"
#include "mainwindow.h"
+#include "subsurfacewebservices.h"
#include "../display.h"
#include <QApplication>
#include <QHeaderView>
@@ -726,6 +727,8 @@ void DiveListView::contextMenuEvent(QContextMenuEvent *event)
popup.addAction(tr("export As UDDF"), this, SLOT(exportSelectedDivesAsUDDF()));
popup.addAction(tr("shift times"), this, SLOT(shiftTimes()));
}
+ if (d)
+ popup.addAction(tr("upload dive(s) to divelogs.de"), this, SLOT(uploadToDivelogsDE()));
// "collapse all" really closes all trips,
// "collapse" keeps the trip with the selected dive open
QAction * actionTaken = popup.exec(event->globalPos());
@@ -781,3 +784,8 @@ void DiveListView::shiftTimes()
{
ShiftTimesDialog::instance()->show();
}
+
+void DiveListView::uploadToDivelogsDE()
+{
+ DivelogsDeWebServices::instance()->prepareDivesForUpload();
+}
diff --git a/qt-ui/divelistview.h b/qt-ui/divelistview.h
index c20b6e822..f65a6780b 100644
--- a/qt-ui/divelistview.h
+++ b/qt-ui/divelistview.h
@@ -49,6 +49,7 @@ public slots:
void saveSelectedDivesAs();
void exportSelectedDivesAsUDDF();
void shiftTimes();
+ void uploadToDivelogsDE();
signals:
void currentDiveChanged(int divenr);
diff --git a/qt-ui/subsurfacewebservices.cpp b/qt-ui/subsurfacewebservices.cpp
index 193f7c41b..a336a4864 100644
--- a/qt-ui/subsurfacewebservices.cpp
+++ b/qt-ui/subsurfacewebservices.cpp
@@ -1,7 +1,6 @@
#include "subsurfacewebservices.h"
#include "../webservice.h"
#include "mainwindow.h"
-
#include <libxml/parser.h>
#include <zip.h>
#include <errno.h>
@@ -99,6 +98,97 @@ static void clear_table(struct dive_table *table)
table->nr = 0;
}
+static char *prepare_dives_for_divelogs(const bool selected)
+{
+ int i;
+ struct dive *dive;
+ FILE *f;
+ char filename[PATH_MAX], *tempfile;
+ size_t streamsize;
+ char *membuf;
+ xmlDoc *doc;
+ xsltStylesheetPtr xslt = NULL;
+ xmlDoc *transformed;
+ struct zip_source *s[dive_table.nr];
+ struct zip *zip;
+ char *error = NULL;
+
+ /* generate a random filename and create/open that file with zip_open */
+ QString tempfileQ = QDir::tempPath() + "/import-" + QString::number(qrand() % 99999999) + ".dld";
+ tempfile = tempfileQ.toLocal8Bit().data();
+ zip = zip_open(tempfile, ZIP_CREATE, NULL);
+
+ if (!zip) {
+ fprintf(stderr, "divelog.de-upload: cannot open file as zip\n");
+ return NULL;
+ }
+ if (!amount_selected) {
+ fprintf(stderr, "divelog.de-upload: no dives selected\n");
+ return NULL;
+ }
+
+ /* walk the dive list in chronological order */
+ for (i = 0; i < dive_table.nr; i++) {
+ dive = get_dive(i);
+ if (!dive)
+ continue;
+ if (selected && !dive->selected)
+ continue;
+ f = tmpfile();
+ if (!f) {
+ fprintf(stderr, "divelog.de-upload: cannot create temp file\n");
+ return NULL;
+ }
+ save_dive(f, dive);
+ fseek(f, 0, SEEK_END);
+ streamsize = ftell(f);
+ rewind(f);
+ membuf = (char *)malloc(streamsize + 1);
+ if (!membuf || !fread(membuf, streamsize, 1, f)) {
+ fprintf(stderr, "divelog.de-upload: memory error\n");
+ return NULL;
+ }
+ membuf[streamsize] = 0;
+ fclose(f);
+ /*
+ * Parse the memory buffer into XML document and
+ * transform it to divelogs.de format, finally dumping
+ * the XML into a character buffer.
+ */
+ doc = xmlReadMemory(membuf, strlen(membuf), "divelog", NULL, 0);
+ if (!doc) {
+ fprintf(stderr, "divelog.de-upload: xml error\n");
+ continue;
+ }
+ free((void *)membuf);
+ // this call is overriding our local variable tempfile! not a good sign!
+ xslt = get_stylesheet("divelogs-export.xslt");
+ if (!xslt) {
+ fprintf(stderr, "divelog.de-upload: missing stylesheet\n");
+ return NULL;
+ }
+ transformed = xsltApplyStylesheet(xslt, doc, NULL);
+ xsltFreeStylesheet(xslt);
+ xmlDocDumpMemory(transformed, (xmlChar **) &membuf, (int *)&streamsize);
+ xmlFreeDoc(doc);
+ xmlFreeDoc(transformed);
+ /*
+ * Save the XML document into a zip file.
+ */
+ snprintf(filename, PATH_MAX, "%d.xml", i + 1);
+ s[i] = zip_source_buffer(zip, membuf, streamsize, 1);
+ if (s[i]) {
+ int64_t ret = zip_add(zip, filename, s[i]);
+ if (ret == -1)
+ fprintf(stderr, "divelog.de-upload: failed to include dive %d\n", i);
+ }
+ }
+ zip_close(zip);
+ /* let's call this again */
+ tempfile = tempfileQ.toLocal8Bit().data();
+ return tempfile;
+}
+
WebServices::WebServices(QWidget* parent, Qt::WindowFlags f): QDialog(parent, f)
, reply(0)
{
@@ -237,9 +327,11 @@ void SubsurfaceWebServices::buttonClicked(QAbstractButton* button)
}
break;
case QDialogButtonBox::RejectRole:
- // we may want to clean up after ourselves
- // reply->deleteLater();
- reply = NULL;
+ if (reply != NULL && reply->isOpen()) {
+ reply->abort();
+ delete reply;
+ reply = NULL;
+ }
resetState();
break;
case QDialogButtonBox::HelpRole:
@@ -447,20 +539,47 @@ void DivelogsDeWebServices::downloadDives()
exec();
}
+void DivelogsDeWebServices::prepareDivesForUpload()
+{
+ QString errorText(tr("Cannot create DLD file"));
+ char *filename = prepare_dives_for_divelogs(true);
+ if (filename) {
+ QFile f(filename);
+ if (f.exists()) {
+ f.open(QIODevice::ReadOnly);
+ uploadDives((QIODevice *)&f);
+ f.close();
+ f.remove();
+ return;
+ }
+ mainWindow()->showError(errorText.append(": ").append(filename));
+ return;
+ }
+ mainWindow()->showError(errorText.append("!"));
+}
+
void DivelogsDeWebServices::uploadDives(QIODevice *dldContent)
{
QHttpMultiPart mp(QHttpMultiPart::FormDataType);
QHttpPart part;
- part.setRawHeader("Content-Disposition", "form-data; name=\"userfile\"");
+ QFile *f = (QFile *)dldContent;
+ QFileInfo fi(*f);
+ QString args("form-data; name=\"userfile\"; filename=\"" + fi.absoluteFilePath() + "\"");
+ part.setRawHeader("Content-Disposition", args.toLatin1());
part.setBodyDevice(dldContent);
mp.append(part);
multipart = &mp;
hideDownload();
+ resetState();
exec();
- multipart = NULL;
- delete reply; // we need to ensure it has stopped using our QHttpMultiPart
+ multipart = NULL;
+ if (reply != NULL && reply->isOpen()) {
+ reply->abort();
+ delete reply;
+ reply = NULL;
+ }
}
DivelogsDeWebServices::DivelogsDeWebServices(QWidget* parent, Qt::WindowFlags f): WebServices(parent, f)
@@ -473,6 +592,11 @@ DivelogsDeWebServices::DivelogsDeWebServices(QWidget* parent, Qt::WindowFlags f)
void DivelogsDeWebServices::startUpload()
{
+ QSettings s;
+ s.setValue("divelogde_user", ui.userID->text());
+ s.setValue("divelogde_pass", ui.password->text());
+ s.sync();
+
ui.status->setText(tr("Uploading dive list..."));
ui.progressBar->setRange(0,0); // this makes the progressbar do an 'infinite spin'
ui.upload->setEnabled(false);
@@ -638,8 +762,25 @@ void DivelogsDeWebServices::uploadFinished()
// check what the server sent us: it might contain
// an error condition, such as a failed login
QByteArray xmlData = reply->readAll();
-
- // ### FIXME: what's the format?
+ reply->deleteLater();
+ reply = NULL;
+ char *resp = xmlData.data();
+ if (resp) {
+ char *parsed = strstr(resp, "<Login>");
+ if (parsed) {
+ if (strstr(resp, "<Login>succeeded</Login>")) {
+ if (strstr(resp, "<FileCopy>failed</FileCopy>")) {
+ ui.status->setText(tr("Upload failed"));
+ return;
+ }
+ ui.status->setText(tr("Upload successful"));
+ return;
+ }
+ ui.status->setText(tr("Login failed"));
+ return;
+ }
+ ui.status->setText(tr("Cannot parse response"));
+ }
}
void DivelogsDeWebServices::setStatusText(int status)
@@ -650,7 +791,7 @@ void DivelogsDeWebServices::setStatusText(int status)
void DivelogsDeWebServices::downloadError(QNetworkReply::NetworkError)
{
resetState();
- ui.status->setText(tr("Download error: %1").arg(reply->errorString()));
+ ui.status->setText(tr("Error: %1").arg(reply->errorString()));
reply->deleteLater();
reply = NULL;
}
@@ -663,22 +804,37 @@ void DivelogsDeWebServices::uploadError(QNetworkReply::NetworkError error)
void DivelogsDeWebServices::buttonClicked(QAbstractButton* button)
{
ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false);
-
switch(ui.buttonBox->buttonRole(button)){
case QDialogButtonBox::ApplyRole:{
- char *errorptr = NULL;
- parse_file(zipFile.fileName().toUtf8().constData(), &errorptr);
+ /* parse file and import dives */
+ char *error = NULL;
+ parse_file(zipFile.fileName().toLocal8Bit().data(), &error);
+ if (error != NULL) {
+ mainWindow()->showError(error);
+ free(error);
+ }
process_dives(TRUE, FALSE);
- // ### FIXME: do something useful with the error - but there shouldn't be one, right?
- if (errorptr)
- qDebug() << errorptr;
+ mainWindow()->refreshDisplay();
+ /* store last entered user/pass in config */
+ QSettings s;
+ s.setValue("divelogde_user", ui.userID->text());
+ s.setValue("divelogde_pass", ui.password->text());
+ s.sync();
hide();
close();
resetState();
- mark_divelist_changed(TRUE);
- mainWindow()->refreshDisplay();
}
+ break;
+ case QDialogButtonBox::RejectRole:
+ // these two seem to be causing a crash:
+ // reply->deleteLater();
+ resetState();
+ break;
+ case QDialogButtonBox::HelpRole:
+ QDesktopServices::openUrl(QUrl("http://divelogs.de"));
+ break;
+ default:
+ break;
}
}
-
diff --git a/qt-ui/subsurfacewebservices.h b/qt-ui/subsurfacewebservices.h
index 3c41b08d1..07f902b8f 100644
--- a/qt-ui/subsurfacewebservices.h
+++ b/qt-ui/subsurfacewebservices.h
@@ -66,7 +66,7 @@ class DivelogsDeWebServices : public WebServices {
public:
static DivelogsDeWebServices * instance();
void downloadDives();
- void uploadDives(QIODevice *dldContent);
+ void prepareDivesForUpload();
private slots:
void startDownload();
@@ -79,6 +79,7 @@ private slots:
void uploadError(QNetworkReply::NetworkError error);
void startUpload();
private:
+ void uploadDives(QIODevice *dldContent);
explicit DivelogsDeWebServices (QWidget* parent = 0, Qt::WindowFlags f = 0);
void setStatusText(int status);
void download_dialog_traverse_xml(xmlNodePtr node, unsigned int *download_status);