summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-07-15 16:06:37 +0000
committerrandomdan <randomdan@localhost>2011-07-15 16:06:37 +0000
commit4677fe8a34329bd0bb124d130b32ac79f33450c6 (patch)
treecfb7cce8fe7017c75cfbd6a4e168da325daf49b1
parentMake *Host parse their XML document on first run of components, fixes sendmai... (diff)
downloadproject2-4677fe8a34329bd0bb124d130b32ac79f33450c6.tar.bz2
project2-4677fe8a34329bd0bb124d130b32ac79f33450c6.tar.xz
project2-4677fe8a34329bd0bb124d130b32ac79f33450c6.zip
Automatically sort the order of the MailParts to make life carefree and fix the order of HTML/plain text alternatives
-rw-r--r--project2/sendmailTask.cpp71
-rw-r--r--project2/sendmailTask.h10
2 files changed, 62 insertions, 19 deletions
diff --git a/project2/sendmailTask.cpp b/project2/sendmailTask.cpp
index ba2f3b0..073022f 100644
--- a/project2/sendmailTask.cpp
+++ b/project2/sendmailTask.cpp
@@ -12,6 +12,8 @@
DECLARE_LOADER("sendmail", SendMailTask);
+uint8_t SendMailTask::MailPart::mimeIdx;
+
class SendEmailFailed : public std::runtime_error {
public:
SendEmailFailed(const std::string & what) : std::runtime_error(what) { }
@@ -45,9 +47,29 @@ SendMailTask::writeMailWrapper(void ** buf, int * len, void * arg)
return static_cast<const SendMailTask*>(arg)->writeMail(buf, len);
}
+SendMailTask::MailPart::MailPart(uint8_t s, uint8_t i, uint8_t p) :
+ sec(s),
+ ind(i),
+ prt(p)
+{
+}
+
+SendMailTask::MailPart::~MailPart()
+{
+}
+
+bool
+SendMailTask::SortMailParts::operator()(const MailPartPtr & a, const MailPartPtr & b) const
+{
+ return (a->sec < b->sec) || ((a->sec == b->sec) && (a->ind < b->ind))
+ || ((a->sec == b->sec) && (a->ind == b->ind) && (a->prt < b->prt));
+}
+
class BoundaryBegin : public SendMailTask::MailPart {
public:
- BoundaryBegin(const std::string & ct) : contentType(ct) {
+ BoundaryBegin(const std::string & ct, uint8_t m) :
+ MailPart(m, MailPart::mimeIdx, 0),
+ contentType(ct) {
}
const char * write(char ** buf, int * len) {
*len = asprintf(buf, "\r\n--<<divider>>\r\nContent-Type: %s\r\n\r\n", contentType.c_str());
@@ -59,6 +81,9 @@ class BoundaryBegin : public SendMailTask::MailPart {
class BoundaryEnd : public SendMailTask::MailPart {
public:
+ BoundaryEnd() :
+ MailPart(255, 0, 0) {
+ }
const char * write(char **, int * len) {
*len = 19;
return "\r\n--<<divider>>--\r\n";
@@ -68,10 +93,14 @@ class BoundaryEnd : public SendMailTask::MailPart {
class Header : public SendMailTask::MailPart {
public:
Header(const std::string & h, const VariableType & v) :
- header(h), value(v) {
+ MailPart(0, 0, 0),
+ header(h),
+ value(v) {
}
Header(const std::string & h, const char * v) :
- header(h), value(v) {
+ MailPart(0, 0, 0),
+ header(h),
+ value(v) {
}
const char * write(char ** buf, int * len) {
writeText(buf, len, value);
@@ -87,7 +116,10 @@ class Header : public SendMailTask::MailPart {
class MimeContent : public SendMailTask::MailPart {
public:
- MimeContent(const char * s, int l) : str(s), length(l) {
+ MimeContent(const char * s, int l, uint8_t m) :
+ MailPart(m, MailPart::mimeIdx, 1),
+ str(s),
+ length(l) {
}
const char * write(char ** buf, int * len) {
*buf = NULL;
@@ -119,23 +151,25 @@ class TransformHtmlToEmail : public TransformImpl<HtmlDocument, SendMailTask::Pa
xmlDoc * doc = const_cast<xmlDoc *>(cdoc->doc);
int len = 0;
xmlDocDumpFormatMemoryEnc(doc, &buf, &len, "utf-8", 1);
- parts->parts.push_back(new BoundaryBegin("text/html; utf-8"));
- parts->parts.push_back(new MimeContent(reinterpret_cast<const char *>(buf), len));
+ parts->parts.insert(new BoundaryBegin("text/html; utf-8", 2));
+ parts->parts.insert(new MimeContent(reinterpret_cast<const char *>(buf), len, 2));
+ SendMailTask::MailPart::mimeIdx += 1;
}
private:
mutable xmlChar * buf;
};
-DECLARE_TRANSFORM(TransformHtmlToEmail)
+DECLARE_TRANSFORM(TransformHtmlToEmail);
class TransformTextToEmail : public TransformImpl<TextDocument, SendMailTask::Parts> {
public:
void transform(const TextDocument * str, SendMailTask::Parts * parts) const
{
- parts->parts.push_back(new BoundaryBegin("text/plain; utf-8"));
- parts->parts.push_back(new MimeContent(str->doc.c_str(), str->doc.length()));
+ parts->parts.insert(new BoundaryBegin("text/plain; utf-8", 1));
+ parts->parts.insert(new MimeContent(str->doc.c_str(), str->doc.length(), 1));
+ SendMailTask::MailPart::mimeIdx += 1;
}
};
-DECLARE_TRANSFORM(TransformTextToEmail)
+DECLARE_TRANSFORM(TransformTextToEmail);
PresenterPtr
SendMailTask::createDefaultPresenter(const xmlpp::Element * n) const
@@ -155,17 +189,18 @@ void
SendMailTask::execute() const
{
parts = new Parts();
- parts->parts.push_back(new Header("To", to));
- parts->parts.push_back(new Header("From", from));
- parts->parts.push_back(new Header("Subject", subject));
- parts->parts.push_back(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\""));
- parts->parts.push_back(new Header("MIME-Version", "1.0"));
- parts->parts.push_back(new Header("Content-Transfer-Encoding", "binary"));
+ MailPart::mimeIdx = 0;
+ parts->parts.insert(new Header("To", to));
+ parts->parts.insert(new Header("From", from));
+ parts->parts.insert(new Header("Subject", subject));
+ parts->parts.insert(new Header("Content-Type", "multipart/alternative; boundary=\"<<divider>>\""));
+ parts->parts.insert(new Header("MIME-Version", "1.0"));
+ parts->parts.insert(new Header("Content-Transfer-Encoding", "binary"));
+ parts->parts.insert(new BoundaryEnd());
ViewHostPtr vsp = new ViewHost("emails", present);
vsp->executeViews(boost::bind(&SendMailTask::createDefaultPresenter, this, _1));
vsp->doTransforms();
- parts->parts.push_back(new BoundaryEnd());
part = parts->parts.begin();
// Write email
@@ -180,7 +215,7 @@ SendMailTask::execute() const
smtp_strerror(smtp_errno(), buf, sizeof buf);
throw SendEmailFailed(buf);
}
- parts->parts.clear();
+ parts.reset();
}
const char *
diff --git a/project2/sendmailTask.h b/project2/sendmailTask.h
index e57a309..f871574 100644
--- a/project2/sendmailTask.h
+++ b/project2/sendmailTask.h
@@ -14,10 +14,18 @@ class SendMailTask : public Task {
public:
class MailPart : public IntrusivePtrBase {
public:
+ MailPart(uint8_t, uint8_t, uint8_t);
+ ~MailPart();
virtual const char * write(char ** buf, int * len) = 0;
+ const uint8_t sec, ind, prt;
+ static uint8_t mimeIdx;
};
typedef boost::intrusive_ptr<MailPart> MailPartPtr;
- typedef std::list<MailPartPtr> PartList;
+ class SortMailParts {
+ public:
+ bool operator()(const MailPartPtr &, const MailPartPtr &) const;
+ };
+ typedef std::multiset<MailPartPtr, SortMailParts> PartList;
class Parts : public TransformChainLink {
public:
PartList parts;