From fe9d2a290682021cd12a00bf21fa4db3012e2049 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Fri, 29 Jul 2016 15:54:09 +0100 Subject: [PATCH] Basics of custom DCP filename components. --- src/lib/cinema_kdms.cc | 6 +-- src/lib/cinema_kdms.h | 6 +-- src/lib/config.cc | 4 ++ src/lib/config.h | 10 ++++ src/lib/kdm_name_format.h | 4 +- src/lib/name_format.cc | 98 ---------------------------------- src/lib/name_format.h | 78 --------------------------- src/lib/screen_kdm.cc | 2 +- src/lib/screen_kdm.h | 2 +- src/lib/send_kdm_email_job.cc | 4 +- src/lib/send_kdm_email_job.h | 4 +- src/lib/util.cc | 10 +++- src/lib/writer.cc | 2 +- src/lib/wscript | 1 - src/tools/dcpomatic_kdm.cc | 2 +- src/tools/dcpomatic_kdm_cli.cc | 2 +- src/wx/config_dialog.cc | 26 +++++++++ src/wx/kdm_dialog.cc | 2 +- src/wx/kdm_output_panel.cc | 2 +- src/wx/name_format_editor.h | 18 +++++-- 20 files changed, 80 insertions(+), 203 deletions(-) delete mode 100644 src/lib/name_format.cc delete mode 100644 src/lib/name_format.h diff --git a/src/lib/cinema_kdms.cc b/src/lib/cinema_kdms.cc index a91fc1c1e..cbfad4bb3 100644 --- a/src/lib/cinema_kdms.cc +++ b/src/lib/cinema_kdms.cc @@ -40,7 +40,7 @@ using std::runtime_error; using boost::shared_ptr; void -CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, NameFormat::Map name_values) const +CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, dcp::NameFormat::Map name_values) const { int error; struct zip* zip = zip_open (zip_file.string().c_str(), ZIP_CREATE | ZIP_EXCL, &error); @@ -120,7 +120,7 @@ CinemaKDMs::write_zip_files ( list cinema_kdms, boost::filesystem::path directory, KDMNameFormat name_format, - NameFormat::Map name_values + dcp::NameFormat::Map name_values ) { /* No specific screen */ @@ -141,7 +141,7 @@ void CinemaKDMs::email ( list cinema_kdms, KDMNameFormat name_format, - NameFormat::Map name_values, + dcp::NameFormat::Map name_values, string cpl_name, shared_ptr log ) diff --git a/src/lib/cinema_kdms.h b/src/lib/cinema_kdms.h index a9ab4867e..53cf84d66 100644 --- a/src/lib/cinema_kdms.h +++ b/src/lib/cinema_kdms.h @@ -27,7 +27,7 @@ class Log; class CinemaKDMs { public: - void make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, NameFormat::Map name_values) const; + void make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, dcp::NameFormat::Map name_values) const; static std::list collect (std::list kdms); @@ -35,13 +35,13 @@ public: std::list cinema_kdms, boost::filesystem::path directory, KDMNameFormat name_format, - NameFormat::Map name_values + dcp::NameFormat::Map name_values ); static void email ( std::list cinema_kdms, KDMNameFormat name_format, - NameFormat::Map name_values, + dcp::NameFormat::Map name_values, std::string cpl_name, boost::shared_ptr log ); diff --git a/src/lib/config.cc b/src/lib/config.cc index a5a42436b..b456c605c 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -31,6 +31,7 @@ #include "cross.h" #include "raw_convert.h" #include "kdm_name_format.h" +#include #include #include #include @@ -110,6 +111,7 @@ Config::set_defaults () _cinemas_file = path ("cinemas.xml"); _show_hints_before_make_dcp = true; _kdm_filename_format = KDMNameFormat ("KDM %f %c %s"); + _dcp_filename_format = dcp::FilenameFormat ("%t_%i"); _allowed_dcp_frame_rates.clear (); _allowed_dcp_frame_rates.push_back (24); @@ -293,6 +295,7 @@ try _cinemas_file = f.optional_string_child("CinemasFile").get_value_or (path ("cinemas.xml").string ()); _show_hints_before_make_dcp = f.optional_bool_child("ShowHintsBeforeMakeDCP").get_value_or (true); _kdm_filename_format = KDMNameFormat (f.optional_string_child("KDMFilenameFormat").get_value_or ("KDM %f %c %s")); + _dcp_filename_format = dcp::FilenameFormat (f.optional_string_child("DCPFilenameFormat").get_value_or ("%t_%i.mxf")); /* Replace any cinemas from config.xml with those from the configured file */ if (boost::filesystem::exists (_cinemas_file)) { @@ -451,6 +454,7 @@ Config::write_config_xml () const root->add_child("CinemasFile")->add_child_text (_cinemas_file.string()); root->add_child("ShowHintsBeforeMakeDCP")->add_child_text (_show_hints_before_make_dcp ? "1" : "0"); root->add_child("KDMFilenameFormat")->add_child_text (_kdm_filename_format.specification ()); + root->add_child("DCPFilenameFormat")->add_child_text (_dcp_filename_format.specification ()); try { doc.write_to_file_formatted (path("config.xml").string ()); diff --git a/src/lib/config.h b/src/lib/config.h index d89adf491..37a55a695 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -28,6 +28,7 @@ #include "isdcf_metadata.h" #include "kdm_name_format.h" #include "types.h" +#include #include #include #include @@ -271,6 +272,10 @@ public: return _kdm_filename_format; } + dcp::FilenameFormat dcp_filename_format () const { + return _dcp_filename_format; + } + /** @param n New number of local encoding threads */ void set_num_local_encoding_threads (int n) { maybe_set (_num_local_encoding_threads, n); @@ -483,6 +488,10 @@ public: maybe_set (_kdm_filename_format, n); } + void set_dcp_filename_format (dcp::FilenameFormat n) { + maybe_set (_dcp_filename_format, n); + } + void clear_history () { _history.clear (); changed (); @@ -595,6 +604,7 @@ private: boost::filesystem::path _cinemas_file; bool _show_hints_before_make_dcp; KDMNameFormat _kdm_filename_format; + dcp::FilenameFormat _dcp_filename_format; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/kdm_name_format.h b/src/lib/kdm_name_format.h index fad5f7265..1f5a9ab61 100644 --- a/src/lib/kdm_name_format.h +++ b/src/lib/kdm_name_format.h @@ -21,9 +21,9 @@ #ifndef DCPOMATIC_KDM_NAME_FORMAT #define DCPOMATIC_KDM_NAME_FORMAT -#include "name_format.h" +#include -class KDMNameFormat : public NameFormat +class KDMNameFormat : public dcp::NameFormat { public: KDMNameFormat () {} diff --git a/src/lib/name_format.cc b/src/lib/name_format.cc deleted file mode 100644 index 07909c5fb..000000000 --- a/src/lib/name_format.cc +++ /dev/null @@ -1,98 +0,0 @@ -/* - Copyright (C) 2016 Carl Hetherington - - This file is part of DCP-o-matic. - - DCP-o-matic is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DCP-o-matic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DCP-o-matic. If not, see . - -*/ - -#include "name_format.h" -#include -#include - -using std::string; -using std::map; -using boost::optional; - -static char -filter (char c) -{ - if (c == '/' || c == ':') { - c = '-'; - } else if (c == ' ') { - c = '_'; - } - - return c; -} - -static string -filter (string c) -{ - string o; - - for (size_t i = 0; i < c.length(); ++i) { - o += filter (c[i]); - } - - return o; -} - -void -NameFormat::add (string name, char placeholder, string title) -{ - _components.push_back (Component (name, placeholder, title)); -} - -optional -NameFormat::component_by_placeholder (char p) const -{ - BOOST_FOREACH (Component const & i, _components) { - if (i.placeholder == p) { - return i; - } - } - - return optional (); -} - -string -NameFormat::get (Map values) const -{ - string result; - for (size_t i = 0; i < _specification.length(); ++i) { - bool done = false; - if (_specification[i] == '%' && (i < _specification.length() - 1)) { - optional c = component_by_placeholder (_specification[i + 1]); - if (c) { - result += filter (values[c->name]); - ++i; - done = true; - } - } - - if (!done) { - result += filter (_specification[i]); - } - } - - return result; -} - -bool -operator== (NameFormat const & a, NameFormat const & b) -{ - return a.specification() == b.specification(); -} diff --git a/src/lib/name_format.h b/src/lib/name_format.h deleted file mode 100644 index 7e06dc0a8..000000000 --- a/src/lib/name_format.h +++ /dev/null @@ -1,78 +0,0 @@ -/* - Copyright (C) 2016 Carl Hetherington - - This file is part of DCP-o-matic. - - DCP-o-matic is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - DCP-o-matic is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with DCP-o-matic. If not, see . - -*/ - -#ifndef DCPOMATIC_NAME_FORMAT -#define DCPOMATIC_NAME_FORMAT - -#include -#include -#include - -class NameFormat -{ -public: - struct Component - { - Component (std::string name_, char placeholder_, std::string title_) - : name (name_) - , placeholder (placeholder_) - , title (title_) - {} - - std::string name; - char placeholder; - std::string title; - }; - - std::list components () const { - return _components; - } - - std::string specification () const { - return _specification; - } - - void set_specification (std::string specification) { - _specification = specification; - } - - typedef std::map Map; - - std::string get (Map) const; - -protected: - NameFormat () {} - - NameFormat (std::string specification) - : _specification (specification) - {} - - void add (std::string name, char placeholder, std::string title); - -private: - boost::optional component_by_placeholder (char p) const; - - std::list _components; - std::string _specification; -}; - -extern bool operator== (NameFormat const & a, NameFormat const & b); - -#endif diff --git a/src/lib/screen_kdm.cc b/src/lib/screen_kdm.cc index 52590bc55..22081fc81 100644 --- a/src/lib/screen_kdm.cc +++ b/src/lib/screen_kdm.cc @@ -35,7 +35,7 @@ operator== (ScreenKDM const & a, ScreenKDM const & b) } void -ScreenKDM::write_files (list screen_kdms, boost::filesystem::path directory, KDMNameFormat name_format, NameFormat::Map name_values) +ScreenKDM::write_files (list screen_kdms, boost::filesystem::path directory, KDMNameFormat name_format, dcp::NameFormat::Map name_values) { /* Write KDMs to the specified directory */ BOOST_FOREACH (ScreenKDM const & i, screen_kdms) { diff --git a/src/lib/screen_kdm.h b/src/lib/screen_kdm.h index 2e015e63e..d9031f188 100644 --- a/src/lib/screen_kdm.h +++ b/src/lib/screen_kdm.h @@ -38,7 +38,7 @@ public: static void write_files ( std::list screen_kdms, boost::filesystem::path directory, - KDMNameFormat name_format, NameFormat::Map name_values + KDMNameFormat name_format, dcp::NameFormat::Map name_values ); boost::shared_ptr screen; diff --git a/src/lib/send_kdm_email_job.cc b/src/lib/send_kdm_email_job.cc index 4834657ed..3bf1887f4 100644 --- a/src/lib/send_kdm_email_job.cc +++ b/src/lib/send_kdm_email_job.cc @@ -34,7 +34,7 @@ using boost::shared_ptr; SendKDMEmailJob::SendKDMEmailJob ( list cinema_kdms, KDMNameFormat name_format, - NameFormat::Map name_values, + dcp::NameFormat::Map name_values, string cpl_name, shared_ptr log ) @@ -51,7 +51,7 @@ SendKDMEmailJob::SendKDMEmailJob ( string SendKDMEmailJob::name () const { - NameFormat::Map::const_iterator i = _name_values.find ("film_name"); + dcp::NameFormat::Map::const_iterator i = _name_values.find ("film_name"); if (i == _name_values.end() || i->second.empty ()) { return _("Email KDMs"); } diff --git a/src/lib/send_kdm_email_job.h b/src/lib/send_kdm_email_job.h index e16716a66..bfb4d6c52 100644 --- a/src/lib/send_kdm_email_job.h +++ b/src/lib/send_kdm_email_job.h @@ -33,7 +33,7 @@ public: SendKDMEmailJob ( std::list cinema_kdms, KDMNameFormat name_format, - NameFormat::Map name_values, + dcp::NameFormat::Map name_values, std::string cpl_name, boost::shared_ptr log ); @@ -44,7 +44,7 @@ public: private: KDMNameFormat _name_format; - NameFormat::Map _name_values; + dcp::NameFormat::Map _name_values; std::string _cpl_name; std::list _cinema_kdms; boost::shared_ptr _log; diff --git a/src/lib/util.cc b/src/lib/util.cc index 4a0965858..09f32dfda 100644 --- a/src/lib/util.cc +++ b/src/lib/util.cc @@ -619,13 +619,19 @@ split_get_request (string url) string video_asset_filename (shared_ptr asset) { - return "j2c_" + asset->id() + ".mxf"; + dcp::NameFormat::Map values; + values["type"] = "j2c"; + values["id"] = asset->id(); + return Config::instance()->dcp_filename_format().get(values) + ".mxf"; } string audio_asset_filename (shared_ptr asset) { - return "pcm_" + asset->id() + ".mxf"; + dcp::NameFormat::Map values; + values["type"] = "pcm"; + values["id"] = asset->id(); + return Config::instance()->dcp_filename_format().get(values) + ".mxf"; } float diff --git a/src/lib/writer.cc b/src/lib/writer.cc index 1874e68f4..00dfcdcbe 100644 --- a/src/lib/writer.cc +++ b/src/lib/writer.cc @@ -512,7 +512,7 @@ Writer::finish () } } - dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, signer); + dcp.write_xml (_film->interop () ? dcp::INTEROP : dcp::SMPTE, meta, signer, Config::instance()->dcp_filename_format()); LOG_GENERAL ( N_("Wrote %1 FULL, %2 FAKE, %3 REPEAT, %4 pushed to disk"), _full_written, _fake_written, _repeat_written, _pushed_to_disk diff --git a/src/lib/wscript b/src/lib/wscript index 84843992b..6a8945d84 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -99,7 +99,6 @@ sources = """ log_entry.cc magick_image_proxy.cc mid_side_decoder.cc - name_format.cc overlaps.cc player.cc player_subtitles.cc diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 5afcb17a4..01f8ef0a3 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -297,7 +297,7 @@ private: screen_kdms.push_back (ScreenKDM (i, kdm.encrypt (signer, i->recipient.get(), i->trusted_devices, _output->formulation()))); } - NameFormat::Map name_values; + dcp::NameFormat::Map name_values; name_values["film_name"] = decrypted.content_title_text(); name_values["from"] = dcp::LocalTime(_timing->from()).date() + " " + dcp::LocalTime(_timing->from()).time_of_day(); name_values["to"] = dcp::LocalTime(_timing->until()).date() + " " + dcp::LocalTime(_timing->until()).time_of_day(); diff --git a/src/tools/dcpomatic_kdm_cli.cc b/src/tools/dcpomatic_kdm_cli.cc index ad5ee1c7b..38808596e 100644 --- a/src/tools/dcpomatic_kdm_cli.cc +++ b/src/tools/dcpomatic_kdm_cli.cc @@ -284,7 +284,7 @@ int main (int argc, char* argv[]) output = "."; } - NameFormat::Map values; + dcp::NameFormat::Map values; values["film_name"] = film->name(); values["from"] = dcp::LocalTime(valid_from.get()).date() + " " + dcp::LocalTime(valid_from.get()).time_of_day(); values["to"] = dcp::LocalTime(valid_to.get()).date() + " " + dcp::LocalTime(valid_to.get()).time_of_day(); diff --git a/src/wx/config_dialog.cc b/src/wx/config_dialog.cc index 8b7cbdae5..c82956c60 100644 --- a/src/wx/config_dialog.cc +++ b/src/wx/config_dialog.cc @@ -32,6 +32,7 @@ #include "server_dialog.h" #include "make_chain_dialog.h" #include "email_dialog.h" +#include "name_format_editor.h" #include "lib/config.h" #include "lib/ratio.h" #include "lib/filter.h" @@ -1398,6 +1399,24 @@ private: table->Add (_only_servers_encode, 1, wxEXPAND | wxALL); table->AddSpacer (0); + { + int flags = wxALIGN_TOP | wxTOP | wxLEFT; + wxString t = _("DCP filename format"); +#ifdef __WXOSX__ + flags |= wxALIGN_RIGHT; + t += wxT (":"); +#endif + wxStaticText* m = new wxStaticText (_panel, wxID_ANY, t); + table->Add (m, 0, flags, DCPOMATIC_SIZER_Y_GAP); + } + + _dcp_filename_format = new NameFormatEditor (_panel, Config::instance()->dcp_filename_format()); + dcp::NameFormat::Map example; + example["type"] = "j2c"; + example["id"] = "eb1c112c-ca3c-4ae6-9263-c6714ff05d64"; + _dcp_filename_format->set_example (example); + table->Add (_dcp_filename_format->panel(), 1, wxEXPAND | wxALL); + #ifdef __WXOSX__ wxStaticText* m = new wxStaticText (_panel, wxID_ANY, _("Log:")); table->Add (m, 0, wxALIGN_TOP | wxLEFT | wxRIGHT | wxEXPAND | wxALL | wxALIGN_RIGHT, 6); @@ -1436,6 +1455,7 @@ private: _maximum_j2k_bandwidth->Bind (wxEVT_COMMAND_SPINCTRL_UPDATED, boost::bind (&AdvancedPage::maximum_j2k_bandwidth_changed, this)); _allow_any_dcp_frame_rate->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::allow_any_dcp_frame_rate_changed, this)); _only_servers_encode->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::only_servers_encode_changed, this)); + _dcp_filename_format->Changed.connect (boost::bind (&AdvancedPage::dcp_filename_format_changed, this)); _log_general->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this)); _log_warning->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this)); _log_error->Bind (wxEVT_COMMAND_CHECKBOX_CLICKED, boost::bind (&AdvancedPage::log_changed, this)); @@ -1482,6 +1502,11 @@ private: Config::instance()->set_only_servers_encode (_only_servers_encode->GetValue ()); } + void dcp_filename_format_changed () + { + Config::instance()->set_dcp_filename_format (_dcp_filename_format->get ()); + } + void log_changed () { int types = 0; @@ -1519,6 +1544,7 @@ private: wxSpinCtrl* _maximum_j2k_bandwidth; wxCheckBox* _allow_any_dcp_frame_rate; wxCheckBox* _only_servers_encode; + NameFormatEditor* _dcp_filename_format; wxCheckBox* _log_general; wxCheckBox* _log_warning; wxCheckBox* _log_error; diff --git a/src/wx/kdm_dialog.cc b/src/wx/kdm_dialog.cc index 253050ddf..cd018686e 100644 --- a/src/wx/kdm_dialog.cc +++ b/src/wx/kdm_dialog.cc @@ -133,7 +133,7 @@ KDMDialog::make_clicked () _screens->screens(), _cpl->cpl(), _timing->from(), _timing->until(), _output->formulation() ); - NameFormat::Map name_values; + dcp::NameFormat::Map name_values; name_values["film_name"] = film->name(); name_values["from"] = dcp::LocalTime(_timing->from()).date() + " " + dcp::LocalTime(_timing->from()).time_of_day(); name_values["to"] = dcp::LocalTime(_timing->until()).date() + " " + dcp::LocalTime(_timing->until()).time_of_day(); diff --git a/src/wx/kdm_output_panel.cc b/src/wx/kdm_output_panel.cc index e2510c929..1d9e56f4b 100644 --- a/src/wx/kdm_output_panel.cc +++ b/src/wx/kdm_output_panel.cc @@ -57,7 +57,7 @@ KDMOutputPanel::KDMOutputPanel (wxWindow* parent, bool interop) } _filename_format = new NameFormatEditor (this, Config::instance()->kdm_filename_format()); - NameFormat::Map ex; + dcp::NameFormat::Map ex; ex["film_name"] = "Bambi"; ex["cinema"] = "Lumière"; ex["screen"] = "Screen 1"; diff --git a/src/wx/name_format_editor.h b/src/wx/name_format_editor.h index ab4787f64..1ca4c0b71 100644 --- a/src/wx/name_format_editor.h +++ b/src/wx/name_format_editor.h @@ -21,8 +21,8 @@ #ifndef DCPOMATIC_NAME_FORMAT_EDITOR_H #define DCPOMATIC_NAME_FORMAT_EDITOR_H -#include "lib/name_format.h" #include "lib/compose.hpp" +#include #include #include @@ -41,7 +41,7 @@ public: _sizer->Add (_example, 0, wxBOTTOM, DCPOMATIC_SIZER_Y_GAP); _panel->SetSizer (_sizer); - BOOST_FOREACH (NameFormat::Component c, name.components ()) { + BOOST_FOREACH (dcp::NameFormat::Component c, name.components ()) { wxStaticText* t = new wxStaticText (_panel, wxID_ANY, std_to_wx (String::compose ("%%%1 %2", c.placeholder, c.title))); _sizer->Add (t); wxFont font = t->GetFont(); @@ -52,7 +52,7 @@ public: } _specification->SetValue (std_to_wx (_name.specification ())); - _specification->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&NameFormatEditor::update_example, this)); + _specification->Bind (wxEVT_COMMAND_TEXT_UPDATED, boost::bind (&NameFormatEditor::changed, this)); update_example (); } @@ -62,7 +62,7 @@ public: return _panel; } - void set_example (NameFormat::Map v) { + void set_example (dcp::NameFormat::Map v) { _example_values = v; update_example (); } @@ -71,8 +71,16 @@ public: return _name; } + boost::signals2::signal Changed; + private: + void changed () + { + update_example (); + Changed (); + } + virtual void update_example () { _name.set_specification (wx_to_std (_specification->GetValue ())); @@ -95,7 +103,7 @@ private: wxTextCtrl* _specification; T _name; - NameFormat::Map _example_values; + dcp::NameFormat::Map _example_values; }; #endif -- 2.30.2