diff options
Diffstat (limited to 'examples/maildirresource/maildirresource.cpp')
-rw-r--r-- | examples/maildirresource/maildirresource.cpp | 113 |
1 files changed, 70 insertions, 43 deletions
diff --git a/examples/maildirresource/maildirresource.cpp b/examples/maildirresource/maildirresource.cpp index 72610a1..3b0c427 100644 --- a/examples/maildirresource/maildirresource.cpp +++ b/examples/maildirresource/maildirresource.cpp | |||
@@ -65,12 +65,54 @@ public: | |||
65 | Sink::EntityBuffer buffer(value); | 65 | Sink::EntityBuffer buffer(value); |
66 | const Sink::Entity &entity = buffer.entity(); | 66 | const Sink::Entity &entity = buffer.entity(); |
67 | const auto adaptor = mFolderAdaptorFactory->createAdaptor(entity); | 67 | const auto adaptor = mFolderAdaptorFactory->createAdaptor(entity); |
68 | auto folderName = adaptor->getProperty("name").toString(); | 68 | auto parentFolder = adaptor->getProperty("parent").toString(); |
69 | //TODO handle non toplevel folders | 69 | if (mMaildirPath.endsWith(adaptor->getProperty("name").toString())) { |
70 | folderPath = mMaildirPath + "/" + folderName; | 70 | folderPath = mMaildirPath; |
71 | } else { | ||
72 | auto folderName = adaptor->getProperty("name").toString(); | ||
73 | //TODO handle non toplevel folders | ||
74 | folderPath = mMaildirPath + "/" + folderName; | ||
75 | } | ||
71 | }); | 76 | }); |
72 | return folderPath; | 77 | return folderPath; |
73 | } | 78 | } |
79 | |||
80 | QString moveMessage(const QString &oldPath, const QByteArray &folder, Sink::Storage::Transaction &transaction) | ||
81 | { | ||
82 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { | ||
83 | const auto path = getPath(folder, transaction); | ||
84 | KPIM::Maildir maildir(path, false); | ||
85 | if (!maildir.isValid(true)) { | ||
86 | qWarning() << "Maildir is not existing: " << path; | ||
87 | } | ||
88 | auto identifier = maildir.addEntryFromPath(oldPath); | ||
89 | return path + "/" + identifier; | ||
90 | } | ||
91 | return oldPath; | ||
92 | } | ||
93 | void updatedIndexedProperties(Sink::ApplicationDomain::BufferAdaptor &newEntity) | ||
94 | { | ||
95 | const auto mimeMessagePath = newEntity.getProperty("mimeMessage").toString(); | ||
96 | auto parts = mimeMessagePath.split('/'); | ||
97 | const auto key = parts.takeLast(); | ||
98 | const auto path = parts.join("/") + "/cur/"; | ||
99 | |||
100 | QDir dir(path); | ||
101 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); | ||
102 | if (list.size() != 1) { | ||
103 | Warning() << "Failed to find message " << path << key << list.size(); | ||
104 | return; | ||
105 | } | ||
106 | |||
107 | KMime::Message *msg = new KMime::Message; | ||
108 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(list.first().filePath()))); | ||
109 | msg->parse(); | ||
110 | |||
111 | newEntity.setProperty("subject", msg->subject(true)->asUnicodeString()); | ||
112 | newEntity.setProperty("sender", msg->from(true)->asUnicodeString()); | ||
113 | newEntity.setProperty("senderName", msg->from(true)->asUnicodeString()); | ||
114 | newEntity.setProperty("date", msg->date(true)->dateTime()); | ||
115 | } | ||
74 | 116 | ||
75 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 117 | void newEntity(const QByteArray &uid, qint64 revision, Sink::ApplicationDomain::BufferAdaptor &newEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE |
76 | { | 118 | { |
@@ -79,46 +121,20 @@ public: | |||
79 | } | 121 | } |
80 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); | 122 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); |
81 | if (mimeMessage.isValid()) { | 123 | if (mimeMessage.isValid()) { |
82 | const auto oldPath = mimeMessage.toString(); | 124 | newEntity.setProperty("mimeMessage", moveMessage(mimeMessage.toString(), newEntity.getProperty("folder").toByteArray(), transaction)); |
83 | if (oldPath.startsWith(Sink::temporaryFileLocation())) { | ||
84 | auto folder = newEntity.getProperty("folder").toByteArray(); | ||
85 | const auto path = getPath(folder, transaction); | ||
86 | KPIM::Maildir maildir(path, false); | ||
87 | if (!maildir.isValid(true)) { | ||
88 | qWarning() << "Maildir is not existing: " << path; | ||
89 | } | ||
90 | auto identifier = maildir.addEntryFromPath(oldPath); | ||
91 | newEntity.setProperty("mimeMessage", path + "/" + identifier); | ||
92 | } | ||
93 | } | ||
94 | |||
95 | { | ||
96 | const auto mimeMessagePath = newEntity.getProperty("mimeMessage").toString(); | ||
97 | auto parts = mimeMessagePath.split('/'); | ||
98 | const auto key = parts.takeLast(); | ||
99 | const auto path = parts.join("/") + "/cur/"; | ||
100 | |||
101 | QDir dir(path); | ||
102 | const QFileInfoList list = dir.entryInfoList(QStringList() << (key+"*"), QDir::Files); | ||
103 | if (list.size() != 1) { | ||
104 | Warning() << "Failed to find message " << path << key << list.size(); | ||
105 | return; | ||
106 | } | ||
107 | |||
108 | KMime::Message *msg = new KMime::Message; | ||
109 | msg->setHead(KMime::CRLFtoLF(KPIM::Maildir::readEntryHeadersFromFile(list.first().filePath()))); | ||
110 | msg->parse(); | ||
111 | |||
112 | newEntity.setProperty("subject", msg->subject(true)->asUnicodeString()); | ||
113 | newEntity.setProperty("sender", msg->from(true)->asUnicodeString()); | ||
114 | newEntity.setProperty("senderName", msg->from(true)->asUnicodeString()); | ||
115 | newEntity.setProperty("date", msg->date(true)->dateTime()); | ||
116 | } | 125 | } |
126 | updatedIndexedProperties(newEntity); | ||
117 | } | 127 | } |
118 | 128 | ||
119 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, | 129 | void modifiedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::ApplicationDomain::BufferAdaptor &newEntity, |
120 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 130 | Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE |
121 | { | 131 | { |
132 | //TODO deal with moves | ||
133 | const auto mimeMessage = newEntity.getProperty("mimeMessage"); | ||
134 | if (mimeMessage.isValid()) { | ||
135 | newEntity.setProperty("mimeMessage", moveMessage(mimeMessage.toString(), newEntity.getProperty("folder").toByteArray(), transaction)); | ||
136 | } | ||
137 | updatedIndexedProperties(newEntity); | ||
122 | } | 138 | } |
123 | 139 | ||
124 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE | 140 | void deletedEntity(const QByteArray &uid, qint64 revision, const Sink::ApplicationDomain::BufferAdaptor &oldEntity, Sink::Storage::Transaction &transaction) Q_DECL_OVERRIDE |
@@ -419,22 +435,33 @@ KAsync::Job<void> MaildirResource::replay(Sink::Storage &synchronizationStore, c | |||
419 | const auto uid = Sink::Storage::uidFromKey(key); | 435 | const auto uid = Sink::Storage::uidFromKey(key); |
420 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction); | 436 | const auto remoteId = resolveLocalId(ENTITY_TYPE_MAIL, uid, synchronizationTransaction); |
421 | Trace() << "Modifying a mail: " << remoteId; | 437 | Trace() << "Modifying a mail: " << remoteId; |
422 | auto parts = remoteId.split('/'); | ||
423 | const auto filename = parts.takeLast(); //filename | ||
424 | parts.removeLast(); //cur/new folder | ||
425 | auto maildirPath = parts.join('/'); | ||
426 | 438 | ||
439 | const auto maildirPath = KPIM::Maildir::getDirectoryFromFile(remoteId); | ||
427 | KPIM::Maildir maildir(maildirPath, false); | 440 | KPIM::Maildir maildir(maildirPath, false); |
428 | 441 | ||
429 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); | 442 | const Sink::ApplicationDomain::Mail mail(mResourceInstanceIdentifier, Sink::Storage::uidFromKey(key), revision, mMailAdaptorFactory->createAdaptor(entity)); |
443 | auto newIdentifier = mail.getMimeMessagePath().split("/").last(); | ||
444 | QString identifier; | ||
445 | if (newIdentifier != KPIM::Maildir::getKeyFromFile(remoteId)) { | ||
446 | //Remove the old mime message if it changed | ||
447 | Trace() << "Removing old mime message: " << remoteId; | ||
448 | QFile(remoteId).remove(); | ||
449 | identifier = newIdentifier; | ||
450 | } else { | ||
451 | //The identifier needs to contain the flags for changeEntryFlags to work | ||
452 | identifier = remoteId.split('/').last(); | ||
453 | } | ||
430 | 454 | ||
431 | //get flags from | 455 | //get flags from |
432 | KPIM::Maildir::Flags flags; | 456 | KPIM::Maildir::Flags flags; |
433 | if (!mail.getProperty("unread").toBool()) { | 457 | if (!mail.getUnread()) { |
434 | flags |= KPIM::Maildir::Seen; | 458 | flags |= KPIM::Maildir::Seen; |
435 | } | 459 | } |
460 | if (mail.getImportant()) { | ||
461 | flags |= KPIM::Maildir::Flagged; | ||
462 | } | ||
436 | 463 | ||
437 | auto newRemoteId = maildir.changeEntryFlags(filename, flags); | 464 | const auto newRemoteId = maildir.changeEntryFlags(identifier, flags); |
438 | updateRemoteId(ENTITY_TYPE_MAIL, uid, QString(maildirPath + "/cur/" + newRemoteId).toUtf8(), synchronizationTransaction); | 465 | updateRemoteId(ENTITY_TYPE_MAIL, uid, QString(maildirPath + "/cur/" + newRemoteId).toUtf8(), synchronizationTransaction); |
439 | } else { | 466 | } else { |
440 | Warning() << "Unkown operation" << operation; | 467 | Warning() << "Unkown operation" << operation; |