Add some basic JSON stuff.
authorCarl Hetherington <cth@carlh.net>
Wed, 19 Feb 2014 10:47:11 +0000 (10:47 +0000)
committerCarl Hetherington <cth@carlh.net>
Wed, 19 Feb 2014 10:47:11 +0000 (10:47 +0000)
18 files changed:
ChangeLog
src/lib/analyse_audio_job.cc
src/lib/analyse_audio_job.h
src/lib/examine_content_job.cc
src/lib/examine_content_job.h
src/lib/job.cc
src/lib/job.h
src/lib/scp_dcp_job.cc
src/lib/scp_dcp_job.h
src/lib/send_kdm_email_job.cc
src/lib/send_kdm_email_job.h
src/lib/transcode_job.cc
src/lib/transcode_job.h
src/lib/util.cc
src/lib/util.h
src/lib/wscript
src/tools/dcpomatic_cli.cc
test/job_test.cc

index 6e645b484014112cfeb15ea3388c0f7a635ea945..9f05f852f4633b76b42d83b9a09327a1e7322745 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2014-02-19  Carl Hetherington  <cth@carlh.net>
+
+       * Add some basic JSON stuff.
+
 2014-02-18  Carl Hetherington  <cth@carlh.net>
 
        * Version 1.64.14 released.
index 8186f9de49b9d89baa81c04d7f454f876b8de963..bfe0ed61f281816a71e20b66f17c18e429d46ac9 100644 (file)
@@ -48,6 +48,12 @@ AnalyseAudioJob::name () const
        return _("Analyse audio");
 }
 
+string
+AnalyseAudioJob::json_name () const
+{
+       return N_("analyse_audio");
+}
+
 void
 AnalyseAudioJob::run ()
 {
index 3d4881983b5234572ce40a47455c5b849a620328..3e376634cd0d9be375fc825ae60c6285db16588a 100644 (file)
@@ -30,6 +30,7 @@ public:
        AnalyseAudioJob (boost::shared_ptr<const Film>, boost::shared_ptr<AudioContent>);
 
        std::string name () const;
+       std::string json_name () const;
        void run ();
 
 private:
index cbf180ffcb3bf451379e410039d5d28dfed75d80..8f16e2e5c0c069e2ab601c4bf91cec39c1e3cebc 100644 (file)
@@ -46,6 +46,12 @@ ExamineContentJob::name () const
        return _("Examine content");
 }
 
+string
+ExamineContentJob::json_name () const
+{
+       return N_("examine_content");
+}
+
 void
 ExamineContentJob::run ()
 {
index b6903b86bebf0ed9e80970a7382c0f07628301cc..c8037224faa708737e6739d5c29bc544ee74ad0f 100644 (file)
@@ -30,6 +30,7 @@ public:
        ~ExamineContentJob ();
 
        std::string name () const;
+       std::string json_name () const;
        void run ();
 
 private:
index 66fa3755dfb69d3c751a15cde8c868d083927339..76976df322c1c3778bcac915709ea39a871f5d68 100644 (file)
@@ -239,7 +239,7 @@ Job::set_progress (float p, bool force)
        }
 }
 
-/** @return fractional progress of this sub-job, or -1 if not known */
+/** @return fractional progress of the current sub-job, or -1 if not known */
 float
 Job::progress () const
 {
@@ -325,6 +325,29 @@ Job::status () const
        return s.str ();
 }
 
+string
+Job::json_status () const
+{
+       boost::mutex::scoped_lock lm (_state_mutex);
+
+       switch (_state) {
+       case NEW:
+               return N_("new");
+       case RUNNING:
+               return N_("running");
+       case PAUSED:
+               return N_("paused");
+       case FINISHED_OK:
+               return N_("finished_ok");
+       case FINISHED_ERROR:
+               return N_("finished_error");
+       case FINISHED_CANCELLED:
+               return N_("finished_cancelled");
+       }
+
+       return "";
+}
+
 /** @return An estimate of the remaining time for this sub-job, in seconds */
 int
 Job::remaining_time () const
index 6310da32ae69a2b87db7bdbc8cb29688b447a418..489464558764bc348d85f741f0ddd634ddbdb9b0 100644 (file)
@@ -43,6 +43,7 @@ public:
 
        /** @return user-readable name of this job */
        virtual std::string name () const = 0;
+       virtual std::string json_name () const = 0;
        /** Run this job in the current thread. */
        virtual void run () = 0;
        
@@ -64,6 +65,7 @@ public:
 
        int elapsed_time () const;
        virtual std::string status () const;
+       std::string json_status () const;
        std::string sub_name () const {
                return _sub_name;
        }
index 22715978a7040ba279843c8e2ab0488a8f98f7a3..0b713b0427b15c62cdda2e39455c0a5e3dab1bc3 100644 (file)
@@ -110,6 +110,12 @@ SCPDCPJob::name () const
        return _("Copy DCP to TMS");
 }
 
+string
+SCPDCPJob::json_name () const
+{
+       return N_("scp_dcp");
+}
+
 void
 SCPDCPJob::run ()
 {
@@ -223,4 +229,3 @@ SCPDCPJob::set_status (string s)
        boost::mutex::scoped_lock lm (_status_mutex);
        _status = s;
 }
-       
index bdc83af187f85a0091d31e107d554ee9dd07ef4c..e3960d73b512dac54d25124be28740d15dfd67cf 100644 (file)
@@ -29,6 +29,7 @@ public:
        SCPDCPJob (boost::shared_ptr<const Film>);
 
        std::string name () const;
+       std::string json_name () const;
        void run ();
        std::string status () const;
 
index 89bce9a1490c84735ee7d7b4725c7352cefbf3ca..8af0b556a13e7f1a5ceffcc066e9c02d0038c04d 100644 (file)
@@ -50,6 +50,12 @@ SendKDMEmailJob::name () const
        return String::compose (_("Email KDMs for %1"), _film->name());
 }
 
+string
+SendKDMEmailJob::json_name () const
+{
+       return N_("send_kdm_email");
+}
+
 void
 SendKDMEmailJob::run ()
 {
index fcab56ce524590fdf17fa21d72f6e6c7340ea517..f4d154a9183b227dc897c97c5660f9f04aef3114 100644 (file)
@@ -34,6 +34,7 @@ public:
                );
 
        std::string name () const;
+       std::string json_name () const;
        void run ();
 
 private:
index 5c195ee1b781227637068f58ff62bf5425ca1612..7b304cb35b48d549e683bd403ec8b5d923b0e4e9 100644 (file)
@@ -50,6 +50,12 @@ TranscodeJob::name () const
        return String::compose (_("Transcode %1"), _film->name());
 }
 
+string
+TranscodeJob::json_name () const
+{
+       return N_("transcode");
+}
+
 void
 TranscodeJob::run ()
 {
index 9128206d29dc9c9e42460cafecfa4748f0a1c0db..6e3c1ead9314cc5af7bb2877f208c38ae4358fa3 100644 (file)
@@ -35,6 +35,7 @@ public:
        TranscodeJob (boost::shared_ptr<const Film> f);
        
        std::string name () const;
+       std::string json_name () const;
        void run ();
        std::string status () const;
 
index b2f8c4470e5af5ee5117489870f4899bd38367bb..a86033e572f7655f5ebc67e5195e04018c4aa358 100644 (file)
@@ -89,6 +89,7 @@ using std::min;
 using std::max;
 using std::list;
 using std::multimap;
+using std::map;
 using std::istream;
 using std::numeric_limits;
 using std::pair;
@@ -939,6 +940,52 @@ make_signer ()
        return shared_ptr<const libdcp::Signer> (new libdcp::Signer (chain, signer_key));
 }
 
+map<string, string>
+split_get_request (string url)
+{
+       enum {
+               AWAITING_QUESTION_MARK,
+               KEY,
+               VALUE
+       } state = AWAITING_QUESTION_MARK;
+       
+       map<string, string> r;
+       string k;
+       string v;
+       for (size_t i = 0; i < url.length(); ++i) {
+               switch (state) {
+               case AWAITING_QUESTION_MARK:
+                       if (url[i] == '?') {
+                               state = KEY;
+                       }
+                       break;
+               case KEY:
+                       if (url[i] == '=') {
+                               v.clear ();
+                               state = VALUE;
+                       } else {
+                               k += url[i];
+                       }
+                       break;
+               case VALUE:
+                       if (url[i] == '&') {
+                               r.insert (make_pair (k, v));
+                               k.clear ();
+                               state = KEY;
+                       } else {
+                               v += url[i];
+                       }
+                       break;
+               }
+       }
+
+       if (state == VALUE) {
+               r.insert (make_pair (k, v));
+       }
+
+       return r;
+}
+
 libdcp::Size
 fit_ratio_within (float ratio, libdcp::Size full_frame)
 {
@@ -959,3 +1006,10 @@ wrapped_av_malloc (size_t s)
        return p;
 }
                
+string
+entities_to_text (string e)
+{
+       boost::algorithm::replace_all (e, "%3A", ":");
+       boost::algorithm::replace_all (e, "%2F", "/");
+       return e;
+}
index a229bbfc9df05ff0aab8a74ef00df6ac55183311..9bf139b8278f3de2143c531c5fac6e23704434c3 100644 (file)
@@ -78,6 +78,8 @@ extern boost::filesystem::path mo_path ();
 extern std::string tidy_for_filename (std::string);
 extern boost::shared_ptr<const libdcp::Signer> make_signer ();
 extern libdcp::Size fit_ratio_within (float ratio, libdcp::Size);
+extern std::string entities_to_text (std::string e);
+extern std::map<std::string, std::string> split_get_request (std::string url);
 
 struct FrameRateConversion
 {
index 4921afaee788e3b8d0db44d605587feaa270bb9b..8702adebbd2de8877b044fb132ff82b40414e0c5 100644 (file)
@@ -37,6 +37,7 @@ sources = """
           job.cc
           job_manager.cc
           kdm.cc
+          json_server.cc
           log.cc
           player.cc
           playlist.cc
index c40ea6662b8f0c7b0b1b476933cb770a03406fcd..a74ece149af2b9e96e7cd46103917dec5bfe98f1 100644 (file)
@@ -33,6 +33,7 @@
 #include "lib/log.h"
 #include "lib/ui_signaller.h"
 #include "lib/server_finder.h"
+#include "lib/json_server.h"
 
 using std::string;
 using std::cerr;
@@ -52,6 +53,8 @@ help (string n)
             << "  -f, --flags        show flags passed to C++ compiler on build\n"
             << "  -n, --no-progress  do not print progress to stdout\n"
             << "  -r, --no-remote    do not use any remote servers\n"
+            << "  -j, --json <port>  run a JSON server on the specified port\n"
+            << "  -k, --keep-going   keep running even when the job is complete\n"
             << "\n"
             << "<FILM> is the film directory.\n";
 }
@@ -63,6 +66,8 @@ main (int argc, char* argv[])
        bool progress = true;
        bool no_remote = false;
        int log_level = 0;
+       int json_port = 0;
+       bool keep_going = false;
 
        int option_index = 0;
        while (1) {
@@ -74,10 +79,12 @@ main (int argc, char* argv[])
                        { "no-progress", no_argument, 0, 'n'},
                        { "no-remote", no_argument, 0, 'r'},
                        { "log-level", required_argument, 0, 'l' },
+                       { "json", required_argument, 0, 'j' },
+                       { "keep-going", no_argument, 0, 'k' },
                        { 0, 0, 0, 0 }
                };
 
-               int c = getopt_long (argc, argv, "vhdfnrl:", long_options, &option_index);
+               int c = getopt_long (argc, argv, "vhdfnrl:j:k", long_options, &option_index);
 
                if (c == -1) {
                        break;
@@ -105,6 +112,12 @@ main (int argc, char* argv[])
                case 'l':
                        log_level = atoi (optarg);
                        break;
+               case 'j':
+                       json_port = atoi (optarg);
+                       break;
+               case 'k':
+                       keep_going = true;
+                       break;
                }
        }
 
@@ -122,6 +135,10 @@ main (int argc, char* argv[])
                ServerFinder::instance()->disable ();
        }
 
+       if (json_port) {
+               new JSONServer (json_port);
+       }
+
        cout << "DCP-o-matic " << dcpomatic_version << " git " << dcpomatic_git_commit;
        char buf[256];
        if (gethostname (buf, 256) == 0) {
@@ -201,6 +218,12 @@ main (int argc, char* argv[])
                }
        }
 
+       if (keep_going) {
+               while (1) {
+                       dcpomatic_sleep (3600);
+               }
+       }
+
        /* This is just to stop valgrind reporting leaks due to JobManager
           indirectly holding onto codecs.
        */
index a3ad1bb6c5936589e475d1d2cf4078d38fc1e2e7..4d32b1e0ccf8692497f5be9778b594d2485b98d2 100644 (file)
@@ -54,6 +54,10 @@ public:
        string name () const {
                return "";
        }
+
+       string json_name () const {
+               return "";
+       }
 };
 
 BOOST_AUTO_TEST_CASE (job_manager_test)