diff options
| author | Carl Hetherington <cth@carlh.net> | 2016-07-29 09:57:58 +0100 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2016-07-29 09:57:58 +0100 |
| commit | 736b3a068ba5a402b541d32f270669e6e1a4e5c4 (patch) | |
| tree | 2185f71bde7283683161bd3a557f13b7a610e967 /src/lib | |
| parent | 71be005818ddaa59cdcca2fa5fb3210d8ea7ae4f (diff) | |
Allow configuration of KDM filename format.
Diffstat (limited to 'src/lib')
| -rw-r--r-- | src/lib/cinema_kdms.cc | 61 | ||||
| -rw-r--r-- | src/lib/cinema_kdms.h | 18 | ||||
| -rw-r--r-- | src/lib/config.cc | 4 | ||||
| -rw-r--r-- | src/lib/config.h | 12 | ||||
| -rw-r--r-- | src/lib/kdm_name_format.cc | 33 | ||||
| -rw-r--r-- | src/lib/kdm_name_format.h | 33 | ||||
| -rw-r--r-- | src/lib/name_format.cc | 98 | ||||
| -rw-r--r-- | src/lib/name_format.h | 78 | ||||
| -rw-r--r-- | src/lib/screen_kdm.cc | 12 | ||||
| -rw-r--r-- | src/lib/screen_kdm.h | 8 | ||||
| -rw-r--r-- | src/lib/send_kdm_email_job.cc | 19 | ||||
| -rw-r--r-- | src/lib/send_kdm_email_job.h | 13 | ||||
| -rw-r--r-- | src/lib/wscript | 2 |
13 files changed, 337 insertions, 54 deletions
diff --git a/src/lib/cinema_kdms.cc b/src/lib/cinema_kdms.cc index f76c96283..a91fc1c1e 100644 --- a/src/lib/cinema_kdms.cc +++ b/src/lib/cinema_kdms.cc @@ -27,6 +27,7 @@ #include "emailer.h" #include "compose.hpp" #include "log.h" +#include "kdm_name_format.h" #include <zip.h> #include <boost/foreach.hpp> @@ -39,7 +40,7 @@ using std::runtime_error; using boost::shared_ptr; void -CinemaKDMs::make_zip_file (string film_name, boost::filesystem::path zip_file) const +CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, NameFormat::Map name_values) const { int error; struct zip* zip = zip_open (zip_file.string().c_str(), ZIP_CREATE | ZIP_EXCL, &error); @@ -52,6 +53,8 @@ CinemaKDMs::make_zip_file (string film_name, boost::filesystem::path zip_file) c list<shared_ptr<string> > kdm_strings; + name_values["cinema"] = cinema->name; + BOOST_FOREACH (ScreenKDM const & i, screen_kdms) { shared_ptr<string> kdm (new string (i.kdm.as_xml ())); kdm_strings.push_back (kdm); @@ -61,7 +64,9 @@ CinemaKDMs::make_zip_file (string film_name, boost::filesystem::path zip_file) c throw runtime_error ("could not create ZIP source"); } - if (zip_add (zip, i.filename(film_name).c_str(), source) == -1) { + name_values["screen"] = i.screen->name; + string const name = name_format.get(name_values) + ".xml"; + if (zip_add (zip, name.c_str(), source) == -1) { throw runtime_error ("failed to add KDM to ZIP archive"); } } @@ -71,6 +76,9 @@ CinemaKDMs::make_zip_file (string film_name, boost::filesystem::path zip_file) c } } +/** Collect a list of ScreenKDMs into a list of CinemaKDMs so that each + * CinemaKDM contains the KDMs for its cinema. + */ list<CinemaKDMs> CinemaKDMs::collect (list<ScreenKDM> screen_kdms) { @@ -106,21 +114,36 @@ CinemaKDMs::collect (list<ScreenKDM> screen_kdms) return cinema_kdms; } +/** Write one ZIP file per cinema into a directory */ void -CinemaKDMs::write_zip_files (string film_name, list<CinemaKDMs> cinema_kdms, boost::filesystem::path directory) +CinemaKDMs::write_zip_files ( + list<CinemaKDMs> cinema_kdms, + boost::filesystem::path directory, + KDMNameFormat name_format, + NameFormat::Map name_values + ) { + /* No specific screen */ + name_values["screen"] = ""; + BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) { boost::filesystem::path path = directory; - path /= tidy_for_filename (i.cinema->name) + ".zip"; - i.make_zip_file (film_name, path); + name_values["cinema"] = i.cinema->name; + path /= name_format.get(name_values) + ".zip"; + i.make_zip_file (path, name_format, name_values); } } -/** @param log Log to write email session transcript to, or 0 */ -/* XXX: should probably get from/to from the KDMs themselves */ +/** Email one ZIP file per cinema to the cinema. + * @param log Log to write email session transcript to, or 0. + */ void CinemaKDMs::email ( - string film_name, string cpl_name, list<CinemaKDMs> cinema_kdms, dcp::LocalTime from, dcp::LocalTime to, shared_ptr<Log> log + list<CinemaKDMs> cinema_kdms, + KDMNameFormat name_format, + NameFormat::Map name_values, + string cpl_name, + shared_ptr<Log> log ) { Config* config = Config::instance (); @@ -129,26 +152,27 @@ CinemaKDMs::email ( throw NetworkError (_("No mail server configured in preferences")); } + /* No specific screen */ + name_values["screen"] = ""; + BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) { + name_values["cinema"] = i.cinema->name; + boost::filesystem::path zip_file = boost::filesystem::temp_directory_path (); zip_file /= boost::filesystem::unique_path().string() + ".zip"; - i.make_zip_file (film_name, zip_file); + i.make_zip_file (zip_file, name_format, name_values); string subject = config->kdm_subject(); - locked_stringstream start; - start << from.date() << " " << from.time_of_day(); - locked_stringstream end; - end << to.date() << " " << to.time_of_day(); boost::algorithm::replace_all (subject, "$CPL_NAME", cpl_name); - boost::algorithm::replace_all (subject, "$START_TIME", start.str ()); - boost::algorithm::replace_all (subject, "$END_TIME", end.str ()); + boost::algorithm::replace_all (subject, "$START_TIME", name_values["from"]); + boost::algorithm::replace_all (subject, "$END_TIME", name_values["to"]); boost::algorithm::replace_all (subject, "$CINEMA_NAME", i.cinema->name); string body = config->kdm_email().c_str(); boost::algorithm::replace_all (body, "$CPL_NAME", cpl_name); - boost::algorithm::replace_all (body, "$START_TIME", start.str ()); - boost::algorithm::replace_all (body, "$END_TIME", end.str ()); + boost::algorithm::replace_all (body, "$START_TIME", name_values["from"]); + boost::algorithm::replace_all (body, "$END_TIME", name_values["to"]); boost::algorithm::replace_all (body, "$CINEMA_NAME", i.cinema->name); locked_stringstream screens; @@ -166,8 +190,7 @@ CinemaKDMs::email ( email.add_bcc (config->kdm_bcc ()); } - string const name = tidy_for_filename(i.cinema->name) + "_" + tidy_for_filename(film_name) + ".zip"; - email.add_attachment (zip_file, name, "application/zip"); + email.add_attachment (zip_file, name_format.get(name_values) + ".zip", "application/zip"); Config* c = Config::instance (); diff --git a/src/lib/cinema_kdms.h b/src/lib/cinema_kdms.h index e7efcb985..a9ab4867e 100644 --- a/src/lib/cinema_kdms.h +++ b/src/lib/cinema_kdms.h @@ -27,16 +27,22 @@ class Log; class CinemaKDMs { public: - void make_zip_file (std::string film_name, boost::filesystem::path zip_file) const; + void make_zip_file (boost::filesystem::path zip_file, KDMNameFormat name_format, NameFormat::Map name_values) const; static std::list<CinemaKDMs> collect (std::list<ScreenKDM> kdms); - static void write_zip_files (std::string film_name, std::list<CinemaKDMs> cinema_kdms, boost::filesystem::path directory); + + static void write_zip_files ( + std::list<CinemaKDMs> cinema_kdms, + boost::filesystem::path directory, + KDMNameFormat name_format, + NameFormat::Map name_values + ); + static void email ( - std::string film_name, - std::string cpl_name, std::list<CinemaKDMs> cinema_kdms, - dcp::LocalTime from, - dcp::LocalTime to, + KDMNameFormat name_format, + NameFormat::Map name_values, + std::string cpl_name, boost::shared_ptr<Log> log ); diff --git a/src/lib/config.cc b/src/lib/config.cc index c6c6cac8b..a5a42436b 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -30,6 +30,7 @@ #include "util.h" #include "cross.h" #include "raw_convert.h" +#include "kdm_name_format.h" #include <dcp/colour_matrix.h> #include <dcp/certificate_chain.h> #include <libcxml/cxml.h> @@ -108,6 +109,7 @@ Config::set_defaults () #endif _cinemas_file = path ("cinemas.xml"); _show_hints_before_make_dcp = true; + _kdm_filename_format = KDMNameFormat ("KDM %f %c %s"); _allowed_dcp_frame_rates.clear (); _allowed_dcp_frame_rates.push_back (24); @@ -290,6 +292,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")); /* Replace any cinemas from config.xml with those from the configured file */ if (boost::filesystem::exists (_cinemas_file)) { @@ -447,6 +450,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 ()); try { doc.write_to_file_formatted (path("config.xml").string ()); diff --git a/src/lib/config.h b/src/lib/config.h index 61c6bfa69..d89adf491 100644 --- a/src/lib/config.h +++ b/src/lib/config.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net> + Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net> This file is part of DCP-o-matic. @@ -26,6 +26,7 @@ #define DCPOMATIC_CONFIG_H #include "isdcf_metadata.h" +#include "kdm_name_format.h" #include "types.h" #include <dcp/certificate_chain.h> #include <dcp/encrypted_kdm.h> @@ -266,6 +267,10 @@ public: return _show_hints_before_make_dcp; } + KDMNameFormat kdm_filename_format () const { + return _kdm_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); @@ -474,6 +479,10 @@ public: maybe_set (_show_hints_before_make_dcp, s); } + void set_kdm_filename_format (KDMNameFormat n) { + maybe_set (_kdm_filename_format, n); + } + void clear_history () { _history.clear (); changed (); @@ -585,6 +594,7 @@ private: std::vector<dcp::EncryptedKDM> _dkdms; boost::filesystem::path _cinemas_file; bool _show_hints_before_make_dcp; + KDMNameFormat _kdm_filename_format; /** Singleton instance, or 0 */ static Config* _instance; diff --git a/src/lib/kdm_name_format.cc b/src/lib/kdm_name_format.cc new file mode 100644 index 000000000..fe4a3fc62 --- /dev/null +++ b/src/lib/kdm_name_format.cc @@ -0,0 +1,33 @@ +/* + Copyright (C) 2016 Carl Hetherington <cth@carlh.net> + + 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 <http://www.gnu.org/licenses/>. + +*/ + +#include "kdm_name_format.h" + +using std::string; + +KDMNameFormat::KDMNameFormat (string specification) + : NameFormat (specification) +{ + add ("film_name", 'f', "film name"); + add ("cinema", 'c', "cinema"); + add ("screen", 's', "screen"); + add ("from", 'b', "from date/time"); + add ("to", 'e', "to date/time"); +} diff --git a/src/lib/kdm_name_format.h b/src/lib/kdm_name_format.h new file mode 100644 index 000000000..fad5f7265 --- /dev/null +++ b/src/lib/kdm_name_format.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2016 Carl Hetherington <cth@carlh.net> + + 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef DCPOMATIC_KDM_NAME_FORMAT +#define DCPOMATIC_KDM_NAME_FORMAT + +#include "name_format.h" + +class KDMNameFormat : public NameFormat +{ +public: + KDMNameFormat () {} + KDMNameFormat (std::string specification); +}; + +#endif diff --git a/src/lib/name_format.cc b/src/lib/name_format.cc new file mode 100644 index 000000000..07909c5fb --- /dev/null +++ b/src/lib/name_format.cc @@ -0,0 +1,98 @@ +/* + Copyright (C) 2016 Carl Hetherington <cth@carlh.net> + + 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 <http://www.gnu.org/licenses/>. + +*/ + +#include "name_format.h" +#include <boost/optional.hpp> +#include <boost/foreach.hpp> + +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> +NameFormat::component_by_placeholder (char p) const +{ + BOOST_FOREACH (Component const & i, _components) { + if (i.placeholder == p) { + return i; + } + } + + return optional<Component> (); +} + +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<Component> 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 new file mode 100644 index 000000000..7e06dc0a8 --- /dev/null +++ b/src/lib/name_format.h @@ -0,0 +1,78 @@ +/* + Copyright (C) 2016 Carl Hetherington <cth@carlh.net> + + 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 <http://www.gnu.org/licenses/>. + +*/ + +#ifndef DCPOMATIC_NAME_FORMAT +#define DCPOMATIC_NAME_FORMAT + +#include <boost/optional.hpp> +#include <map> +#include <list> + +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<Component> components () const { + return _components; + } + + std::string specification () const { + return _specification; + } + + void set_specification (std::string specification) { + _specification = specification; + } + + typedef std::map<std::string, std::string> 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<NameFormat::Component> component_by_placeholder (char p) const; + + std::list<Component> _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 5cdf1c77b..52590bc55 100644 --- a/src/lib/screen_kdm.cc +++ b/src/lib/screen_kdm.cc @@ -34,18 +34,14 @@ operator== (ScreenKDM const & a, ScreenKDM const & b) return a.screen == b.screen && a.kdm == b.kdm; } -string -ScreenKDM::filename (string film_name) const -{ - return tidy_for_filename (film_name) + "_" + tidy_for_filename (screen->cinema->name) + "_" + tidy_for_filename (screen->name) + ".kdm.xml"; -} - void -ScreenKDM::write_files (string film_name, list<ScreenKDM> screen_kdms, boost::filesystem::path directory) +ScreenKDM::write_files (list<ScreenKDM> screen_kdms, boost::filesystem::path directory, KDMNameFormat name_format, NameFormat::Map name_values) { /* Write KDMs to the specified directory */ BOOST_FOREACH (ScreenKDM const & i, screen_kdms) { - boost::filesystem::path out = directory / i.filename(film_name); + name_values["cinema"] = i.screen->cinema->name; + name_values["screen"] = i.screen->name; + boost::filesystem::path out = directory / (name_format.get(name_values) + ".xml"); i.kdm.as_xml (out); } } diff --git a/src/lib/screen_kdm.h b/src/lib/screen_kdm.h index 7ec8e9cd9..2e015e63e 100644 --- a/src/lib/screen_kdm.h +++ b/src/lib/screen_kdm.h @@ -21,6 +21,7 @@ #ifndef DCPOMATIC_SCREEN_KDM_H #define DCPOMATIC_SCREEN_KDM_H +#include "kdm_name_format.h" #include <dcp/encrypted_kdm.h> #include <boost/shared_ptr.hpp> @@ -35,9 +36,10 @@ public: , kdm (k) {} - std::string filename (std::string film_name) const; - - static void write_files (std::string film_name, std::list<ScreenKDM> screen_kdms, boost::filesystem::path directory); + static void write_files ( + std::list<ScreenKDM> screen_kdms, boost::filesystem::path directory, + KDMNameFormat name_format, NameFormat::Map name_values + ); boost::shared_ptr<Screen> screen; dcp::EncryptedKDM kdm; diff --git a/src/lib/send_kdm_email_job.cc b/src/lib/send_kdm_email_job.cc index 82fb55d80..4834657ed 100644 --- a/src/lib/send_kdm_email_job.cc +++ b/src/lib/send_kdm_email_job.cc @@ -32,18 +32,16 @@ using boost::shared_ptr; /** @param log Log to write to, or 0 */ SendKDMEmailJob::SendKDMEmailJob ( - string film_name, - string cpl_name, - boost::posix_time::ptime from, - boost::posix_time::ptime to, list<CinemaKDMs> cinema_kdms, + KDMNameFormat name_format, + NameFormat::Map name_values, + string cpl_name, shared_ptr<Log> log ) : Job (shared_ptr<Film>()) - , _film_name (film_name) + , _name_format (name_format) + , _name_values (name_values) , _cpl_name (cpl_name) - , _from (from) - , _to (to) , _cinema_kdms (cinema_kdms) , _log (log) { @@ -53,11 +51,12 @@ SendKDMEmailJob::SendKDMEmailJob ( string SendKDMEmailJob::name () const { - if (_film_name.empty ()) { + NameFormat::Map::const_iterator i = _name_values.find ("film_name"); + if (i == _name_values.end() || i->second.empty ()) { return _("Email KDMs"); } - return String::compose (_("Email KDMs for %1"), _film_name); + return String::compose (_("Email KDMs for %1"), i->second); } string @@ -70,7 +69,7 @@ void SendKDMEmailJob::run () { set_progress_unknown (); - CinemaKDMs::email (_film_name, _cpl_name, _cinema_kdms, dcp::LocalTime (_from), dcp::LocalTime (_to), _log); + CinemaKDMs::email (_cinema_kdms, _name_format, _name_values, _cpl_name, _log); set_progress (1); set_state (FINISHED_OK); } diff --git a/src/lib/send_kdm_email_job.h b/src/lib/send_kdm_email_job.h index cb968301f..e16716a66 100644 --- a/src/lib/send_kdm_email_job.h +++ b/src/lib/send_kdm_email_job.h @@ -19,6 +19,7 @@ */ #include "job.h" +#include "kdm_name_format.h" #include <dcp/types.h> #include <boost/filesystem.hpp> @@ -30,11 +31,10 @@ class SendKDMEmailJob : public Job { public: SendKDMEmailJob ( - std::string film_name, - std::string cpl_name, - boost::posix_time::ptime from, - boost::posix_time::ptime to, std::list<CinemaKDMs> cinema_kdms, + KDMNameFormat name_format, + NameFormat::Map name_values, + std::string cpl_name, boost::shared_ptr<Log> log ); @@ -43,10 +43,9 @@ public: void run (); private: - std::string _film_name; + KDMNameFormat _name_format; + NameFormat::Map _name_values; std::string _cpl_name; - boost::posix_time::ptime _from; - boost::posix_time::ptime _to; std::list<CinemaKDMs> _cinema_kdms; boost::shared_ptr<Log> _log; }; diff --git a/src/lib/wscript b/src/lib/wscript index 9883f31d6..84843992b 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -94,10 +94,12 @@ sources = """ job.cc job_manager.cc json_server.cc + kdm_name_format.cc log.cc log_entry.cc magick_image_proxy.cc mid_side_decoder.cc + name_format.cc overlaps.cc player.cc player_subtitles.cc |
