Part of work to add emailing of KDMs.
authorCarl Hetherington <cth@carlh.net>
Wed, 25 Sep 2013 11:20:26 +0000 (12:20 +0100)
committerCarl Hetherington <cth@carlh.net>
Wed, 25 Sep 2013 11:20:26 +0000 (12:20 +0100)
src/lib/config.cc
src/lib/config.h
src/lib/util.cc
src/lib/wscript
src/wx/config_dialog.cc
src/wx/config_dialog.h
src/wx/kdm_dialog.cc
src/wx/kdm_dialog.h
wscript

index 3a3a87faa53f227bee8d8a66a23128b3c026fbde..e53e15a810c1e793984bc77787fe8b946edca721 100644 (file)
@@ -58,6 +58,9 @@ Config::Config ()
        , _default_container (Ratio::from_id ("185"))
        , _default_dcp_content_type (DCPContentType::from_dci_name ("TST"))
        , _default_j2k_bandwidth (200000000)
+       , _kdm_email (
+               "Dear Projectionist\n\nPlease find attached KDMs for $CPL_NAME.\n\nBest regards,\nDCP-o-matic"
+               )
 {
        _allowed_dcp_frame_rates.push_back (24);
        _allowed_dcp_frame_rates.push_back (25);
@@ -142,6 +145,7 @@ Config::read ()
 
        _mail_server = f.string_child ("MailServer");
        _kdm_from = f.string_child ("KDMFrom");
+       _kdm_email = f.string_child ("KDMEmail");
 }
 
 void
@@ -300,6 +304,7 @@ Config::write () const
 
        root->add_child("MailServer")->add_child_text (_mail_server);
        root->add_child("KDMFrom")->add_child_text (_kdm_from);
+       root->add_child("KDMEmail")->add_child_text (_kdm_email);
 
        doc.write_to_file_formatted (file(false).string ());
 }
index 8dcb513a52b8fa245c2cb70a07c1478580921a78..7dd5abd178ec498ee22daf7337e0386bd25dff91 100644 (file)
@@ -142,6 +142,10 @@ public:
                return _kdm_from;
        }
 
+       std::string kdm_email () const {
+               return _kdm_email;
+       }
+
        /** @param n New number of local encoding threads */
        void set_num_local_encoding_threads (int n) {
                _num_local_encoding_threads = n;
@@ -244,6 +248,10 @@ public:
        void set_kdm_from (std::string f) {
                _kdm_from = f;
        }
+
+       void set_kdm_email (std::string e) {
+               _kdm_email = e;
+       }
        
        void write () const;
 
@@ -294,6 +302,7 @@ private:
        std::list<boost::shared_ptr<Cinema> > _cinemas;
        std::string _mail_server;
        std::string _kdm_from;
+       std::string _kdm_email;
 
        /** Singleton instance, or 0 */
        static Config* _instance;
index baa37ae7c4da838027ba6d152cc5383460185146..739a327d6a91ed319db66417e74331622193ea33 100644 (file)
@@ -54,6 +54,7 @@ extern "C" {
 #include <libpostproc/postprocess.h>
 #include <libavutil/pixfmt.h>
 }
+#include <curl/curl.h>
 #include "util.h"
 #include "exceptions.h"
 #include "scaler.h"
@@ -816,4 +817,53 @@ tidy_for_filename (string f)
 
        return t;
 }
+
+struct EmailState
+{
+       string message;
+       int done;
+};
+
+static size_t
+send_email_function (void* ptr, size_t size, size_t nmemb, void* userdata)
+{
+       EmailState* state = reinterpret_cast<EmailState*> (userdata);
+
+       int const now = min (size * nmemb, state->message.length() - state->done);
+
+       memcpy (ptr, state->message.c_str() + state->done, now);
+       state->done += now;
+
+       return now;
+}
        
+bool
+send_email (string from, string to, string message)
+{
+       CURL* curl = curl_easy_init ();
+       if (!curl) {
+               return true;
+       }
+
+       string const url = "smtp://" + Config::instance()->mail_server();
+
+       curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
+       curl_easy_setopt (curl, CURLOPT_MAIL_FROM, from.c_str ());
+       struct curl_slist* recipients = 0;
+       recipients = curl_slist_append (recipients, to.c_str ());
+       curl_easy_setopt (curl, CURLOPT_READFUNCTION, send_email_function);
+
+       EmailState state;
+       state.message = message;
+       state.done = 0;
+       curl_easy_setopt (curl, CURLOPT_READDATA, &state);
+
+       if (curl_easy_perform (curl) != CURLE_OK) {
+               return true;
+       }
+
+       curl_slist_free_all (recipients);
+       curl_easy_cleanup (curl);
+
+       return false;
+}
index e91666f7f31929dcc3a2abe579531029f9410718..8c02ff1581c57ad8689f2e9b50dfa2e36f554d07 100644 (file)
@@ -74,6 +74,7 @@ def build(bld):
                  AVCODEC AVUTIL AVFORMAT AVFILTER SWSCALE SWRESAMPLE 
                  BOOST_FILESYSTEM BOOST_THREAD BOOST_DATETIME BOOST_SIGNALS2 
                  SNDFILE OPENJPEG POSTPROC TIFF MAGICK SSH DCP CXML GLIB LZMA XML++
+                 CURL
                  """
 
     obj.source = sources + ' version.cc'
index 65cc39f24f52953049149bdece47810a1e6823a6..d6bc965db9131762f9444215df9eced3053df99f 100644 (file)
@@ -66,6 +66,8 @@ ConfigDialog::ConfigDialog (wxWindow* parent)
        _notebook->AddPage (_metadata_panel, _("Metadata"), false);
        make_tms_panel ();
        _notebook->AddPage (_tms_panel, _("TMS"), false);
+       make_kdm_email_panel ();
+       _notebook->AddPage (_kdm_email_panel, _("KDM email"), false);
 
        wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
        overall_sizer->Add (s, 1, wxEXPAND | wxALL, DCPOMATIC_DIALOG_BORDER);
@@ -478,3 +480,23 @@ ConfigDialog::kdm_from_changed ()
 {
        Config::instance()->set_kdm_from (wx_to_std (_kdm_from->GetValue ()));
 }
+
+void
+ConfigDialog::make_kdm_email_panel ()
+{
+       _kdm_email_panel = new wxPanel (_notebook);
+       wxBoxSizer* s = new wxBoxSizer (wxVERTICAL);
+       _kdm_email_panel->SetSizer (s);
+
+       _kdm_email = new wxTextCtrl (_kdm_email_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE);
+       s->Add (_kdm_email, 1, wxEXPAND | wxALL);
+
+       _kdm_email->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&ConfigDialog::kdm_email_changed, this));
+       _kdm_email->SetValue (wx_to_std (Config::instance()->kdm_email ()));
+}
+
+void
+ConfigDialog::kdm_email_changed ()
+{
+       Config::instance()->set_kdm_email (wx_to_std (_kdm_email->GetValue ()));
+}
index 3df7a6a2612a92f57e3c696f95aa27f6ea354ba0..b1a59e8b9d4161d0a646ed0d62d552bde8aebbdb 100644 (file)
@@ -61,6 +61,7 @@ private:
        void default_j2k_bandwidth_changed ();
        void mail_server_changed ();
        void kdm_from_changed ();
+       void kdm_email_changed ();
 
        void setup_language_sensitivity ();
 
@@ -69,6 +70,7 @@ private:
        void make_metadata_panel ();
        void make_servers_panel ();
        void make_colour_conversions_panel ();
+       void make_kdm_email_panel ();
 
        wxNotebook* _notebook;
        wxPanel* _misc_panel;
@@ -97,5 +99,7 @@ private:
        wxTextCtrl* _issuer;
        wxTextCtrl* _creator;
        wxSpinCtrl* _default_j2k_bandwidth;
+       wxPanel* _kdm_email_panel;
+       wxTextCtrl* _kdm_email;
 };
 
index 170a242d93efd842cb3aaaf7331bf48bccca2079..9db512780754a69196a640dff7ddf4c50d2ca7fa 100644 (file)
@@ -79,19 +79,20 @@ KDMDialog::KDMDialog (wxWindow* parent)
        vertical->Add (targets, 1, wxEXPAND | wxALL, 6);
 
        wxFlexGridSizer* table = new wxFlexGridSizer (3, 2, 6);
-       add_label_to_sizer (table, this, "From", true);
+       add_label_to_sizer (table, this, _("From"), true);
        _from_date = new wxDatePickerCtrl (this, wxID_ANY);
        table->Add (_from_date, 1, wxEXPAND);
        _from_time = new wxTimePickerCtrl (this, wxID_ANY);
        table->Add (_from_time, 1, wxEXPAND);
        
-       add_label_to_sizer (table, this, "Until", true);
+       add_label_to_sizer (table, this, _("Until"), true);
        _until_date = new wxDatePickerCtrl (this, wxID_ANY);
        table->Add (_until_date, 1, wxEXPAND);
        _until_time = new wxTimePickerCtrl (this, wxID_ANY);
        table->Add (_until_time, 1, wxEXPAND);
 
-       add_label_to_sizer (table, this, "Write to", true);
+       _write_to = new wxRadioButton (this, wxID_ANY, _("Write to"));
+       table->Add (_write_to, 1, wxEXPAND);
 
 #ifdef DCPOMATIC_USE_OWN_DIR_PICKER
        _folder = new DirPickerCtrl (this); 
@@ -102,6 +103,11 @@ KDMDialog::KDMDialog (wxWindow* parent)
        _folder->SetPath (wxStandardPaths::Get().GetDocumentsDir());
        
        table->Add (_folder, 1, wxEXPAND);
+       table->AddSpacer (0);
+
+       _email = new wxRadioButton (this, wxID_ANY, _("Send by email"));
+       table->Add (_email, 1, wxEXPAND);
+       table->AddSpacer (0);
        
        vertical->Add (table, 0, wxEXPAND | wxALL, 6);
 
@@ -110,15 +116,18 @@ KDMDialog::KDMDialog (wxWindow* parent)
                vertical->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
        }
 
-       _targets->Connect (wxID_ANY, wxEVT_COMMAND_TREE_SEL_CHANGED, wxCommandEventHandler (KDMDialog::targets_selection_changed), 0, this);
+       _targets->Bind       (wxEVT_COMMAND_TREE_SEL_CHANGED, boost::bind (&KDMDialog::setup_sensitivity, this));
+
+       _add_cinema->Bind    (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::add_cinema_clicked, this));
+       _edit_cinema->Bind   (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::edit_cinema_clicked, this));
+       _remove_cinema->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::remove_cinema_clicked, this));
 
-       _add_cinema->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::add_cinema_clicked), 0, this);
-       _edit_cinema->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::edit_cinema_clicked), 0, this);
-       _remove_cinema->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::remove_cinema_clicked), 0, this);
+       _add_screen->Bind    (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::add_screen_clicked, this));
+       _edit_screen->Bind   (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::edit_screen_clicked, this));
+       _remove_screen->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&KDMDialog::remove_screen_clicked, this));
 
-       _add_screen->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::add_screen_clicked), 0, this);
-       _edit_screen->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::edit_screen_clicked), 0, this);
-       _remove_screen->Connect (wxID_ANY, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler (KDMDialog::remove_screen_clicked), 0, this);
+       _write_to->Bind      (wxEVT_COMMAND_RADIOBUTTON_SELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
+       _email->Bind         (wxEVT_COMMAND_RADIOBUTTON_SELECTED, boost::bind (&KDMDialog::setup_sensitivity, this));
 
        setup_sensitivity ();
        
@@ -161,12 +170,6 @@ KDMDialog::selected_screens () const
        return c;
 }
 
-void
-KDMDialog::targets_selection_changed (wxCommandEvent &)
-{
-       setup_sensitivity ();
-}
-
 void
 KDMDialog::setup_sensitivity ()
 {
@@ -182,6 +185,8 @@ KDMDialog::setup_sensitivity ()
 
        wxButton* ok = dynamic_cast<wxButton *> (FindWindowById (wxID_OK));
        ok->Enable (sc || ss);
+
+       _folder->Enable (_write_to->GetValue ());
 }
 
 void
@@ -211,7 +216,7 @@ KDMDialog::add_screen (shared_ptr<Cinema> c, shared_ptr<Screen> s)
 }
 
 void
-KDMDialog::add_cinema_clicked (wxCommandEvent &)
+KDMDialog::add_cinema_clicked ()
 {
        CinemaDialog* d = new CinemaDialog (this, "Add Cinema");
        d->ShowModal ();
@@ -226,7 +231,7 @@ KDMDialog::add_cinema_clicked (wxCommandEvent &)
 }
 
 void
-KDMDialog::edit_cinema_clicked (wxCommandEvent &)
+KDMDialog::edit_cinema_clicked ()
 {
        if (selected_cinemas().size() != 1) {
                return;
@@ -247,7 +252,7 @@ KDMDialog::edit_cinema_clicked (wxCommandEvent &)
 }
 
 void
-KDMDialog::remove_cinema_clicked (wxCommandEvent &)
+KDMDialog::remove_cinema_clicked ()
 {
        if (selected_cinemas().size() != 1) {
                return;
@@ -262,7 +267,7 @@ KDMDialog::remove_cinema_clicked (wxCommandEvent &)
 }
 
 void
-KDMDialog::add_screen_clicked (wxCommandEvent &)
+KDMDialog::add_screen_clicked ()
 {
        if (selected_cinemas().size() != 1) {
                return;
@@ -283,7 +288,7 @@ KDMDialog::add_screen_clicked (wxCommandEvent &)
 }
 
 void
-KDMDialog::edit_screen_clicked (wxCommandEvent &)
+KDMDialog::edit_screen_clicked ()
 {
        if (selected_screens().size() != 1) {
                return;
@@ -304,7 +309,7 @@ KDMDialog::edit_screen_clicked (wxCommandEvent &)
 }
 
 void
-KDMDialog::remove_screen_clicked (wxCommandEvent &)
+KDMDialog::remove_screen_clicked ()
 {
        if (selected_screens().size() != 1) {
                return;
index e6a26c86b55440876f5ec1006402c8dfa55a0964..0acf9a61e1ac15865abbc9cb04030b370cf297ce 100644 (file)
@@ -46,13 +46,12 @@ public:
 private:
        void add_cinema (boost::shared_ptr<Cinema>);
        void add_screen (boost::shared_ptr<Cinema>, boost::shared_ptr<Screen>);
-       void targets_selection_changed (wxCommandEvent &);
-       void add_cinema_clicked (wxCommandEvent &);
-       void edit_cinema_clicked (wxCommandEvent &);
-       void remove_cinema_clicked (wxCommandEvent &);
-       void add_screen_clicked (wxCommandEvent &);
-       void edit_screen_clicked (wxCommandEvent &);
-       void remove_screen_clicked (wxCommandEvent &);
+       void add_cinema_clicked ();
+       void edit_cinema_clicked ();
+       void remove_cinema_clicked ();
+       void add_screen_clicked ();
+       void edit_screen_clicked ();
+       void remove_screen_clicked ();
        std::list<std::pair<wxTreeItemId, boost::shared_ptr<Cinema> > > selected_cinemas () const;
        std::list<std::pair<wxTreeItemId, boost::shared_ptr<Screen> > > selected_screens () const;
        void setup_sensitivity ();
@@ -70,11 +69,13 @@ private:
        wxDatePickerCtrl* _until_date;
        wxTimePickerCtrl* _from_time;
        wxTimePickerCtrl* _until_time;
+       wxRadioButton* _write_to;
 #ifdef DCPOMATIC_USE_OWN_DIR_PICKER
        DirPickerCtrl* _folder;
 #else
        wxDirPickerCtrl* _folder;
 #endif
+       wxRadioButton* _email;
 
        wxTreeItemId _root;
        std::map<wxTreeItemId, boost::shared_ptr<Cinema> > _cinemas;
diff --git a/wscript b/wscript
index 75bb681bbf03ea88049df6ebb23f7b1c5271fc64..7d582f9e56d0fd01322a80b71dc4c0a7c73e7068 100644 (file)
--- a/wscript
+++ b/wscript
@@ -125,6 +125,7 @@ def configure(conf):
     conf.check_cfg(package='glib-2.0', args='--cflags --libs', uselib_store='GLIB', mandatory=True)
     conf.check_cfg(package= '', path=conf.options.magickpp_config, args='--cppflags --cxxflags --libs', uselib_store='MAGICK', mandatory=True)
     conf.check_cfg(package='libxml++-2.6', args='--cflags --libs', uselib_store='XML++', mandatory=True)
+    conf.check_cfg(package='libcurl', args='--cflags --libs', uselib_store='CURL', mandatory=True)
 
     conf.check_cxx(fragment="""
                             #include <boost/version.hpp>\n