1 | /* |
2 | Copyright (c) 2009 Andras Mantia <amantia@kde.org> |
3 | |
4 | This library is free software; you can redistribute it and/or modify it |
5 | under the terms of the GNU Library General Public License as published by |
6 | the Free Software Foundation; either version 2 of the License, or (at your |
7 | option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, but WITHOUT |
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
12 | License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to the |
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
17 | 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "setmetadatajob.h" |
21 | |
22 | #include <KDE/KLocalizedString> |
23 | #include <KDE/KDebug> |
24 | |
25 | #include "metadatajobbase_p.h" |
26 | #include "message_p.h" |
27 | #include "session_p.h" |
28 | #include "rfccodecs.h" |
29 | |
30 | namespace KIMAP |
31 | { |
32 | class SetMetaDataJobPrivate : public MetaDataJobBasePrivate |
33 | { |
34 | public: |
35 | SetMetaDataJobPrivate( Session *session, const QString& name ) : MetaDataJobBasePrivate( session, name ), metaDataErrors( 0 ), maxAcceptedSize( -1 ) { } |
36 | ~SetMetaDataJobPrivate() { } |
37 | |
38 | QMap<QByteArray, QByteArray> entries; |
39 | QMap<QByteArray, QByteArray>::ConstIterator entriesIt; |
40 | QByteArray entryName; |
41 | SetMetaDataJob::MetaDataErrors metaDataErrors; |
42 | qint64 maxAcceptedSize; |
43 | }; |
44 | } |
45 | |
46 | using namespace KIMAP; |
47 | |
48 | SetMetaDataJob::SetMetaDataJob( Session *session ) |
49 | : MetaDataJobBase( *new SetMetaDataJobPrivate( session, i18n( "SetMetaData" ) ) ) |
50 | { |
51 | } |
52 | |
53 | SetMetaDataJob::~SetMetaDataJob() |
54 | { |
55 | } |
56 | |
57 | void SetMetaDataJob::doStart() |
58 | { |
59 | Q_D( SetMetaDataJob ); |
60 | QByteArray parameters; |
61 | parameters = '\"' + KIMAP::encodeImapFolderName( d->mailBox.toUtf8() ) + "\" " ; |
62 | d->entriesIt = d->entries.constBegin(); |
63 | |
64 | QByteArray command = "SETMETADATA" ; |
65 | if ( d->serverCapability == Annotatemore ) { |
66 | command = "SETANNOTATION" ; |
67 | parameters += '\"' + d->entryName + "\" (" ; |
68 | d->m_name = i18n( "SetAnnotation" ); |
69 | if ( !d->entries.isEmpty() ) { |
70 | for ( ; d->entriesIt != d->entries.constEnd(); ++d->entriesIt ) { |
71 | parameters += '\"' + d->entriesIt.key() + "\" \"" + d->entriesIt.value() + "\" " ; |
72 | } |
73 | parameters[parameters.length() - 1] = ')'; |
74 | } |
75 | } else { |
76 | parameters += '('; |
77 | if ( !d->entries.isEmpty() ) { |
78 | parameters += '\"' + d->entriesIt.key() + '\"'; |
79 | parameters += ' '; |
80 | parameters += " {" + QByteArray::number( d->entriesIt.value().size() ) + '}'; |
81 | } |
82 | } |
83 | |
84 | if ( d->entries.isEmpty() ) { |
85 | parameters += ')'; |
86 | } |
87 | |
88 | d->tags << d->sessionInternal()->sendCommand( command, parameters ); |
89 | // kDebug() << "SENT: " << command << " " << parameters; |
90 | } |
91 | |
92 | void SetMetaDataJob::handleResponse( const Message &response ) |
93 | { |
94 | Q_D( SetMetaDataJob ); |
95 | |
96 | //TODO: Test if a server can really return more then one untagged NO response. If not, no need to OR the error codes |
97 | if ( !response.content.isEmpty() && |
98 | d->tags.contains( response.content.first().toString() ) ) { |
99 | if ( response.content[1].toString() == "NO" ) { |
100 | setError( UserDefinedError ); |
101 | setErrorText( i18n( "%1 failed, server replied: %2" , d->m_name, QLatin1String(response.toString().constData()) ) ); |
102 | if ( response.content[2].toString() == "[ANNOTATEMORE TOOMANY]" || |
103 | response.content[2].toString() == "[METADATA TOOMANY]" ) { |
104 | d->metaDataErrors |= TooMany; |
105 | } else if ( response.content[2].toString() == "[ANNOTATEMORE TOOBIG]" || |
106 | response.content[2].toString().startsWith( "[METADATA MAXSIZE" ) ) { //krazy:exclude=strings |
107 | d->metaDataErrors |= TooBig; |
108 | d->maxAcceptedSize = -1; |
109 | if ( response.content[2].toString().startsWith( "[METADATA MAXSIZE" ) ) { //krazy:exclude=strings |
110 | QByteArray max = response.content[2].toString(); |
111 | max.replace( "[METADATA MAXSIZE" , "" ); //krazy:exclude=doublequote_chars |
112 | max.replace( "]" , "" ); //krazy:exclude=doublequote_chars |
113 | d->maxAcceptedSize = max.toLongLong(); |
114 | } |
115 | } else if ( response.content[2].toString() == "[METADATA NOPRIVATE]" ) { |
116 | d->metaDataErrors |= NoPrivate; |
117 | } |
118 | } else if ( response.content.size() < 2 ) { |
119 | setErrorText( i18n( "%1 failed, malformed reply from the server." , d->m_name ) ); |
120 | } else if ( response.content[1].toString() != "OK" ) { |
121 | setError( UserDefinedError ); |
122 | setErrorText( i18n( "%1 failed, server replied: %2" , d->m_name, QLatin1String(response.toString().constData()) ) ); |
123 | } |
124 | emitResult(); |
125 | } else if ( d->serverCapability == Metadata && response.content[0].toString() == "+" ) { |
126 | QByteArray content = d->entriesIt.value(); |
127 | ++d->entriesIt; |
128 | if ( d->entriesIt == d->entries.constEnd() ) { |
129 | content += ')'; |
130 | } else { |
131 | content += " {" + QByteArray::number( d->entriesIt.value().size() ) + '}'; |
132 | } |
133 | // kDebug() << "SENT: " << content; |
134 | d->sessionInternal()->sendData( content ); |
135 | } |
136 | } |
137 | |
138 | void SetMetaDataJob::addMetaData(const QByteArray &name, const QByteArray &value) |
139 | { |
140 | Q_D( SetMetaDataJob ); |
141 | if ( d->serverCapability == Annotatemore && ( name.startsWith( "/shared" ) || name.startsWith( "/private" ) ) ) { |
142 | const QByteArray &attribute = d->getAttribute( name ); |
143 | d->entries[attribute] = value; |
144 | d->entryName = d->removePrefix( name ); |
145 | } else { |
146 | d->entries[name] = value; |
147 | } |
148 | } |
149 | |
150 | void SetMetaDataJob::setEntry(const QByteArray &entry) |
151 | { |
152 | Q_D( SetMetaDataJob ); |
153 | d->entryName = entry; |
154 | } |
155 | |
156 | SetMetaDataJob::MetaDataErrors SetMetaDataJob::metaDataErrors() const |
157 | { |
158 | Q_D( const SetMetaDataJob ); |
159 | return d->metaDataErrors; |
160 | } |
161 | |