X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Ftools%2Fdcpomatic_kdm.cc;h=da856d3589af6246df58ee6f96c1eb70517c3548;hp=2b0d25836dbf4cb0e77234f09a2fe10e99ef5f1f;hb=0a1d944d74308ccb940194bcb627652c72128650;hpb=6bfda50f36b35a6635e9da7a25f84319ca29d92f diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 2b0d25836..da856d358 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -38,14 +38,16 @@ #include "lib/util.h" #include "lib/screen.h" #include "lib/job_manager.h" -#include "lib/screen_kdm.h" +#include "lib/kdm_with_metadata.h" #include "lib/exceptions.h" -#include "lib/cinema_kdms.h" #include "lib/send_kdm_email_job.h" #include "lib/compose.hpp" #include "lib/cinema.h" #include "lib/dkdm_wrapper.h" #include "lib/cross.h" +#ifdef DCPOMATIC_VARIANT_SWAROOP +#include "lib/decrypted_ecinema_kdm.h" +#endif #include #include #include @@ -74,6 +76,7 @@ using boost::bind; using boost::optional; using boost::ref; using boost::dynamic_pointer_cast; +using namespace dcpomatic; enum { ID_help_report_a_problem = 1, @@ -160,6 +163,8 @@ public: dkdm_buttons->Add (_add_dkdm_folder, 0, wxALL | wxEXPAND, DCPOMATIC_BUTTON_STACK_GAP); _remove_dkdm = new Button (overall_panel, _("Remove")); dkdm_buttons->Add (_remove_dkdm, 0, wxALL | wxEXPAND, DCPOMATIC_BUTTON_STACK_GAP); + _export_dkdm = new Button (overall_panel, _("Export...")); + dkdm_buttons->Add (_export_dkdm, 0, wxALL | wxEXPAND, DCPOMATIC_BUTTON_STACK_GAP); dkdm_sizer->Add (dkdm_buttons, 0, wxEXPAND | wxALL, DCPOMATIC_SIZER_GAP); right->Add (dkdm_sizer, 1, wxEXPAND | wxALL, DCPOMATIC_SIZER_Y_GAP); @@ -189,6 +194,7 @@ public: _add_dkdm->Bind (wxEVT_BUTTON, bind (&DOMFrame::add_dkdm_clicked, this)); _add_dkdm_folder->Bind (wxEVT_BUTTON, bind (&DOMFrame::add_dkdm_folder_clicked, this)); _remove_dkdm->Bind (wxEVT_BUTTON, bind (&DOMFrame::remove_dkdm_clicked, this)); + _export_dkdm->Bind (wxEVT_BUTTON, bind (&DOMFrame::export_dkdm_clicked, this)); setup_sensitivity (); } @@ -295,55 +301,115 @@ private: if (!dkdm_base) { return; } - shared_ptr dkdm = boost::dynamic_pointer_cast (dkdm_base); - if (!dkdm) { - return; - } - /* Decrypt the DKDM */ - dcp::DecryptedKDM decrypted (dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); - - /* This is the signer for our new KDMs */ - shared_ptr signer = Config::instance()->signer_chain (); - if (!signer->valid ()) { - throw InvalidSignerError (); + list kdms; + string title; + +#ifdef DCPOMATIC_VARIANT_SWAROOP + shared_ptr ecinema_dkdm = boost::dynamic_pointer_cast (dkdm_base); + if (ecinema_dkdm) { + DecryptedECinemaKDM decrypted (ecinema_dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); + title = decrypted.name (); + + BOOST_FOREACH (shared_ptr i, _screens->screens()) { + + if (!i->recipient) { + continue; + } + + dcp::LocalTime begin(_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); + dcp::LocalTime end(_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); + + DecryptedECinemaKDM kdm ( + decrypted.id(), + decrypted.name(), + decrypted.key(), + begin, + end + ); + + dcp::NameFormat::Map name_values; + name_values['c'] = i->cinema->name; + name_values['s'] = i->name; + name_values['f'] = title; + name_values['b'] = begin.date() + " " + begin.time_of_day(true, false); + name_values['e'] = end.date() + " " + end.time_of_day(true, false); + name_values['i'] = kdm.id(); + + /* Encrypt */ + kdms.push_back ( + KDMWithMetadataPtr( + new ECinemaKDMWithMetadata(name_values, i->cinema, kdm.encrypt(i->recipient.get())) + ) + ); + } } +#endif + + shared_ptr dkdm = boost::dynamic_pointer_cast (dkdm_base); + if (dkdm) { - list screen_kdms; - BOOST_FOREACH (shared_ptr i, _screens->screens()) { + /* Decrypt the DKDM */ + dcp::DecryptedKDM decrypted (dkdm->dkdm(), Config::instance()->decryption_chain()->key().get()); + title = decrypted.content_title_text (); - if (!i->recipient) { - continue; + /* This is the signer for our new KDMs */ + shared_ptr signer = Config::instance()->signer_chain (); + if (!signer->valid ()) { + throw InvalidSignerError (); } - /* Make an empty KDM */ - dcp::DecryptedKDM kdm ( - dcp::LocalTime (_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), - dcp::LocalTime (_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()), - decrypted.annotation_text().get_value_or (""), - decrypted.content_title_text(), - dcp::LocalTime().as_string() - ); + BOOST_FOREACH (shared_ptr i, _screens->screens()) { - /* Add keys from the DKDM */ - BOOST_FOREACH (dcp::DecryptedKDMKey const & j, decrypted.keys()) { - kdm.add_key (j); - } + if (!i->recipient) { + continue; + } + + dcp::LocalTime begin(_timing->from(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); + dcp::LocalTime end(_timing->until(), i->cinema->utc_offset_hour(), i->cinema->utc_offset_minute()); + + /* Make an empty KDM */ + dcp::DecryptedKDM kdm ( + begin, + end, + decrypted.annotation_text().get_value_or (""), + decrypted.content_title_text(), + dcp::LocalTime().as_string() + ); - /* Encrypt */ - screen_kdms.push_back ( - ScreenKDM ( - i, - kdm.encrypt ( + /* Add keys from the DKDM */ + BOOST_FOREACH (dcp::DecryptedKDMKey const & j, decrypted.keys()) { + kdm.add_key (j); + } + + dcp::EncryptedKDM const encrypted = kdm.encrypt( signer, i->recipient.get(), i->trusted_device_thumbprints(), _output->formulation(), !_output->forensic_mark_video(), _output->forensic_mark_audio() ? boost::optional() : 0 + ); + + dcp::NameFormat::Map name_values; + name_values['c'] = i->cinema->name; + name_values['s'] = i->name; + name_values['f'] = title; + name_values['b'] = begin.date() + " " + begin.time_of_day(true, false); + name_values['e'] = end.date() + " " + end.time_of_day(true, false); + name_values['i'] = encrypted.cpl_id (); + + /* Encrypt */ + kdms.push_back ( + KDMWithMetadataPtr( + new DCPKDMWithMetadata(name_values, i->cinema, encrypted) ) - ) - ); + ); + } + } + + if (kdms.empty()) { + return; } pair, int> result = _output->make ( - screen_kdms, decrypted.content_title_text(), _timing, bind (&DOMFrame::confirm_overwrite, this, _1) + kdms, title, bind (&DOMFrame::confirm_overwrite, this, _1) ); if (result.first) { @@ -379,7 +445,11 @@ private: _output->setup_sensitivity (); wxArrayTreeItemIds sel; _dkdm->GetSelections (sel); + shared_ptr group = dynamic_pointer_cast(selected_dkdm()); + shared_ptr dkdm = dynamic_pointer_cast(selected_dkdm()); _create->Enable (!_screens->screens().empty() && sel.GetCount() > 0); + _remove_dkdm->Enable (sel.GetCount() > 0 && (!group || group->name() != "root")); + _export_dkdm->Enable (sel.GetCount() > 0 && dkdm); } void dkdm_begin_drag (wxTreeEvent& ev) @@ -415,16 +485,53 @@ private: { wxFileDialog* d = new wxFileDialog (this, _("Select DKDM file")); if (d->ShowModal() == wxID_OK) { - shared_ptr new_dkdm; + shared_ptr chain = Config::instance()->decryption_chain(); + DCPOMATIC_ASSERT (chain->key()); + +#ifdef DCPOMATIC_VARIANT_SWAROOP try { - dcp::EncryptedKDM ekdm(dcp::file_to_string (wx_to_std (d->GetPath ()), MAX_KDM_SIZE)); + cxml::Document test_doc; + string const xml_string = dcp::file_to_string (wx_to_std(d->GetPath()), MAX_KDM_SIZE); + test_doc.read_string (xml_string); + if (test_doc.root_name() == "ECinemaSecurityMessage") { + EncryptedECinemaKDM ekdm(xml_string); + /* Decrypt the DKDM to make sure that we can */ + DecryptedECinemaKDM dkdm(ekdm, chain->key().get()); + + shared_ptr new_dkdm(new ECinemaDKDM(ekdm)); + shared_ptr group = dynamic_pointer_cast (selected_dkdm()); + if (!group) { + group = Config::instance()->dkdms(); + } + add_dkdm_model (new_dkdm, group); + add_dkdm_view (new_dkdm); + d->Destroy (); + return; + } + } catch (KDMError& e) { + error_dialog ( + this, "Could not read file as a KDM. Perhaps it is badly formatted, created with the wrong certificate, or not a KDM at all.", + std_to_wx(e.what()) + ); + d->Destroy (); + return; + } catch (dcp::MiscError& e) { + error_dialog ( + this, + _("Could not read file as a KDM. It is much too large. Make sure you are loading a DKDM (XML) file."), + std_to_wx(e.what()) + ); + d->Destroy (); + return; + } +#endif + try { + dcp::EncryptedKDM ekdm(dcp::file_to_string (wx_to_std (d->GetPath ()), MAX_KDM_SIZE)); /* Decrypt the DKDM to make sure that we can */ - shared_ptr chain = Config::instance()->decryption_chain(); - DCPOMATIC_ASSERT (chain->key()); dcp::DecryptedKDM dkdm(ekdm, chain->key().get()); - new_dkdm.reset(new DKDM(ekdm)); + shared_ptr new_dkdm(new DKDM(ekdm)); shared_ptr group = dynamic_pointer_cast (selected_dkdm ()); if (!group) { group = Config::instance()->dkdms (); @@ -538,6 +645,29 @@ private: Config::instance()->changed (); } + void export_dkdm_clicked () + { + shared_ptr removed = selected_dkdm (); + if (!removed) { + return; + } + + shared_ptr dkdm = dynamic_pointer_cast(removed); + if (!dkdm) { + return; + } + + wxFileDialog* d = new wxFileDialog ( + this, _("Select DKDM File"), wxEmptyString, wxEmptyString, wxT("XML files (*.xml)|*.xml"), + wxFD_SAVE | wxFD_OVERWRITE_PROMPT + ); + + if (d->ShowModal() == wxID_OK) { + dkdm->dkdm().as_xml(wx_to_std(d->GetPath())); + } + d->Destroy (); + } + wxPreferencesEditor* _config_dialog; ScreensPanel* _screens; KDMTimingPanel* _timing; @@ -547,6 +677,7 @@ private: wxButton* _add_dkdm; wxButton* _add_dkdm_folder; wxButton* _remove_dkdm; + wxButton* _export_dkdm; wxButton* _create; KDMOutputPanel* _output; JobViewDialog* _job_view;