summaryrefslogtreecommitdiffstats
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/maildirresource/libmaildir/maildir.cpp166
-rw-r--r--examples/maildirresource/libmaildir/maildir.h15
-rw-r--r--examples/maildirresource/maildirresource.cpp37
-rw-r--r--examples/maildirresource/maildirresource.h5
4 files changed, 123 insertions, 100 deletions
diff --git a/examples/maildirresource/libmaildir/maildir.cpp b/examples/maildirresource/libmaildir/maildir.cpp
index f8ca606..daf2e8f 100644
--- a/examples/maildirresource/libmaildir/maildir.cpp
+++ b/examples/maildirresource/libmaildir/maildir.cpp
@@ -142,7 +142,6 @@ public:
142 { 142 {
143 // KeyCache* keyCache = KeyCache::self(); 143 // KeyCache* keyCache = KeyCache::self();
144 // if (keyCache->isNewKey(path, key)) { 144 // if (keyCache->isNewKey(path, key)) {
145 qWarning() << path + QString::fromLatin1("/new/") + key;
146 if (QFile::exists(path + QString::fromLatin1("/new/") + key)) { 145 if (QFile::exists(path + QString::fromLatin1("/new/") + key)) {
147#ifdef DEBUG_KEYCACHE_CONSITENCY 146#ifdef DEBUG_KEYCACHE_CONSITENCY
148 if (!QFile::exists(path + QString::fromLatin1("/new/") + key)) { 147 if (!QFile::exists(path + QString::fromLatin1("/new/") + key)) {
@@ -688,88 +687,89 @@ bool Maildir::removeEntry(const QString& key)
688 // return QFile::remove(realKey); 687 // return QFile::remove(realKey);
689} 688}
690 689
691// QString Maildir::changeEntryFlags(const QString& key, const Sink::Item::Flags& flags) 690QString Maildir::changeEntryFlags(const QString& key, const Maildir::Flags& flags)
692// { 691{
693// QString realKey(d->findRealKey(key)); 692 QString realKey(d->findRealKey(key));
694// if (realKey.isEmpty()) { 693 if (realKey.isEmpty()) {
695// qWarning() << "Maildir::changeEntryFlags unable to find: " << key; 694 qWarning() << "Maildir::changeEntryFlags unable to find: " << key;
696// d->lastError = i18n("Cannot locate mail file %1." , key); 695 // d->lastError = i18n("Cannot locate mail file %1." , key);
697// return QString(); 696 return QString();
698// } 697 }
699// 698
700// const QRegExp rx = *(statusSeparatorRx()); 699 const QRegExp rx = *(statusSeparatorRx());
701// QString finalKey = key.left(key.indexOf(rx)); 700 QString finalKey = key.left(key.indexOf(rx));
702// 701
703// QStringList mailDirFlags; 702 QStringList mailDirFlags;
704// Q_FOREACH (const Sink::Item::Flag &flag, flags) { 703 if (flags & Forwarded)
705// if (flag == Sink::MessageFlags::Forwarded) 704 mailDirFlags << QLatin1String("P");
706// mailDirFlags << QLatin1String("P"); 705 if (flags & Replied)
707// if (flag == Sink::MessageFlags::Replied) 706 mailDirFlags << QLatin1String("R");
708// mailDirFlags << QLatin1String("R"); 707 if (flags & Seen)
709// if (flag == Sink::MessageFlags::Seen) 708 mailDirFlags << QLatin1String("S");
710// mailDirFlags << QLatin1String("S"); 709 if (flags & Deleted)
711// if (flag == Sink::MessageFlags::Deleted) 710 mailDirFlags << QLatin1String("T");
712// mailDirFlags << QLatin1String("T"); 711 if (flags & Flagged)
713// if (flag == Sink::MessageFlags::Flagged) 712 mailDirFlags << QLatin1String("F");
714// mailDirFlags << QLatin1String("F"); 713
715// } 714 mailDirFlags.sort();
716// mailDirFlags.sort(); 715 if (!mailDirFlags.isEmpty()) {
717// if (!mailDirFlags.isEmpty()) { 716#ifdef Q_OS_WIN
718// #ifdef Q_OS_WIN 717 finalKey.append(QLatin1String("!2,") + mailDirFlags.join(QString()));
719// finalKey.append(QLatin1String("!2,") + mailDirFlags.join(QString())); 718#else
720// #else 719 finalKey.append(QLatin1String(":2,") + mailDirFlags.join(QString()));
721// finalKey.append(QLatin1String(":2,") + mailDirFlags.join(QString())); 720#endif
722// #endif 721 }
723// } 722
724// 723 QString newUniqueKey = finalKey; //key without path
725// QString newUniqueKey = finalKey; //key without path 724 finalKey.prepend(d->path + QString::fromLatin1("/cur/"));
726// finalKey.prepend(d->path + QString::fromLatin1("/cur/")); 725
727// 726 if (realKey == finalKey) {
728// if (realKey == finalKey) { 727 // Somehow it already is named this way (e.g. migration bug -> wrong status in sink)
729// // Somehow it already is named this way (e.g. migration bug -> wrong status in sink) 728 qWarning() << "File already named that way: " << newUniqueKey << finalKey;
730// return newUniqueKey; 729 return newUniqueKey;
731// } 730 }
732// 731
733// QFile f(realKey); 732 QFile f(realKey);
734// if (QFile::exists(finalKey)) { 733 if (QFile::exists(finalKey)) {
735// QFile destFile(finalKey); 734 QFile destFile(finalKey);
736// QByteArray destContent; 735 QByteArray destContent;
737// if (destFile.open(QIODevice::ReadOnly)) { 736 if (destFile.open(QIODevice::ReadOnly)) {
738// destContent = destFile.readAll(); 737 destContent = destFile.readAll();
739// destFile.close(); 738 destFile.close();
740// } 739 }
741// QByteArray sourceContent; 740 QByteArray sourceContent;
742// if (f.open(QIODevice::ReadOnly)) { 741 if (f.open(QIODevice::ReadOnly)) {
743// sourceContent = f.readAll(); 742 sourceContent = f.readAll();
744// f.close(); 743 f.close();
745// } 744 }
746// 745
747// if (destContent != sourceContent) { 746 if (destContent != sourceContent) {
748// QString newFinalKey = QLatin1String("1-") + newUniqueKey; 747 QString newFinalKey = QLatin1String("1-") + newUniqueKey;
749// int i = 1; 748 int i = 1;
750// while (QFile::exists(d->path + QString::fromLatin1("/cur/") + newFinalKey)) { 749 while (QFile::exists(d->path + QString::fromLatin1("/cur/") + newFinalKey)) {
751// i++; 750 i++;
752// newFinalKey = QString::number(i) + QLatin1Char('-') + newUniqueKey; 751 newFinalKey = QString::number(i) + QLatin1Char('-') + newUniqueKey;
753// } 752 }
754// finalKey = d->path + QString::fromLatin1("/cur/") + newFinalKey; 753 finalKey = d->path + QString::fromLatin1("/cur/") + newFinalKey;
755// } else { 754 } else {
756// QFile::remove(finalKey); //they are the same 755 QFile::remove(finalKey); //they are the same
757// } 756 }
758// } 757 }
759// 758
760// if (!f.rename(finalKey)) { 759 if (!f.rename(finalKey)) {
761// qWarning() << "Maildir: Failed to rename entry: " << f.fileName() << " to " << finalKey << "! Error: " << f.errorString(); 760 qWarning() << "Maildir: Failed to rename entry: " << f.fileName() << " to " << finalKey << "! Error: " << f.errorString();
762// d->lastError = i18n("Failed to update the file name %1 to %2 on the disk. The error was: %3." , f.fileName(), finalKey, f.errorString()); 761 // d->lastError = i18n("Failed to update the file name %1 to %2 on the disk. The error was: %3." , f.fileName(), finalKey, f.errorString());
763// return QString(); 762 return QString();
764// } 763 }
765// 764 qWarning() << "Renamed file: " << f.fileName() << finalKey;
766// KeyCache *keyCache = KeyCache::self(); 765
767// keyCache->removeKey(d->path, key); 766 // KeyCache *keyCache = KeyCache::self();
768// keyCache->addCurKey(d->path, newUniqueKey); 767 // keyCache->removeKey(d->path, key);
769// 768 // keyCache->addCurKey(d->path, newUniqueKey);
770// return newUniqueKey; 769
771// } 770 return newUniqueKey;
772// 771}
772
773Maildir::Flags Maildir::readEntryFlags(const QString& key) 773Maildir::Flags Maildir::readEntryFlags(const QString& key)
774{ 774{
775 Flags flags; 775 Flags flags;
diff --git a/examples/maildirresource/libmaildir/maildir.h b/examples/maildirresource/libmaildir/maildir.h
index 42d53e6..5936515 100644
--- a/examples/maildirresource/libmaildir/maildir.h
+++ b/examples/maildirresource/libmaildir/maildir.h
@@ -167,13 +167,14 @@ public:
167 */ 167 */
168 QByteArray readEntry( const QString& key ) const; 168 QByteArray readEntry( const QString& key ) const;
169 169
170 enum MailFlags { 170 enum Flag {
171 Forwarded, 171 Forwarded = 0x1,
172 Replied, 172 Replied = 0x2,
173 Seen, 173 Seen = 0x4,
174 Flagged 174 Flagged = 0x8,
175 Deleted = 0x10
175 }; 176 };
176 Q_DECLARE_FLAGS(Flags, MailFlags); 177 Q_DECLARE_FLAGS(Flags, Flag);
177 178
178 /** 179 /**
179 * Return the flags encoded in the maildir file name for an entry 180 * Return the flags encoded in the maildir file name for an entry
@@ -211,7 +212,7 @@ public:
211 * Change the flags for an entry specified by @p key. Returns the new key of the entry (the key might change because 212 * Change the flags for an entry specified by @p key. Returns the new key of the entry (the key might change because
212 * flags are stored in the unique filename). 213 * flags are stored in the unique filename).
213 */ 214 */
214 // QString changeEntryFlags( const QString& key, const Sink::Item::Flags& flags ); 215 QString changeEntryFlags( const QString& key, const Flags& flags );
215 216
216 /** 217 /**
217 * Moves this maildir into @p destination. 218 * Moves this maildir into @p destination.
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp
index 3b263a7..cb51881 100644
--- a/examples/maildirresource/maildirresource.cpp
+++ b/examples/maildirresource/maildirresource.cpp
@@ -269,9 +269,9 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c
269 const auto parentFolderPath = parentFolderRemoteId; 269 const auto parentFolderPath = parentFolderRemoteId;
270 KPIM::Maildir maildir(parentFolderPath, false); 270 KPIM::Maildir maildir(parentFolderPath, false);
271 //FIXME assemble the MIME message 271 //FIXME assemble the MIME message
272 const auto id = maildir.addEntry("foobar"); 272 const auto remoteId = maildir.addEntry("foobar");
273 Trace() << "Creating a new mail: " << id; 273 Trace() << "Creating a new mail: " << remoteId;
274 recordRemoteId(ENTITY_TYPE_MAIL, mail.identifier(), id.toUtf8(), synchronizationTransaction); 274 recordRemoteId(ENTITY_TYPE_MAIL, mail.identifier(), remoteId.toUtf8(), synchronizationTransaction);
275 } else if (operation == Sink::Operation_Removal) { 275 } else if (operation == Sink::Operation_Removal) {
276 const auto uid = Sink::Storage::uidFromKey(key); 276 const auto uid = Sink::Storage::uidFromKey(key);
277 const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction); 277 const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction);
@@ -279,7 +279,26 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c
279 QFile::remove(remoteId); 279 QFile::remove(remoteId);
280 removeRemoteId(ENTITY_TYPE_MAIL, uid, remoteId, synchronizationTransaction); 280 removeRemoteId(ENTITY_TYPE_MAIL, uid, remoteId, synchronizationTransaction);
281 } else if (operation == Sink::Operation_Modification) { 281 } else if (operation == Sink::Operation_Modification) {
282 Warning() << "Mail modifications are not implemented"; 282 const auto uid = Sink::Storage::uidFromKey(key);
283 const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction);
284 Trace() << "Modifying a mail: " << remoteId;
285 auto parts = remoteId.split('/');
286 const auto filename = parts.takeLast(); //filename
287 parts.removeLast(); //cur/new folder
288 auto maildirPath = parts.join('/');
289
290 KPIM::Maildir maildir(maildirPath, false);
291
292 const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity));
293
294 //get flags from
295 KPIM::Maildir::Flags flags;
296 if (!mail.getProperty("unread").toBool()) {
297 flags |= KPIM::Maildir::Seen;
298 }
299
300 auto newRemoteId = maildir.changeEntryFlags(filename, flags);
301 updateRemoteId(ENTITY_TYPE_MAIL, uid, QString(maildirPath + "/cur/" + newRemoteId).toUtf8(), synchronizationTransaction);
283 } else { 302 } else {
284 Warning() << "Unkown operation" << operation; 303 Warning() << "Unkown operation" << operation;
285 } 304 }
@@ -303,11 +322,11 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray
303 if (property == "unread") { 322 if (property == "unread") {
304 const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, entityId, synchronizationTransaction); 323 const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, entityId, synchronizationTransaction);
305 const auto flags = KPIM::Maildir::readEntryFlags(remoteId.split('/').last()); 324 const auto flags = KPIM::Maildir::readEntryFlags(remoteId.split('/').last());
306 if (expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) { 325 if (expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) {
307 return KAsync::error<void>(1, "Expected seen but couldn't find it."); 326 return KAsync::error<void>(1, "Expected unread but couldn't find it.");
308 } 327 }
309 if (!expectedValue.toBool() && (flags & KPIM::Maildir::Seen)) { 328 if (!expectedValue.toBool() && !(flags & KPIM::Maildir::Seen)) {
310 return KAsync::error<void>(1, "Expected seen but couldn't find it."); 329 return KAsync::error<void>(1, "Expected read but couldn't find it.");
311 } 330 }
312 return KAsync::null<void>(); 331 return KAsync::null<void>();
313 } 332 }
@@ -319,7 +338,7 @@ KAsync::Job<void> MaildirResource::inspect(int inspectionType, const QByteArray
319 msg->parse(); 338 msg->parse();
320 339
321 if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) { 340 if (msg->subject(true)->asUnicodeString() != expectedValue.toString()) {
322 return KAsync::error<void>(1, "Subject not as expected."); 341 return KAsync::error<void>(1, "Subject not as expected: " + msg->subject(true)->asUnicodeString());
323 } 342 }
324 return KAsync::null<void>(); 343 return KAsync::null<void>();
325 } 344 }
diff --git a/examples/maildirresource/maildirresource.h b/examples/maildirresource/maildirresource.h
index 9af2f39..32eb88c 100644
--- a/examples/maildirresource/maildirresource.h
+++ b/examples/maildirresource/maildirresource.h
@@ -32,12 +32,15 @@ class MaildirMailAdaptorFactory;
32class MaildirFolderAdaptorFactory; 32class MaildirFolderAdaptorFactory;
33 33
34/** 34/**
35 * A maildir resource 35 * A maildir resource.
36 * 36 *
37 * Implementation details: 37 * Implementation details:
38 * The remoteid's have the following formats: 38 * The remoteid's have the following formats:
39 * files: full file path 39 * files: full file path
40 * directories: full directory path 40 * directories: full directory path
41 *
42 * The resource moves all messages from new to cur during sync and thus expectes all messages that are in the store to always reside in cur.
43 * The tmp directory is never directly used
41 */ 44 */
42class MaildirResource : public Sink::GenericResource 45class MaildirResource : public Sink::GenericResource
43{ 46{