summaryrefslogtreecommitdiffstats
path: root/examples/imapresource/imapserverproxy.cpp
diff options
context:
space:
mode:
authorChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-22 13:10:39 +0200
committerChristian Mollekopf <chrigi_1@fastmail.fm>2016-05-22 13:10:39 +0200
commit6864e4accaafa4fa90332719bff5a85a0e92b242 (patch)
tree31c0d6df98112674e55ea5ad636c2ad780add49c /examples/imapresource/imapserverproxy.cpp
parentde52c17a7a08e72affc4c182fb1650d18d8b3b2b (diff)
downloadsink-6864e4accaafa4fa90332719bff5a85a0e92b242.tar.gz
sink-6864e4accaafa4fa90332719bff5a85a0e92b242.zip
ImapResource prototype
Diffstat (limited to 'examples/imapresource/imapserverproxy.cpp')
-rw-r--r--examples/imapresource/imapserverproxy.cpp209
1 files changed, 209 insertions, 0 deletions
diff --git a/examples/imapresource/imapserverproxy.cpp b/examples/imapresource/imapserverproxy.cpp
new file mode 100644
index 0000000..9630096
--- /dev/null
+++ b/examples/imapresource/imapserverproxy.cpp
@@ -0,0 +1,209 @@
1/*
2 * Copyright (C) 2015 Christian Mollekopf <chrigi_1@fastmail.fm>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19#include "imapserverproxy.h"
20
21#include <QDir>
22#include <QFile>
23#include <KIMAP/KIMAP/LoginJob>
24#include <KIMAP/KIMAP/SelectJob>
25#include <KIMAP/KIMAP/AppendJob>
26
27#include <KIMAP/KIMAP/SessionUiProxy>
28#include <KCoreAddons/KJob>
29
30#include "log.h"
31
32static KAsync::Job<void> runJob(KJob *job)
33{
34 return KAsync::start<void>([job](KAsync::Future<void> &future) {
35 QObject::connect(job, &KJob::result, job, [&future](KJob *job) {
36 if (job->error()) {
37 Warning() << "Job failed: " << job->errorString();
38 future.setError(job->error(), job->errorString());
39 } else {
40 future.setFinished();
41 }
42 });
43 job->start();
44 });
45}
46
47class SessionUiProxy : public KIMAP::SessionUiProxy {
48 public:
49 bool ignoreSslError( const KSslErrorUiData &errorData ) {
50 return true;
51 }
52};
53
54ImapServerProxy::ImapServerProxy(const QString &serverUrl, int port) : mSession(new KIMAP::Session(serverUrl, port))
55{
56 mSession->setUiProxy(SessionUiProxy::Ptr(new SessionUiProxy));
57 mSession->setTimeout(10);
58}
59
60KAsync::Job<void> ImapServerProxy::login(const QString &username, const QString &password)
61{
62 if (mSession->state() == KIMAP::Session::State::Authenticated || mSession->state() == KIMAP::Session::State::Selected) {
63 return KAsync::null<void>();
64 }
65 auto loginJob = new KIMAP::LoginJob(mSession);
66 loginJob->setUserName(username);
67 loginJob->setPassword(password);
68 loginJob->setAuthenticationMode(KIMAP::LoginJob::Plain);
69 loginJob->setEncryptionMode(KIMAP::LoginJob::EncryptionMode::AnySslVersion);
70 return runJob(loginJob);
71}
72
73KAsync::Job<void> ImapServerProxy::select(const QString &mailbox)
74{
75 if (mSession->state() == KIMAP::Session::State::Disconnected) {
76 return KAsync::error<void>(1, "Not connected");
77 }
78 auto select = new KIMAP::SelectJob(mSession);
79 select->setMailBox(mailbox);
80 // select->setCondstoreEnabled(serverSupportsCondstore());
81 return runJob(select);
82}
83
84KAsync::Job<void> ImapServerProxy::append(const QString &mailbox, const QByteArray &content, const QList<QByteArray> &flags, const QDateTime &internalDate)
85{
86 if (mSession->state() == KIMAP::Session::State::Disconnected) {
87 return KAsync::error<void>(1, "Not connected");
88 }
89 auto append = new KIMAP::AppendJob(mSession);
90 append->setMailBox(mailbox);
91 append->setContent(content);
92 append->setFlags(flags);
93 append->setInternalDate(internalDate);
94 return runJob(append);
95}
96
97KAsync::Job<void> ImapServerProxy::fetch(const KIMAP::ImapSet &set, KIMAP::FetchJob::FetchScope scope, FetchCallback callback)
98{
99 if (mSession->state() == KIMAP::Session::State::Disconnected) {
100 return KAsync::error<void>(1, "Not connected");
101 }
102 auto fetch = new KIMAP::FetchJob(mSession);
103 fetch->setSequenceSet(set);
104 fetch->setUidBased(true);
105 fetch->setScope(scope);
106 QObject::connect(fetch, static_cast<void(KIMAP::FetchJob::*)(const QString &,
107 const QMap<qint64,qint64> &,
108 const QMap<qint64,qint64> &,
109 const QMap<qint64,KIMAP::MessageAttribute> &,
110 const QMap<qint64,KIMAP::MessageFlags> &,
111 const QMap<qint64,KIMAP::MessagePtr> &)>(&KIMAP::FetchJob::headersReceived),
112 callback);
113 return runJob(fetch);
114}
115
116KAsync::Job<QList<qint64>> ImapServerProxy::fetchHeaders(const QString &mailbox)
117{
118 auto list = QSharedPointer<QList<qint64>>::create();
119 KIMAP::FetchJob::FetchScope scope;
120 scope.parts.clear();
121 scope.mode = KIMAP::FetchJob::FetchScope::Headers;
122
123 //Fetch headers of all messages
124 return fetch(KIMAP::ImapSet(1, 0), scope,
125 [list](const QString &mailbox,
126 const QMap<qint64,qint64> &uids,
127 const QMap<qint64,qint64> &sizes,
128 const QMap<qint64,KIMAP::MessageAttribute> &attrs,
129 const QMap<qint64,KIMAP::MessageFlags> &flags,
130 const QMap<qint64,KIMAP::MessagePtr> &messages) {
131 Trace() << "Received " << uids.size() << " headers from " << mailbox;
132 Trace() << uids.size() << sizes.size() << attrs.size() << flags.size() << messages.size();
133
134 //TODO based on the data available here, figure out which messages to actually fetch
135 //(we only fetched headers and structure so far)
136 //We could i.e. build chunks to fetch based on the size
137
138 for (const auto &id : uids.keys()) {
139 list->append(uids.value(id));
140 }
141 })
142 .then<QList<qint64>>([list](){
143 return *list;
144 });
145}
146
147KAsync::Job<void> ImapServerProxy::list(KIMAP::ListJob::Option option, const std::function<void(const QList<KIMAP::MailBoxDescriptor> &mailboxes,const QList<QList<QByteArray> > &flags)> &callback)
148{
149 auto listJob = new KIMAP::ListJob(mSession);
150 listJob->setOption(option);
151 // listJob->setQueriedNamespaces(serverNamespaces());
152 QObject::connect(listJob, &KIMAP::ListJob::mailBoxesReceived,
153 listJob, callback);
154 return runJob(listJob);
155}
156
157KAsync::Future<void> ImapServerProxy::fetchFolders(std::function<void(const QStringList &)> callback)
158{
159 Trace() << "Fetching folders";
160 auto job = login("doe", "doe").then<void>(list(KIMAP::ListJob::IncludeUnsubscribed, [callback](const QList<KIMAP::MailBoxDescriptor> &mailboxes, const QList<QList<QByteArray> > &flags){
161 QStringList list;
162 for (const auto &mailbox : mailboxes) {
163 Trace() << "Found mailbox: " << mailbox.name;
164 list << mailbox.name;
165 }
166 callback(list);
167 }),
168 [](int errorCode, const QString &errorString) {
169 Warning() << "Failed to list folders: " << errorCode << errorString;
170 });
171 return job.exec();
172}
173
174KAsync::Future<void> ImapServerProxy::fetchMessages(const QString &folder, std::function<void(const QVector<Message> &)> callback)
175{
176 auto job = login("doe", "doe").then<void>(select(folder)).then<void, KAsync::Job<void>>([this, callback, folder]() -> KAsync::Job<void> {
177 return fetchHeaders(folder).then<void, KAsync::Job<void>, QList<qint64>>([this, callback](const QList<qint64> &uidsToFetch){
178 Trace() << "Uids to fetch: " << uidsToFetch;
179 if (uidsToFetch.isEmpty()) {
180 Trace() << "Nothing to fetch";
181 return KAsync::null<void>();
182 }
183 KIMAP::FetchJob::FetchScope scope;
184 scope.parts.clear();
185 scope.mode = KIMAP::FetchJob::FetchScope::Full;
186
187 KIMAP::ImapSet set;
188 set.add(uidsToFetch.toVector());
189 return fetch(set, scope,
190 [callback](const QString &mailbox,
191 const QMap<qint64,qint64> &uids,
192 const QMap<qint64,qint64> &sizes,
193 const QMap<qint64,KIMAP::MessageAttribute> &attrs,
194 const QMap<qint64,KIMAP::MessageFlags> &flags,
195 const QMap<qint64,KIMAP::MessagePtr> &messages) {
196 Trace() << "Received " << uids.size() << " messages from " << mailbox;
197 Trace() << uids.size() << sizes.size() << attrs.size() << flags.size() << messages.size();
198
199 QVector<Message> list;
200 for (const auto &id : uids.keys()) {
201 list << Message{uids.value(id), sizes.value(id), attrs.value(id), flags.value(id), messages.value(id)};
202 }
203 callback(list);
204 });
205 });
206
207 });
208 return job.exec();
209}