diff options
| author | Carl Hetherington <cth@carlh.net> | 2025-06-21 13:25:20 +0200 |
|---|---|---|
| committer | Carl Hetherington <cth@carlh.net> | 2025-07-04 23:02:26 +0200 |
| commit | de8cd4118d57591804ccd63f979aa9e495df9c93 (patch) | |
| tree | 82bd16a3a8cb44d34a21cd51581a1933a819018c | |
| parent | 1650465106b7c20a7cc9ae5eec1cf9bf406c1dcf (diff) | |
Go back to the old way of handling KDM timing.
Once again the KDM gets its timezone from the cinema.
| -rw-r--r-- | src/lib/kdm_cli.cc | 61 | ||||
| -rw-r--r-- | src/lib/screen.cc | 15 | ||||
| -rw-r--r-- | src/lib/screen.h | 4 | ||||
| -rw-r--r-- | src/tools/dcpomatic_kdm.cc | 1 | ||||
| -rw-r--r-- | src/wx/kdm_dialog.cc | 1 | ||||
| -rw-r--r-- | src/wx/kdm_timing_panel.cc | 73 | ||||
| -rw-r--r-- | src/wx/kdm_timing_panel.h | 15 | ||||
| -rw-r--r-- | test/kdm_cli_test.cc | 2 | ||||
| -rw-r--r-- | test/kdm_naming_test.cc | 14 |
9 files changed, 64 insertions, 122 deletions
diff --git a/src/lib/kdm_cli.cc b/src/lib/kdm_cli.cc index 4c5eb46d3..50bf9ea51 100644 --- a/src/lib/kdm_cli.cc +++ b/src/lib/kdm_cli.cc @@ -73,8 +73,8 @@ help(std::function<void (string)> out) out(" -o, --output <path> output file or directory"); out(" -K, --filename-format <format> filename format for KDMs"); out(" -Z, --container-name-format <format> filename format for ZIP containers"); - out(" -f, --valid-from <time> valid from time (e.g. \"2013-09-28T01:41:51+04:00\", \"2018-01-01T12:00:30\") or \"now\""); - out(" -t, --valid-to <time> valid to time (e.g. \"2014-09-28T01:41:51\")"); + out(" -f, --valid-from <time> valid from time (in local time zone of the cinema) (e.g. \"2013-09-28 01:41:51\") or \"now\""); + out(" -t, --valid-to <time> valid to time (in local time zone of the cinema) (e.g. \"2014-09-28T01:41:51\")"); out(" -d, --valid-duration <duration> valid duration (e.g. \"1 day\", \"4 hours\", \"2 weeks\")"); out(" -F, --formulation <formulation> modified-transitional-1, multiple-modified-transitional-1, dci-any or dci-specific [default modified-transitional-1]"); out(" -p, --disable-forensic-marking-picture disable forensic marking of pictures essences"); @@ -110,6 +110,17 @@ public: }; +static boost::posix_time::ptime +time_from_string(string t) +{ + if (t == "now") { + return boost::posix_time::second_clock::local_time(); + } + + return boost::posix_time::time_from_string(t); +} + + static boost::posix_time::time_duration duration_from_string(string d) { @@ -204,8 +215,8 @@ from_film( boost::filesystem::path output, dcp::NameFormat container_name_format, dcp::NameFormat filename_format, - dcp::LocalTime valid_from, - dcp::LocalTime valid_to, + boost::posix_time::ptime valid_from, + boost::posix_time::ptime valid_to, dcp::Formulation formulation, bool disable_forensic_marking_picture, optional<int> disable_forensic_marking_audio, @@ -365,8 +376,8 @@ from_dkdm( boost::filesystem::path output, dcp::NameFormat container_name_format, dcp::NameFormat filename_format, - dcp::LocalTime valid_from, - dcp::LocalTime valid_to, + boost::posix_time::ptime valid_from, + boost::posix_time::ptime valid_to, dcp::Formulation formulation, bool disable_forensic_marking_picture, optional<int> disable_forensic_marking_audio, @@ -384,12 +395,15 @@ from_dkdm( continue; } + dcp::LocalTime begin(valid_from, screen_details.cinema.utc_offset); + dcp::LocalTime end(valid_to, screen_details.cinema.utc_offset); + auto const kdm = kdm_from_dkdm( dkdm, screen_details.screen.recipient().get(), screen_details.screen.trusted_device_thumbprints(), - valid_from, - valid_to, + begin, + end, formulation, disable_forensic_marking_picture, disable_forensic_marking_audio @@ -399,8 +413,8 @@ from_dkdm( name_values['c'] = screen_details.cinema.name; name_values['s'] = screen_details.screen.name; name_values['f'] = kdm.content_title_text(); - name_values['b'] = valid_from.date() + " " + valid_from.time_of_day(true, false); - name_values['e'] = valid_to.date() + " " + valid_to.time_of_day(true, false); + 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.cpl_id(); kdms.push_back(make_shared<KDMWithMetadata>(name_values, screen_details.cinema_id, screen_details.cinema.emails, kdm)); @@ -437,22 +451,6 @@ dump_dkdm_group(shared_ptr<DKDMGroup> group, int indent, std::function<void (str } -static -dcp::LocalTime -time_from_string(string time) -{ - if (time == "now") { - return {}; - } - - if (time.length() > 10 && time[10] == ' ') { - time[10] = 'T'; - } - - return dcp::LocalTime(time); -} - - void dump_decryption_certificate(std::function<void (string)> out) { @@ -482,8 +480,8 @@ try /* trusted devices that we will use to make up a temporary cinema and screen */ vector<TrustedDevice> trusted_devices; optional<dcp::EncryptedKDM> dkdm; - optional<dcp::LocalTime> valid_from; - optional<dcp::LocalTime> valid_to; + optional<boost::posix_time::ptime> valid_from; + optional<boost::posix_time::ptime> valid_to; bool zip = false; string command = "create"; optional<string> duration_string; @@ -547,7 +545,7 @@ try valid_from = time_from_string(optarg); break; case 't': - valid_to = dcp::LocalTime(optarg); + valid_to = time_from_string(optarg); break; case 'd': duration_string = optarg; @@ -709,12 +707,11 @@ try } if (duration_string) { - valid_to = valid_from.get(); - valid_to->add(duration_from_string(*duration_string)); + valid_to = valid_from.get() + duration_from_string(*duration_string); } if (verbose) { - out(String::compose("Making KDMs valid from %1 to %2", valid_from->as_string(), valid_to->as_string())); + out(String::compose("Making KDMs valid from %1 to %2", boost::posix_time::to_simple_string(valid_from.get()), boost::posix_time::to_simple_string(valid_to.get()))); } string const thing = argv[optind]; diff --git a/src/lib/screen.cc b/src/lib/screen.cc index 304fb52f3..57e792672 100644 --- a/src/lib/screen.cc +++ b/src/lib/screen.cc @@ -57,8 +57,8 @@ kdm_for_screen ( CinemaID cinema_id, Cinema const& cinema, Screen const& screen, - dcp::LocalTime valid_from, - dcp::LocalTime valid_to, + boost::posix_time::ptime valid_from, + boost::posix_time::ptime valid_to, dcp::Formulation formulation, bool disable_forensic_marking_picture, optional<int> disable_forensic_marking_audio, @@ -69,14 +69,17 @@ kdm_for_screen ( return {}; } - period_checks.push_back(check_kdm_and_certificate_validity_periods(cinema.name, screen.name, screen.recipient().get(), valid_from, valid_to)); + dcp::LocalTime const begin(valid_from, cinema.utc_offset); + dcp::LocalTime const end (valid_to, cinema.utc_offset); + + period_checks.push_back(check_kdm_and_certificate_validity_periods(cinema.name, screen.name, screen.recipient().get(), begin, end)); auto signer = Config::instance()->signer_chain(); if (!signer->valid()) { throw InvalidSignerError(); } - auto kdm = make_kdm(valid_from, valid_to).encrypt( + auto kdm = make_kdm(begin, end).encrypt( signer, screen.recipient().get(), screen.trusted_device_thumbprints(), formulation, disable_forensic_marking_picture, disable_forensic_marking_audio ); @@ -84,8 +87,8 @@ kdm_for_screen ( name_values['c'] = cinema.name; name_values['s'] = screen.name; name_values['f'] = kdm.content_title_text(); - name_values['b'] = valid_from.date() + " " + valid_from.time_of_day(true, false); - name_values['e'] = valid_to.date() + " " + valid_to.time_of_day(true, false); + 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.cpl_id(); return make_shared<KDMWithMetadata>(name_values, cinema_id, cinema.emails, kdm); diff --git a/src/lib/screen.h b/src/lib/screen.h index 326bc9403..d870f7ab3 100644 --- a/src/lib/screen.h +++ b/src/lib/screen.h @@ -88,8 +88,8 @@ kdm_for_screen ( CinemaID cinema_id, Cinema const& cinema, dcpomatic::Screen const& screen, - dcp::LocalTime valid_from, - dcp::LocalTime valid_to, + boost::posix_time::ptime valid_from, + boost::posix_time::ptime valid_to, dcp::Formulation formulation, bool disable_forensic_marking_picture, boost::optional<int> disable_forensic_marking_audio, diff --git a/src/tools/dcpomatic_kdm.cc b/src/tools/dcpomatic_kdm.cc index 843684103..d596f8ca2 100644 --- a/src/tools/dcpomatic_kdm.cc +++ b/src/tools/dcpomatic_kdm.cc @@ -835,7 +835,6 @@ private: void screens_changed() { - _timing->suggest_utc_offset(_screens->best_utc_offset()); setup_sensitivity(); } diff --git a/src/wx/kdm_dialog.cc b/src/wx/kdm_dialog.cc index f96c89c98..c2dce905f 100644 --- a/src/wx/kdm_dialog.cc +++ b/src/wx/kdm_dialog.cc @@ -143,7 +143,6 @@ KDMDialog::KDMDialog (wxWindow* parent, shared_ptr<const Film> film) void KDMDialog::screens_changed() { - _timing->suggest_utc_offset(_screens->best_utc_offset()); setup_sensitivity(); } diff --git a/src/wx/kdm_timing_panel.cc b/src/wx/kdm_timing_panel.cc index 03267102f..6c365e114 100644 --- a/src/wx/kdm_timing_panel.cc +++ b/src/wx/kdm_timing_panel.cc @@ -25,7 +25,6 @@ #include "time_picker.h" #include "wx_util.h" #include "lib/config.h" -#include <dcp/utc_offset.h> #include <dcp/warnings.h> LIBDCP_DISABLE_WARNINGS #include <wx/datectrl.h> @@ -97,10 +96,6 @@ KDMTimingPanel::KDMTimingPanel (wxWindow* parent) table->Add (_until_time, 0, wxALIGN_CENTER_VERTICAL); - add_label_to_sizer(table, this, _("UTC offset (time zone)"), true, 1, wxALIGN_CENTRE_VERTICAL); - _utc_offset = new Choice(this); - table->Add(_utc_offset, 0, wxALIGN_CENTRE_VERTICAL | wxLEFT, DCPOMATIC_SIZER_X_GAP); - overall_sizer->Add (table, 0, wxTOP, DCPOMATIC_SIZER_GAP); _warning = new StaticText(this, {}); @@ -111,13 +106,6 @@ KDMTimingPanel::KDMTimingPanel (wxWindow* parent) _warning->SetForegroundColour (wxColour (255, 0, 0)); _warning->SetFont(font); - /* Default to UTC */ - auto const sel = get_offsets(_offsets); - for (auto const& offset: _offsets) { - _utc_offset->add_entry(offset.name); - } - _utc_offset->set(sel); - /* I said I've been to the year 3000. Not much has changed but they live underwater. And your In-in-in-interop DCP is pretty fine. */ @@ -128,38 +116,32 @@ KDMTimingPanel::KDMTimingPanel (wxWindow* parent) _until_date->Bind (wxEVT_DATE_CHANGED, bind (&KDMTimingPanel::changed, this)); _from_time->Changed.connect (bind (&KDMTimingPanel::changed, this)); _until_time->Changed.connect (bind (&KDMTimingPanel::changed, this)); - _utc_offset->bind(&KDMTimingPanel::utc_offset_changed, this); SetSizer (overall_sizer); } -dcp::LocalTime +boost::posix_time::ptime KDMTimingPanel::from () const { - return local_time(_from_date, _from_time, utc_offset()); + return posix_time(_from_date, _from_time); } -dcp::LocalTime -KDMTimingPanel::local_time(wxDatePickerCtrl* date_picker, TimePicker* time_picker, dcp::UTCOffset offset) +boost::posix_time::ptime +KDMTimingPanel::posix_time(wxDatePickerCtrl* date_picker, TimePicker* time_picker) { - auto const date = date_picker->GetValue (); - return dcp::LocalTime( - date.GetYear(), - date.GetMonth() + 1, - date.GetDay(), - time_picker->hours(), - time_picker->minutes(), - offset - ); + auto const date = date_picker->GetValue(); + return boost::posix_time::ptime( + boost::gregorian::date(date.GetYear(), date.GetMonth() + 1, date.GetDay()), + boost::posix_time::time_duration(time_picker->hours(), time_picker->minutes(), 0)); } -dcp::LocalTime +boost::posix_time::ptime KDMTimingPanel::until () const { - return local_time(_until_date, _until_time, utc_offset()); + return posix_time(_until_date, _until_time); } @@ -181,38 +163,3 @@ KDMTimingPanel::changed () const TimingChanged (); } - - -dcp::UTCOffset -KDMTimingPanel::utc_offset() const -{ - auto const sel = _utc_offset->get(); - if (!sel || *sel >= int(_offsets.size())) { - return {}; - } - - return _offsets[*sel].offset; -} - - -void -KDMTimingPanel::utc_offset_changed() -{ - _utc_offset_changed_once = true; - changed(); -} - - -void -KDMTimingPanel::suggest_utc_offset(dcp::UTCOffset offset) -{ - if (!_utc_offset_changed_once) { - for (size_t i = 0; i < _offsets.size(); ++i) { - if (_offsets[i].offset == offset) { - _utc_offset->set(i); - break; - } - } - } -} - diff --git a/src/wx/kdm_timing_panel.h b/src/wx/kdm_timing_panel.h index a6199534a..21478b1ab 100644 --- a/src/wx/kdm_timing_panel.h +++ b/src/wx/kdm_timing_panel.h @@ -39,31 +39,22 @@ class KDMTimingPanel : public wxPanel public: explicit KDMTimingPanel (wxWindow* parent); - dcp::LocalTime from() const; - dcp::LocalTime until() const; + boost::posix_time::ptime from() const; + boost::posix_time::ptime until() const; bool valid () const; - /** Give a UTC offset from a cinema that the user just selected. If the user - * never changed the UTC offset in the panel, the suggested UTC will be set. - */ - void suggest_utc_offset(dcp::UTCOffset offset); - boost::signals2::signal<void ()> TimingChanged; private: void changed () const; - void utc_offset_changed(); - dcp::UTCOffset utc_offset() const; - static dcp::LocalTime local_time(wxDatePickerCtrl *, TimePicker *, dcp::UTCOffset offset); + static boost::posix_time::ptime posix_time(wxDatePickerCtrl *, TimePicker *); wxDatePickerCtrl* _from_date; wxDatePickerCtrl* _until_date; TimePicker* _from_time; TimePicker* _until_time; - Choice* _utc_offset; - bool _utc_offset_changed_once = false; wxStaticText* _warning; std::vector<Offset> _offsets; }; diff --git a/test/kdm_cli_test.cc b/test/kdm_cli_test.cc index a788a9642..4292da17e 100644 --- a/test/kdm_cli_test.cc +++ b/test/kdm_cli_test.cc @@ -317,7 +317,7 @@ BOOST_AUTO_TEST_CASE(kdm_cli_time) vector<string> args = { "kdm_cli", "--verbose", - "--valid-from", now.as_string(), + "--valid-from", "2025-01-28 01:41:51", "--valid-duration", "2 weeks", "-c", "Dean's Screens", "-S", "Screen 2", diff --git a/test/kdm_naming_test.cc b/test/kdm_naming_test.cc index fe7da7f31..4735ef75e 100644 --- a/test/kdm_naming_test.cc +++ b/test/kdm_naming_test.cc @@ -101,6 +101,9 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) dcp::LocalTime until = sign_cert.not_after(); until.add_months (-2); + auto const from_string = from.date() + " " + from.time_of_day(true, false); + auto const until_string = until.date() + " " + until.time_of_day(true, false); + std::vector<KDMCertificatePeriod> period_checks; auto cpl = cpls.front().cpl_file; @@ -112,8 +115,8 @@ BOOST_AUTO_TEST_CASE (single_kdm_naming_test) context.cinema_a, *cinemas.cinema(context.cinema_a), *cinemas.screen(context.cinema_a_screen_1), - from, - until, + boost::posix_time::time_from_string(from_string), + boost::posix_time::time_from_string(until_string), dcp::Formulation::MODIFIED_TRANSITIONAL_1, false, optional<int>(), @@ -165,6 +168,9 @@ BOOST_AUTO_TEST_CASE(directory_kdm_naming_test) dcp::LocalTime until (sign_cert.not_after()); until.add_months (-2); + auto const from_string = from.date() + " " + from.time_of_day(true, false); + auto const until_string = until.date() + " " + until.time_of_day(true, false); + vector<pair<CinemaID, ScreenID>> screens = { { context.cinema_a, context.cinema_a_screen_2 }, { context.cinema_b, context.cinema_b_screen_x }, @@ -188,8 +194,8 @@ BOOST_AUTO_TEST_CASE(directory_kdm_naming_test) screen.first, *cinemas.cinema(screen.first), *cinemas.screen(screen.second), - from, - until, + boost::posix_time::time_from_string(from_string), + boost::posix_time::time_from_string(until_string), dcp::Formulation::MODIFIED_TRANSITIONAL_1, false, optional<int>(), |
