Commit c6f22482 authored by Martin Straka's avatar Martin Straka

Files refactoring - part 1

parent 9643366c
......@@ -85,6 +85,7 @@ TRANSLATIONS_FILES += \
SOURCES += \
src/accounts.cpp \
src/auxiliaries/attachment_helper.cpp \
src/auxiliaries/email_helper.cpp \
src/dialogues/dialogues.cpp \
src/dialogues/qml_dialogue_helper.cpp \
src/dialogues/qml_input_dialogue.cpp \
......@@ -144,6 +145,7 @@ SOURCES += \
HEADERS += \
src/accounts.h \
src/auxiliaries/attachment_helper.h \
src/auxiliaries/email_helper.h \
src/common.h \
src/dialogues/dialogues.h \
src/dialogues/qml_dialogue_helper.h \
......
......@@ -172,7 +172,7 @@ Component {
isds.doIsdsAction("downloadMessage", userName)
pageView.pop(StackView.Immediate)
} else if (index == 1) {
files.sendAttachmentsWithEmailFromDb(userName, msgId)
files.sendAttachmentsWithEmail(userName, msgId)
pageView.pop(StackView.Immediate)
} else if (index == 2) {
files.saveAttachmentsToDiskDb(userName, msgId)
......
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#include <QDateTime>
#include <QMimeDatabase>
#include <QMimeType>
#include "src/auxiliaries/email_helper.h"
void addAttachmentToEmailMessage(QString &message, const QString &attachName,
const QByteArray &base64, const QString &boundary)
{
const QString newLine("\n"); /* "\r\n" ? */
QMimeDatabase mimeDb;
QMimeType mimeType(
mimeDb.mimeTypeForData(QByteArray::fromBase64(base64)));
message += newLine;
message += "--" + boundary + newLine;
message += "Content-Type: " + mimeType.name() + "; charset=UTF-8;"
+ newLine + " name=\"" + attachName + "\"" + newLine;
message += "Content-Transfer-Encoding: base64" + newLine;
message += "Content-Disposition: attachment;" + newLine +
" filename=\"" + attachName + "\"" + newLine;
for (int i = 0; i < base64.size(); ++i) {
if ((i % 60) == 0) {
message += newLine;
}
message += base64.at(i);
}
message += newLine;
}
QString createEmailMessage(const QString &body, const QString &subj,
const QString &boundary)
{
const QString newLine("\n"); /* "\r\n" ? */
/* Rudimentary header. */
QString message("Subject: " + subj + newLine);
message += "MIME-Version: 1.0" + newLine;
message += "Content-Type: multipart/mixed;" + newLine +
" boundary=\"" + boundary + "\"" + newLine;
/* Body. */
message += newLine;
message += "--" + boundary + newLine;
message += "Content-Type: text/plain; charset=UTF-8" + newLine;
message += "Content-Transfer-Encoding: 8bit" + newLine;
message += newLine;
message += "-- " + newLine; /* Must contain the space. */
message += body + newLine;
return message;
}
void finishEmailMessage(QString &message, const QString &boundary)
{
const QString newLine("\n"); /* "\r\n" ? */
message += newLine + "--" + boundary + "--" + newLine;
}
QString generateBoundaryString(void)
{
return "-----123456789asdfghj_" +
QDateTime::currentDateTimeUtc().toString("dd.MM.yyyy-HH:mm:ss.zzz");
}
QString generateEmailBodyText(qint64 dmId, const QString &from,
const QString &to, const QString &delivered)
{
QString body(QObject::tr("ID") + ": ");
body += QString::number(dmId) + "\n";
body += QObject::tr("FROM") + ": ";
body += from + "\n";
body += QObject::tr("TO") + ": ";
body += to + "\n";
body += QObject::tr("DELIVERED") + ": ";
body += delivered + "\n\n---\n";
body += QObject::tr("This email has been generated with Datovka "
"application based on a data message (%1) delivered "
"to databox.").arg(dmId);
body += "\n";
return body;
}
/*
* Copyright (C) 2014-2017 CZ.NIC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* In addition, as a special exception, the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file, and distribute linked combinations including
* the two.
*/
#ifndef _EMAIL_HELPER_H_
#define _EMAIL_HELPER_H_
#include <QObject>
/*!
* @brief Add attachment into email.
*
* @param[in,out] message String to append data to.
* @param[in] attachName Attachment name.
* @param[in] base64 Base64-encoded attachment.
* @param[in] boundary Boundary to be used.
*/
void addAttachmentToEmailMessage(QString &message, const QString &attachName,
const QByteArray &base64, const QString &boundary);
/*!
* @brief Creates email header and message body.
*
* @param[in] body Email body.
* @param[in] subj Subject text.
* @param[in] boundary Boundary to be used.
* @return Email header string.
*/
QString createEmailMessage(const QString &body, const QString &subject,
const QString &boundary);
/*!
* @brief Adds last line into email.
*
* @param[in,out] message String to append data to.
* @param[in] boundary Boundary to be used.
*/
void finishEmailMessage(QString &message, const QString &boundary);
/*!
* @brief Generates boundary string for email body parts.
*
* @return Boundary string.
*/
QString generateBoundaryString(void);
/*!
* @brief Creates email body text.
*
* @param[in] dmId Message ID.
* @param[in] from Sender name.
* @param[in] to Recipient name.
* @param[in] delivered Delivery time.
* @return Email body string.
*/
QString generateEmailBodyText(qint64 dmId, const QString &from,
const QString &to, const QString &delivered);
#endif /* _EMAIL_HELPER_H_ */
......@@ -24,13 +24,12 @@
#include <QDebug>
#include <QDesktopServices>
#include <QFileInfo>
#include <QMimeDatabase>
#include <QMimeType>
#include <QUrl>
#include <QQmlEngine> /* qmlRegisterType */
#include "ios/src/url_opener.h"
#include "src/auxiliaries/attachment_helper.h"
#include "src/auxiliaries/email_helper.h"
#include "src/common.h"
#include "src/dialogues/dialogues.h"
#include "src/files.h"
......@@ -49,85 +48,37 @@
#endif
/*!
* @brief Creates email header and message body.
*
* @param[in,out] message String to append data to.
* @param[in] body Email body.
* @param[in] subj Subject text.
* @param[in] boundary Boundary to be used,
*/
static
void createEmailMessage(QString &message, const QString &body,
const QString &subj, const QString &boundary)
{
message.clear();
const QString newLine("\n"); /* "\r\n" ? */
/* Rudimentary header. */
message += "Subject: " + subj + newLine;
message += "MIME-Version: 1.0" + newLine;
message += "Content-Type: multipart/mixed;" + newLine +
" boundary=\"" + boundary + "\"" + newLine;
/* Body. */
message += newLine;
message += "--" + boundary + newLine;
message += "Content-Type: text/plain; charset=UTF-8" + newLine;
message += "Content-Transfer-Encoding: 8bit" + newLine;
message += newLine;
message += "-- " + newLine; /* Must contain the space. */
message += body + newLine;
}
/*!
* @brief Adds attachment into email.
* @brief Obtain attachment from database.
*
* @param[in,out] message String to append data to.
* @param[in] attachName Attachment name.
* @param[in] base64 Base64-encoded attachment.
* @param[in] boundary Boundary to be used.
* @param[out] file File data to be acquired.
* @param[in] userName User name identifying the account.
* @param[in] msgIdStr String with message id.
* @param[in] fileId Attachment file identifier.
*/
static
void addAttachmentToEmailMessage(QString &message, const QString &attachName,
const QByteArray &base64, const QString &boundary)
void getAttchment(FileDb::FileData &file, const QString &userName,
qint64 msgId, int fileId)
{
const QString newLine("\n"); /* "\r\n" ? */
QMimeDatabase mimeDb;
file.filename = QString();
file.content = QString();
QMimeType mimeType(
mimeDb.mimeTypeForData(QByteArray::fromBase64(base64)));
if (userName.isEmpty() || (msgId <= 0) || (fileId < 0)) {
return;
}
message += newLine;
message += "--" + boundary + newLine;
message += "Content-Type: " + mimeType.name() + "; charset=UTF-8;"
+ newLine + " name=\"" + attachName + "\"" + newLine;
message += "Content-Transfer-Encoding: base64" + newLine;
message += "Content-Disposition: attachment;" + newLine +
" filename=\"" + attachName + "\"" + newLine;
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
for (int i = 0; i < base64.size(); ++i) {
if ((i % 60) == 0) {
message += newLine;
}
message += base64.at(i);
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return;
}
message += newLine;
file = fDb->getFileContentFromDb(fileId);
}
/*!
* @brief Adds last line into email.
*
* @param[in,out] message String to append data to.
* @param[in] boundary Boundary to be used.
*/
static
void finishEmailMessage(QString &message, const QString &boundary)
Files::Files(QObject *parent) : QObject(parent)
{
const QString newLine("\n"); /* "\r\n" ? */
message += newLine + "--" + boundary + "--" + newLine;
}
void Files::declareQML(void)
......@@ -136,26 +87,21 @@ void Files::declareQML(void)
qRegisterMetaType<Files::FileIdType>();
}
Files::Files(QObject *parent) : QObject(parent)
void Files::attachmentSavingNotification(const QString &destPath)
{
QFileInfo fi(destPath);
Dialogues::errorMessage(
!destPath.isEmpty() ? Dialogues::INFORMATION : Dialogues::CRITICAL,
QObject::tr("Attachment saving"),
!destPath.isEmpty() ? QObject::tr("Attachments have been saved.") :
QObject::tr("Attachments have not been saved!"),
QObject::tr("Path: '%1'").arg(fi.absolutePath()));
}
/*!
* @brief Set attachment model content.
*
* @param[in,out] model Model to be set.
* @param[in] fileList Attachment list to be added into the model.
*/
static
void setZfoFilesToModel(FileListModel &model,
const QList<AttachmentData> &fileList)
QString Files::fileSaveLocation(void)
{
model.clearAll();
foreach (const AttachmentData &file, fileList) {
model.appendFileEntry(FileListModel::Entry(-1, file.dmFileDescr(),
file._dmFileSize(), file._icon(), file.dmEncodedContent(), QString()));
}
return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
}
void Files::deleteExpiredFilesFromDbs(int days)
......@@ -193,36 +139,6 @@ void Files::deleteExpiredFilesFromDbs(int days)
}
}
/*!
* @brief Obtain attachment from database.
*
* @param[out] file File data to be acquired.
* @param[in] userName User name identifying the account.
* @param[in] msgIdStr String with message id.
* @param[in] fileId Attachment file identifier.
*/
static
void getAttchment(FileDb::FileData &file, const QString &userName,
qint64 msgId, int fileId)
{
file.filename = QString();
file.content = QString();
if (userName.isEmpty() || (msgId <= 0) || (fileId < 0)) {
return;
}
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == Q_NULLPTR) {
qCritical() << "Cannot open file database!";
return;
}
file = fDb->getFileContentFromDb(fileId);
}
QString Files::getAttachmentFileIcon(const QString &fileName)
{
return getAttachmentFileIconFromFileExtension(fileName);
......@@ -341,8 +257,7 @@ void Files::openAttachmentFromPath(const QString &filePath)
#endif /* defined Q_OS_IOS */
}
void Files::sendAttachmentsWithEmailFromDb(const QString &userName,
qint64 msgId)
void Files::sendAttachmentsWithEmail(const QString &userName, qint64 msgId)
{
qDebug("%s()", __func__);
......@@ -354,14 +269,8 @@ void Files::sendAttachmentsWithEmailFromDb(const QString &userName,
QString subject;
QStringList fileList;
QString emailMessage;
const QString boundary("-----123456789asdfghj_" +
QDateTime::currentDateTimeUtc().toString(
"dd.MM.yyyy-HH:mm:ss.zzz"));
MessageDb *msgDb = NULL;
msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
MessageDb *msgDb = globMessageDbsPtr->accessMessageDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (msgDb == NULL) {
qDebug() << "ERROR: Message database cannot open!";
return;
......@@ -371,30 +280,27 @@ void Files::sendAttachmentsWithEmailFromDb(const QString &userName,
return;
}
FileDb *fDb = NULL;
fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation, userName,
AccountListModel::globAccounts[userName].storeToDisk());
FileDb *fDb = globFileDbsPtr->accessFileDb(globSet.dbsLocation,
userName, AccountListModel::globAccounts[userName].storeToDisk());
if (fDb == NULL) {
qDebug() << "ERROR: File database cannot open!";
return;
}
QList<FileDb::FileData> filelist;
filelist = fDb->getFilesFromDb(msgId);
if (filelist.isEmpty()) {
qDebug() << "ERROR: File list is empty!";
return;
}
createEmailMessage(emailMessage, body, subject, boundary);
const QString boundary = generateBoundaryString();
QString emailMessage = createEmailMessage(body, subject, boundary);
deleteFilesFromDir(EMAIL_DIR_NAME);
QString fileName;
foreach (const FileDb::FileData &file, filelist) {
fileName = file.filename;
QString fileName = file.filename;
if (fileName.isEmpty()) {
qDebug() << "ERROR: File name is empty!";
return;
......@@ -599,16 +505,11 @@ void Files::sendAttachmentEmailZfo(const QVariant &attachModelVariant,
}
QStringList fileList;
QString emailMessage;
QString boundary("-----123456789asdfghj_" +
QDateTime::currentDateTimeUtc().toString(
"dd.MM.yyyy-HH:mm:ss.zzz"));
createEmailMessage(emailMessage, body, subject, boundary);
deleteFilesFromDir(EMAIL_DIR_NAME);
const QString boundary = generateBoundaryString();
QString emailMessage = createEmailMessage(body, subject, boundary);
QString filePath;
QByteArray data;
deleteFilesFromDir(EMAIL_DIR_NAME);
for (int row = 0; row < attachModel->rowCount(); ++row) {
QModelIndex idx(attachModel->index(row));
......@@ -633,36 +534,6 @@ void Files::sendAttachmentEmailZfo(const QVariant &attachModelVariant,
sendEmail(emailMessage, fileList, subject, body, msgId);
}
/*!
* @brief Obtain path for storing attachments.
*
* @return Path to location where attachment can be stored.
*/
static
QString fileSaveLocation(void)
{
return QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation);
}
/*!
* @brief Generates a notification dialogue about the result of attachment
* saving.
*
* @param[in] destPath Path to which the attachment was saved.
*/
static
void attachmentSavingNotification(const QString &destPath)
{
QFileInfo fi(destPath);
Dialogues::errorMessage(
!destPath.isEmpty() ? Dialogues::INFORMATION : Dialogues::CRITICAL,
QObject::tr("Attachment saving"),
!destPath.isEmpty() ? QObject::tr("Attachments have been saved.") :
QObject::tr("Attachments have not been saved!"),
QObject::tr("Path: '%1'").arg(fi.absolutePath()));
}
void Files::saveAttachmentsToDiskDb(const QString &userName,
const QString &msgIdStr)
{
......@@ -700,12 +571,11 @@ void Files::saveAttachmentsToDiskDb(const QString &userName,
}
QString path(fileSaveLocation());
QString destPath;
foreach (const FileDb::FileData &file, filelist) {
QByteArray data = QByteArray::fromBase64(file.content.toUtf8());
destPath = writeFileToDir(path, file.filename, msgId, data);
destPath = writeFileToDir(fileSaveLocation(), file.filename,
msgId, data);
}
attachmentSavingNotification(destPath);
......@@ -731,14 +601,12 @@ void Files::saveAttachmentsToDiskZfo(const QVariant &attachModelVariant,
return;
}
QString path(fileSaveLocation());
QString destPath;
for (int row = 0; row < attachModel->rowCount(); ++row) {
QModelIndex idx(attachModel->index(row));
QByteArray data(QByteArray::fromBase64(attachModel->data(
idx, FileListModel::ROLE_FILE_DATA).toByteArray()));
destPath = writeFileToDir(path,
destPath = writeFileToDir(fileSaveLocation(),
attachModel->data(idx,
FileListModel::ROLE_FILE_NAME).toString(),
msgId, data);
......@@ -760,11 +628,6 @@ void Files::deleteTmpFileFromStorage(const QString &filePath)
void Files::sendEmail(const QString &emailMessage, const QStringList &fileList,
const QString &subject, const QString &body, qint64 msgId)
{
Q_UNUSED(subject);
Q_UNUSED(body);
Q_UNUSED(emailMessage);
Q_UNUSED(msgId);
if (!fileList.isEmpty()) {
#if defined Q_OS_IOS
......@@ -786,6 +649,11 @@ void Files::sendEmail(const QString &emailMessage, const QStringList &fileList,
} else {
qDebug() << "Tmp file save error";
}
Q_UNUSED(subject);
Q_UNUSED(body);
Q_UNUSED(emailMessage);
Q_UNUSED(msgId);
}
QByteArray Files::getXmlFromCms(const QByteArray &rawData)
......@@ -841,8 +709,6 @@ bool Files::parseXmlData(enum MsgInfo::ZfoType *type, QString *idStr,
return false;
}
//qDebug() << xmlData;
xmlData.prepend("<?xml version='1.0' encoding='utf-8'?>"
"<SOAP-ENV:Envelope "
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
......@@ -1018,21 +884,10 @@ bool Files::parseAndShowXmlData(enum MsgInfo::ZfoType type, QString *idStr,
html += divEnd;
// Create body for email
QString body = QObject::tr("ID") + ": ";
body += QString::number(msg.dmID()) + "\n";
body += QObject::tr("FROM") + ": ";
body += msg.dmSender() + "\n";
body += QObject::tr("TO") + ": ";
body += msg.dmRecipient() + "\n";
body += QObject::tr("DELIVERED") + ": ";
body += dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(msg.dmAcceptanceTime()),
DATETIME_QML_FORMAT)
+ "\n\n---\n";
body += QObject::tr("This email has been generated with Datovka "
"application based on a data message (%1) delivered "
"to databox.").arg(msg.dmID());
body += "\n";
QString body = generateEmailBodyText(msg.dmID(), msg.dmSender(),
msg.dmRecipient(), dateTimeStrFromDbFormat(
dateTimeStrToUTCDbFormat(msg.dmAcceptanceTime()),
DATETIME_QML_FORMAT));
if (idStr != Q_NULLPTR) {
*idStr = QString::number(msg.dmID());
......@@ -1044,7 +899,11 @@ bool Files::parseAndShowXmlData(enum MsgInfo::ZfoType type, QString *idStr,
*msgDescrHtml = html;
}
if (attachModel != Q_NULLPTR) {
setZfoFilesToModel(*attachModel, fileList);
attachModel->clearAll();
foreach (const AttachmentData &file, fileList) {
attachModel->appendFileEntry(FileListModel::Entry(-1, file.dmFileDescr(),
file._dmFileSize(), file._icon(), file.dmEncodedContent(), QString()));
}
}
if (emailBody != Q_NULLPTR) {
*emailBody = body;
......
......@@ -45,10 +45,6 @@ public:
};
Q_ENUM(FileIdType)
/* Don't forget to declare various properties to the QML system. */
static
void declareQML(void);
/*!
* @brief Constructor.
*
......@@ -56,13 +52,36 @@ public:
*/
explicit Files(QObject *parent = Q_NULLPTR);
/*!
* @brief Declare various properties to the QML system.
*/
static
void declareQML(void);
/*!
* @brief Generates a notification dialogue about the
* result of attachment saving.
*
* @param[in] destPath Path to which the attachment was saved.
*/