| 
									
										
										
										
											2017-04-27 20:26:05 +02:00
										 |  |  | // SPDX-License-Identifier: GPL-2.0
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "desktop-widgets/subsurfacewebservices.h"
 | 
					
						
							| 
									
										
										
										
											2018-06-03 22:15:19 +02:00
										 |  |  | #include "core/qthelper.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "core/webservice.h"
 | 
					
						
							| 
									
										
										
										
											2018-09-08 19:46:11 +02:00
										 |  |  | #include "core/settings/qPrefCloudStorage.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "desktop-widgets/mainwindow.h"
 | 
					
						
							|  |  |  | #include "desktop-widgets/usersurvey.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-13 15:08:40 +01:00
										 |  |  | #include "commands/command.h"
 | 
					
						
							| 
									
										
										
										
											2019-05-31 16:09:14 +02:00
										 |  |  | #include "core/trip.h"
 | 
					
						
							| 
									
										
										
										
											2019-08-05 19:41:15 +02:00
										 |  |  | #include "core/errorhelper.h"
 | 
					
						
							| 
									
										
										
										
											2019-03-03 22:29:40 +01:00
										 |  |  | #include "core/file.h"
 | 
					
						
							| 
									
										
										
										
											2017-07-15 23:43:19 +03:00
										 |  |  | #include "desktop-widgets/mapwidget.h"
 | 
					
						
							| 
									
										
										
										
											2017-04-04 19:21:30 +02:00
										 |  |  | #include "desktop-widgets/tab-widgets/maintab.h"
 | 
					
						
							| 
									
										
										
										
											2019-11-24 15:02:34 +01:00
										 |  |  | #include "core/selection.h"
 | 
					
						
							| 
									
										
										
										
											2016-04-04 22:02:03 -07:00
										 |  |  | #include "core/membuffer.h"
 | 
					
						
							|  |  |  | #include "core/cloudstorage.h"
 | 
					
						
							| 
									
										
										
										
											2018-05-11 08:25:41 -07:00
										 |  |  | #include "core/subsurface-string.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-09 09:52:10 +01:00
										 |  |  | #include "core/uploadDiveLogsDE.h"
 | 
					
						
							| 
									
										
										
										
											2019-12-09 11:47:59 +01:00
										 |  |  | #include "core/settings/qPrefCloudStorage.h"
 | 
					
						
							| 
									
										
										
										
											2013-06-06 11:31:55 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | #include <QDir>
 | 
					
						
							|  |  |  | #include <QHttpMultiPart>
 | 
					
						
							|  |  |  | #include <QMessageBox>
 | 
					
						
							|  |  |  | #include <QXmlStreamReader>
 | 
					
						
							| 
									
										
										
										
											2013-06-06 11:31:55 -03:00
										 |  |  | #include <qdesktopservices.h>
 | 
					
						
							| 
									
										
										
										
											2014-04-25 10:44:23 -07:00
										 |  |  | #include <QShortcut>
 | 
					
						
							| 
									
										
										
										
											2015-02-17 16:01:49 +02:00
										 |  |  | #include <QDebug>
 | 
					
						
							| 
									
										
										
										
											2019-03-03 22:29:40 +01:00
										 |  |  | #include <errno.h>
 | 
					
						
							| 
									
										
										
										
											2019-08-05 20:07:10 +02:00
										 |  |  | #include <zip.h>
 | 
					
						
							| 
									
										
										
										
											2013-06-06 10:33:15 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | #ifdef Q_OS_UNIX
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | #include <unistd.h> // for dup(2)
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | #include <QUrlQuery>
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:30:34 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-08-27 23:12:05 +02:00
										 |  |  | #ifndef PATH_MAX
 | 
					
						
							|  |  |  | #define PATH_MAX 4096
 | 
					
						
							|  |  |  | #endif
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | WebServices::WebServices(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f), reply(0) | 
					
						
							| 
									
										
										
										
											2013-10-24 22:30:21 -02:00
										 |  |  | { | 
					
						
							|  |  |  | 	ui.setupUi(this); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	connect(ui.buttonBox, SIGNAL(clicked(QAbstractButton *)), this, SLOT(buttonClicked(QAbstractButton *))); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:30:21 -02:00
										 |  |  | 	connect(ui.download, SIGNAL(clicked(bool)), this, SLOT(startDownload())); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	connect(ui.upload, SIGNAL(clicked(bool)), this, SLOT(startUpload())); | 
					
						
							| 
									
										
										
										
											2013-11-14 17:47:35 -08:00
										 |  |  | 	connect(&timeout, SIGNAL(timeout()), this, SLOT(downloadTimedOut())); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:30:21 -02:00
										 |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2013-11-14 17:47:35 -08:00
										 |  |  | 	timeout.setSingleShot(true); | 
					
						
							| 
									
										
										
										
											2013-12-09 19:23:32 +02:00
										 |  |  | 	defaultApplyText = ui.buttonBox->button(QDialogButtonBox::Apply)->text(); | 
					
						
							| 
									
										
										
										
											2015-02-23 09:09:48 -08:00
										 |  |  | 	userAgent = getUserAgent(); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:30:21 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebServices::hidePassword() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.password->hide(); | 
					
						
							|  |  |  | 	ui.passLabel->hide(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebServices::hideUpload() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.upload->hide(); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.download->show(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebServices::hideDownload() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.download->hide(); | 
					
						
							|  |  |  | 	ui.upload->show(); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:30:21 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 17:47:35 -08:00
										 |  |  | void WebServices::downloadTimedOut() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!reply) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	reply->deleteLater(); | 
					
						
							|  |  |  | 	reply = NULL; | 
					
						
							|  |  |  | 	resetState(); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.status->setText(tr("Operation timed out")); | 
					
						
							| 
									
										
										
										
											2013-11-14 17:47:35 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 16:52:08 -08:00
										 |  |  | void WebServices::updateProgress(qint64 current, qint64 total) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!reply) | 
					
						
							|  |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 	if (total == -1) { | 
					
						
							|  |  |  | 		total = INT_MAX / 2 - 1; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-14 16:52:08 -08:00
										 |  |  | 	if (total >= INT_MAX / 2) { | 
					
						
							|  |  |  | 		// over a gigabyte!
 | 
					
						
							|  |  |  | 		if (total >= Q_INT64_C(1) << 47) { | 
					
						
							|  |  |  | 			total >>= 16; | 
					
						
							|  |  |  | 			current >>= 16; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		total >>= 16; | 
					
						
							|  |  |  | 		current >>= 16; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	ui.progressBar->setRange(0, total); | 
					
						
							|  |  |  | 	ui.progressBar->setValue(current); | 
					
						
							| 
									
										
										
										
											2014-09-12 18:29:56 +02:00
										 |  |  | 	ui.status->setText(tr("Transferring data...")); | 
					
						
							| 
									
										
										
										
											2013-11-14 16:52:08 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// reset the timer: 30 seconds after we last got any data
 | 
					
						
							|  |  |  | 	timeout.start(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void WebServices::connectSignalsForDownload(QNetworkReply *reply) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	connect(reply, SIGNAL(finished()), this, SLOT(downloadFinished())); | 
					
						
							|  |  |  | 	connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), | 
					
						
							|  |  |  | 		this, SLOT(downloadError(QNetworkReply::NetworkError))); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, | 
					
						
							|  |  |  | 		SLOT(updateProgress(qint64, qint64))); | 
					
						
							| 
									
										
										
										
											2013-11-14 17:47:35 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	timeout.start(30000); // 30s
 | 
					
						
							| 
									
										
										
										
											2013-11-14 16:52:08 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 16:50:46 -08:00
										 |  |  | void WebServices::resetState() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.download->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.upload->setEnabled(true); | 
					
						
							|  |  |  | 	ui.userID->setEnabled(true); | 
					
						
							|  |  |  | 	ui.password->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2013-11-14 16:50:46 -08:00
										 |  |  | 	ui.progressBar->reset(); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	ui.progressBar->setRange(0, 1); | 
					
						
							| 
									
										
										
										
											2013-11-14 16:50:46 -08:00
										 |  |  | 	ui.status->setText(QString()); | 
					
						
							| 
									
										
										
										
											2013-12-09 19:23:32 +02:00
										 |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setText(defaultApplyText); | 
					
						
							| 
									
										
										
										
											2013-11-14 16:50:46 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-06-06 11:57:12 -03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | // #
 | 
					
						
							|  |  |  | // #
 | 
					
						
							|  |  |  | // #		Divelogs DE  Web Service Implementation.
 | 
					
						
							|  |  |  | // #
 | 
					
						
							|  |  |  | // #
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | struct DiveListResult { | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	QString errorCondition; | 
					
						
							|  |  |  | 	QString errorDetails; | 
					
						
							|  |  |  | 	QByteArray idList; // comma-separated, suitable to be sent in the fetch request
 | 
					
						
							|  |  |  | 	int idCount; | 
					
						
							|  |  |  | }; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static DiveListResult parseDiveLogsDeDiveList(const QByteArray &xmlData) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 	/* XML format seems to be:
 | 
					
						
							|  |  |  | 	 * <DiveDateReader version="1.0"> | 
					
						
							|  |  |  | 	 *   <DiveDates> | 
					
						
							|  |  |  | 	 *     <date diveLogsId="nnn" lastModified="YYYY-MM-DD hh:mm:ss">DD.MM.YYYY hh:mm</date> | 
					
						
							|  |  |  | 	 *     [repeat <date></date>] | 
					
						
							|  |  |  | 	 *   </DiveDates> | 
					
						
							|  |  |  | 	 * </DiveDateReader> | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	QXmlStreamReader reader(xmlData); | 
					
						
							| 
									
										
										
										
											2018-07-03 16:52:20 +02:00
										 |  |  | 	const QString invalidXmlError = gettextFromC::tr("Invalid response from server"); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 	bool seenDiveDates = false; | 
					
						
							|  |  |  | 	DiveListResult result; | 
					
						
							|  |  |  | 	result.idCount = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (reader.readNextStartElement() && reader.name() != "DiveDateReader") { | 
					
						
							|  |  |  | 		result.errorCondition = invalidXmlError; | 
					
						
							|  |  |  | 		result.errorDetails = | 
					
						
							| 
									
										
										
										
											2018-07-03 16:52:20 +02:00
										 |  |  | 			gettextFromC::tr("Expected XML tag 'DiveDateReader', got instead '%1") | 
					
						
							| 
									
										
										
										
											2014-05-22 11:40:22 -07:00
										 |  |  | 				.arg(reader.name().toString()); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 		goto out; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	while (reader.readNextStartElement()) { | 
					
						
							|  |  |  | 		if (reader.name() != "DiveDates") { | 
					
						
							|  |  |  | 			if (reader.name() == "Login") { | 
					
						
							|  |  |  | 				QString status = reader.readElementText(); | 
					
						
							|  |  |  | 				// qDebug() << "Login status:" << status;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 				// Note: there has to be a better way to determine a successful login...
 | 
					
						
							|  |  |  | 				if (status == "failed") { | 
					
						
							|  |  |  | 					result.errorCondition = "Login failed"; | 
					
						
							|  |  |  | 					goto out; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				// qDebug() << "Skipping" << reader.name();
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		// process <DiveDates>
 | 
					
						
							|  |  |  | 		seenDiveDates = true; | 
					
						
							|  |  |  | 		while (reader.readNextStartElement()) { | 
					
						
							|  |  |  | 			if (reader.name() != "date") { | 
					
						
							|  |  |  | 				// qDebug() << "Skipping" << reader.name();
 | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			QStringRef id = reader.attributes().value("divelogsId"); | 
					
						
							|  |  |  | 			// qDebug() << "Found" << reader.name() << "with id =" << id;
 | 
					
						
							|  |  |  | 			if (!id.isEmpty()) { | 
					
						
							|  |  |  | 				result.idList += id.toLatin1(); | 
					
						
							|  |  |  | 				result.idList += ','; | 
					
						
							|  |  |  | 				++result.idCount; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 			reader.skipCurrentElement(); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// chop the ending comma, if any
 | 
					
						
							|  |  |  | 	result.idList.chop(1); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	if (!seenDiveDates) { | 
					
						
							|  |  |  | 		result.errorCondition = invalidXmlError; | 
					
						
							| 
									
										
										
										
											2018-07-03 16:52:20 +02:00
										 |  |  | 		result.errorDetails = gettextFromC::tr("Expected XML tag 'DiveDates' not found"); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | out: | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 	if (reader.hasError()) { | 
					
						
							|  |  |  | 		// if there was an XML error, overwrite the result or other error conditions
 | 
					
						
							|  |  |  | 		result.errorCondition = invalidXmlError; | 
					
						
							| 
									
										
										
										
											2018-07-03 16:52:20 +02:00
										 |  |  | 		result.errorDetails = gettextFromC::tr("Malformed XML response. Line %1: %2") | 
					
						
							| 
									
										
										
										
											2014-05-22 11:40:22 -07:00
										 |  |  | 						.arg(reader.lineNumber()) | 
					
						
							|  |  |  | 						.arg(reader.errorString()); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:09:08 -08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return result; | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | DivelogsDeWebServices *DivelogsDeWebServices::instance() | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-12 15:22:54 +01:00
										 |  |  | 	static DivelogsDeWebServices *self = new DivelogsDeWebServices(MainWindow::instance()); | 
					
						
							| 
									
										
										
										
											2013-10-24 23:02:59 -02:00
										 |  |  | 	return self; | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | void DivelogsDeWebServices::downloadDives() | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-09 19:23:32 +02:00
										 |  |  | 	uploadMode = false; | 
					
						
							|  |  |  | 	resetState(); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	hideUpload(); | 
					
						
							|  |  |  | 	exec(); | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-05-20 19:33:32 +03:00
										 |  |  | void DivelogsDeWebServices::prepareDivesForUpload(bool selected) | 
					
						
							| 
									
										
										
										
											2019-12-09 12:51:16 +01:00
										 |  |  | { | 
					
						
							|  |  |  | 	// this is called when the user selects the divelogs.de radiobutton
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 13:24:08 +01:00
										 |  |  | 	// Remember if all dives or selected dives are to be uploaded
 | 
					
						
							|  |  |  | 	useSelectedDives = selected; | 
					
						
							| 
									
										
										
										
											2019-12-09 12:51:16 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Adjust UI
 | 
					
						
							|  |  |  | 	hideDownload(); | 
					
						
							|  |  |  | 	resetState(); | 
					
						
							|  |  |  | 	uploadMode = true; | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(true); | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setText(tr("Done")); | 
					
						
							|  |  |  | 	exec(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-25 02:41:38 -03:00
										 |  |  | DivelogsDeWebServices::DivelogsDeWebServices(QWidget *parent, Qt::WindowFlags f) : WebServices(parent, f), | 
					
						
							|  |  |  | 	uploadMode(false) | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-03-19 08:22:51 -07:00
										 |  |  | 	// should DivelogDE user and pass be stored in the prefs struct or something?
 | 
					
						
							| 
									
										
										
										
											2019-12-09 11:47:59 +01:00
										 |  |  | 	ui.userID->setText(qPrefCloudStorage::divelogde_user()); | 
					
						
							|  |  |  | 	ui.password->setText(qPrefCloudStorage::divelogde_pass()); | 
					
						
							| 
									
										
										
										
											2014-04-11 11:47:35 +05:30
										 |  |  | 	ui.saveUidLocal->hide(); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	hideUpload(); | 
					
						
							| 
									
										
										
										
											2014-04-25 10:44:23 -07:00
										 |  |  | 	QShortcut *close = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_W), this); | 
					
						
							|  |  |  | 	connect(close, SIGNAL(activated()), this, SLOT(close())); | 
					
						
							|  |  |  | 	QShortcut *quit = new QShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q), this); | 
					
						
							|  |  |  | 	connect(quit, SIGNAL(activated()), parent, SLOT(close())); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::startUpload() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-09 11:47:59 +01:00
										 |  |  | 	qPrefCloudStorage::set_divelogde_user(ui.userID->text()); | 
					
						
							|  |  |  | 	qPrefCloudStorage::set_divelogde_pass(ui.password->text()); | 
					
						
							| 
									
										
										
										
											2013-12-09 16:45:54 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.status->setText(tr("Uploading dive list...")); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	ui.progressBar->setRange(0, 0); // this makes the progressbar do an 'infinite spin'
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.upload->setEnabled(false); | 
					
						
							|  |  |  | 	ui.userID->setEnabled(false); | 
					
						
							|  |  |  | 	ui.password->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 14:02:05 +01:00
										 |  |  | 	// do upload in shared backend
 | 
					
						
							|  |  |  | 	connect(uploadDiveLogsDE::instance(), SIGNAL(uploadFinish(bool, const QString &)), | 
					
						
							|  |  |  | 			this, SLOT(uploadFinished(bool, const QString &))); | 
					
						
							|  |  |  | 	connect(uploadDiveLogsDE::instance(), SIGNAL(uploadProgress(qreal, qreal)), | 
					
						
							|  |  |  | 			this, SLOT(updateProgress(qreal, qreal))); | 
					
						
							|  |  |  | 	connect(uploadDiveLogsDE::instance(), SIGNAL(uploadStatus(const QString &)), | 
					
						
							|  |  |  | 			this, SLOT(uploadStatus(const QString &))); | 
					
						
							|  |  |  | 	uploadDiveLogsDE::instance()->doUpload(useSelectedDives, | 
					
						
							|  |  |  | 							   qPrefCloudStorage::divelogde_user(), | 
					
						
							|  |  |  | 							   qPrefCloudStorage::divelogde_pass()); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::startDownload() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.status->setText(tr("Downloading dive list...")); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	ui.progressBar->setRange(0, 0); // this makes the progressbar do an 'infinite spin'
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.download->setEnabled(false); | 
					
						
							|  |  |  | 	ui.userID->setEnabled(false); | 
					
						
							|  |  |  | 	ui.password->setEnabled(false); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QNetworkRequest request; | 
					
						
							|  |  |  | 	request.setUrl(QUrl("https://divelogs.de/xml_available_dives.php")); | 
					
						
							|  |  |  | 	request.setRawHeader("Accept", "text/xml, application/xml"); | 
					
						
							| 
									
										
										
										
											2014-07-31 11:20:11 -07:00
										 |  |  | 	request.setRawHeader("User-Agent", userAgent.toUtf8()); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QUrlQuery body; | 
					
						
							|  |  |  | 	body.addQueryItem("user", ui.userID->text()); | 
					
						
							| 
									
										
										
										
											2016-02-22 20:11:22 +02:00
										 |  |  | 	body.addQueryItem("pass", ui.password->text().replace("+", "%2b")); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:30:33 +01:00
										 |  |  | 	reply = manager()->post(request, body.query(QUrl::FullyEncoded).toLatin1()); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	connect(reply, SIGNAL(finished()), this, SLOT(listDownloadFinished())); | 
					
						
							|  |  |  | 	connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), | 
					
						
							|  |  |  | 		this, SLOT(downloadError(QNetworkReply::NetworkError))); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	timeout.start(30000); // 30s
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::listDownloadFinished() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!reply) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	QByteArray xmlData = reply->readAll(); | 
					
						
							|  |  |  | 	reply->deleteLater(); | 
					
						
							|  |  |  | 	reply = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// parse the XML data we downloaded
 | 
					
						
							|  |  |  | 	DiveListResult diveList = parseDiveLogsDeDiveList(xmlData); | 
					
						
							|  |  |  | 	if (!diveList.errorCondition.isEmpty()) { | 
					
						
							|  |  |  | 		// error condition
 | 
					
						
							|  |  |  | 		resetState(); | 
					
						
							|  |  |  | 		ui.status->setText(diveList.errorCondition); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ui.status->setText(tr("Downloading %1 dives...").arg(diveList.idCount)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QNetworkRequest request; | 
					
						
							| 
									
										
										
										
											2013-12-28 21:04:07 -08:00
										 |  |  | 	request.setUrl(QUrl("https://divelogs.de/DivelogsDirectExport.php")); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	request.setRawHeader("Accept", "application/zip, */*"); | 
					
						
							| 
									
										
										
										
											2014-07-31 11:20:11 -07:00
										 |  |  | 	request.setRawHeader("User-Agent", userAgent.toUtf8()); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	QUrlQuery body; | 
					
						
							|  |  |  | 	body.addQueryItem("user", ui.userID->text()); | 
					
						
							| 
									
										
										
										
											2016-02-22 20:11:22 +02:00
										 |  |  | 	body.addQueryItem("pass", ui.password->text().replace("+", "%2b")); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	body.addQueryItem("ids", diveList.idList); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-01-15 09:30:33 +01:00
										 |  |  | 	reply = manager()->post(request, body.query(QUrl::FullyEncoded).toLatin1()); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	connect(reply, SIGNAL(readyRead()), this, SLOT(saveToZipFile())); | 
					
						
							|  |  |  | 	connectSignalsForDownload(reply); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::saveToZipFile() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	if (!zipFile.isOpen()) { | 
					
						
							|  |  |  | 		zipFile.setFileTemplate(QDir::tempPath() + "/import-XXXXXX.dld"); | 
					
						
							|  |  |  | 		zipFile.open(); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	zipFile.write(reply->readAll()); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::downloadFinished() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	if (!reply) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ui.download->setEnabled(true); | 
					
						
							|  |  |  | 	ui.status->setText(tr("Download finished - %1").arg(reply->attribute(QNetworkRequest::HttpReasonPhraseAttribute).toString())); | 
					
						
							|  |  |  | 	reply->deleteLater(); | 
					
						
							|  |  |  | 	reply = NULL; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	int errorcode; | 
					
						
							|  |  |  | 	zipFile.seek(0); | 
					
						
							| 
									
										
										
										
											2013-12-19 17:01:54 -08:00
										 |  |  | #if defined(Q_OS_UNIX) && defined(LIBZIP_VERSION_MAJOR)
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	int duppedfd = dup(zipFile.handle()); | 
					
						
							| 
									
										
										
										
											2015-06-22 06:46:01 -07:00
										 |  |  | 	struct zip *zip = NULL; | 
					
						
							|  |  |  | 	if (duppedfd >= 0) { | 
					
						
							|  |  |  | 		zip = zip_fdopen(duppedfd, 0, &errorcode); | 
					
						
							|  |  |  | 		if (!zip) | 
					
						
							|  |  |  | 			::close(duppedfd); | 
					
						
							| 
									
										
										
										
											2015-06-22 22:23:04 -07:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		QMessageBox::critical(this, tr("Problem with download"), | 
					
						
							| 
									
										
										
										
											2019-03-24 11:07:45 +01:00
										 |  |  | 				      tr("The archive could not be opened:\n%1").arg(QString::fromLocal8Bit(strerror(errno)))); | 
					
						
							| 
									
										
										
										
											2015-06-22 22:23:04 -07:00
										 |  |  | 		return; | 
					
						
							| 
									
										
										
										
											2015-06-22 06:46:01 -07:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | #else
 | 
					
						
							| 
									
										
										
										
											2013-12-19 17:02:34 -08:00
										 |  |  | 	struct zip *zip = zip_open(QFile::encodeName(zipFile.fileName()), 0, &errorcode); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | #endif
 | 
					
						
							|  |  |  | 	if (!zip) { | 
					
						
							|  |  |  | 		char buf[512]; | 
					
						
							|  |  |  | 		zip_error_to_str(buf, sizeof(buf), errorcode, errno); | 
					
						
							|  |  |  | 		QMessageBox::critical(this, tr("Corrupted download"), | 
					
						
							|  |  |  | 				      tr("The archive could not be opened:\n%1").arg(QString::fromLocal8Bit(buf))); | 
					
						
							|  |  |  | 		zipFile.close(); | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 	// now allow the user to cancel or accept
 | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	zip_close(zip); | 
					
						
							|  |  |  | 	zipFile.close(); | 
					
						
							| 
									
										
										
										
											2014-03-06 15:08:27 -08:00
										 |  |  | #if defined(Q_OS_UNIX) && defined(LIBZIP_VERSION_MAJOR)
 | 
					
						
							|  |  |  | 	::close(duppedfd); | 
					
						
							|  |  |  | #endif
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 14:02:05 +01:00
										 |  |  | void DivelogsDeWebServices::uploadFinished(bool success, const QString &text) | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	ui.progressBar->setRange(0, 1); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	ui.upload->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2013-12-09 21:28:05 +02:00
										 |  |  | 	ui.userID->setEnabled(true); | 
					
						
							|  |  |  | 	ui.password->setEnabled(true); | 
					
						
							| 
									
										
										
										
											2013-12-09 19:23:32 +02:00
										 |  |  | 	ui.buttonBox->button(QDialogButtonBox::Cancel)->setEnabled(false); | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(true); | 
					
						
							|  |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setText(tr("Done")); | 
					
						
							| 
									
										
										
										
											2019-12-09 14:02:05 +01:00
										 |  |  | 	ui.status->setText(text); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-05-21 18:09:09 +02:00
										 |  |  | void DivelogsDeWebServices::setStatusText(int) | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | void DivelogsDeWebServices::downloadError(QNetworkReply::NetworkError) | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	resetState(); | 
					
						
							| 
									
										
										
										
											2013-12-09 17:42:06 +02:00
										 |  |  | 	ui.status->setText(tr("Error: %1").arg(reply->errorString())); | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | 	reply->deleteLater(); | 
					
						
							|  |  |  | 	reply = NULL; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-09 14:02:05 +01:00
										 |  |  | void DivelogsDeWebServices::updateProgress(qreal current, qreal total) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	ui.progressBar->setRange(0, total); | 
					
						
							|  |  |  | 	ui.progressBar->setValue(current); | 
					
						
							|  |  |  | 	ui.status->setText(tr("Transferring data...")); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void DivelogsDeWebServices::uploadStatus(const QString &text) | 
					
						
							| 
									
										
										
										
											2013-11-14 18:57:09 -08:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2019-12-09 14:02:05 +01:00
										 |  |  | 	ui.status->setText(text); | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | void DivelogsDeWebServices::buttonClicked(QAbstractButton *button) | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 	ui.buttonBox->button(QDialogButtonBox::Apply)->setEnabled(false); | 
					
						
							| 
									
										
										
										
											2014-01-16 11:50:56 +07:00
										 |  |  | 	switch (ui.buttonBox->buttonRole(button)) { | 
					
						
							|  |  |  | 	case QDialogButtonBox::ApplyRole: { | 
					
						
							| 
									
										
										
										
											2013-12-09 19:23:32 +02:00
										 |  |  | 		/* in 'uploadMode' button is called 'Done' and closes the dialog */ | 
					
						
							|  |  |  | 		if (uploadMode) { | 
					
						
							|  |  |  | 			hide(); | 
					
						
							|  |  |  | 			close(); | 
					
						
							|  |  |  | 			resetState(); | 
					
						
							|  |  |  | 			break; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2013-12-07 14:33:43 +02:00
										 |  |  | 		/* parse file and import dives */ | 
					
						
							| 
									
										
										
										
											2018-09-28 10:21:23 +02:00
										 |  |  | 		struct dive_table table = { 0 }; | 
					
						
							| 
									
										
										
										
											2018-12-23 12:46:45 +01:00
										 |  |  | 		struct trip_table trips = { 0 }; | 
					
						
							| 
									
										
										
										
											2019-03-03 15:12:22 +01:00
										 |  |  | 		struct dive_site_table sites = { 0 }; | 
					
						
							|  |  |  | 		parse_file(QFile::encodeName(zipFile.fileName()), &table, &trips, &sites); | 
					
						
							|  |  |  | 		Command::importDives(&table, &trips, &sites, IMPORT_MERGE_ALL_TRIPS, QStringLiteral("divelogs.de")); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2013-12-07 14:33:43 +02:00
										 |  |  | 		/* store last entered user/pass in config */ | 
					
						
							| 
									
										
										
										
											2019-12-09 11:47:59 +01:00
										 |  |  | 		qPrefCloudStorage::set_divelogde_user(ui.userID->text()); | 
					
						
							|  |  |  | 		qPrefCloudStorage::set_divelogde_pass(ui.password->text()); | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 		hide(); | 
					
						
							|  |  |  | 		close(); | 
					
						
							|  |  |  | 		resetState(); | 
					
						
							| 
									
										
										
										
											2014-02-27 20:09:57 -08:00
										 |  |  | 	} break; | 
					
						
							| 
									
										
										
										
											2013-12-07 14:33:43 +02:00
										 |  |  | 	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; | 
					
						
							| 
									
										
										
										
											2013-12-06 17:10:32 -08:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2013-10-24 22:52:11 -02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-30 07:19:22 -07:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 22:47:19 +02:00
										 |  |  | UserSurveyServices::UserSurveyServices(QWidget *parent, Qt::WindowFlags f) : QDialog(parent, f) | 
					
						
							| 
									
										
										
										
											2014-06-30 07:19:22 -07:00
										 |  |  | { | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-09-29 22:47:19 +02:00
										 |  |  | QNetworkReply *UserSurveyServices::sendSurvey(QString values) | 
					
						
							| 
									
										
										
										
											2014-06-30 07:19:22 -07:00
										 |  |  | { | 
					
						
							|  |  |  | 	QNetworkRequest request; | 
					
						
							| 
									
										
										
										
											2014-11-18 13:01:54 +00:00
										 |  |  | 	request.setUrl(QString("http://subsurface-divelog.org/survey?%1").arg(values)); | 
					
						
							| 
									
										
										
										
											2014-06-30 07:19:22 -07:00
										 |  |  | 	request.setRawHeader("Accept", "text/xml"); | 
					
						
							| 
									
										
										
										
											2018-09-29 22:47:19 +02:00
										 |  |  | 	request.setRawHeader("User-Agent", getUserAgent().toUtf8()); | 
					
						
							|  |  |  | 	QNetworkReply *reply = manager()->get(request); | 
					
						
							| 
									
										
										
										
											2014-07-16 17:20:21 -03:00
										 |  |  | 	return reply; | 
					
						
							| 
									
										
										
										
											2016-02-22 20:11:22 +02:00
										 |  |  | } |