From bd1622c27e744971b8fc70b90e9c9d175acec2f2 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sun, 10 Apr 2016 11:00:57 +0200 Subject: Use the MailtransportResource for mailtransport. --- accounts/maildir/maildirsettings.cpp | 85 +++++++++++++++++++++- accounts/maildir/maildirsettings.h | 11 +++ .../package/contents/ui/MaildirAccountSettings.qml | 40 ++++------ accounts/maildir/tests/settingstest.cpp | 13 +++- components/package/contents/ui/Composer.qml | 6 +- framework/domain/actions/mailactions.cpp | 19 ----- framework/domain/actions/sinkactions.cpp | 43 +++++++++++ framework/domain/composercontroller.cpp | 35 +++------ framework/domain/composercontroller.h | 13 ++-- 9 files changed, 184 insertions(+), 81 deletions(-) diff --git a/accounts/maildir/maildirsettings.cpp b/accounts/maildir/maildirsettings.cpp index 847ce92e..fa30851c 100644 --- a/accounts/maildir/maildirsettings.cpp +++ b/accounts/maildir/maildirsettings.cpp @@ -38,6 +38,18 @@ void MaildirSettings::setAccountIdentifier(const QByteArray &id) return; } mAccountIdentifier = id; + + //Clear + mIcon = QString(); + mName = QString(); + mPath = QString(); + mSmtpServer = QString(); + mSmtpUsername = QString(); + mSmtpPassword = QString(); + emit changed(); + emit pathChanged(); + emit smtpResourceChanged(); + Q_ASSERT(!id.isEmpty()); Sink::Store::fetchOne(Sink::Query::IdentityFilter(id)) .then([this](const Sink::ApplicationDomain::SinkAccount &account) { @@ -46,7 +58,7 @@ void MaildirSettings::setAccountIdentifier(const QByteArray &id) emit changed(); }).exec(); - Sink::Store::fetchOne(Sink::Query::PropertyFilter("account", QVariant::fromValue(id))) + Sink::Store::fetchOne(Sink::Query::PropertyFilter("account", QVariant::fromValue(id)) + Sink::Query::PropertyFilter("type", QString("org.kde.maildir"))) .then([this](const Sink::ApplicationDomain::SinkResource &resource) { mIdentifier = resource.identifier(); auto path = resource.getProperty("path").toString(); @@ -54,6 +66,21 @@ void MaildirSettings::setAccountIdentifier(const QByteArray &id) mPath = path; emit pathChanged(); } + }, + [](int errorCode, const QString &errorMessage) { + qWarning() << "Failed to find the maildir resource: " << errorMessage; + }).exec(); + + Sink::Store::fetchOne(Sink::Query::PropertyFilter("account", QVariant::fromValue(id)) + Sink::Query::PropertyFilter("type", QString("org.kde.mailtransport"))) + .then([this](const Sink::ApplicationDomain::SinkResource &resource) { + mMailtransportIdentifier = resource.identifier(); + mSmtpServer = resource.getProperty("server").toString(); + mSmtpUsername = resource.getProperty("username").toString(); + mSmtpPassword = resource.getProperty("password").toString(); + emit smtpResourceChanged(); + }, + [](int errorCode, const QString &errorMessage) { + qWarning() << "Failed to find the maildir resource: " << errorMessage; }).exec(); } @@ -92,13 +119,32 @@ QValidator *MaildirSettings::pathValidator() const return pathValidator; } +QValidator *MaildirSettings::smtpServerValidator() const +{ + class SmtpServerValidator : public QValidator { + State validate(QString &input, int &pos) const { + Q_UNUSED(pos); + // smtps://mainserver.example.net:475 + const QUrl url(input); + static QSet validProtocols = QSet() << "smtp" << "smtps"; + if (url.isValid() && validProtocols.contains(url.scheme().toLower())) { + return Acceptable; + } else { + return Intermediate; + } + } + }; + static SmtpServerValidator *validator = new SmtpServerValidator; + return validator; +} + void MaildirSettings::save() { if (!QDir(mPath).exists()) { qWarning() << "The path doesn't exist: " << mPath; return; } - qDebug() << "Saving account " << mAccountIdentifier << mIdentifier; + qDebug() << "Saving account " << mAccountIdentifier << mIdentifier << mMailtransportIdentifier; Q_ASSERT(!mAccountIdentifier.isEmpty()); Sink::ApplicationDomain::SinkAccount account(mAccountIdentifier); account.setProperty("type", "maildir"); @@ -133,6 +179,34 @@ void MaildirSettings::save() }) .exec(); } + + if (!mMailtransportIdentifier.isEmpty()) { + Sink::ApplicationDomain::SinkResource resource(mMailtransportIdentifier); + resource.setProperty("server", mSmtpServer); + resource.setProperty("username", mSmtpUsername); + resource.setProperty("password", mSmtpPassword); + Sink::Store::modify(resource).then([](){}, [](int errorCode, const QString &errorMessage) { + qWarning() << "Error while modifying resource: " << errorMessage; + }) + .exec(); + } else { + //FIXME we shouldn't have to do this magic + const auto resourceIdentifier = "org.kde.mailtransport." + QUuid::createUuid().toByteArray(); + mMailtransportIdentifier = resourceIdentifier; + + Sink::ApplicationDomain::SinkResource resource; + resource.setProperty("identifier", resourceIdentifier); + resource.setProperty("type", "org.kde.mailtransport"); + resource.setProperty("account", mAccountIdentifier); + resource.setProperty("server", mSmtpServer); + resource.setProperty("username", mSmtpUsername); + resource.setProperty("password", mSmtpPassword); + Sink::Store::create(resource).then([]() {}, + [](int errorCode, const QString &errorMessage) { + qWarning() << "Error while creating resource: " << errorMessage; + }) + .exec(); + } } void MaildirSettings::remove() @@ -140,6 +214,13 @@ void MaildirSettings::remove() if (mIdentifier.isEmpty()) { qWarning() << "We're missing an identifier"; } else { + Sink::ApplicationDomain::SinkResource mailTransportResource("", mMailtransportIdentifier, 0, QSharedPointer::create()); + Sink::Store::remove(mailTransportResource).then([]() {}, + [](int errorCode, const QString &errorMessage) { + qWarning() << "Error while removing resource: " << errorMessage; + }) + .exec(); + Sink::ApplicationDomain::SinkResource resource("", mIdentifier, 0, QSharedPointer::create()); Sink::Store::remove(resource).then([]() {}, [](int errorCode, const QString &errorMessage) { diff --git a/accounts/maildir/maildirsettings.h b/accounts/maildir/maildirsettings.h index f79208db..be69ffb8 100644 --- a/accounts/maildir/maildirsettings.h +++ b/accounts/maildir/maildirsettings.h @@ -29,6 +29,10 @@ class MaildirSettings : public QObject Q_PROPERTY(QValidator* pathValidator READ pathValidator CONSTANT) Q_PROPERTY(QString icon MEMBER mIcon NOTIFY changed) Q_PROPERTY(QString accountName MEMBER mName NOTIFY changed) + Q_PROPERTY(QString smtpServer MEMBER mSmtpServer NOTIFY smtpResourceChanged) + Q_PROPERTY(QValidator* smtpServerValidator READ smtpServerValidator CONSTANT) + Q_PROPERTY(QString smtpUsername MEMBER mSmtpUsername NOTIFY smtpResourceChanged) + Q_PROPERTY(QString smtpPassword MEMBER mSmtpPassword NOTIFY smtpResourceChanged) public: MaildirSettings(QObject *parent = 0); @@ -40,17 +44,24 @@ public: QUrl path() const; QValidator *pathValidator() const; + QValidator *smtpServerValidator() const; + Q_INVOKABLE void save(); Q_INVOKABLE void remove(); signals: void pathChanged(); + void smtpResourceChanged(); void changed(); private: QByteArray mIdentifier; QByteArray mAccountIdentifier; + QByteArray mMailtransportIdentifier; QString mPath; QString mIcon; QString mName; + QString mSmtpServer; + QString mSmtpUsername; + QString mSmtpPassword; }; diff --git a/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml b/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml index d6292072..e508a475 100644 --- a/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml +++ b/accounts/maildir/package/contents/ui/MaildirAccountSettings.qml @@ -78,7 +78,7 @@ Rectangle { Button { iconName: "folder" onClicked: { - fileDialogObject = fileDialogComponent.createObject(parent); + fileDialogComponent.createObject(parent); } Component { @@ -92,10 +92,8 @@ Rectangle { onAccepted: { maildirSettings.path = fileDialog.fileUrl - fileDialogObject.destroy() } onRejected: { - fileDialogObject.destroy() } } } @@ -110,29 +108,33 @@ Rectangle { Label { text: "Username" } TextField { - id: username - placeholderText: "username" + placeholderText: "Username" Layout.fillWidth: true - text: transportSettings.username - onTextChanged: { transportSettings.username = text; } + text: maildirSettings.smtpUsername + onTextChanged: { maildirSettings.smtpUsername = text; } } Label { text: "Password" } TextField { - id: password - placeholderText: "password" + placeholderText: "Password" Layout.fillWidth: true - text: transportSettings.password - onTextChanged: { transportSettings.password = text; } + text: maildirSettings.smtpPassword + onTextChanged: { maildirSettings.smtpPassword = text; } } Label { text: "Server" } TextField { id: server - placeholderText: "server" + placeholderText: "smtps://mainserver.example.net:465" Layout.fillWidth: true - text: transportSettings.server - onTextChanged: { transportSettings.server = text; } + text: maildirSettings.smtpServer + onTextChanged: { maildirSettings.smtpServer = text; } + validator: maildirSettings.smtpServerValidator + Rectangle { + anchors.fill: parent + opacity: 0.2 + color: server.acceptableInput ? "green" : "yellow" + } } MaildirAccount.MaildirSettings { @@ -140,19 +142,9 @@ Rectangle { accountIdentifier: accountId } - KubeSettings.Settings { - id: transportSettings - //TODO set a proper identifier - identifier: "transport.current" - property string server; - property string username; - property string password; - } - Button { text: "Save" onClicked: { - transportSettings.save(); maildirSettings.save(); } } diff --git a/accounts/maildir/tests/settingstest.cpp b/accounts/maildir/tests/settingstest.cpp index 8f8471f0..07665c24 100644 --- a/accounts/maildir/tests/settingstest.cpp +++ b/accounts/maildir/tests/settingstest.cpp @@ -23,14 +23,20 @@ private slots: { auto accountId = "accountid"; auto maildirPath = QDir::tempPath(); + auto smtpServer = QString("smtpserver"); + auto smtpUsername = QString("username"); + auto smtpPassword = QString("password"); MaildirSettings settings; settings.setAccountIdentifier(accountId); settings.setPath(maildirPath); + settings.setProperty("smtpServer", smtpServer); + settings.setProperty("smtpUsername", smtpUsername); + settings.setProperty("smtpPassword", smtpPassword); settings.save(); Sink::Store::fetchAll(Sink::Query()).then>([](const QList &resources) { - QCOMPARE(resources.size(), 1); + QCOMPARE(resources.size(), 2); }) .exec().waitForFinished(); @@ -38,10 +44,15 @@ private slots: { MaildirSettings readSettings; QSignalSpy spy(&readSettings, &MaildirSettings::pathChanged); + QSignalSpy spy1(&readSettings, &MaildirSettings::smtpResourceChanged); readSettings.setAccountIdentifier(accountId); QTRY_VERIFY(spy.count()); + QTRY_VERIFY(spy1.count()); QVERIFY(!readSettings.accountIdentifier().isEmpty()); QCOMPARE(readSettings.path().toString(), maildirPath); + QCOMPARE(readSettings.property("smtpServer").toString(), smtpServer); + QCOMPARE(readSettings.property("smtpUsername").toString(), smtpUsername); + QCOMPARE(readSettings.property("smtpPassword").toString(), smtpPassword); } { diff --git a/components/package/contents/ui/Composer.qml b/components/package/contents/ui/Composer.qml index 16cd9830..34fd3ca4 100644 --- a/components/package/contents/ui/Composer.qml +++ b/components/package/contents/ui/Composer.qml @@ -67,14 +67,14 @@ Item { } ComboBox { + id: identityCombo model: composer.identityModel + textRole: "name" Layout.fillWidth: true - currentIndex: composer.fromIndex - onCurrentIndexChanged: { - composer.fromIndex = currentIndex + composer.currentIdentityIndex = currentIndex } } diff --git a/framework/domain/actions/mailactions.cpp b/framework/domain/actions/mailactions.cpp index dab0533e..fde98c85 100644 --- a/framework/domain/actions/mailactions.cpp +++ b/framework/domain/actions/mailactions.cpp @@ -27,22 +27,3 @@ using namespace Kube; -static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail", - [](Context *context) -> bool { - auto username = context->property("username").value(); - auto password = context->property("password").value(); - auto server = context->property("server").value(); - auto message = context->property("message").value(); - return !username.isEmpty() && !password.isEmpty() && !server.isEmpty() && message; - }, - [](Context *context) { - auto username = context->property("username").value(); - auto password = context->property("password").value(); - auto server = context->property("server").value(); - //For ssl use "smtps://mainserver.example.net - QByteArray cacert; // = "/path/to/certificate.pem"; - auto message = context->property("message").value(); - qWarning() << "Sending a mail: "; - MailTransport::sendMessage(message, server, username, password, cacert); - } -); diff --git a/framework/domain/actions/sinkactions.cpp b/framework/domain/actions/sinkactions.cpp index 57d63752..dea6fc72 100644 --- a/framework/domain/actions/sinkactions.cpp +++ b/framework/domain/actions/sinkactions.cpp @@ -19,6 +19,9 @@ #include #include +#include +#include + #include using namespace Kube; @@ -70,6 +73,46 @@ static ActionHandlerHelper synchronizeHandler("org.kde.kube.actions.synchronize" } ); +static ActionHandlerHelper sendMailHandler("org.kde.kube.actions.sendmail", + [](Context *context) -> bool { + auto accountId = context->property("accountId").value(); + auto message = context->property("message").value(); + return !accountId.isEmpty() && message; + }, + [](Context *context) { + auto accountId = context->property("accountId").value(); + //For ssl use "smtps://mainserver.example.net + // QByteArray cacert; // = "/path/to/certificate.pem"; + auto message = context->property("message").value(); + auto mimeMessage = Sink::Store::getTemporaryFilePath(); + QFile file(mimeMessage); + if (!file.open(QIODevice::ReadWrite)) { + qWarning() << "Failed to open the file: " << file.errorString() << mimeMessage; + return; + } + file.write(message->encodedContent()); + qWarning() << "Sending a mail: "; + + Sink::Query query; + query += Sink::Query::PropertyFilter("type", "org.kde.mailtransport"); + query += Sink::Query::PropertyFilter("account", QVariant::fromValue(accountId)); + Sink::Store::fetchAll(query) + .then>([=](const QList &resources) { + if (resources.isEmpty()) { + qWarning() << "Failed to find a mailtransport resource"; + } else { + auto resourceId = resources[0]->identifier(); + qDebug() << "Sending message via resource: " << resourceId; + Sink::ApplicationDomain::Mail mail(resourceId); + mail.setProperty("mimeMessage", mimeMessage); + Sink::Store::create(mail).exec(); + // return Sink::Store::create(mail); + } + return KAsync::error(0, "Failed to find a MailTransport resource."); + }).exec(); + } +); + // static ActionHandlerHelper saveAsDraft("org.kde.kube.actions.save-as-draft", // [](Context *context) -> bool { // return context->property("mail").isValid(); diff --git a/framework/domain/composercontroller.cpp b/framework/domain/composercontroller.cpp index 4ab4ac21..a383de26 100644 --- a/framework/domain/composercontroller.cpp +++ b/framework/domain/composercontroller.cpp @@ -26,12 +26,13 @@ #include #include #include +#include +#include "accountsmodel.h" #include "mailtemplates.h" ComposerController::ComposerController(QObject *parent) : QObject(parent) { - m_identityModel << "Kuberich " << "Uni " << "Spam "; } QString ComposerController::to() const @@ -99,22 +100,11 @@ void ComposerController::setBody(const QString &body) } } -QStringList ComposerController::identityModel() const +QAbstractItemModel *ComposerController::identityModel() const { - return m_identityModel; -} - -int ComposerController::fromIndex() const -{ - return m_fromIndex; -} - -void ComposerController::setFromIndex(int fromIndex) -{ - if(m_fromIndex != fromIndex) { - m_fromIndex = fromIndex; - emit fromIndexChanged(); - } + static auto accountsModel = new AccountsModel(); + QQmlEngine::setObjectOwnership(accountsModel, QQmlEngine::CppOwnership); + return accountsModel;; } QStringList ComposerController::attachemts() const @@ -165,6 +155,8 @@ KMime::Message::Ptr ComposerController::assembleMessage() KEmailAddress::splitAddress(to.toUtf8(), displayName, addrSpec, comment); mail->to(true)->addAddress(addrSpec, displayName); } + //FIXME set "from" from identity (or do that in the action directly?) + // mail->from(true)->addAddress("test@example.com", "John Doe"); mail->subject(true)->fromUnicodeString(m_subject, "utf-8"); mail->setBody(m_body.toUtf8()); mail->assemble(); @@ -174,17 +166,13 @@ KMime::Message::Ptr ComposerController::assembleMessage() void ComposerController::send() { auto mail = assembleMessage(); - Kube::ApplicationContext settings; - auto account = settings.currentAccount(); - auto identity = account.primaryIdentity(); - auto transport = identity.transport(); + auto currentAccountId = identityModel()->index(m_currentAccountIndex, 0).data(AccountsModel::AccountId).toByteArray(); Kube::Context context; context.setProperty("message", QVariant::fromValue(mail)); + context.setProperty("accountId", QVariant::fromValue(currentAccountId)); - context.setProperty("username", transport.username()); - context.setProperty("password", transport.password()); - context.setProperty("server", transport.server()); + qDebug() << "Current account " << currentAccountId; Kube::Action("org.kde.kube.actions.sendmail", context).execute(); clear(); @@ -206,5 +194,4 @@ void ComposerController::clear() setTo(""); setCc(""); setBcc(""); - setFromIndex(-1); } diff --git a/framework/domain/composercontroller.h b/framework/domain/composercontroller.h index b410ce9b..4ad505d8 100644 --- a/framework/domain/composercontroller.h +++ b/framework/domain/composercontroller.h @@ -23,6 +23,7 @@ #include #include #include +#include namespace KMime { class Message; @@ -37,8 +38,8 @@ class ComposerController : public QObject Q_PROPERTY (QString bcc READ bcc WRITE setBcc NOTIFY bccChanged) Q_PROPERTY (QString subject READ subject WRITE setSubject NOTIFY subjectChanged) Q_PROPERTY (QString body READ body WRITE setBody NOTIFY bodyChanged) - Q_PROPERTY (QStringList identityModel READ identityModel) - Q_PROPERTY (int fromIndex READ fromIndex WRITE setFromIndex NOTIFY fromIndexChanged) + Q_PROPERTY (QAbstractItemModel* identityModel READ identityModel CONSTANT) + Q_PROPERTY (int currentIdentityIndex MEMBER m_currentAccountIndex) Q_PROPERTY (QStringList attachments READ attachemts NOTIFY attachmentsChanged) public: @@ -59,10 +60,7 @@ public: QString body() const; void setBody(const QString &body); - QStringList identityModel() const; - - int fromIndex() const; - void setFromIndex(int fromIndex); + QAbstractItemModel *identityModel() const; QStringList attachemts() const; @@ -91,9 +89,8 @@ private: QString m_bcc; QString m_subject; QString m_body; - QStringList m_identityModel; - int m_fromIndex; QStringList m_attachments; QVariant m_originalMessage; QVariant m_msg; + int m_currentAccountIndex; }; -- cgit v1.2.3