#include #include "sender.hpp" #include "builder/date.hpp" #include "builder/mail_to.hpp" #include "builder/cc.hpp" #include "builder/subject.hpp" #include "builder/text.hpp" #include "builder/from.hpp" #include "managment/logger.hpp" namespace smtp::message { static std::string mText = ""; // // Constructors/Destructors // Sender::Sender( manage::Settings& settings_storage, manage::Mail const& mail_to ) : mSettingsStorage( settings_storage ), mMailTo( mail_to ) { } // //Public methods // bool Sender::Send( std::string const& mail_from, std::string const& subject, std::string const& text ) { CURLcode result = CURLE_OK; curl_slist *recipients = NULL; WriteThis upload_ctx{}; auto curl = curl_easy_init(); //TODO сделать инициализацию через регистратор инициализаторов mSettingsStorage.ReloadSettings(); if( !InitCurl( curl, upload_ctx, mail_from ) ) { manage::Logger::LogError("Error to initializate curl"); return false; } //TODO раздать mail_to другим методам auto mail_to = mMailTo.GetMailToSend(); if( mail_to.empty() ) { manage::Logger::LogError("We haven't any mail to"); return false; } FillRecipients( curl, recipients ); UpdateMailText( mail_from, subject, text); result = curl_easy_perform(curl); if ( result != CURLE_OK ) { std::string message = "Error to send messge: " + std::string( curl_easy_strerror( result )); manage::Logger::LogError(message); return false; } //TODO сделать деинициализацию через регистратор деинициализаторов curl_slist_free_all( recipients ); curl_easy_cleanup( curl ); return true; } // //Private methods // bool smtp::message::Sender::InitCurl( CURL* curl, WriteThis const& upload_ctx, std::string const& mail_from ) { if( !curl ) { return false; } curl_easy_setopt(curl, CURLOPT_USERNAME, mSettingsStorage.GetUserName().c_str()); curl_easy_setopt(curl, CURLOPT_PASSWORD, mSettingsStorage.GetPassword().c_str()); curl_easy_setopt(curl, CURLOPT_URL, GetHostPortData().c_str()); curl_easy_setopt(curl, CURLOPT_USE_SSL, (long)CURLUSESSL_ALL); curl_easy_setopt(curl, CURLOPT_MAIL_FROM, mail_from.c_str()); curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallBack); curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx); curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L); curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); return true; } void Sender::UpdateMailText( std::string const& mail_from, std::string const& subject, std::string const& text ) const { auto mail_to = mMailTo.GetMailToSend(); auto text_decorator = std::make_shared( text ); text_decorator->Apply( std::make_shared( subject ) ) .Apply( std::make_shared( mail_to ) ) .Apply( std::make_shared( mail_from ) ) .Apply( std::make_shared( mail_to ) ) .Apply( std::make_shared() ); mText = text_decorator->Get(); } void Sender::FillRecipients( CURL* curl, curl_slist* recipients ) { auto mail_to = mMailTo.GetMailToSend(); for( const auto& recipient : mail_to ) { recipients = curl_slist_append( recipients, recipient.c_str() ); } curl_easy_setopt( curl, CURLOPT_MAIL_RCPT, recipients ); } std::string Sender::GetHostPortData() const { auto result = "smtp://" + mSettingsStorage.GetHost(); if( !mSettingsStorage.GetPort().empty() ) { result += ":" + mSettingsStorage.GetPort(); } return result; } //TODO Надо убрать этот ужас. Без статики!!! size_t Sender::ReadCallBack( void *ptr, size_t size, size_t nmemb, void *userp ) { struct WriteThis *pooh = reinterpret_cast( userp ); if( size * nmemb < 1 || pooh->counter++ > 0 ) { return 0; } memcpy( ptr, mText.c_str(), mText.size() ); return mText.size(); } }