IMAP: downloading mails is now working.
* Changed the way the attributes are written to make sure that everything that can be written once is in fact written just once. * The rename code in BMailProtocol::_ProcessFetchedHeader() was broken, and caused the hang of the last commit.
This commit is contained in:
@@ -21,8 +21,10 @@ public:
|
|||||||
virtual ~BMailFilter();
|
virtual ~BMailFilter();
|
||||||
|
|
||||||
// Message hooks if filter is installed to an inbound protocol
|
// Message hooks if filter is installed to an inbound protocol
|
||||||
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file);
|
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file,
|
||||||
virtual void BodyFetched(const entry_ref& ref, BFile& file);
|
BMessage& attributes);
|
||||||
|
virtual void BodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes);
|
||||||
virtual void MailboxSynchronized(status_t status);
|
virtual void MailboxSynchronized(status_t status);
|
||||||
|
|
||||||
// Message hooks if filter is installed to an outbound protocol
|
// Message hooks if filter is installed to an outbound protocol
|
||||||
|
|||||||
@@ -95,9 +95,11 @@ protected:
|
|||||||
|
|
||||||
// Filter notifications
|
// Filter notifications
|
||||||
BMailFilterAction ProcessHeaderFetched(entry_ref& ref,
|
BMailFilterAction ProcessHeaderFetched(entry_ref& ref,
|
||||||
BFile& mail);
|
BFile& mail, BMessage& attributes);
|
||||||
void NotifyBodyFetched(const entry_ref& ref,
|
void NotifyBodyFetched(const entry_ref& ref,
|
||||||
BFile& mail);
|
BFile& mail, BMessage& attributes);
|
||||||
|
BMailFilterAction ProcessMessageFetched(entry_ref& ref,
|
||||||
|
BFile& mail, BMessage& attributes);
|
||||||
void NotifyMessageReadyToSend(const entry_ref& ref,
|
void NotifyMessageReadyToSend(const entry_ref& ref,
|
||||||
BFile& mail);
|
BFile& mail);
|
||||||
void NotifyMessageSent(const entry_ref& ref,
|
void NotifyMessageSent(const entry_ref& ref,
|
||||||
@@ -108,6 +110,10 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
BMailFilter* _LoadFilter(const BMailAddOnSettings& settings);
|
BMailFilter* _LoadFilter(const BMailAddOnSettings& settings);
|
||||||
|
BMailFilterAction _ProcessHeaderFetched(entry_ref& ref,
|
||||||
|
BFile& mail, BMessage& attributes);
|
||||||
|
void _NotifyBodyFetched(const entry_ref& ref,
|
||||||
|
BFile& mail, BMessage& attributes);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const BMailAccountSettings fAccountSettings;
|
const BMailAccountSettings fAccountSettings;
|
||||||
|
|||||||
@@ -489,7 +489,8 @@ public:
|
|||||||
status_t SetRect(const char* name, const BRect& value);
|
status_t SetRect(const char* name, const BRect& value);
|
||||||
status_t SetSize(const char* name, const BSize& value);
|
status_t SetSize(const char* name, const BSize& value);
|
||||||
status_t SetData(const char* name, type_code type,
|
status_t SetData(const char* name, type_code type,
|
||||||
const void* data, ssize_t numBytes);
|
const void* data, ssize_t numBytes,
|
||||||
|
bool fixedSize = true, int count = 1);
|
||||||
|
|
||||||
class Private;
|
class Private;
|
||||||
struct message_header;
|
struct message_header;
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ RuleFilter::RuleFilter(BMailProtocol& protocol,
|
|||||||
|
|
||||||
|
|
||||||
BMailFilterAction
|
BMailFilterAction
|
||||||
RuleFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
RuleFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
|
||||||
{
|
{
|
||||||
// That field doesn't exist? NO match
|
// That field doesn't exist? NO match
|
||||||
if (fAttribute == "")
|
if (fAttribute == "")
|
||||||
@@ -68,16 +68,8 @@ RuleFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
|||||||
|| info.type != B_STRING_TYPE)
|
|| info.type != B_STRING_TYPE)
|
||||||
return B_NO_MAIL_ACTION;
|
return B_NO_MAIL_ACTION;
|
||||||
|
|
||||||
char* buffer = new char[info.size];
|
BString data = attributes.GetString(fAttribute.String(), NULL);
|
||||||
if (file.ReadAttr(fAttribute, B_STRING_TYPE, 0, buffer, info.size) < 0) {
|
if (data.IsEmpty() || !fMatcher.Match(data)) {
|
||||||
delete[] buffer;
|
|
||||||
return B_NO_MAIL_ACTION;
|
|
||||||
}
|
|
||||||
|
|
||||||
BString data = buffer;
|
|
||||||
delete[] buffer;
|
|
||||||
|
|
||||||
if (!fMatcher.Match(data)) {
|
|
||||||
// We're not supposed to do anything
|
// We're not supposed to do anything
|
||||||
return B_NO_MAIL_ACTION;
|
return B_NO_MAIL_ACTION;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,8 @@ public:
|
|||||||
RuleFilter(BMailProtocol& protocol,
|
RuleFilter(BMailProtocol& protocol,
|
||||||
const BMailAddOnSettings& settings);
|
const BMailAddOnSettings& settings);
|
||||||
|
|
||||||
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file);
|
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BString fAttribute;
|
BString fAttribute;
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ SpamFilter::~SpamFilter()
|
|||||||
|
|
||||||
|
|
||||||
BMailFilterAction
|
BMailFilterAction
|
||||||
SpamFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
SpamFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
|
||||||
{
|
{
|
||||||
_CheckForSpam(file);
|
_CheckForSpam(file);
|
||||||
return B_NO_MAIL_ACTION;
|
return B_NO_MAIL_ACTION;
|
||||||
@@ -75,7 +75,7 @@ SpamFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
SpamFilter::BodyFetched(const entry_ref& ref, BFile& file)
|
SpamFilter::BodyFetched(const entry_ref& ref, BFile& file, BMessage& attributes)
|
||||||
{
|
{
|
||||||
if (fHeaderOnly)
|
if (fHeaderOnly)
|
||||||
return;
|
return;
|
||||||
@@ -85,7 +85,7 @@ SpamFilter::BodyFetched(const entry_ref& ref, BFile& file)
|
|||||||
// untrain the partial part before training on the complete message, but we
|
// untrain the partial part before training on the complete message, but we
|
||||||
// don't know how big it was, so instead just ignore the message.
|
// don't know how big it was, so instead just ignore the message.
|
||||||
attr_info attributeInfo;
|
attr_info attributeInfo;
|
||||||
if (file.GetAttrInfo ("MAIL:classification", &attributeInfo) == B_OK)
|
if (file.GetAttrInfo("MAIL:classification", &attributeInfo) == B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_CheckForSpam(file);
|
_CheckForSpam(file);
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ public:
|
|||||||
const BMailAddOnSettings& settings);
|
const BMailAddOnSettings& settings);
|
||||||
virtual ~SpamFilter();
|
virtual ~SpamFilter();
|
||||||
|
|
||||||
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file);
|
virtual BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file,
|
||||||
virtual void BodyFetched(const entry_ref& ref, BFile& file);
|
BMessage& attributes);
|
||||||
|
virtual void BodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _CheckForSpam(BFile& file);
|
status_t _CheckForSpam(BFile& file);
|
||||||
|
|||||||
@@ -231,7 +231,14 @@ IMAPFolder::MessageStored(entry_ref& ref, BFile& file, uint32 fetchFlags,
|
|||||||
if ((fetchFlags & IMAP::kFetchFlags) != 0)
|
if ((fetchFlags & IMAP::kFetchFlags) != 0)
|
||||||
_WriteFlags(file, flags);
|
_WriteFlags(file, flags);
|
||||||
|
|
||||||
fProtocol.MessageStored(*this, ref, file, fetchFlags);
|
// TODO: add some utility function for this in libmail.so
|
||||||
|
BMessage attributes;
|
||||||
|
if ((flags & IMAP::kAnswered) != 0)
|
||||||
|
attributes.AddString(B_MAIL_ATTR_STATUS, "Answered");
|
||||||
|
else if ((flags & IMAP::kSeen) != 0)
|
||||||
|
attributes.AddString(B_MAIL_ATTR_STATUS, "Read");
|
||||||
|
|
||||||
|
fProtocol.MessageStored(*this, ref, file, fetchFlags, attributes);
|
||||||
file.Unset();
|
file.Unset();
|
||||||
|
|
||||||
fRefMap.insert(std::make_pair(uid, ref));
|
fRefMap.insert(std::make_pair(uid, ref));
|
||||||
@@ -282,7 +289,8 @@ IMAPFolder::StoreBody(uint32 uid, BDataIO& stream, size_t& length,
|
|||||||
void
|
void
|
||||||
IMAPFolder::BodyStored(entry_ref& ref, BFile& file, uint32 uid)
|
IMAPFolder::BodyStored(entry_ref& ref, BFile& file, uint32 uid)
|
||||||
{
|
{
|
||||||
fProtocol.MessageStored(*this, ref, file, IMAP::kFetchBody);
|
BMessage attributes;
|
||||||
|
fProtocol.MessageStored(*this, ref, file, IMAP::kFetchBody, attributes);
|
||||||
file.Unset();
|
file.Unset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -124,15 +124,16 @@ IMAPProtocol::WorkerQuit(IMAPConnectionWorker* worker)
|
|||||||
|
|
||||||
void
|
void
|
||||||
IMAPProtocol::MessageStored(IMAPFolder& folder, entry_ref& ref, BFile& stream,
|
IMAPProtocol::MessageStored(IMAPFolder& folder, entry_ref& ref, BFile& stream,
|
||||||
uint32 fetchFlags)
|
uint32 fetchFlags, BMessage& attributes)
|
||||||
{
|
{
|
||||||
if ((fetchFlags & IMAP::kFetchHeader) != 0) {
|
if ((fetchFlags & (IMAP::kFetchHeader | IMAP::kFetchBody))
|
||||||
BMailFilterAction action = ProcessHeaderFetched(ref, stream);
|
== IMAP::kFetchHeader | IMAP::kFetchBody) {
|
||||||
if (action < B_OK || action == B_DELETE_MAIL_ACTION)
|
ProcessMessageFetched(ref, stream, attributes);
|
||||||
return;
|
} else if ((fetchFlags & IMAP::kFetchHeader) != 0) {
|
||||||
|
ProcessHeaderFetched(ref, stream, attributes);
|
||||||
|
} else if ((fetchFlags & IMAP::kFetchBody) != 0) {
|
||||||
|
NotifyBodyFetched(ref, stream, attributes);
|
||||||
}
|
}
|
||||||
if ((fetchFlags & IMAP::kFetchBody) != 0)
|
|
||||||
NotifyBodyFetched(ref, stream);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ public:
|
|||||||
|
|
||||||
void MessageStored(IMAPFolder& folder,
|
void MessageStored(IMAPFolder& folder,
|
||||||
entry_ref& ref, BFile& stream,
|
entry_ref& ref, BFile& stream,
|
||||||
uint32 fetchFlags);
|
uint32 fetchFlags, BMessage& attributes);
|
||||||
|
|
||||||
virtual status_t SyncMessages();
|
virtual status_t SyncMessages();
|
||||||
virtual status_t FetchBody(const entry_ref& ref);
|
virtual status_t FetchBody(const entry_ref& ref);
|
||||||
|
|||||||
@@ -203,14 +203,11 @@ POP3Protocol::SyncMessages()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BMailMessageIO mailIO(this, &file, toRetrieve);
|
BMailMessageIO mailIO(this, &file, toRetrieve);
|
||||||
|
BMessage attributes;
|
||||||
|
|
||||||
entry_ref ref;
|
entry_ref ref;
|
||||||
entry.GetRef(&ref);
|
entry.GetRef(&ref);
|
||||||
|
|
||||||
// the ref becomes invalid after renaming the file thus we already
|
|
||||||
// write the status here
|
|
||||||
MarkMessageAsRead(ref, B_UNREAD);
|
|
||||||
|
|
||||||
int32 size = MessageSize(toRetrieve);
|
int32 size = MessageSize(toRetrieve);
|
||||||
if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) {
|
if (fFetchBodyLimit < 0 || size <= fFetchBodyLimit) {
|
||||||
error = mailIO.Seek(0, SEEK_END);
|
error = mailIO.Seek(0, SEEK_END);
|
||||||
@@ -218,8 +215,7 @@ POP3Protocol::SyncMessages()
|
|||||||
printf("POP3: Failed to download body %s\n ", uid);
|
printf("POP3: Failed to download body %s\n ", uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ProcessHeaderFetched(ref, file);
|
ProcessMessageFetched(ref, file, attributes);
|
||||||
NotifyBodyFetched(ref, file);
|
|
||||||
|
|
||||||
if (!leaveOnServer)
|
if (!leaveOnServer)
|
||||||
Delete(toRetrieve);
|
Delete(toRetrieve);
|
||||||
@@ -230,7 +226,7 @@ POP3Protocol::SyncMessages()
|
|||||||
printf("POP3: Failed to download header %s\n ", uid);
|
printf("POP3: Failed to download header %s\n ", uid);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
ProcessHeaderFetched(ref, file);
|
ProcessHeaderFetched(ref, file, attributes);
|
||||||
}
|
}
|
||||||
ReportProgress(1, 0);
|
ReportProgress(1, 0);
|
||||||
|
|
||||||
@@ -302,7 +298,8 @@ POP3Protocol::FetchBody(const entry_ref& ref)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
NotifyBodyFetched(ref, file);
|
BMessage attributes;
|
||||||
|
NotifyBodyFetched(ref, file, attributes);
|
||||||
|
|
||||||
if (!leaveOnServer)
|
if (!leaveOnServer)
|
||||||
Delete(toRetrieve);
|
Delete(toRetrieve);
|
||||||
|
|||||||
@@ -3194,20 +3194,21 @@ BMessage::GetString(const char* name, int32 index,
|
|||||||
status_t
|
status_t
|
||||||
BMessage::SetString(const char* name, const BString& value)
|
BMessage::SetString(const char* name, const BString& value)
|
||||||
{
|
{
|
||||||
return SetData(name, B_STRING_TYPE, value.String(), value.Length() + 1);
|
return SetData(name, B_STRING_TYPE, value.String(), value.Length() + 1,
|
||||||
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMessage::SetString(const char* name, const char* value)
|
BMessage::SetString(const char* name, const char* value)
|
||||||
{
|
{
|
||||||
return SetData(name, B_STRING_TYPE, value, strlen(value) + 1);
|
return SetData(name, B_STRING_TYPE, value, strlen(value) + 1, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BMessage::SetData(const char* name, type_code type, const void* data,
|
BMessage::SetData(const char* name, type_code type, const void* data,
|
||||||
ssize_t numBytes)
|
ssize_t numBytes, bool fixedSize, int count)
|
||||||
{
|
{
|
||||||
if (numBytes <= 0 || data == NULL)
|
if (numBytes <= 0 || data == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@@ -3215,5 +3216,5 @@ BMessage::SetData(const char* name, type_code type, const void* data,
|
|||||||
if (ReplaceData(name, type, data, numBytes) == B_OK)
|
if (ReplaceData(name, type, data, numBytes) == B_OK)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
return AddData(name, type, data, numBytes);
|
return AddData(name, type, data, numBytes, fixedSize, count);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,6 @@
|
|||||||
#include <NodeInfo.h>
|
#include <NodeInfo.h>
|
||||||
|
|
||||||
#include <mail_util.h>
|
#include <mail_util.h>
|
||||||
#include <NodeMessage.h>
|
|
||||||
|
|
||||||
|
|
||||||
struct mail_header_field {
|
struct mail_header_field {
|
||||||
@@ -98,11 +97,11 @@ HaikuMailFormatFilter::DescriptiveName() const
|
|||||||
|
|
||||||
|
|
||||||
BMailFilterAction
|
BMailFilterAction
|
||||||
HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
{
|
{
|
||||||
file.Seek(0, SEEK_SET);
|
file.Seek(0, SEEK_SET);
|
||||||
|
|
||||||
BMessage attributes;
|
|
||||||
// TODO: attributes.AddInt32(B_MAIL_ATTR_CONTENT, length);
|
// TODO: attributes.AddInt32(B_MAIL_ATTR_CONTENT, length);
|
||||||
attributes.AddInt32(B_MAIL_ATTR_ACCOUNT_ID, fAccountID);
|
attributes.AddInt32(B_MAIL_ATTR_ACCOUNT_ID, fAccountID);
|
||||||
attributes.AddString(B_MAIL_ATTR_ACCOUNT, fAccountName);
|
attributes.AddString(B_MAIL_ATTR_ACCOUNT, fAccountName);
|
||||||
@@ -196,11 +195,10 @@ HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
|||||||
_RemoveLeadingDots(name);
|
_RemoveLeadingDots(name);
|
||||||
// Avoid files starting with a dot.
|
// Avoid files starting with a dot.
|
||||||
|
|
||||||
file << attributes;
|
if (!attributes.HasString(B_MAIL_ATTR_STATUS))
|
||||||
|
attributes.AddString(B_MAIL_ATTR_STATUS, "New");
|
||||||
|
|
||||||
// TODO: find a way to not set that twice for each complete mail
|
_SetType(attributes, B_PARTIAL_MAIL_TYPE);
|
||||||
BNodeInfo info(&file);
|
|
||||||
info.SetType(B_PARTIAL_MAIL_TYPE);
|
|
||||||
|
|
||||||
ref.set_name(name.String());
|
ref.set_name(name.String());
|
||||||
|
|
||||||
@@ -209,10 +207,10 @@ HaikuMailFormatFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
HaikuMailFormatFilter::BodyFetched(const entry_ref& ref, BFile& file)
|
HaikuMailFormatFilter::BodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
{
|
{
|
||||||
BNodeInfo info(&file);
|
_SetType(attributes, B_MAIL_TYPE);
|
||||||
info.SetType(B_MAIL_TYPE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -307,3 +305,11 @@ HaikuMailFormatFilter::_ExtractName(const BString& from)
|
|||||||
name.Trim();
|
name.Trim();
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
HaikuMailFormatFilter::_SetType(BMessage& attributes, const char* mimeType)
|
||||||
|
{
|
||||||
|
return attributes.SetData("BEOS:TYPE", B_MIME_STRING_TYPE, mimeType,
|
||||||
|
strlen(mimeType) + 1, false);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ public:
|
|||||||
|
|
||||||
virtual BString DescriptiveName() const;
|
virtual BString DescriptiveName() const;
|
||||||
|
|
||||||
BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file);
|
BMailFilterAction HeaderFetched(entry_ref& ref, BFile& file,
|
||||||
void BodyFetched(const entry_ref& ref, BFile& file);
|
BMessage& attributes);
|
||||||
|
void BodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes);
|
||||||
|
|
||||||
void MessageSent(const entry_ref& ref, BFile& file);
|
void MessageSent(const entry_ref& ref, BFile& file);
|
||||||
|
|
||||||
@@ -27,6 +29,8 @@ private:
|
|||||||
void _RemoveExtraWhitespace(BString& name);
|
void _RemoveExtraWhitespace(BString& name);
|
||||||
void _RemoveLeadingDots(BString& name);
|
void _RemoveLeadingDots(BString& name);
|
||||||
BString _ExtractName(const BString& from);
|
BString _ExtractName(const BString& from);
|
||||||
|
status_t _SetType(BMessage& attributes,
|
||||||
|
const char* mimeType);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int32 fAccountID;
|
int32 fAccountID;
|
||||||
|
|||||||
@@ -22,14 +22,15 @@ BMailFilter::~BMailFilter()
|
|||||||
|
|
||||||
|
|
||||||
BMailFilterAction
|
BMailFilterAction
|
||||||
BMailFilter::HeaderFetched(entry_ref& ref, BFile& file)
|
BMailFilter::HeaderFetched(entry_ref& ref, BFile& file, BMessage& attributes)
|
||||||
{
|
{
|
||||||
return B_NO_MAIL_ACTION;
|
return B_NO_MAIL_ACTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMailFilter::BodyFetched(const entry_ref& ref, BFile& file)
|
BMailFilter::BodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
|
|
||||||
#include <mail_util.h>
|
#include <mail_util.h>
|
||||||
#include <MailPrivate.h>
|
#include <MailPrivate.h>
|
||||||
|
#include <NodeMessage.h>
|
||||||
|
|
||||||
#include "HaikuMailFormatFilter.h"
|
#include "HaikuMailFormatFilter.h"
|
||||||
|
|
||||||
@@ -210,83 +211,53 @@ BMailProtocol::NotifyNewMessagesToFetch(int32 count)
|
|||||||
|
|
||||||
|
|
||||||
BMailFilterAction
|
BMailFilterAction
|
||||||
BMailProtocol::ProcessHeaderFetched(entry_ref& ref, BFile& data)
|
BMailProtocol::ProcessHeaderFetched(entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
{
|
{
|
||||||
entry_ref outRef = ref;
|
BMailFilterAction action = _ProcessHeaderFetched(ref, file, attributes);
|
||||||
|
if (action >= B_OK && action != B_DELETE_MAIL_ACTION)
|
||||||
|
file << attributes;
|
||||||
|
|
||||||
for (int i = 0; i < fFilterList.CountItems(); i++) {
|
return action;
|
||||||
BMailFilterAction action = fFilterList.ItemAt(i)->HeaderFetched(outRef,
|
|
||||||
data);
|
|
||||||
if (action == B_DELETE_MAIL_ACTION) {
|
|
||||||
// We have to delete the message
|
|
||||||
BEntry entry(&ref);
|
|
||||||
status_t status = entry.Remove();
|
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could "
|
|
||||||
"not delete mail: %s\n", strerror(status));
|
|
||||||
}
|
|
||||||
return B_DELETE_MAIL_ACTION;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ref == outRef)
|
|
||||||
return B_NO_MAIL_ACTION;
|
|
||||||
|
|
||||||
// We have to rename the file
|
|
||||||
node_ref newParentRef;
|
|
||||||
newParentRef.device = outRef.device;
|
|
||||||
newParentRef.node = outRef.directory;
|
|
||||||
|
|
||||||
BDirectory newParent(&newParentRef);
|
|
||||||
status_t status = newParent.InitCheck();
|
|
||||||
BString workerName;
|
|
||||||
if (status == B_OK) {
|
|
||||||
int32 uniqueNumber = 1;
|
|
||||||
do {
|
|
||||||
workerName = outRef.name;
|
|
||||||
if (uniqueNumber > 1)
|
|
||||||
workerName << "_" << ++uniqueNumber;
|
|
||||||
|
|
||||||
// TODO: support copying to another device!
|
|
||||||
BEntry entry(&ref);
|
|
||||||
status = entry.Rename(workerName);
|
|
||||||
} while (status == B_FILE_EXISTS);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status != B_OK) {
|
|
||||||
fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could not "
|
|
||||||
"rename mail (%s)! (should be: %s)\n", strerror(status),
|
|
||||||
workerName.String());
|
|
||||||
}
|
|
||||||
|
|
||||||
ref = outRef;
|
|
||||||
ref.set_name(workerName.String());
|
|
||||||
|
|
||||||
return B_MOVE_MAIL_ACTION;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMailProtocol::NotifyBodyFetched(const entry_ref& ref, BFile& data)
|
BMailProtocol::NotifyBodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fFilterList.CountItems(); i++)
|
_NotifyBodyFetched(ref, file, attributes);
|
||||||
fFilterList.ItemAt(i)->BodyFetched(ref, data);
|
file << attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMailFilterAction
|
||||||
|
BMailProtocol::ProcessMessageFetched(entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
|
{
|
||||||
|
BMailFilterAction action = _ProcessHeaderFetched(ref, file, attributes);
|
||||||
|
if (action >= B_OK && action != B_DELETE_MAIL_ACTION) {
|
||||||
|
_NotifyBodyFetched(ref, file, attributes);
|
||||||
|
file << attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
return action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMailProtocol::NotifyMessageReadyToSend(const entry_ref& ref, BFile& data)
|
BMailProtocol::NotifyMessageReadyToSend(const entry_ref& ref, BFile& file)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fFilterList.CountItems(); i++)
|
for (int i = 0; i < fFilterList.CountItems(); i++)
|
||||||
fFilterList.ItemAt(i)->MessageReadyToSend(ref, data);
|
fFilterList.ItemAt(i)->MessageReadyToSend(ref, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BMailProtocol::NotifyMessageSent(const entry_ref& ref, BFile& data)
|
BMailProtocol::NotifyMessageSent(const entry_ref& ref, BFile& file)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < fFilterList.CountItems(); i++)
|
for (int i = 0; i < fFilterList.CountItems(); i++)
|
||||||
fFilterList.ItemAt(i)->MessageSent(ref, data);
|
fFilterList.ItemAt(i)->MessageSent(ref, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -331,6 +302,75 @@ BMailProtocol::_LoadFilter(const BMailAddOnSettings& settings)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BMailFilterAction
|
||||||
|
BMailProtocol::_ProcessHeaderFetched(entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
|
{
|
||||||
|
entry_ref outRef = ref;
|
||||||
|
|
||||||
|
for (int i = 0; i < fFilterList.CountItems(); i++) {
|
||||||
|
BMailFilterAction action = fFilterList.ItemAt(i)->HeaderFetched(outRef,
|
||||||
|
file, attributes);
|
||||||
|
if (action == B_DELETE_MAIL_ACTION) {
|
||||||
|
// We have to delete the message
|
||||||
|
BEntry entry(&ref);
|
||||||
|
status_t status = entry.Remove();
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could "
|
||||||
|
"not delete mail: %s\n", strerror(status));
|
||||||
|
}
|
||||||
|
return B_DELETE_MAIL_ACTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ref == outRef)
|
||||||
|
return B_NO_MAIL_ACTION;
|
||||||
|
|
||||||
|
// We have to rename the file
|
||||||
|
node_ref newParentRef;
|
||||||
|
newParentRef.device = outRef.device;
|
||||||
|
newParentRef.node = outRef.directory;
|
||||||
|
|
||||||
|
BDirectory newParent(&newParentRef);
|
||||||
|
status_t status = newParent.InitCheck();
|
||||||
|
BString workerName;
|
||||||
|
if (status == B_OK) {
|
||||||
|
int32 uniqueNumber = 1;
|
||||||
|
do {
|
||||||
|
workerName = outRef.name;
|
||||||
|
if (uniqueNumber > 1)
|
||||||
|
workerName << "_" << uniqueNumber;
|
||||||
|
|
||||||
|
// TODO: support copying to another device!
|
||||||
|
BEntry entry(&ref);
|
||||||
|
status = entry.Rename(workerName);
|
||||||
|
|
||||||
|
uniqueNumber++;
|
||||||
|
} while (status == B_FILE_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status != B_OK) {
|
||||||
|
fprintf(stderr, "BMailProtocol::NotifyHeaderFetched(): could not "
|
||||||
|
"rename mail (%s)! (should be: %s)\n", strerror(status),
|
||||||
|
workerName.String());
|
||||||
|
}
|
||||||
|
|
||||||
|
ref = outRef;
|
||||||
|
ref.set_name(workerName.String());
|
||||||
|
|
||||||
|
return B_MOVE_MAIL_ACTION;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BMailProtocol::_NotifyBodyFetched(const entry_ref& ref, BFile& file,
|
||||||
|
BMessage& attributes)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < fFilterList.CountItems(); i++)
|
||||||
|
fFilterList.ItemAt(i)->BodyFetched(ref, file, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user