diff --git a/kimap/getmetadatajob.h b/kimap/getmetadatajob.h index 72c82a5b2..84a248c83 100644 --- a/kimap/getmetadatajob.h +++ b/kimap/getmetadatajob.h @@ -1,97 +1,196 @@ /* Copyright (c) 2009 Andras Mantia This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIMAP_GETMETADATAJOB_H #define KIMAP_GETMETADATAJOB_H #include "kimap_export.h" #include "metadatajobbase.h" namespace KIMAP { class Session; struct Message; class GetMetaDataJobPrivate; +/** + * Fetches mailbox metadata. + * + * Provides support for the IMAP METADATA extension; both the + * final RFC version + * (RFC 5464) + * and the older, incompatible draft version (known as ANNOTATEMORE) + * (draft-daboo-imap-annotatemore-07). See setServerCompatibility(). + * + * This job can only be run when the session is in the + * authenticated (or selected) state. + * + * If the server supports ACLs, the user will need the + * Acl::Lookup right on the mailbox, as well as one of + * - Acl::Read + * - Acl::KeepSeen + * - Acl::Write + * - Acl::Insert + * - Acl::Post + * Otherwise, the user must be able to list the mailbox + * and either read or write the message content. + * + * Note also that on servers that implement the Annotatemore + * version of the extension, only Acl::Lookup rights are + * required (ie: the user must be able to list the mailbox). + */ class KIMAP_EXPORT GetMetaDataJob : public MetaDataJobBase { Q_OBJECT - Q_DECLARE_PRIVATE(GetMetaDataJob) + Q_DECLARE_PRIVATE( GetMetaDataJob ) friend class SessionPrivate; public: explicit GetMetaDataJob( Session *session ); virtual ~GetMetaDataJob(); + /** + * Used to specify the depth of the metadata heirachy to walk. + */ enum Depth { - NoDepth = 0, - OneLevel, - AllLevels + NoDepth = 0, /**< Only the requested entries */ + OneLevel, /**< The requested entries and all their direct children */ + AllLevels /**< The requested entries and all their descendants */ }; - Q_DECLARE_FLAGS(Depths, Depth) + Q_DECLARE_FLAGS( Depths, Depth ) /** - * Add an entry, attribute pair to query, if the job is operating in Annotatemore mode, the attribute name is used.In Metadata mode the @param attribute is ignored. - * @param entry the metadata entry name - * @param attribute the attribute name, in Annotatemore mode + * Add an entry to the query list. + * + * See SetMetaDataJob for a description of metadata entry names. + * + * When operating in Annotatemore mode, you should provide an attribute + * name. Typically this will be "value", "value.priv" or "value.shared", + * although you might want to fetch the "content-type" or + * "content-language" attributes as well. + * + * @param entry the metadata entry name + * @param attribute the attribute name, in Annotatemore mode */ - void addEntry(const QByteArray &entry, const QByteArray &attribute = QByteArray()); + void addEntry( const QByteArray &entry, const QByteArray &attribute = QByteArray() ); /** - * Only entry values that are less than or equal in octet size to the specified @param size limit are returned. In - * Annotatemore mode, this setting is ignored. + * Limits the size of returned metadata entries. + * + * In order to save time or bandwidth, it is possible to prevent the + * server from returning metadata entries that are larger than a + * certain size. These entries will simply not appear in the + * list returned by allMetaData(), and will not be accessible using + * metaData(). + * + * Note that this is only used when the server capability mode is + * Metadata. + * + * The default is no limit (-1). A value of less than -1 will cause + * the job to fail. + * + * @param size the entry size limit, in octets, or -1 for no limit */ - void setMaximumSize(qint64 size); + void setMaximumSize( qint64 size ); /** - * Default is NoDepth. In Annotatemore mode, this setting is ignored. - * @param depth + * Sets whether to retreive children or descendants of the requested entries. + * + * Metadata entry names are heirachical, much like UNIX path names. + * It therefore makes sense to ask for an entry and all its children + * (OneLevel) or an entry and all its descendants (AllLevels). + * + * For example, /shared/foo/bar/baz is a child of /shared/foo/bar and a + * descendent of /shared/foo. So if you request the entry "/shared/foo" + * with depth NoDepth, you will only get the "/shared/foo" entry. If + * you set the depth to OneLevel, you will also get "/shared/foo/bar". + * If you set the depth to AllLevels, you will also get + * "/shared/foo/bar/baz", and every other metadata entry that starts + * with "/shared/foo/". + * + * Note that this is only used when the server capability mode is + * Metadata. + * + * @param depth the depth of the metadata tree to return */ - void setDepth(Depth depth); + void setDepth( Depth depth ); /** - * Get the metadata. If used in Metadata mode, @param attribute is ignored. - * @param mailBox - * @param entry - * @param attribute - * @return + * Get a single metadata entry. + * + * The metadata must have been requested using addEntry(), and + * the job must have completed successfully, or this method + * will not return anything. + * + * Note that if setMaximumSize() was used to limit the size of + * returned metadata, this method may return an empty QByteArray + * even if the metadata entry was requested and exists on the + * server. This will happen when the metadata entry is larger + * than the size limit given to setMaximumSize(). + * + * @param mailBox the mailbox the metadata is attached to, or + * an empty string for server metadata + * @param entry the entry to get + * @param attribute (only in Annotatemore mode) the attribute to get + * @return the metadata entry value */ - QByteArray metaData(const QString &mailBox, const QByteArray &entry, - const QByteArray &attribute = QByteArray()) const; + // XXX: what's with the mailBox argument in a class that has setMailBox()? + // KJobs are not intended to be run more than once + QByteArray metaData( const QString &mailBox, const QByteArray &entry, + const QByteArray &attribute = QByteArray() ) const; /** * Get all the metadata for a given mailbox. * - * @param mailBox - * @return + * The returned map is from metadata entry names to attributes or values. + * + * If operating in Metadata mode, the metadata value is stored against the + * empty QByteArray: + * @code + * map = job.allMetaData( "INBOX" ); + * QByteArray value = map[ "/shared/comment" ].value( QByteArray() ); + * @endcode + * + * The equivalent in Annotatemore mode would be: + * @code + * map = job.allMetaData( "INBOX" ); + * QByteArray value = map[ "/comment" ].value( "value.shared" ); + * @endcode + * + * @param mailBox a mailbox name or an empty string for server metadata + * @return a map from metadata entry names to attributes or values */ - QMap > allMetaData(const QString &mailBox) const; + // XXX: what's with the mailBox argument in a class that has setMailBox()? + // KJobs are not intended to be run more than once + QMap > allMetaData( const QString &mailBox ) const; protected: virtual void doStart(); virtual void handleResponse( const Message &response ); }; } #endif diff --git a/kimap/metadatajobbase.h b/kimap/metadatajobbase.h index edf7e06fa..e0745a8bd 100644 --- a/kimap/metadatajobbase.h +++ b/kimap/metadatajobbase.h @@ -1,74 +1,126 @@ /* Copyright (c) 2009 Andras Mantia This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIMAP_METADATAJOBBASE_H #define KIMAP_METADATAJOBBASE_H #include "kimap_export.h" #include "job.h" namespace KIMAP { class Session; struct Message; class MetaDataJobBasePrivate; -/** @short Base class of Metadata/Annotatemore related jobs. It cannot be used directly, you must subclass it and reimplement at least the -doStart() method. +/** + * Base class for jobs that operate on mailbox metadata + * + * Provides support for the IMAP METADATA extension; both the + * final RFC version + * (RFC 5464) + * and the older, incompatible draft version (known as ANNOTATEMORE) + * (draft-daboo-imap-annotatemore-07). + * + * This class cannot be used directly, you must subclass it and reimplement + * at least the doStart() method. */ class KIMAP_EXPORT MetaDataJobBase : public Job { Q_OBJECT Q_DECLARE_PRIVATE(MetaDataJobBase) friend class SessionPrivate; public: explicit MetaDataJobBase( Session *session ); virtual ~MetaDataJobBase(); + /** + * Represents the capability level of the server. + */ enum ServerCapability { - Metadata = 0, //rfc5464 - Annotatemore //compatibility with draft-daboo-imap-annotatemore-07 + /** + * Used to indicate that the server supports the RFC 5464 version + * of the extension. + * + * This corresponds to the METADATA server capability. + */ + Metadata = 0, + /** + * Used to indicate that the server supports the + * draft-daboo-imap-annotatemore-07 version of the extension. + * + * This corresponds to the ANNOTATEMORE server capability. + */ + Annotatemore }; + /** + * Set the mailbox to act on + * + * This may be an empty string, in which case metadata for the + * server (rather than a specific mailbox) will be retreived. + * + * @param mailBox the name of an existing mailbox, or an empty string + */ void setMailBox( const QString &mailBox ); + /** + * The mailbox that will be acted upon. + * + * If this is an empty string, server metadata will be retreived. + * + * @return a mailbox name, or an empty string + */ QString mailBox() const; /** - * Set what kind of annotation does the server support. The commands send out depend on the mode set here. - * @param capability Metadata (RFC5464 mode) or Annotatemore (draft-daboo-imap-annotatemore-07 mode) + * Set what version of the metadata extension to be compatible with. + * + * This will determine the commands that will be sent to the server. + * + * The draft for the metadata extension changed in an incompatible + * way between versions 7 and 8, and some servers support version 7. + * It should be possible to check which version the server supports + * using CapabilityJob: servers implementing + * draft-daboo-imap-annotatemore-07 should advertise the + * ANNOTATEMORE capability, whereas servers implementing the final + * RFC 5464 should advertise the METADATA capability. + * + * The default mode is Metadata. + * + * @param capability the version of the extension implemented by the server */ - void setServerCapability(const ServerCapability& capability); - + void setServerCapability( const ServerCapability &capability ); /** - * Check the operating mode. - * @return the annotation capability of the server, see ServerCapability + * The version of the metadata extension that will be used. */ ServerCapability serverCapability() const; protected: MetaDataJobBase( JobPrivate &dd ); }; } #endif diff --git a/kimap/setmetadatajob.h b/kimap/setmetadatajob.h index d6d64e4b8..0ea9e3a4f 100644 --- a/kimap/setmetadatajob.h +++ b/kimap/setmetadatajob.h @@ -1,90 +1,216 @@ /* Copyright (c) 2009 Andras Mantia This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KIMAP_SETMETADATAJOB_H #define KIMAP_SETMETADATAJOB_H #include "kimap_export.h" #include "metadatajobbase.h" namespace KIMAP { class Session; struct Message; class SetMetaDataJobPrivate; +/** + * Sets mailbox metadata. + * + * Provides support for the IMAP METADATA extension; both the + * final RFC version + * (RFC 5464) + * and the older, incompatible draft version (known as ANNOTATEMORE) + * (draft-daboo-imap-annotatemore-07). See setServerCompatibility(). + * + * Note that in Annotatemore mode, this job can only operate on + * one metadata entry at once. + * + * This job can only be run when the session is in the + * authenticated (or selected) state. + * + * If the server supports ACLs, the user will need the + * Acl::Lookup right on the mailbox, as well as one of + * - Acl::Read + * - Acl::KeepSeen + * - Acl::Write + * - Acl::Insert + * - Acl::Post + * Otherwise, the user must be able to list the mailbox + * and either read or write the message content. + * + * Note that even if the user has these permissions, the + * server may refuse to allow the user to write metadata + * based on some other criteria. + * + * Note also that on servers that implement the Annotatemore + * version of the extension, only Acl::Lookup rights are + * required (ie: the user must be able to list the mailbox). + */ class KIMAP_EXPORT SetMetaDataJob : public MetaDataJobBase { Q_OBJECT Q_DECLARE_PRIVATE(SetMetaDataJob) friend class SessionPrivate; public: explicit SetMetaDataJob( Session *session ); virtual ~SetMetaDataJob(); /** - * Add a metadata to the mailbox. Depending on the supported standard by the server (setServerCapability), - * the @param name can have a different meaning. - * @param name the entry name if serverCapability() returns Metadata (RFC5464 mode), the attribute value name - * if serverCapability() is Annotatemore (draft-daboo-imap-annotatemore-07 mode). - * @param value the value of the entry/attribute + * Adds a metadata entry or attribute to the list of modifications to make + * + * When in Metadata mode, this method adds a metadata + * entry to the list of metadata additions and updates that + * will be performed when the job is run. + * + * @p name must be a valid ASCII string and may not contain two + * consecutive forward slashes ('/'), must not end with '/' and + * must not contain '*', '%', non-ASCII characters or characters + * in the ASCII range 0x00 to 0x19 (in practise, all control + * characters should be avoided). The name is case-insensitive. + * + * The first part of the entry name should be "/private" or + * "/shared", indicating the scope of the entry. Note that + * private metadata may not be supported by all servers. + * + * Server metadata entry names include: + * - /shared/comment + * - /shared/admin - a URI for contacting the server administrator + * (eg: a mailto: or tel: URI) + * - /shared/vendor//something + * - /private/vendor//something + * + * Mailbox metadata entry names include: + * - /shared/comment + * - /private/comment + * - /shared/vendor//something + * - /private/vendor//something + * + * @p value can be any data, although if it is a multi-line string + * value, CRLF line-endings must be used. + * + * When in Annotatemore mode, this method adds an attribute + * entry to the list of additions and updates that will be + * performed on the metadata entry when the job is run. + * + * @p name must be a valid UTF-8 string, and may not contain the + * '%' or '*' characters, or NUL. Use of non-visible UTF-8 characters + * is strongly discouraged. + * + * Possible attribute name prefixes are: + * - value - the data value of the attribute + * - content-type - a MIME content type and subtype + * - content-language - a RFC 3282 language code + * - vendor. - a vendor-specific attribute + * + * Attribute names an attribute name prefix followed by ".priv" for + * private attributes or ".shared" for shared attributes. Note that + * the attributes "size.priv" and "size.shared" are read-only + * attributes set by the server, and so cannot be used with + * SetMetaDataJob. + * + * @param name the metadata entry name (Metadata mode) in ASCII or + * attribute name (Annotatemore mode) in UTF-8 + * @param value the value of the entry or attribute */ void addMetaData(const QByteArray &name, const QByteArray &value); + /** - * Set the entry name for the metada, if the job is operating in Annotatemore mode. In Metadata mode, this setting is - * ignored. - * @param entry the metadata entry name + * Sets the metadata entry name to operate on (in Annotatemore mode) + * + * In Annotatemore mode, this specifies the metadata entry name to + * operate on. For server metadata, this is one of: + * - /comment + * - /motd + * - /admin + * - /vendor//something + * + * For mailbox metadata, this is one of: + * - /comment + * - /sort + * - /thread + * - /check + * - /checkperiod + * - /vendor//something + * + * Entry names must be valid UTF-8 strings that do not contain the + * '%' or '*' characters, or NUL. Use of non-visible UTF-8 + * characters is strongly discouraged. + * + * In Metadata mode, this has no effect. Metadata entry names + * should instead be specified as the first argument to addMetaData(). + * + * @see setServerCapability() + * + * @param entry the metadata entry name in UTF-8 */ + // KDE5: this API is horrible for Annotatemore mode: use an overload of + // addMetaData() instead: + // void addMetaData(const QString &entry, const QByteArray &value, + // const QByteArray &encoding = QByteArray(), + // const QByteArray &language = QByteArray(), + // const QMap vendorAttributes = + // QMap()); void setEntry(const QByteArray &entry); + /** + * Possible error codes that may be returned by the server. + */ enum MetaDataError { - NoError = 0, - TooMany = 1, - TooBig = 2, - NoPrivate = 4 + NoError = 0, /**< Used to indicate that no errors have been received */ + TooMany = 1, /**< Cannot add a new metadata item, because the limit has already been reached */ + TooBig = 2, /**< A metadata value was too big (see maxAcceptedSize()) */ + NoPrivate = 4 /**< The server does not support private metadata entries */ }; // Q_DECLARE_WHATEVER_THAT_WAS missing Q_DECLARE_FLAGS(MetaDataErrors, MetaDataError) /** * The metadata errors received from the server. - * @return OR connected error codes, see MetaDataError + * + * @return a set of error codes */ MetaDataErrors metaDataErrors() const; /** * The maximum accepted metadata size. - * @return the accepted metadata size, -1 means the limit is unknown. + * + * If the server replied that one of the metadata values was too + * large (see metaDataErrors), this should indicate what the + * maximum size accepted by the server is. + * + * @return the maximum value size in octets, or -1 if the limit is unknown */ qint64 maxAcceptedSize(); protected: virtual void doStart(); virtual void handleResponse( const Message &response ); }; } Q_DECLARE_OPERATORS_FOR_FLAGS( KIMAP::SetMetaDataJob::MetaDataErrors ) #endif