DiveShare patch
Dirk Hohndel
dirk at hohndel.org
Tue Oct 14 01:22:04 PDT 2014
This is missing a Signed-Off-By: line
and it doesn't compile (toAscii() doesn't exist... did you mean toUtf8()?)
/D
On Tue, Oct 14, 2014 at 09:41:36AM +0200, Salvo Tomaselli wrote:
> From 441da7c4e1b8fd41709919e29fb79944999d1209 Mon Sep 17 00:00:00 2001
> From: Salvo 'LtWorf' Tomaselli <tiposchi at tiscali.it>
> Signed-off-by: Salvo 'LtWorf' Tomaselli <tiposchi at tiscali.it>
> Date: Sun, 21 Sep 2014 16:11:58 +0200
> Subject: [PATCH] Export to DiveShare
>
> Adds the possibility of exporting dives to DiveShare.
> ---
> qt-ui/divelogexportdialog.cpp | 5 +
> qt-ui/divelogexportdialog.ui | 10 ++
> qt-ui/diveshareexportdialog.cpp | 142 +++++++++++++++++++++
> qt-ui/diveshareexportdialog.h | 34 +++++
> qt-ui/diveshareexportdialog.ui | 268 ++++++++++++++++++++++++++++++++++++++++
> save-html.c | 3 +-
> save-html.h | 2 +
> subsurface.pro | 9 +-
> 8 files changed, 469 insertions(+), 4 deletions(-)
> create mode 100644 qt-ui/diveshareexportdialog.cpp
> create mode 100644 qt-ui/diveshareexportdialog.h
> create mode 100644 qt-ui/diveshareexportdialog.ui
>
> diff --git a/qt-ui/divelogexportdialog.cpp b/qt-ui/divelogexportdialog.cpp
> index 67803ee..6c50c75 100644
> --- a/qt-ui/divelogexportdialog.cpp
> +++ b/qt-ui/divelogexportdialog.cpp
> @@ -9,6 +9,7 @@
>
> #include "mainwindow.h"
> #include "divelogexportdialog.h"
> +#include "diveshareexportdialog.h"
> #include "ui_divelogexportdialog.h"
> #include "subsurfacewebservices.h"
> #include "worldmap-save.h"
> @@ -70,6 +71,8 @@ void DiveLogExportDialog::showExplanation()
> ui->description->setText(tr("Comma separated values that include the most relevant information of the dive profile."));
> } else if (ui->exportDivelogs->isChecked()) {
> ui->description->setText(tr("Send the dive data to divelogs.de website."));
> + } else if (ui->exportDiveshare->isChecked()) {
> + ui->description->setText(tr("Send the dive data to dive-share.appspot.com website"));
> } else if (ui->exportWorldMap->isChecked()) {
> ui->description->setText(tr("HTML export of the dive locations, visualized on a world map."));
> } else if (ui->exportSubsurfaceXML->isChecked()) {
> @@ -243,6 +246,8 @@ void DiveLogExportDialog::on_buttonBox_accepted()
> tr("CSV files (*.csv *.CSV)"));
> } else if (ui->exportDivelogs->isChecked()) {
> DivelogsDeWebServices::instance()->prepareDivesForUpload(ui->exportSelected->isChecked());
> + } else if (ui->exportDiveshare->isChecked()) {
> + DiveShareExportDialog::instance()->prepareDivesForUpload(ui->exportSelected->isChecked());
> } else if (ui->exportWorldMap->isChecked()) {
> filename = QFileDialog::getSaveFileName(this, tr("Export world map"), lastDir,
> tr("HTML files (*.html)"));
> diff --git a/qt-ui/divelogexportdialog.ui b/qt-ui/divelogexportdialog.ui
> index 9510b5f..8e37196 100644
> --- a/qt-ui/divelogexportdialog.ui
> +++ b/qt-ui/divelogexportdialog.ui
> @@ -84,6 +84,16 @@
> </widget>
> </item>
> <item>
> + <widget class="QRadioButton" name="exportDiveshare">
> + <property name="text">
> + <string>DiveShare</string>
> + </property>
> + <attribute name="buttonGroup">
> + <string notr="true">exportGroup</string>
> + </attribute>
> + </widget>
> + </item>
> + <item>
> <widget class="QRadioButton" name="exportCSV">
> <property name="text">
> <string>CSV</string>
> diff --git a/qt-ui/diveshareexportdialog.cpp b/qt-ui/diveshareexportdialog.cpp
> new file mode 100644
> index 0000000..165df5e
> --- /dev/null
> +++ b/qt-ui/diveshareexportdialog.cpp
> @@ -0,0 +1,142 @@
> +#include "diveshareexportdialog.h"
> +#include "ui_diveshareexportdialog.h"
> +#include "mainwindow.h"
> +#include "save-html.h"
> +#include "qt-ui/usersurvey.h"
> +#include "qt-ui/subsurfacewebservices.h"
> +
> +#include <QDesktopServices>
> +#include <QUrl>
> +#include <QSettings>
> +
> +DiveShareExportDialog::DiveShareExportDialog(QWidget *parent) :
> + QDialog(parent),
> + ui(new Ui::DiveShareExportDialog),
> + reply(NULL)
> +{
> + ui->setupUi(this);
> +}
> +
> +DiveShareExportDialog::~DiveShareExportDialog()
> +{
> + delete ui;
> + delete reply;
> +}
> +
> +void DiveShareExportDialog::UIDFromBrowser()
> +{
> + QDesktopServices::openUrl(QUrl(DIVESHARE_BASE_URI "/secret"));
> +}
> +
> +DiveShareExportDialog *DiveShareExportDialog::instance()
> +{
> + static DiveShareExportDialog *self = new DiveShareExportDialog(MainWindow::instance());
> + self->setAttribute(Qt::WA_QuitOnClose, false);
> + self->ui->txtResult->setHtml("");
> + self->ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
> + return self;
> +}
> +
> +void DiveShareExportDialog::prepareDivesForUpload(bool selected)
> +{
> + exportSelected = selected;
> + ui->frameConfigure->setVisible(true);
> + ui->frameResults->setVisible(false);
> +
> + QSettings settings;
> + if (settings.contains("diveshareExport/uid"))
> + ui->txtUID->setText(settings.value("diveshareExport/uid").toString());
> +
> + if (settings.contains("diveshareExport/private"))
> + ui->chkPrivate->setChecked(settings.value("diveshareExport/private").toBool());
> +
> + show();
> +}
> +
> +static QByteArray generate_html_list(const QByteArray &data)
> +{
> + QList<QByteArray> dives = data.split('\n');
> + QByteArray html;
> + html.append("<html><body><table>");
> + for (int i = 0; i < dives.length(); i++ ) {
> + html.append("<tr>");
> + QList<QByteArray> dive_details = dives[i].split(',');
> + if (dive_details.length() < 3)
> + continue;
> +
> + QByteArray dive_id = dive_details[0];
> + QByteArray dive_delete = dive_details[1];
> +
> + html.append("<td>");
> + html.append("<a href=\"" DIVESHARE_BASE_URI "/dive/" + dive_id + "\">");
> +
> + //Title gets separated too, this puts it back together
> + const char *sep = "";
> + for (int t = 2; t < dive_details.length(); t++) {
> + html.append(sep);
> + html.append(dive_details[t]);
> + sep = ",";
> + }
> +
> + html.append("</a>");
> + html.append("</td>");
> + html.append("<td>");
> + html.append("<a href=\"" DIVESHARE_BASE_URI "/delete/dive/" + dive_delete + "\">Delete dive</a>");
> + html.append("</td>" );
> +
> + html.append("</tr>");
> + }
> +
> + html.append("</table></body></html>");
> + return html;
> +}
> +
> +void DiveShareExportDialog::finishedSlot()
> +{
> + ui->progressBar->setVisible(false);
> + if (reply->error() != 0) {
> + ui->buttonBox->setStandardButtons(QDialogButtonBox::Cancel);
> + ui->txtResult->setText(reply->errorString());
> + } else {
> + ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok);
> + ui->txtResult->setHtml(generate_html_list(reply->readAll()));
> + }
> +
> + reply->deleteLater();
> +}
> +
> +void DiveShareExportDialog::doUpload()
> +{
> + //Store current settings
> + QSettings settings;
> + settings.setValue("diveshareExport/uid", ui->txtUID->text());
> + settings.setValue("diveshareExport/private", ui->chkPrivate->isChecked());
> +
> + //Change UI into results mode
> + ui->frameConfigure->setVisible(false);
> + ui->frameResults->setVisible(true);
> + ui->progressBar->setVisible(true);
> + ui->progressBar->setRange(0, 0);
> +
> + //generate json
> + struct membuffer buf = { 0 };
> + export_list(&buf, NULL, exportSelected, false);
> + QByteArray json_data(buf.buffer, buf.len);
> + free_buffer(&buf);
> +
> + //Request to server
> + QNetworkRequest request;
> +
> + if (ui->chkPrivate->isChecked())
> + request.setUrl(QUrl(DIVESHARE_BASE_URI "/upload?private=true"));
> + else
> + request.setUrl(QUrl(DIVESHARE_BASE_URI "/upload"));
> +
> + request.setRawHeader("User-Agent", UserSurvey::getUserAgent().toAscii());
> + if (ui->txtUID->text().length() != 0)
> + request.setRawHeader("X-UID", ui->txtUID->text().toAscii());
> +
> + reply = WebServices::manager()->put(request, json_data);
> +
> + QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot()));
> +}
> diff --git a/qt-ui/diveshareexportdialog.h b/qt-ui/diveshareexportdialog.h
> new file mode 100644
> index 0000000..85dadf5
> --- /dev/null
> +++ b/qt-ui/diveshareexportdialog.h
> @@ -0,0 +1,34 @@
> +#ifndef DIVESHAREEXPORTDIALOG_H
> +#define DIVESHAREEXPORTDIALOG_H
> +
> +#include <QDialog>
> +#include <QNetworkReply>
> +#include <QNetworkAccessManager>
> +
> +#define DIVESHARE_WEBSITE "dive-share.appspot.com"
> +#define DIVESHARE_BASE_URI "http://" DIVESHARE_WEBSITE
> +
> +namespace Ui {
> +class DiveShareExportDialog;
> +}
> +
> +class DiveShareExportDialog : public QDialog
> +{
> + Q_OBJECT
> +public:
> + explicit DiveShareExportDialog(QWidget *parent = 0);
> + ~DiveShareExportDialog();
> + static DiveShareExportDialog *instance();
> + void prepareDivesForUpload(bool);
> +private:
> + Ui::DiveShareExportDialog *ui;
> + bool exportSelected;
> + QNetworkReply *reply;
> +private
> +slots:
> + void UIDFromBrowser();
> + void doUpload();
> + void finishedSlot();
> +};
> +
> +#endif // DIVESHAREEXPORTDIALOG_H
> diff --git a/qt-ui/diveshareexportdialog.ui b/qt-ui/diveshareexportdialog.ui
> new file mode 100644
> index 0000000..051f4f3
> --- /dev/null
> +++ b/qt-ui/diveshareexportdialog.ui
> @@ -0,0 +1,268 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> +<ui version="4.0">
> + <class>DiveShareExportDialog</class>
> + <widget class="QDialog" name="DiveShareExportDialog">
> + <property name="geometry">
> + <rect>
> + <x>0</x>
> + <y>0</y>
> + <width>320</width>
> + <height>309</height>
> + </rect>
> + </property>
> + <property name="windowTitle">
> + <string>Dialog</string>
> + </property>
> + <layout class="QVBoxLayout" name="verticalLayout_2">
> + <item>
> + <widget class="QFrame" name="frameConfigure">
> + <property name="frameShape">
> + <enum>QFrame::NoFrame</enum>
> + </property>
> + <property name="frameShadow">
> + <enum>QFrame::Plain</enum>
> + </property>
> + <property name="lineWidth">
> + <number>0</number>
> + </property>
> + <layout class="QVBoxLayout" name="verticalLayout">
> + <item>
> + <layout class="QHBoxLayout" name="horizontalLayout">
> + <item>
> + <widget class="QLabel" name="label">
> + <property name="text">
> + <string>User ID</string>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <widget class="QLineEdit" name="txtUID">
> + <property name="toolTip">
> + <string/>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <widget class="QPushButton" name="cmdClear">
> + <property name="text">
> + <string>⌫</string>
> + </property>
> + <property name="flat">
> + <bool>true</bool>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <widget class="QPushButton" name="getUIDbutton">
> + <property name="text">
> + <string>Get UserID</string>
> + </property>
> + </widget>
> + </item>
> + </layout>
> + </item>
> + <item>
> + <widget class="QLabel" name="label_2">
> + <property name="text">
> + <string><html><head/><body><p><span style=" font-size:20pt; font-weight:600; color:#ff8000;">⚠</span> Not using a UserID means that you will need to manually keep bookmarks to your dives, to find them again.</p></body></html></string>
> + </property>
> + <property name="textFormat">
> + <enum>Qt::AutoText</enum>
> + </property>
> + <property name="wordWrap">
> + <bool>true</bool>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <widget class="QCheckBox" name="chkPrivate">
> + <property name="toolTip">
> + <string>Private dives will not appear in "related dives" lists, and will only be accessible if their URL is known.</string>
> + </property>
> + <property name="text">
> + <string>Keep dives private</string>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <layout class="QHBoxLayout" name="horizontalLayout_2">
> + <item>
> + <spacer name="horizontalSpacer">
> + <property name="orientation">
> + <enum>Qt::Horizontal</enum>
> + </property>
> + <property name="sizeHint" stdset="0">
> + <size>
> + <width>40</width>
> + <height>20</height>
> + </size>
> + </property>
> + </spacer>
> + </item>
> + <item>
> + <widget class="QPushButton" name="doUploadButton">
> + <property name="text">
> + <string>Upload dive data</string>
> + </property>
> + <property name="autoDefault">
> + <bool>false</bool>
> + </property>
> + <property name="default">
> + <bool>true</bool>
> + </property>
> + </widget>
> + </item>
> + </layout>
> + </item>
> + </layout>
> + </widget>
> + </item>
> + <item>
> + <widget class="QFrame" name="frameResults">
> + <property name="frameShape">
> + <enum>QFrame::NoFrame</enum>
> + </property>
> + <property name="frameShadow">
> + <enum>QFrame::Raised</enum>
> + </property>
> + <layout class="QVBoxLayout" name="verticalLayout_3">
> + <item>
> + <widget class="QTextBrowser" name="txtResult">
> + <property name="readOnly">
> + <bool>true</bool>
> + </property>
> + <property name="html">
> + <string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
> +<html><head><meta name="qrichtext" content="1" /><style type="text/css">
> +p, li { white-space: pre-wrap; }
> +</style></head><body style=" font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;">
> +<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><a href="http://www.google.com"><span style=" text-decoration: underline; color:#0000ff;">asd</span></a></p></body></html></string>
> + </property>
> + <property name="openExternalLinks">
> + <bool>true</bool>
> + </property>
> + </widget>
> + </item>
> + <item>
> + <widget class="QProgressBar" name="progressBar">
> + <property name="value">
> + <number>24</number>
> + </property>
> + </widget>
> + </item>
> + </layout>
> + </widget>
> + </item>
> + <item>
> + <spacer name="verticalSpacer">
> + <property name="orientation">
> + <enum>Qt::Vertical</enum>
> + </property>
> + <property name="sizeHint" stdset="0">
> + <size>
> + <width>20</width>
> + <height>68</height>
> + </size>
> + </property>
> + </spacer>
> + </item>
> + <item>
> + <widget class="QDialogButtonBox" name="buttonBox">
> + <property name="orientation">
> + <enum>Qt::Horizontal</enum>
> + </property>
> + <property name="standardButtons">
> + <set>QDialogButtonBox::Cancel</set>
> + </property>
> + </widget>
> + </item>
> + </layout>
> + </widget>
> + <resources/>
> + <connections>
> + <connection>
> + <sender>buttonBox</sender>
> + <signal>rejected()</signal>
> + <receiver>DiveShareExportDialog</receiver>
> + <slot>reject()</slot>
> + <hints>
> + <hint type="sourcelabel">
> + <x>97</x>
> + <y>299</y>
> + </hint>
> + <hint type="destinationlabel">
> + <x>286</x>
> + <y>252</y>
> + </hint>
> + </hints>
> + </connection>
> + <connection>
> + <sender>getUIDbutton</sender>
> + <signal>clicked()</signal>
> + <receiver>DiveShareExportDialog</receiver>
> + <slot>UIDFromBrowser()</slot>
> + <hints>
> + <hint type="sourcelabel">
> + <x>223</x>
> + <y>29</y>
> + </hint>
> + <hint type="destinationlabel">
> + <x>159</x>
> + <y>215</y>
> + </hint>
> + </hints>
> + </connection>
> + <connection>
> + <sender>doUploadButton</sender>
> + <signal>clicked()</signal>
> + <receiver>DiveShareExportDialog</receiver>
> + <slot>doUpload()</slot>
> + <hints>
> + <hint type="sourcelabel">
> + <x>223</x>
> + <y>120</y>
> + </hint>
> + <hint type="destinationlabel">
> + <x>159</x>
> + <y>215</y>
> + </hint>
> + </hints>
> + </connection>
> + <connection>
> + <sender>cmdClear</sender>
> + <signal>clicked()</signal>
> + <receiver>txtUID</receiver>
> + <slot>clear()</slot>
> + <hints>
> + <hint type="sourcelabel">
> + <x>148</x>
> + <y>36</y>
> + </hint>
> + <hint type="destinationlabel">
> + <x>105</x>
> + <y>27</y>
> + </hint>
> + </hints>
> + </connection>
> + <connection>
> + <sender>buttonBox</sender>
> + <signal>accepted()</signal>
> + <receiver>DiveShareExportDialog</receiver>
> + <slot>accept()</slot>
> + <hints>
> + <hint type="sourcelabel">
> + <x>159</x>
> + <y>288</y>
> + </hint>
> + <hint type="destinationlabel">
> + <x>159</x>
> + <y>154</y>
> + </hint>
> + </hints>
> + </connection>
> + </connections>
> + <slots>
> + <slot>getUID()</slot>
> + <slot>doUpload()</slot>
> + </slots>
> +</ui>
> diff --git a/save-html.c b/save-html.c
> index b517b19..2befb41 100644
> --- a/save-html.c
> +++ b/save-html.c
> @@ -290,7 +290,8 @@ void write_one_dive(struct membuffer *b, struct dive *dive, const char *photos_d
> put_HTML_samples(b, dive);
> put_HTML_bookmarks(b, dive);
> write_dive_status(b, dive);
> - save_photos(b, photos_dir, dive);
> + if (photos_dir)
> + save_photos(b, photos_dir, dive);
> write_divecomputers(b, dive);
> }
> put_HTML_notes(b, dive, "\"notes\":\"", "\"");
> diff --git a/save-html.h b/save-html.h
> index f47ae3b..fddbf26 100644
> --- a/save-html.h
> +++ b/save-html.h
> @@ -16,6 +16,8 @@ void put_HTML_notes(struct membuffer *b, struct dive *dive, const char *pre, con
> void put_HTML_quoted(struct membuffer *b, const char *text);
>
> void export_HTML(const char *file_name, const char *photos_dir, const bool selected_only, const bool list_only);
> +void export_list(struct membuffer *b, const char *photos_dir, bool selected_only, const bool list_only);
> +
> void export_translation(const char *file_name);
>
> extern void copy_image_and_overwrite(const char *cfileName, const char *cnewName);
> diff --git a/subsurface.pro b/subsurface.pro
> index 1e85b11..b6bb36e 100644
> --- a/subsurface.pro
> +++ b/subsurface.pro
> @@ -99,7 +99,8 @@ HEADERS = \
> qt-ui/statistics/monthstatistics.h \
> qt-ui/statistics/statisticswidget.h \
> qt-ui/statistics/statisticsbar.h \
> - qt-ui/statistics/yearstatistics.h
> + qt-ui/statistics/yearstatistics.h \
> + qt-ui/diveshareexportdialog.h
>
> android: HEADERS -= \
> qt-ui/usermanual.h \
> @@ -188,7 +189,8 @@ SOURCES = \
> qt-ui/statistics/statisticswidget.cpp \
> qt-ui/statistics/yearstatistics.cpp \
> qt-ui/statistics/statisticsbar.cpp \
> - qt-ui/statistics/monthstatistics.cpp
> + qt-ui/statistics/monthstatistics.cpp \
> + qt-ui/diveshareexportdialog.cpp
>
> android: SOURCES += android.cpp
> else: linux*: SOURCES += linux.c
> @@ -222,7 +224,8 @@ FORMS = \
> qt-ui/usersurvey.ui \
> qt-ui/divecomponentselection.ui \
> qt-ui/configuredivecomputerdialog.ui \
> - qt-ui/tagfilter.ui
> + qt-ui/tagfilter.ui \
> + qt-ui/diveshareexportdialog.ui
>
> # Nether usermanual or printing is supported on android right now
> android: FORMS -= qt-ui/printoptions.ui
> --
> 2.1.1
>
> _______________________________________________
> subsurface mailing list
> subsurface at subsurface-divelog.org
> http://lists.subsurface-divelog.org/cgi-bin/mailman/listinfo/subsurface
More information about the subsurface
mailing list