sendvcardsjob.cpp 4.52 KB
Newer Older
Laurent Montel's avatar
Laurent Montel committed
1
/*
Laurent Montel's avatar
Laurent Montel committed
2
   SPDX-FileCopyrightText: 2015-2022 Laurent Montel <montel@kde.org>
Laurent Montel's avatar
Laurent Montel committed
3

4
   SPDX-License-Identifier: GPL-2.0-or-later
Laurent Montel's avatar
Laurent Montel committed
5
6
7
*/

#include "sendvcardsjob.h"
8

Laurent Montel's avatar
Laurent Montel committed
9
#include "kaddressbook_sendvcardsplugin_debug.h"
10
#include <Akonadi/ContactGroupExpandJob>
11
12
#include <Akonadi/ItemFetchJob>
#include <Akonadi/ItemFetchScope>
13
#include <KEMailClientLauncherJob>
Laurent Montel's avatar
Laurent Montel committed
14
#include <KLocalizedString>
Laurent Montel's avatar
Laurent Montel committed
15
16
17
#include <MimeTreeParser/AttachmentTemporaryFilesDirs>
#include <QFile>
#include <QTemporaryDir>
Laurent Montel's avatar
Laurent Montel committed
18
19
20
21

using namespace KABSendVCards;

SendVcardsJob::SendVcardsJob(const Akonadi::Item::List &listItem, QObject *parent)
Laurent Montel's avatar
Laurent Montel committed
22
23
    : QObject(parent)
    , mListItem(listItem)
Laurent Montel's avatar
Laurent Montel committed
24
{
Laurent Montel's avatar
Laurent Montel committed
25
    // Don't delete it.
26
    mAttachmentTemporary = new MimeTreeParser::AttachmentTemporaryFilesDirs();
Laurent Montel's avatar
Laurent Montel committed
27
28
29
30
31
}

SendVcardsJob::~SendVcardsJob()
{
    delete mTempDir;
Laurent Montel's avatar
Laurent Montel committed
32
    mTempDir = nullptr;
Laurent Montel's avatar
Laurent Montel committed
33
    // Don't delete it.
Laurent Montel's avatar
Laurent Montel committed
34
    mAttachmentTemporary = nullptr;
Laurent Montel's avatar
Laurent Montel committed
35
36
37
38
39
}

bool SendVcardsJob::start()
{
    if (mListItem.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
40
        qCDebug(KADDRESSBOOK_SENDVCARDS_LOG) << " No Item found";
Laurent Montel's avatar
Laurent Montel committed
41
        mAttachmentTemporary->deleteLater();
Laurent Montel's avatar
Laurent Montel committed
42
        mAttachmentTemporary = nullptr;
Laurent Montel's avatar
Laurent Montel committed
43
44
45
46
        deleteLater();
        return false;
    }

47
    for (const Akonadi::Item &item : std::as_const(mListItem)) {
Laurent Montel's avatar
Laurent Montel committed
48
        if (item.hasPayload<KContacts::Addressee>()) {
Laurent Montel's avatar
Laurent Montel committed
49
            const auto contact = item.payload<KContacts::Addressee>();
Laurent Montel's avatar
Laurent Montel committed
50
            QByteArray data = item.payloadData();
Laurent Montel's avatar
Laurent Montel committed
51
            // Workaround about broken kaddressbook fields.
Laurent Montel's avatar
Laurent Montel committed
52
53
54
            KContacts::adaptIMAttributes(data);
            createTemporaryDir();
            const QString contactRealName(contact.realName());
Laurent Montel's avatar
Laurent Montel committed
55
            const QString attachmentName = (contactRealName.isEmpty() ? QStringLiteral("vcard") : contactRealName) + QStringLiteral(".vcf");
Laurent Montel's avatar
Laurent Montel committed
56
57
58
            createTemporaryFile(data, attachmentName);
        } else if (item.hasPayload<KContacts::ContactGroup>()) {
            ++mExpandGroupJobCount;
Laurent Montel's avatar
Laurent Montel committed
59
            const auto group = item.payload<KContacts::ContactGroup>();
Laurent Montel's avatar
Laurent Montel committed
60
            const QString groupName(group.name());
Laurent Montel's avatar
Laurent Montel committed
61
            const QString attachmentName = (groupName.isEmpty() ? QStringLiteral("vcard") : groupName) + QStringLiteral(".vcf");
62
            auto expandJob = new Akonadi::ContactGroupExpandJob(group, this);
Laurent Montel's avatar
Laurent Montel committed
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
            expandJob->setProperty("groupName", attachmentName);
            connect(expandJob, &KJob::result, this, &SendVcardsJob::slotExpandGroupResult);
            expandJob->start();
        }
    }

    if (mExpandGroupJobCount == 0) {
        jobFinished();
    }
    return true;
}

void SendVcardsJob::createTemporaryDir()
{
    if (!mTempDir) {
Laurent Montel's avatar
Laurent Montel committed
78
        mTempDir = new QTemporaryDir(QDir::tempPath() + QLatin1Char('/') + QStringLiteral("sendvcards"));
Laurent Montel's avatar
Laurent Montel committed
79
80
81
82
83
84
85
        mTempDir->setAutoRemove(false);
        mAttachmentTemporary->addTempDir(mTempDir->path());
    }
}

void SendVcardsJob::jobFinished()
{
86
87
88
89
90
    const QStringList tempFilePaths{mAttachmentTemporary->temporaryFiles()};
    QList<QUrl> lstAttachment;
    for (const QString &path : tempFilePaths) {
        lstAttachment.append(QUrl::fromLocalFile(path));
    }
Laurent Montel's avatar
Laurent Montel committed
91
    if (!lstAttachment.isEmpty()) {
Laurent Montel's avatar
Laurent Montel committed
92
        auto job = new KEMailClientLauncherJob(this);
93
94
        job->setAttachments(lstAttachment);
        job->start();
Laurent Montel's avatar
Laurent Montel committed
95
    } else {
Laurent Montel's avatar
Laurent Montel committed
96
        Q_EMIT sendVCardsError(i18n("No vCard created."));
Laurent Montel's avatar
Laurent Montel committed
97
98
99
100
101
102
103
104
105
106
    }
    mAttachmentTemporary->removeTempFiles();
    deleteLater();
}

KContacts::VCardConverter::Version SendVcardsJob::version() const
{
    return mVersion;
}

Laurent Montel's avatar
Laurent Montel committed
107
void SendVcardsJob::setVersion(KContacts::VCardConverter::Version version)
Laurent Montel's avatar
Laurent Montel committed
108
109
110
111
112
113
{
    mVersion = version;
}

void SendVcardsJob::slotExpandGroupResult(KJob *job)
{
114
    auto expandJob = qobject_cast<Akonadi::ContactGroupExpandJob *>(job);
Laurent Montel's avatar
Laurent Montel committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    Q_ASSERT(expandJob);

    const QString attachmentName = expandJob->property("groupName").toString();
    KContacts::VCardConverter converter;
    const QByteArray groupData = converter.exportVCards(expandJob->contacts(), mVersion);
    createTemporaryDir();
    createTemporaryFile(groupData, attachmentName);

    --mExpandGroupJobCount;
    if (mExpandGroupJobCount == 0) {
        jobFinished();
    }
}

void SendVcardsJob::createTemporaryFile(const QByteArray &data, const QString &filename)
{
    QFile file(mTempDir->path() + QLatin1Char('/') + filename);
    if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
Laurent Montel's avatar
Laurent Montel committed
133
        qCDebug(KADDRESSBOOK_SENDVCARDS_LOG) << "Cannot write vcard filename :" << filename;
Laurent Montel's avatar
Laurent Montel committed
134
        Q_EMIT sendVCardsError(i18n("Temporary file \'%1\' cannot be created", filename));
Laurent Montel's avatar
Laurent Montel committed
135
136
137
138
139
140
141
142
        return;
    }

    QTextStream out(&file);
    out << data;
    file.close();
    mAttachmentTemporary->addTempFile(file.fileName());
}