Some work on making KDMs in Film
authorCarl Hetherington <cth@carlh.net>
Fri, 11 Jan 2013 00:24:34 +0000 (00:24 +0000)
committerCarl Hetherington <cth@carlh.net>
Fri, 11 Jan 2013 00:24:34 +0000 (00:24 +0000)
src/lib/cinema.h
src/lib/config.cc
src/lib/config.h
src/lib/exceptions.h
src/lib/film.cc

index 02b38c4964d1d8dc0ea5f939b41c6db44accf7dc..0cec013845aba4e6bfce92dabf9c88ae45a72cc4 100644 (file)
@@ -8,7 +8,7 @@ public:
        {}
        
        std::string name;
-       libdcp::Certificate certificate;
+       boost::shared_ptr<libdcp::Certificate> certificate;
 };
 
 class Cinema
index 80d357e1a667cac0a900544b65b84f5c7817ff2d..fe50a5cc20dc3201f125cb8748bfcb966b07fa07 100644 (file)
@@ -48,7 +48,7 @@ Config::Config ()
        , _tms_path (".")
        , _sound_processor (SoundProcessor::from_id ("dolby_cp750"))
 {
-       ifstream f (file().c_str ());
+       ifstream f (read_file().c_str ());
        string line;
 
        shared_ptr<Cinema> cinema;
@@ -117,14 +117,40 @@ Config::Config ()
 
 /** @return Filename to write configuration to */
 string
-Config::file () const
+Config::write_file () const
 {
+       boost::filesystem::path p;
+       p /= g_get_user_config_dir ();
+       p /= "dvdomatic";
+       boost::filesystem::create_directory (p);
+       p /= "config";
+       return p.string ();
+}
+
+string
+Config::read_file () const
+{
+       if (boost::filesystem::exists (write_file ())) {
+               return write_file ();
+       }
+       
        boost::filesystem::path p;
        p /= g_get_user_config_dir ();
        p /= ".dvdomatic";
        return p.string ();
 }
 
+string
+Config::crypt_chain_directory () const
+{
+       boost::filesystem::path p;
+       p /= g_get_user_config_dir ();
+       p /= "dvdomatic";
+       p /= "crypt";
+       boost::filesystem::create_directories (p);
+       return p.string ();
+}
+
 /** @return Singleton instance */
 Config *
 Config::instance ()
@@ -140,7 +166,7 @@ Config::instance ()
 void
 Config::write () const
 {
-       ofstream f (file().c_str ());
+       ofstream f (write_file().c_str ());
        f << "num_local_encoding_threads " << _num_local_encoding_threads << "\n"
          << "default_directory " << _default_directory << "\n"
          << "server_port " << _server_port << "\n"
index 2d5b82ac595adac0078b6f4cfc54a7b5e9218bbd..785fff1374f73f02cf479e0132503bb5b79a4cb2 100644 (file)
@@ -179,11 +179,14 @@ public:
        
        void write () const;
 
+       std::string crypt_chain_directory () const;
+
        static Config* instance ();
 
 private:
        Config ();
-       std::string file () const;
+       std::string read_file () const;
+       std::string write_file () const;
 
        /** number of threads to use for J2K encoding on the local machine */
        int _num_local_encoding_threads;
index bf8e85f0bdfb7d939f76b90ad41c4571361bd874..06177863ab27e5720125c91b0320827c627251b7 100644 (file)
@@ -224,3 +224,11 @@ public:
                : StringError (s)
        {}
 };
+
+class KDMError : public StringError
+{
+public:
+       KDMError (std::string s)
+               : StringError (s)
+       {}
+};
index 012495226656d5920258d80a27641c01e405171d..48677ba613848f419864efe0e4307a6842c5bea9 100644 (file)
 #include <boost/algorithm/string.hpp>
 #include <boost/lexical_cast.hpp>
 #include <boost/date_time.hpp>
+#include <libxml++/libxml++.h>
+#include <libdcp/crypt_chain.h>
+#include <libdcp/certificates.h>
+#include "cinema.h"
 #include "film.h"
 #include "format.h"
 #include "job.h"
@@ -1388,12 +1392,66 @@ Film::audio_stream () const
 
 void
 Film::make_kdms (
-       list<shared_ptr<Screen> >,
+       list<shared_ptr<Screen> > screens,
        boost::posix_time::ptime from,
        boost::posix_time::ptime until,
        string directory
        ) const
 {
-       
+       string const cd = Config::instance()->crypt_chain_directory ();
+       if (boost::filesystem::is_empty (cd)) {
+               libdcp::make_crypt_chain (cd);
+       }
+
+       libdcp::CertificateChain chain;
+
+       {
+               boost::filesystem::path p (cd);
+               p /= "ca.self-signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p.string ())));
+       }
+
+       {
+               boost::filesystem::path p (cd);
+               p /= "intermediate.signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p.string ())));
+       }
+
+       {
+               boost::filesystem::path p (cd);
+               p /= "leaf.signed.pem";
+               chain.add (shared_ptr<libdcp::Certificate> (new libdcp::Certificate (p.string ())));
+       }
+
+       boost::filesystem::path signer_key (cd);
+       signer_key /= "leaf.key";
+
+       /* Find the DCP to make the KDM for */
+       string const dir = this->directory ();
+       list<string> dcps;
+       for (boost::filesystem::directory_iterator i = boost::filesystem::directory_iterator(dir); i != boost::filesystem::directory_iterator(); ++i) {
+               if (boost::filesystem::is_directory (*i) && i->path().leaf() != "j2c" && i->path().leaf() != "wavs") {
+                       dcps.push_back (i->path().string());
+               }
+       }
+
+       if (dcps.empty()) {
+               throw KDMError ("Could not find DCP to make KDM for");
+       } else if (dcps.size() > 1) {
+               throw KDMError ("More than one possible DCP to make KDM for");
+       }
+
+       for (list<shared_ptr<Screen> >::iterator i = screens.begin(); i != screens.end(); ++i) {
+
+               libdcp::DCP dcp (dcps.front ());
+               dcp.read ();
+               
+               /* XXX: single CPL only */
+               shared_ptr<xmlpp::Document> kdm = dcp.cpls().front()->make_kdm (chain, signer_key.string(), (*i)->certificate, from, until);
+
+               boost::filesystem::path out = directory;
+               out /= "kdm.xml";
+               kdm->write_to_file_formatted (out.string());
+       }
 }