Export to DiveShare

Adds the possibility of exporting dives to DiveShare.

Signed-off-by: Salvo 'LtWorf' Tomaselli <tiposchi@tiscali.it>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This commit is contained in:
Salvo 'LtWorf' Tomaselli 2014-09-21 16:11:58 +02:00 committed by Dirk Hohndel
parent 64d1ccc550
commit 4cdb80c4cd
8 changed files with 469 additions and 4 deletions

View file

@ -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()) {
@ -245,6 +248,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)"));

View file

@ -153,6 +153,16 @@
</attribute>
</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">

View file

@ -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().toUtf8());
if (ui->txtUID->text().length() != 0)
request.setRawHeader("X-UID", ui->txtUID->text().toUtf8());
reply = WebServices::manager()->put(request, json_data);
QObject::connect(reply, SIGNAL(finished()), this, SLOT(finishedSlot()));
}

View file

@ -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

View file

@ -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>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-size:20pt; font-weight:600; color:#ff8000;&quot;&gt;⚠&lt;/span&gt; Not using a UserID means that you will need to manually keep bookmarks to your dives, to find them again.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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 &quot;related dives&quot; 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>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans Serif'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;a href=&quot;http://www.google.com&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;asd&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</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>

View file

@ -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\":\"", "\"");

View file

@ -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);

View file

@ -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: win32: SOURCES += windows.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