Store successful DCP encodes.
authorCarl Hetherington <cth@carlh.net>
Sun, 14 Apr 2019 19:17:35 +0000 (20:17 +0100)
committerCarl Hetherington <cth@carlh.net>
Sun, 14 Apr 2019 19:17:35 +0000 (20:17 +0100)
src/lib/analytics.cc [new file with mode: 0644]
src/lib/analytics.h [new file with mode: 0644]
src/lib/config.cc
src/lib/config.h
src/lib/state.cc [new file with mode: 0644]
src/lib/state.h [new file with mode: 0644]
src/lib/transcode_job.cc
src/lib/wscript
src/tools/dcpomatic_cli.cc
src/tools/dcpomatic_create.cc

diff --git a/src/lib/analytics.cc b/src/lib/analytics.cc
new file mode 100644 (file)
index 0000000..74c21a2
--- /dev/null
@@ -0,0 +1,87 @@
+/*
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "analytics.h"
+#include "exceptions.h"
+#include <dcp/raw_convert.h>
+#include <libcxml/cxml.h>
+#include <libxml++/libxml++.h>
+#include <boost/filesystem.hpp>
+#include <boost/algorithm/string.hpp>
+
+using std::string;
+using dcp::raw_convert;
+using boost::algorithm::trim;
+
+Analytics* Analytics::_instance;
+int const Analytics::_current_version = 1;
+
+Analytics::Analytics ()
+       : _successful_dcp_encodes (0)
+{
+
+}
+
+void
+Analytics::successful_dcp_encode ()
+{
+       ++_successful_dcp_encodes;
+       write ();
+}
+
+void
+Analytics::write () const
+{
+       xmlpp::Document doc;
+       xmlpp::Element* root = doc.create_root_node ("Analytics");
+
+       root->add_child("Version")->add_child_text(raw_convert<string>(_current_version));
+       root->add_child("SuccessfulDCPEncodes")->add_child_text(raw_convert<string>(_successful_dcp_encodes));
+
+       try {
+               doc.write_to_file_formatted(path("analytics.xml").string());
+       } catch (xmlpp::exception& e) {
+               string s = e.what ();
+               trim (s);
+               throw FileError (s, path("analytics.xml"));
+       }
+}
+
+void
+Analytics::read ()
+try
+{
+       cxml::Document f ("Analytics");
+       f.read_file (path("analytics.xml"));
+       _successful_dcp_encodes = f.number_child<int>("SuccessfulDCPEncodes");
+} catch (...) {
+       /* Never mind */
+}
+
+Analytics*
+Analytics::instance ()
+{
+       if (!_instance) {
+               _instance = new Analytics();
+               _instance->read();
+       }
+
+       return _instance;
+}
diff --git a/src/lib/analytics.h b/src/lib/analytics.h
new file mode 100644 (file)
index 0000000..b439fca
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "state.h"
+
+class Analytics : public State
+{
+public:
+       Analytics ();
+
+       void successful_dcp_encode ();
+
+       void write () const;
+       void read ();
+
+       static Analytics* instance ();
+
+private:
+       int _successful_dcp_encodes;
+
+       static Analytics* _instance;
+       static int const _current_version;
+};
index c71f3ac..2e40ab3 100644 (file)
@@ -70,7 +70,6 @@ int const Config::_current_version = 3;
 boost::signals2::signal<void ()> Config::FailedToLoad;
 boost::signals2::signal<void (string)> Config::Warning;
 boost::signals2::signal<bool (void)> Config::BadSignerChain;
-boost::optional<boost::filesystem::path> Config::override_path;
 
 /** Construct default configuration */
 Config::Config ()
@@ -609,33 +608,6 @@ catch (...) {
        write ();
 }
 
-/** @return Filename to write configuration to */
-boost::filesystem::path
-Config::path (string file, bool create_directories)
-{
-       boost::filesystem::path p;
-       if (override_path) {
-               p = *override_path;
-       } else {
-#ifdef DCPOMATIC_OSX
-               p /= g_get_home_dir ();
-               p /= "Library";
-               p /= "Preferences";
-               p /= "com.dcpomatic";
-               p /= "2";
-#else
-               p /= g_get_user_config_dir ();
-               p /= "dcpomatic2";
-#endif
-       }
-       boost::system::error_code ec;
-       if (create_directories) {
-               boost::filesystem::create_directories (p, ec);
-       }
-       p /= file;
-       return p;
-}
-
 /** @return Singleton instance */
 Config *
 Config::instance ()
@@ -663,7 +635,7 @@ Config::write_config () const
        xmlpp::Element* root = doc.create_root_node ("Config");
 
        /* [XML] Version The version number of the configuration file format. */
-       root->add_child("Version")->add_child_text (String::compose ("%1", _current_version));
+       root->add_child("Version")->add_child_text (raw_convert<string>(_current_version));
        /* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
        root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
        /* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */
index a982c97..8cc25d7 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "isdcf_metadata.h"
 #include "types.h"
+#include "state.h"
 #include "edid.h"
 #include <dcp/name_format.h>
 #include <dcp/certificate_chain.h>
@@ -46,7 +47,7 @@ class DKDMGroup;
 /** @class Config
  *  @brief A singleton class holding configuration.
  */
-class Config : public boost::noncopyable
+class Config : public State
 {
 public:
        /** @return number of threads which a master DoM should use for J2K encoding on the local machine */
@@ -1094,10 +1095,6 @@ public:
        static void restore_defaults ();
        static bool have_existing (std::string);
        static boost::filesystem::path config_file ();
-       static boost::filesystem::path path (std::string file, bool create_directories = true);
-
-       /** If set, this overrides the standard path (in home, Library, AppData or wherever) for config.xml and cinemas.xml */
-       static boost::optional<boost::filesystem::path> override_path;
 
 private:
        Config ();
diff --git a/src/lib/state.cc b/src/lib/state.cc
new file mode 100644 (file)
index 0000000..abb1976
--- /dev/null
@@ -0,0 +1,54 @@
+/*
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include "state.h"
+#include <glib.h>
+
+using std::string;
+
+boost::optional<boost::filesystem::path> State::override_path;
+
+/** @param file State filename
+ *  @return Full path to write @file to */
+boost::filesystem::path
+State::path (string file, bool create_directories)
+{
+       boost::filesystem::path p;
+       if (override_path) {
+               p = *override_path;
+       } else {
+#ifdef DCPOMATIC_OSX
+               p /= g_get_home_dir ();
+               p /= "Library";
+               p /= "Preferences";
+               p /= "com.dcpomatic";
+               p /= "2";
+#else
+               p /= g_get_user_config_dir ();
+               p /= "dcpomatic2";
+#endif
+       }
+       boost::system::error_code ec;
+       if (create_directories) {
+               boost::filesystem::create_directories (p, ec);
+       }
+       p /= file;
+       return p;
+}
diff --git a/src/lib/state.h b/src/lib/state.h
new file mode 100644 (file)
index 0000000..b60c666
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+    Copyright (C) 2018 Carl Hetherington <cth@carlh.net>
+
+    This file is part of DCP-o-matic.
+
+    DCP-o-matic is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    DCP-o-matic is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
+
+*/
+
+#include <boost/noncopyable.hpp>
+#include <boost/filesystem.hpp>
+#include <boost/optional.hpp>
+
+class State : public boost::noncopyable
+{
+public:
+       virtual ~State () {}
+       virtual void read () = 0;
+       virtual void write () const = 0;
+
+       /** If set, this overrides the standard path (in home, Library, AppData or wherever) for config.xml, cinemas.xml etc. */
+       static boost::optional<boost::filesystem::path> override_path;
+
+protected:
+       static boost::filesystem::path path (std::string file, bool create_directories = true);
+};
index da7571b..6aa31af 100644 (file)
@@ -31,6 +31,7 @@
 #include "log.h"
 #include "dcpomatic_log.h"
 #include "compose.hpp"
+#include "analytics.h"
 #include <iostream>
 #include <iomanip>
 
@@ -41,6 +42,7 @@ using std::fixed;
 using std::setprecision;
 using std::cout;
 using boost::shared_ptr;
+using boost::dynamic_pointer_cast;
 
 /** @param film Film to use */
 TranscodeJob::TranscodeJob (shared_ptr<const Film> film)
@@ -89,6 +91,11 @@ TranscodeJob::run ()
                }
 
                LOG_GENERAL (N_("Transcode job completed successfully: %1 fps"), fps);
+
+               if (dynamic_pointer_cast<DCPEncoder>(_encoder)) {
+                       Analytics::instance()->successful_dcp_encode();
+               }
+
                _encoder.reset ();
 
                /* XXX: this shouldn't be here */
index cf38b36..267600b 100644 (file)
@@ -23,6 +23,7 @@ import i18n
 sources = """
           active_text.cc
           analyse_audio_job.cc
+          analytics.cc
           atmos_mxf_content.cc
           atomicity_checker.cc
           audio_analysis.cc
@@ -144,6 +145,7 @@ sources = """
           send_problem_report_job.cc
           server.cc
           shuffler.cc
+          state.cc
           spl.cc
           spl_entry.cc
           string_log_entry.cc
index 5535e62..f049c0c 100644 (file)
@@ -270,7 +270,7 @@ main (int argc, char* argv[])
        }
 
        if (config) {
-               Config::override_path = *config;
+               State::override_path = *config;
        }
 
        if (servers) {
index 66a1c0d..1dfabd2 100644 (file)
@@ -80,7 +80,7 @@ main (int argc, char* argv[])
        }
 
        if (cc.config_dir) {
-               Config::override_path = *cc.config_dir;
+               State::override_path = *cc.config_dir;
        }
 
        signal_manager = new SimpleSignalManager ();