File indexing completed on 2024-05-12 05:17:13

0001 /*
0002     SPDX-FileCopyrightText: 2009 Andras Mantia <amantia@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "kimap_export.h"
0010 
0011 #include "metadatajobbase.h"
0012 
0013 namespace KIMAP
0014 {
0015 class Session;
0016 struct Response;
0017 class GetMetaDataJobPrivate;
0018 
0019 /**
0020  * Fetches mailbox metadata.
0021  *
0022  * Provides support for the IMAP METADATA extension; both the
0023  * final RFC version
0024  * (<a href="https://tools.ietf.org/html/rfc5464">RFC 5464</a>)
0025  * and the older, incompatible draft version (known as ANNOTATEMORE)
0026  * (<a
0027  * href="https://tools.ietf.org/html/draft-daboo-imap-annotatemore-07"
0028  * >draft-daboo-imap-annotatemore-07</a>).  See setServerCompatibility().
0029  *
0030  * This job can only be run when the session is in the
0031  * authenticated (or selected) state.
0032  *
0033  * If the server supports ACLs, the user will need the
0034  * Acl::Lookup right on the mailbox, as well as one of
0035  * - Acl::Read
0036  * - Acl::KeepSeen
0037  * - Acl::Write
0038  * - Acl::Insert
0039  * - Acl::Post
0040  * Otherwise, the user must be able to list the mailbox
0041  * and either read or write the message content.
0042  *
0043  * Note also that on servers that implement the Annotatemore
0044  * version of the extension, only Acl::Lookup rights are
0045  * required (ie: the user must be able to list the mailbox).
0046  */
0047 class KIMAP_EXPORT GetMetaDataJob : public MetaDataJobBase
0048 {
0049     Q_OBJECT
0050     Q_DECLARE_PRIVATE(GetMetaDataJob)
0051 
0052     friend class SessionPrivate;
0053 
0054 public:
0055     explicit GetMetaDataJob(Session *session);
0056     ~GetMetaDataJob() override;
0057 
0058     /**
0059      * Used to specify the depth of the metadata hierarchy to walk.
0060      */
0061     enum Depth {
0062         NoDepth = 0, /**< Only the requested entries */
0063         OneLevel, /**< The requested entries and all their direct children */
0064         AllLevels /**< The requested entries and all their descendants */
0065     };
0066 
0067     Q_DECLARE_FLAGS(Depths, Depth)
0068 
0069     /**
0070      * Add an entry to the query list.
0071      *
0072      * See SetMetaDataJob for a description of metadata entry names.
0073      *
0074      * When operating in Annotatemore mode, you should provide an attribute
0075      * name.  Typically this will be "value", "value.priv" or "value.shared",
0076      * although you might want to fetch the "content-type" or
0077      * "content-language" attributes as well.
0078      *
0079      * @param entry      the metadata entry name
0080      * @param attribute  the attribute name, in Annotatemore mode
0081      *
0082      * @deprecated use addRequestedEntry(QByteArray) instead
0083      */
0084     KIMAP_DEPRECATED void addEntry(const QByteArray &entry, const QByteArray &attribute = QByteArray());
0085 
0086     /**
0087      * Add an entry to the query list.
0088      *
0089      * See SetMetaDataJob for a description of metadata entry names.
0090      *
0091      * Note that this expects METADATA style entries (with a /shared or /private prefix typically).
0092      * In ANNOTATEMORE mode, this prefix is automatically replaced with an appropriate attribute.
0093      *
0094      * @param entry the metadata entry name
0095      */
0096     void addRequestedEntry(const QByteArray &entry);
0097 
0098     /**
0099      * Limits the size of returned metadata entries.
0100      *
0101      * In order to save time or bandwidth, it is possible to prevent the
0102      * server from returning metadata entries that are larger than a
0103      * certain size.  These entries will simply not appear in the
0104      * list returned by allMetaData(), and will not be accessible using
0105      * metaData().
0106      *
0107      * Note that this is only used when the server capability mode is
0108      * Metadata.
0109      *
0110      * The default is no limit (-1).  A value of less than -1 will cause
0111      * the job to fail.
0112      *
0113      * @param size  the entry size limit, in octets, or -1 for no limit
0114      */
0115     void setMaximumSize(qint64 size);
0116 
0117     /**
0118      * Sets whether to retrieve children or descendants of the requested entries.
0119      *
0120      * Metadata entry names are hierarchical, much like UNIX path names.
0121      * It therefore makes sense to ask for an entry and all its children
0122      * (OneLevel) or an entry and all its descendants (AllLevels).
0123      *
0124      * For example, /shared/foo/bar/baz is a child of /shared/foo/bar and a
0125      * descendent of /shared/foo.  So if you request the entry "/shared/foo"
0126      * with depth NoDepth, you will only get the "/shared/foo" entry.  If
0127      * you set the depth to OneLevel, you will also get "/shared/foo/bar".
0128      * If you set the depth to AllLevels, you will also get
0129      * "/shared/foo/bar/baz", and every other metadata entry that starts
0130      * with "/shared/foo/".
0131      *
0132      * Note that this is only used when the server capability mode is
0133      * Metadata.
0134      *
0135      * @param depth  the depth of the metadata tree to return
0136      */
0137     void setDepth(Depth depth);
0138 
0139     /**
0140      * Get a single metadata entry.
0141      *
0142      * The metadata must have been requested using addEntry(), and
0143      * the job must have completed successfully, or this method
0144      * will not return anything.
0145      *
0146      * Note that if setMaximumSize() was used to limit the size of
0147      * returned metadata, this method may return an empty QByteArray
0148      * even if the metadata entry was requested and exists on the
0149      * server.  This will happen when the metadata entry is larger
0150      * than the size limit given to setMaximumSize().
0151      *
0152      * @param mailBox    the mailbox the metadata is attached to, or
0153      *                   an empty string for server metadata
0154      * @param entry      the entry to get
0155      * @param attribute  (only in Annotatemore mode) the attribute to get
0156      * @return  the metadata entry value
0157      *
0158      * @deprecated use metaData(QByteArray entry) instead
0159      */
0160     // XXX: what's with the mailBox argument in a class that has setMailBox()?
0161     //      KJobs are not intended to be run more than once
0162     KIMAP_DEPRECATED QByteArray metaData(const QString &mailBox, const QByteArray &entry, const QByteArray &attribute = QByteArray()) const;
0163 
0164     /**
0165      * Get a single metadata entry.
0166      *
0167      * The metadata must have been requested using addEntry(), and
0168      * the job must have completed successfully, or this method
0169      * will not return anything.
0170      *
0171      * Note that if setMaximumSize() was used to limit the size of
0172      * returned metadata, this method may return an empty QByteArray
0173      * even if the metadata entry was requested and exists on the
0174      * server.  This will happen when the metadata entry is larger
0175      * than the size limit given to setMaximumSize().
0176      *
0177      * Note that this expects METADATA style entries (with a /shared or /private prefix typically).
0178      * In ANNOTATEMORE mode, this prefix is automatically replaced with an appropriate attribute.
0179      *
0180      * @param entry the entry to get
0181      * @return  the metadata entry value
0182      */
0183     QByteArray metaData(const QByteArray &entry) const;
0184 
0185     /**
0186      * Get all the metadata for a given mailbox.
0187      *
0188      * The returned map is from metadata entry names to attributes or values.
0189      *
0190      * If operating in Metadata mode, the metadata value is stored against the
0191      * empty QByteArray:
0192      * @code
0193      * map = job.allMetaData( "INBOX" );
0194      * QByteArray value = map[ "/shared/comment" ].value( QByteArray() );
0195      * @endcode
0196      *
0197      * The equivalent in Annotatemore mode would be:
0198      * @code
0199      * map = job.allMetaData( "INBOX" );
0200      * QByteArray value = map[ "/comment" ].value( "value.shared" );
0201      * @endcode
0202      *
0203      * @param mailBox  a mailbox name or an empty string for server metadata
0204      * @return  a map from metadata entry names to attributes or values
0205      */
0206     // XXX: what's with the mailBox argument in a class that has setMailBox()?
0207     //      KJobs are not intended to be run more than once
0208     QMap<QByteArray, QMap<QByteArray, QByteArray>> allMetaData(const QString &mailBox) const;
0209 
0210     /**
0211      * Get all the metadata for the mailbox set with setMailBox().
0212      *
0213      * Note that the returned map uses METADATA style entries (with a /shared or /private prefix typically),
0214      * also in ANNOTATEMORE mode.
0215      *
0216      * @return a map from metadata entry names to values
0217      */
0218     QMap<QByteArray, QByteArray> allMetaData() const;
0219 
0220     /**
0221      * Get all the metadata for the mailbox.
0222      *
0223      * Note that the returned map uses METADATA style entries (with a /shared or /private prefix typically),
0224      * also in ANNOTATEMORE mode.
0225      *
0226      * @return a map from metadata entry names to values
0227      */
0228     QMap<QByteArray, QByteArray> allMetaDataForMailbox(const QString &mailbox) const;
0229 
0230     /**
0231      * Get all the metadata for for all mailboxes.
0232      *
0233      * Note that the returned map uses METADATA style entries (with a /shared or /private prefix typically),
0234      * also in ANNOTATEMORE mode.
0235      *
0236      * @return a map in the form (mailbox, (entry, value))
0237      */
0238     QHash<QString, QMap<QByteArray, QByteArray>> allMetaDataForMailboxes() const;
0239 
0240 protected:
0241     void doStart() override;
0242     void handleResponse(const Response &response) override;
0243 };
0244 
0245 }