Changeset 11cf105fe323361072281747558cb61752f33fa8

Show
Ignore:
Timestamp:
09/19/10 22:57:42 (20 months ago)
Author:
Antti-Juhani Kaijanaho <antti-juhani@…>
Children:
383796fa5544ac0c42f5599e6de3d3aa06cde8bb
Parents:
99057e4d73dbb905f06f5ccc4ea49708b8aaa0a8
git-committer:
Antti-Juhani Kaijanaho <antti-juhani@…> (09/19/10 22:57:42)
Message:

#60: Add a footer to email distributed posts

Signed-off-by: Antti-Juhani Kaijanaho <antti-juhani@…>

Files:
7 modified

Legend:

Unmodified
Added
Removed
  • db/group.cc

    r99057e4 r11cf105  
    2525#include "../config.hh" 
    2626#include "../msg/entity.hh" 
     27#include "../msg/multipart.hh" 
     28#include "../msg/text_plain.hh" 
    2729#include "../smtp_client/smtp_client.hh" 
     30#include "../tlate/data_model.hh" 
     31#include "../tlate/group_value.hh" 
     32#include "../tlate/tlate.hh" 
    2833 
    2934#include "../assert.hh" 
     
    6974                if (recv.empty()) return rv; 
    7075 
    71                 ::msg::entity::ptr nm = m->get_entity()->clone(); 
     76                ::msg::multipart::ptr nm = 
     77                          m->get_entity()->clone_as_multipart(); 
    7278                { 
    7379                        std::string subject = nm->get_field("subject", false); 
     
    8692                                  config["canonical-name"].as<std::string>() + 
    8793                                  ">"); 
     94 
     95                tlate::data_model::ptr mam(new tlate::data_model); 
     96                mam->insert("group", new tlate::group_value(shared_from_this(), 
     97                                                            user::ptr())); 
     98 
     99                boost::shared_ptr<tlate::tlate> tl = 
     100                        tlate::tlate::parse("sub_footer.txt"); 
     101                std::ostringstream mos; 
     102                mos << tl->eval(mam); 
     103                ::msg::text_plain::ptr sub(new ::msg::text_plain 
     104                                           (mos.str(), 
     105                                            ::msg::content_type(DEFAULT_CT))); 
     106                nm->append_part(sub); 
    88107                                   
    89108                cb.smtpc().send_mail(recv, nm->get_entity()); 
  • msg/entity.cc

    r99057e4 r11cf105  
    2020#include "content_type.hh" 
    2121#include "entity.hh" 
     22#include "lexutils.hh" 
    2223#include "message_entity.hh" 
    2324#include "multipart.hh" 
     
    3031#include <boost/algorithm/string/case_conv.hpp> 
    3132#include <boost/format.hpp> 
     33#include <boost/nondet_random.hpp> 
    3234 
    3335#include "../assert.hh" 
     
    8789        } 
    8890 
     91        multipart::ptr entity::clone_as_multipart() const 
     92        { 
     93                static const char *const content_ = "content-"; 
     94                boost::random_device urand; 
     95 
     96                entity_header::ptr envh(new entity_header(*hdr)); 
     97                entity_header::ptr subh(new entity_header(DEFAULT_CT)); 
     98 
     99                for (field_iterator it = hdr->fields_begin(); 
     100                     it != hdr->fields_end(); it++) 
     101                { 
     102                        std::string fld = *it; 
     103                        size_t colon = fld.find(':'); 
     104                        if (colon == std::string::npos) colon = 0; 
     105                        std::string name = fld.substr(0, colon); 
     106                        size_t start = colon + 1 < fld.length() 
     107                                ? (fld[colon+1] == ' ' ? colon + 1 : colon) 
     108                                : colon; 
     109                        std::string content = fld.substr(start); 
     110                        util::strip_crlf(content); 
     111                        boost::to_lower(name); 
     112                        if (name.substr(0, sizeof content_) != content_) 
     113                                continue; 
     114                        subh->replace_field(name, content); 
     115                        envh->delete_field(name); 
     116                } 
     117 
     118                std::string body = get_body(); 
     119 
     120                std::string boundary; 
     121        redo: 
     122                { 
     123                        std::ostringstream ss; 
     124                        ss << urand() << urand() << urand() << urand(); 
     125                        if (body.find(ss.str()) != std::string::npos) 
     126                                goto redo; 
     127                        boundary = ss.str(); 
     128                } 
     129 
     130                bool bit8 = false; 
     131                for (size_t i = 0; i < body.length(); i++) 
     132                { 
     133                        if ((unsigned char)body[i] > 0x7f) 
     134                        { 
     135                                bit8 = true; 
     136                                break; 
     137                        } 
     138                } 
     139 
     140                envh->replace_field("MIME-Version", "1.0"); 
     141                envh->add_field("Content-Type", 
     142                                std::string("multipart/mixed; boundary=") + 
     143                                make_phrase(boundary)); 
     144                envh->add_field("Content-Transfer-Encoding", 
     145                                bit8 ? "8bit" : "7bit"); 
     146 
     147                std::ostringstream nbss; 
     148                nbss << "--" << boundary << "\r\n" 
     149                     << subh->get_header() << "\r\n" 
     150                     << body 
     151                     << "\r\n--" << boundary << "--\r\n"; 
     152                 
     153                multipart::ptr rv(new multipart(envh, nbss.str())); 
     154                return rv; 
     155        } 
     156 
    89157} 
  • msg/entity.hh

    r99057e4 r11cf105  
    3030{ 
    3131        class content_type; 
    32         class mime_entity; 
     32        class multipart; 
    3333 
    3434        class entity 
     
    4646 
    4747                virtual ptr clone() const = 0; 
     48 
     49                virtual boost::shared_ptr<multipart> clone_as_multipart() const; 
    4850 
    4951                virtual boost::shared_ptr<tlate::value> 
  • msg/entity_header.cc

    r99057e4 r11cf105  
    231231                                    : default_ct); 
    232232        } 
     233 
     234        void entity_header::delete_field(std::string the_name) 
     235        { 
     236                boost::to_lower(the_name); 
     237                for (std::list<std::string>::iterator it = 
     238                             field_content.begin(); 
     239                     it != field_content.end(); /**/) 
     240                { 
     241                        std::string fld = *it; 
     242                        size_t colon = fld.find(':'); 
     243                        if (colon == std::string::npos) colon = 0; 
     244                        std::string name = fld.substr(0, colon); 
     245                        boost::to_lower(name); 
     246                        if (name != the_name) { it++; continue; } 
     247                        it = field_content.erase(it); 
     248                } 
     249                fields.erase(the_name); 
     250                if (the_name == "date") 
     251                        the_date = boost::posix_time::not_a_date_time; 
     252        } 
    233253} 
  • msg/entity_header.hh

    r99057e4 r11cf105  
    9292                std::string get_field(std::string s, bool full) const; 
    9393 
     94                void add_field(std::string name, std::string body) { 
     95                        field_content.push_front(name + ": " + body + "\r\n"); 
     96                        boost::to_lower(name); 
     97                        fields[name] = field_content.begin(); 
     98                        if (name == "date") 
     99                                the_date = boost::posix_time::not_a_date_time; 
     100                } 
    94101                void replace_field(std::string name, std::string body); 
     102                void delete_field(std::string name); 
    95103 
    96104                content_type get_content_type() const; 
  • msg/multipart.hh

    r99057e4 r11cf105  
    3030                std::vector<entity::ptr> parts; 
    3131                std::string preamble, trailer; 
     32 
     33                multipart(const multipart &o) 
     34                        : entity(o) 
     35                        , preamble(o.preamble) 
     36                        , trailer(o.trailer) { 
     37                        for (size_t i = 0; i < o.parts.size(); i++) { 
     38                                parts.push_back(o.parts[i]->clone()); 
     39                        } 
     40                } 
     41                         
    3242        public: 
     43                typedef boost::shared_ptr<multipart> ptr; 
     44                typedef boost::shared_ptr<const multipart> const_ptr; 
     45 
    3346                multipart(entity_header::ptr hdr, std::string body); 
    3447 
    3548                entity::ptr clone() const { 
    36                         entity::ptr rv(new multipart(*this)); 
     49                        multipart::ptr rv(new multipart(*this)); 
    3750                        return rv; 
    3851                } 
     
    4154 
    4255                boost::shared_ptr<tlate::value> get_tlate_value(bool) const; 
     56 
     57                void append_part(entity::const_ptr p) { 
     58                        entity::ptr np = p->clone(); // FIXME default_ct 
     59                        parts.push_back(np); 
     60                } 
    4361        }; 
    4462} 
  • msg/text_plain.hh

    r99057e4 r11cf105  
    3232        { 
    3333        public: 
     34                typedef boost::shared_ptr<text_plain> ptr; 
     35                typedef boost::shared_ptr<const text_plain> const_ptr; 
     36 
    3437                class para 
    3538                {