/* * Copyright (C) 2015 Christian Mollekopf * * 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 2 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, write to the * Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #pragma once #include #include #include #include #include #include namespace Imap { namespace Flags { /// The flag for a message being seen (i.e. opened by user). extern const char* Seen; /// The flag for a message being deleted by the user. extern const char* Deleted; /// The flag for a message being replied to by the user. extern const char* Answered; /// The flag for a message being marked as flagged. extern const char* Flagged; } namespace FolderFlags { extern const char* Noinferiors; extern const char* Noselect; extern const char* Marked; extern const char* Unmarked; } struct Message { qint64 uid; qint64 size; KIMAP2::MessageAttributes attributes; KIMAP2::MessageFlags flags; KMime::Message::Ptr msg; }; struct Folder { Folder() = default; Folder(const QString &path, const QChar &separator, bool noselect_) : noselect(noselect_), mPath(path), pathParts(path.split(separator)), mSeparator(separator) { } Folder(const QString &path_) : mPath(path_) { } QString normalizedPath() const { return path('/'); } QString path(const QChar &s) const { Q_ASSERT(!s.isNull()); return pathParts.join(s); } QString path() const { Q_ASSERT(!mPath.isEmpty()); return mPath; } QString parentPath() const { Q_ASSERT(!mSeparator.isNull()); auto parts = pathParts; parts.removeLast(); return parts.join(mSeparator); } QString normalizedParentPath() const { Q_ASSERT(!pathParts.isEmpty()); auto parts = pathParts; parts.removeLast(); return parts.join('/'); } QString name() const { Q_ASSERT(!pathParts.isEmpty()); return pathParts.last(); } bool noselect = false; private: QString mPath; QList pathParts; QChar mSeparator; }; struct SelectResult { qint64 uidValidity; qint64 uidNext; quint64 highestModSequence; }; class ImapServerProxy { KIMAP2::Session *mSession; QStringList mCapabilities; QSet mPersonalNamespaces; QChar mPersonalNamespaceSeparator; QSet mSharedNamespaces; QChar mSharedNamespaceSeparator; QSet mUserNamespaces; QChar mUserNamespaceSeparator; public: ImapServerProxy(const QString &serverUrl, int port); //Standard IMAP calls KAsync::Job login(const QString &username, const QString &password); KAsync::Job select(const QString &mailbox); KAsync::Job append(const QString &mailbox, const QByteArray &content, const QList &flags = QList(), const QDateTime &internalDate = QDateTime()); KAsync::Job store(const KIMAP2::ImapSet &set, const QList &flags); KAsync::Job storeFlags(const KIMAP2::ImapSet &set, const QList &flags); KAsync::Job addFlags(const KIMAP2::ImapSet &set, const QList &flags); KAsync::Job removeFlags(const KIMAP2::ImapSet &set, const QList &flags); KAsync::Job create(const QString &mailbox); KAsync::Job rename(const QString &mailbox, const QString &newMailbox); KAsync::Job remove(const QString &mailbox); KAsync::Job expunge(); KAsync::Job expunge(const KIMAP2::ImapSet &set); KAsync::Job copy(const KIMAP2::ImapSet &set, const QString &newMailbox); KAsync::Job> search(const KIMAP2::ImapSet &set); KAsync::Job> search(const KIMAP2::Term &term); typedef std::function FetchCallback; KAsync::Job fetch(const KIMAP2::ImapSet &set, KIMAP2::FetchJob::FetchScope scope, FetchCallback callback); KAsync::Job fetch(const KIMAP2::ImapSet &set, KIMAP2::FetchJob::FetchScope scope, const std::function &callback); KAsync::Job list(KIMAP2::ListJob::Option option, const std::function &flags)> &callback); QStringList getCapabilities() const; //Composed calls that do login etc. KAsync::Job> fetchHeaders(const QString &mailbox, qint64 minUid = 1); KAsync::Job remove(const QString &mailbox, const KIMAP2::ImapSet &set); KAsync::Job remove(const QString &mailbox, const QByteArray &imapSet); KAsync::Job move(const QString &mailbox, const KIMAP2::ImapSet &set, const QString &newMailbox); KAsync::Job createSubfolder(const QString &parentMailbox, const QString &folderName); KAsync::Job renameSubfolder(const QString &mailbox, const QString &newName); KAsync::Job> fetchUids(const QString &mailbox); KAsync::Job> fetchUidsSince(const QString &mailbox, const QDate &since); QString mailboxFromFolder(const Folder &) const; KAsync::Job fetchFolders(std::function callback); KAsync::Job fetchMessages(const Folder &folder, std::function callback, std::function progress = std::function()); KAsync::Job fetchMessages(const Folder &folder, qint64 uidNext, std::function callback, std::function progress = std::function()); KAsync::Job fetchMessages(const Folder &folder, const QVector &uidsToFetch, std::function callback, std::function progress); KAsync::Job fetchFlags(const Folder &folder, const KIMAP2::ImapSet &set, qint64 changedsince, std::function callback); KAsync::Job> fetchUids(const Folder &folder); private: QObject mGuard; }; }