Change end() to only do one thing, and copy the required stuff into pause()
[dcpomatic.git] / src / lib / kdm_cli.cc
index e8ce6d155fbd2e530febf38137d7d0c46339122d..1129130421c29c1427fd6d5192155962a0f29943 100644 (file)
@@ -35,6 +35,7 @@
 #include <dcp/certificate.h>
 #include <dcp/decrypted_kdm.h>
 #include <dcp/encrypted_kdm.h>
+#include <dcp/filesystem.h>
 #include <getopt.h>
 
 
@@ -61,8 +62,10 @@ 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 (in local time zone of the cinema) (e.g. \"2013-09-28 01:41:51\") or \"now\"");
+       out ("  -f, --valid-from <time>                  valid from time (e.g. \"2013-09-2 01:41:51\") or \"now\"");
        out ("  -t, --valid-to <time>                    valid to time (in local time zone of the cinema) (e.g. \"2014-09-28 01:41:51\")");
+       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 ("  -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");
@@ -74,6 +77,7 @@ help (std::function<void (string)> out)
        out ("  -S, --screen <name>                      screen name (when using -C) or screen name (to filter screens when using -c)");
        out ("  -C, --certificate <file>                 file containing projector certificate");
        out ("  -T, --trusted-device <file>              file containing a trusted device's certificate");
+       out ("      --cinemas-file <file>                use the given file as a list of cinemas instead of the current configuration");
        out ("      --list-cinemas                       list known cinemas from the DCP-o-matic settings");
        out ("      --list-dkdm-cpls                     list CPLs for which DCP-o-matic has DKDMs");
        out ("");
@@ -97,17 +101,6 @@ 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)
 {
@@ -209,8 +202,8 @@ from_film (
        boost::filesystem::path output,
        dcp::NameFormat container_name_format,
        dcp::NameFormat filename_format,
-       boost::posix_time::ptime valid_from,
-       boost::posix_time::ptime valid_to,
+       dcp::LocalTime valid_from,
+       dcp::LocalTime valid_to,
        dcp::Formulation formulation,
        bool disable_forensic_marking_picture,
        optional<int> disable_forensic_marking_audio,
@@ -255,13 +248,21 @@ from_film (
                }
 
 
-               if (find(period_checks.begin(), period_checks.end(), KDMCertificatePeriod::KDM_OUTSIDE_CERTIFICATE) != period_checks.end()) {
+               if (find_if(
+                       period_checks.begin(),
+                       period_checks.end(),
+                       [](KDMCertificatePeriod const& p) { return p.overlap == KDMCertificateOverlap::KDM_OUTSIDE_CERTIFICATE; }
+                  ) != period_checks.end()) {
                        throw KDMCLIError(
                                "Some KDMs would have validity periods which are completely outside the recipient certificate periods.  Such KDMs are very unlikely to work, so will not be created."
                                );
                }
 
-               if (find(period_checks.begin(), period_checks.end(), KDMCertificatePeriod::KDM_OVERLAPS_CERTIFICATE) != period_checks.end()) {
+               if (find_if(
+                       period_checks.begin(),
+                       period_checks.end(),
+                       [](KDMCertificatePeriod const& p) { return p.overlap == KDMCertificateOverlap::KDM_OVERLAPS_CERTIFICATE; }
+                  ) != period_checks.end()) {
                        out("For some of these KDMs the recipient certificate's validity period will not cover the whole of the KDM validity period.  This might cause problems with the KDMs.");
                }
 
@@ -352,8 +353,8 @@ from_dkdm (
        boost::filesystem::path output,
        dcp::NameFormat container_name_format,
        dcp::NameFormat filename_format,
-       boost::posix_time::ptime valid_from,
-       boost::posix_time::ptime valid_to,
+       dcp::LocalTime valid_from,
+       dcp::LocalTime valid_to,
        dcp::Formulation formulation,
        bool disable_forensic_marking_picture,
        optional<int> disable_forensic_marking_audio,
@@ -371,18 +372,12 @@ from_dkdm (
                                continue;
                        }
 
-                       int const offset_hour = i->cinema ? i->cinema->utc_offset_hour() : 0;
-                       int const offset_minute = i->cinema ? i->cinema->utc_offset_minute() : 0;
-
-                       dcp::LocalTime begin(valid_from, dcp::UTCOffset(offset_hour, offset_minute));
-                       dcp::LocalTime end(valid_to, dcp::UTCOffset(offset_hour, offset_minute));
-
                        auto const kdm = kdm_from_dkdm(
                                                        dkdm,
                                                        i->recipient.get(),
                                                        i->trusted_device_thumbprints(),
-                                                       begin,
-                                                       end,
+                                                       valid_from,
+                                                       valid_to,
                                                        formulation,
                                                        disable_forensic_marking_picture,
                                                        disable_forensic_marking_audio
@@ -392,8 +387,8 @@ from_dkdm (
                        name_values['c'] = i->cinema ? i->cinema->name : "";
                        name_values['s'] = i->name;
                        name_values['f'] = kdm.content_title_text();
-                       name_values['b'] = begin.date() + " " + begin.time_of_day(true, false);
-                       name_values['e'] = end.date() + " " + end.time_of_day(true, false);
+                       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['i'] = kdm.cpl_id();
 
                        kdms.push_back(make_shared<KDMWithMetadata>(name_values, i->cinema.get(), i->cinema ? i->cinema->emails : vector<string>(), kdm));
@@ -434,7 +429,7 @@ optional<string>
 kdm_cli (int argc, char* argv[], std::function<void (string)> out)
 try
 {
-       boost::filesystem::path output = boost::filesystem::current_path();
+       boost::filesystem::path output = dcp::filesystem::current_path();
        auto container_name_format = Config::instance()->kdm_container_name_format();
        auto filename_format = Config::instance()->kdm_filename_format();
        optional<string> cinema_name;
@@ -443,8 +438,8 @@ try
        optional<string> screen;
        vector<shared_ptr<Screen>> screens;
        optional<dcp::EncryptedKDM> dkdm;
-       optional<boost::posix_time::ptime> valid_from;
-       optional<boost::posix_time::ptime> valid_to;
+       optional<dcp::LocalTime> valid_from;
+       optional<dcp::LocalTime> valid_to;
        bool zip = false;
        bool list_cinemas = false;
        bool list_dkdm_cpls = false;
@@ -454,6 +449,7 @@ try
        bool disable_forensic_marking_picture = false;
        optional<int> disable_forensic_marking_audio;
        bool email = false;
+       optional<boost::filesystem::path> cinemas_file;
 
        program_name = argv[0];
 
@@ -482,10 +478,11 @@ try
                        { "trusted-device", required_argument, 0, 'T' },
                        { "list-cinemas", no_argument, 0, 'B' },
                        { "list-dkdm-cpls", no_argument, 0, 'D' },
+                       { "cinemas-file", required_argument, 0, 'E' },
                        { 0, 0, 0, 0 }
                };
 
-               int c = getopt_long (argc, argv, "ho:K:Z:f:t:d:F:pae::zvc:S:C:T:BD", long_options, &option_index);
+               int c = getopt_long (argc, argv, "ho:K:Z:f:t:d:F:pae::zvc:S:C:T:BDE:", long_options, &option_index);
 
                if (c == -1) {
                        break;
@@ -494,7 +491,7 @@ try
                switch (c) {
                case 'h':
                        help (out);
-                       exit (EXIT_SUCCESS);
+                       return {};
                case 'o':
                        output = optarg;
                        break;
@@ -505,10 +502,14 @@ try
                        container_name_format = dcp::NameFormat (optarg);
                        break;
                case 'f':
-                       valid_from = time_from_string (optarg);
+                       if (string(optarg) == "now") {
+                               valid_from = dcp::LocalTime();
+                       } else {
+                               valid_from = dcp::LocalTime(optarg);
+                       }
                        break;
                case 't':
-                       valid_to = time_from_string (optarg);
+                       valid_to = dcp::LocalTime(optarg);
                        break;
                case 'd':
                        duration_string = optarg;
@@ -552,7 +553,7 @@ try
                           (for lookup) and by creating a Cinema which the next Screen will be added to.
                        */
                        cinema_name = optarg;
-                       cinema = make_shared<Cinema>(optarg, vector<string>(), "", 0, 0);
+                       cinema = make_shared<Cinema>(optarg, vector<string>(), "");
                        break;
                case 'S':
                        /* Similarly, this could be the name of a new (temporary) screen or the name of a screen
@@ -575,9 +576,16 @@ try
                case 'D':
                        list_dkdm_cpls = true;
                        break;
+               case 'E':
+                       cinemas_file = optarg;
+                       break;
                }
        }
 
+       if (cinemas_file) {
+               Config::instance()->set_cinemas_file(*cinemas_file);
+       }
+
        if (certificate) {
                /* Make a new screen and add it to the current cinema */
                dcp::CertificateChain chain(dcp::file_to_string(*certificate));
@@ -593,12 +601,12 @@ try
                for (auto i: cinemas) {
                        out (String::compose("%1 (%2)", i->name, Emailer::address_list (i->emails)));
                }
-               exit (EXIT_SUCCESS);
+               return {};
        }
 
        if (list_dkdm_cpls) {
                dump_dkdm_group (Config::instance()->dkdms(), 0, out);
-               exit (EXIT_SUCCESS);
+               return {};
        }
 
        if (!duration_string && !valid_to) {
@@ -625,15 +633,16 @@ try
        }
 
        if (duration_string) {
-               valid_to = valid_from.get() + duration_from_string (*duration_string);
+               valid_to = valid_from.get();
+               valid_to->add(duration_from_string(*duration_string));
        }
 
        if (verbose) {
-               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())));
+               out(String::compose("Making KDMs valid from %1 to %2", valid_from->as_string(), valid_to->as_string()));
        }
 
        string const thing = argv[optind];
-       if (boost::filesystem::is_directory(thing) && boost::filesystem::is_regular_file(boost::filesystem::path(thing) / "metadata.xml")) {
+       if (dcp::filesystem::is_directory(thing) && dcp::filesystem::is_regular_file(boost::filesystem::path(thing) / "metadata.xml")) {
                from_film (
                        screens,
                        thing,
@@ -651,7 +660,7 @@ try
                        out
                        );
        } else {
-               if (boost::filesystem::is_regular_file(thing)) {
+               if (dcp::filesystem::is_regular_file(thing)) {
                        dkdm = dcp::EncryptedKDM (dcp::file_to_string (thing));
                } else {
                        dkdm = find_dkdm (thing);