2016-03-08 Carl Hetherington <cth@carlh.net>
+ * Store time zone with cinemas and use them to
+ mark KDM start and end times correctly (#788).
+
* Bump ffmpeg to git master, somewhere post 3.0.
2016-03-08 Carl Hetherington <cth@carlh.net>
/*
- Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "cinema.h"
#include "screen.h"
+#include "dcpomatic_assert.h"
#include <libcxml/cxml.h>
+#include <dcp/raw_convert.h>
#include <libxml++/libxml++.h>
#include <boost/foreach.hpp>
+#include <iostream>
using std::list;
using std::string;
Cinema::Cinema (cxml::ConstNodePtr node)
: name (node->string_child ("Name"))
+ , _utc_offset (node->optional_number_child<int>("UTCOffset").get_value_or (0))
{
BOOST_FOREACH (cxml::ConstNodePtr i, node->node_children("Email")) {
emails.push_back (i->content ());
parent->add_child("Email")->add_child_text (i);
}
+ parent->add_child("UTCOffset")->add_child_text (dcp::raw_convert<string> (_utc_offset));
+
BOOST_FOREACH (shared_ptr<Screen> i, _screens) {
i->as_xml (parent->add_child ("Screen"));
}
{
_screens.remove (s);
}
+
+void
+Cinema::set_utc_offset (int o)
+{
+ DCPOMATIC_ASSERT (o >= -11 && o <= 12);
+ _utc_offset = o;
+}
/*
- Copyright (C) 2013-2014 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2013-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
/** @class Cinema
* @brief A description of a Cinema for KDM generation.
*
- * This is a cinema name, contact email addresses and a list of
+ * This is a cinema name, some metadata and a list of
* Screen objects.
*/
class Cinema : public boost::enable_shared_from_this<Cinema>
{
public:
- Cinema (std::string const & n, std::list<std::string> const & e)
+ Cinema (std::string const & n, std::list<std::string> const & e, int utc_offset)
: name (n)
, emails (e)
+ , _utc_offset (utc_offset)
{}
Cinema (cxml::ConstNodePtr);
void add_screen (boost::shared_ptr<Screen>);
void remove_screen (boost::shared_ptr<Screen>);
+ void set_utc_offset (int o);
+
std::string name;
std::list<std::string> emails;
+ int utc_offset () const {
+ return _utc_offset;
+ }
std::list<boost::shared_ptr<Screen> > screens () const {
return _screens;
}
private:
std::list<boost::shared_ptr<Screen> > _screens;
+ /** Offset such that the equivalent time in UTC can be determined
+ by subtracting the offset from the local time.
+ */
+ int _utc_offset;
};
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "ffmpeg_content.h"
#include "dcp_content.h"
#include "screen_kdm.h"
+#include "cinema.h"
#include <libcxml/cxml.h>
#include <dcp/cpl.h>
#include <dcp/certificate_chain.h>
return fit_ratio_within (container()->ratio(), full_frame ());
}
+/** @param from KDM from time expressed as a local time with an offset from UTC
+ * @param to KDM to time expressed as a local time with an offset from UTC
+ */
dcp::EncryptedKDM
Film::make_kdm (
dcp::Certificate recipient,
).encrypt (signer, recipient, trusted_devices, formulation);
}
+/** @param from KDM from time expressed as a local time in the time zone of the Screen's Cinema.
+ * @param to KDM to time expressed as a local time in the time zone of the Screen's Cinema.
+ */
list<ScreenKDM>
Film::make_kdms (
list<shared_ptr<Screen> > screens,
boost::filesystem::path dcp,
- dcp::LocalTime from,
- dcp::LocalTime until,
+ boost::posix_time::ptime from,
+ boost::posix_time::ptime until,
dcp::Formulation formulation
) const
{
BOOST_FOREACH (shared_ptr<Screen> i, screens) {
if (i->recipient) {
- kdms.push_back (ScreenKDM (i, make_kdm (i->recipient.get(), i->trusted_devices, dcp, from, until, formulation)));
+ dcp::EncryptedKDM const kdm = make_kdm (
+ i->recipient.get(),
+ i->trusted_devices,
+ dcp,
+ dcp::LocalTime (from, i->cinema->utc_offset(), 0),
+ dcp::LocalTime (until, i->cinema->utc_offset(), 0),
+ formulation
+ );
+
+ kdms.push_back (ScreenKDM (i, kdm));
}
}
/*
- Copyright (C) 2012-2015 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
std::list<ScreenKDM> make_kdms (
std::list<boost::shared_ptr<Screen> >,
boost::filesystem::path cpl_file,
- dcp::LocalTime from,
- dcp::LocalTime until,
+ boost::posix_time::ptime from,
+ boost::posix_time::ptime until,
dcp::Formulation formulation
) const;
#include "lib/cinema_kdms.h"
#include "lib/send_kdm_email_job.h"
#include "lib/compose.hpp"
+#include "lib/cinema.h"
#include <dcp/encrypted_kdm.h>
#include <dcp/decrypted_kdm.h>
#include <dcp/exceptions.h>
/* Make an empty KDM */
dcp::DecryptedKDM kdm (
- _timing->from(), _timing->until(), decrypted.annotation_text(), decrypted.content_title_text(), dcp::LocalTime().as_string()
+ dcp::LocalTime (_timing->from(), i->cinema->utc_offset(), 0),
+ dcp::LocalTime (_timing->until(), i->cinema->utc_offset(), 0),
+ decrypted.annotation_text(),
+ decrypted.content_title_text(),
+ dcp::LocalTime().as_string()
);
/* Add keys from the DKDM */
cerr << "Syntax: " << program_name << " [OPTION] [<FILM>]\n"
" -h, --help show this help\n"
" -o, --output output file or directory\n"
- " -f, --valid-from valid from time (in local time zone) (e.g. \"2013-09-28 01:41:51\") or \"now\"\n"
- " -t, --valid-to valid to time (in local time zone) (e.g. \"2014-09-28 01:41:51\")\n"
+ " -f, --valid-from valid from time (in local time zone of the cinema) (e.g. \"2013-09-28 01:41:51\") or \"now\"\n"
+ " -t, --valid-to valid to time (in local time zone of the cinema) (e.g. \"2014-09-28 01:41:51\")\n"
" -d, --valid-duration valid duration (e.g. \"1 day\", \"4 hours\", \"2 weeks\")\n"
" --formulation modified-transitional-1, dci-any or dci-specific [default modified-transitional-1]\n"
" -z, --zip ZIP each cinema's KDMs into its own file\n"
try {
list<ScreenKDM> screen_kdms = film->make_kdms (
- (*i)->screens(), cpl, dcp::LocalTime (valid_from.get()), dcp::LocalTime (valid_to.get()), formulation
+ (*i)->screens(), cpl, valid_from.get(), valid_to.get(), formulation
);
if (zip) {
/*
- Copyright (C) 2012 Carl Hetherington <cth@carlh.net>
+ Copyright (C) 2012-2016 Carl Hetherington <cth@carlh.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "cinema_dialog.h"
#include "wx_util.h"
+#include "lib/dcpomatic_assert.h"
#include <boost/foreach.hpp>
using std::string;
return s;
}
-CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<string> emails)
+CinemaDialog::CinemaDialog (wxWindow* parent, string title, string name, list<string> emails, int utc_offset)
: wxDialog (parent, wxID_ANY, std_to_wx (title))
{
wxBoxSizer* overall_sizer = new wxBoxSizer (wxVERTICAL);
sizer->Add (_name, wxGBPosition (r, 1));
++r;
+ add_label_to_sizer (sizer, this, _("UTC offset (time zone)"), true, wxGBPosition (r, 0));
+ _utc_offset = new wxChoice (this, wxID_ANY);
+ sizer->Add (_utc_offset, wxGBPosition (r, 1));
+ ++r;
+
add_label_to_sizer (sizer, this, _("Email addresses for KDM delivery"), false, wxGBPosition (r, 0), wxGBSpan (1, 2));
++r;
overall_sizer->Add (buttons, wxSizerFlags().Expand().DoubleBorder());
}
+ for (int i = -11; i <= -1; ++i) {
+ _utc_offset->Append (wxString::Format (_("UTC%d"), i));
+ }
+ _utc_offset->Append (_("UTC"));
+ for (int i = 1; i <= 12; ++i) {
+ _utc_offset->Append (wxString::Format (_("UTC+%d"), i));
+ }
+
+ _utc_offset->SetSelection (utc_offset + 11);
+
overall_sizer->Layout ();
overall_sizer->SetSizeHints (this);
}
copy (_emails.begin(), _emails.end(), back_inserter (e));
return e;
}
+
+int
+CinemaDialog::utc_offset () const
+{
+ return _utc_offset->GetSelection() - 11;
+}
class CinemaDialog : public wxDialog
{
public:
- CinemaDialog (wxWindow *, std::string, std::string name = "", std::list<std::string> emails = std::list<std::string> ());
+ CinemaDialog (wxWindow *, std::string, std::string name = "", std::list<std::string> emails = std::list<std::string> (), int utc_offset = 0);
std::string name () const;
std::list<std::string> emails () const;
+ int utc_offset () const;
private:
std::vector<std::string> get_emails () const;
wxTextCtrl* _name;
EditableList<std::string, EmailDialog>* _email_list;
std::vector<std::string> _emails;
+ wxChoice* _utc_offset;
};
KDMDialog (wxWindow *, boost::shared_ptr<const Film>);
std::list<boost::shared_ptr<Screen> > screens () const;
- /** @return KDM from time in local time */
+ /** @return KDM from time in local time; note that ptime has no time zone information */
boost::posix_time::ptime from () const;
- /** @return KDM until time in local time */
+ /** @return KDM until time in local time; note that ptime has no time zone information */
boost::posix_time::ptime until () const;
boost::filesystem::path cpl () const;
{
CinemaDialog* d = new CinemaDialog (this, "Add Cinema");
if (d->ShowModal () == wxID_OK) {
- shared_ptr<Cinema> c (new Cinema (d->name(), d->emails()));
+ shared_ptr<Cinema> c (new Cinema (d->name(), d->emails(), d->utc_offset()));
Config::instance()->add_cinema (c);
add_cinema (c);
}
pair<wxTreeItemId, shared_ptr<Cinema> > c = *_selected_cinemas.begin();
- CinemaDialog* d = new CinemaDialog (this, "Edit cinema", c.second->name, c.second->emails);
+ CinemaDialog* d = new CinemaDialog (this, "Edit cinema", c.second->name, c.second->emails, c.second->utc_offset());
if (d->ShowModal () == wxID_OK) {
c.second->name = d->name ();
c.second->emails = d->emails ();
+ c.second->set_utc_offset (d->utc_offset ());
_targets->SetItemText (c.first, std_to_wx (d->name()));
Config::instance()->changed ();
}