Upload analytics. attic/analytics
authorCarl Hetherington <cth@carlh.net>
Tue, 14 Aug 2018 15:28:31 +0000 (16:28 +0100)
committerCarl Hetherington <cth@carlh.net>
Tue, 14 Aug 2018 15:28:31 +0000 (16:28 +0100)
src/lib/analytics.cc
src/lib/analytics.h
src/tools/dcpomatic.cc

index cbb8843025e6b62a22cdf41515ac04e5124ae1a0..b3c5de0fb3da897cd567e251eb54427d55d7798c 100644 (file)
 #include "analytics.h"
 #include "exceptions.h"
 #include "job.h"
+#include "cross.h"
 #include <dcp/raw_convert.h>
 #include <dcp/util.h>
 #include <libcxml/cxml.h>
+#include <curl/curl.h>
 #include <libxml++/libxml++.h>
 #include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
@@ -94,10 +96,76 @@ Event::dump () const
 
 Analytics::Analytics ()
        : _id (dcp::make_uuid())
+       , _thread (0)
 {
 
 }
 
+Analytics::~Analytics ()
+{
+       if (!_thread) {
+               return;
+       }
+
+       _thread->interrupt();
+       if (_thread->joinable()) {
+               try {
+                       _thread->join();
+               } catch (...) {
+                       /* Too late to do anything about this */
+               }
+       }
+
+       delete _thread;
+}
+
+void
+Analytics::start ()
+{
+       _thread = new boost::thread (boost::bind(&Analytics::thread, this));
+#ifdef DCPOMATIC_LINUX
+       pthread_setname_np (_thread->native_handle(), "update-checker");
+#endif
+}
+
+void
+Analytics::thread ()
+try
+{
+       while (true) {
+
+               {
+                       boost::mutex::scoped_lock lm (_mutex);
+                       if (_events.empty ()) {
+                               continue;
+                       }
+
+                       CURL* curl = curl_easy_init ();
+                       if (!curl) {
+                               continue;
+                       }
+
+                       curl_easy_setopt (curl, CURLOPT_URL, "https://dcpomatic.com/analytics");
+                       xmlpp::Document doc;
+                       xmlpp_document (doc);
+                       curl_easy_setopt (curl, CURLOPT_POST, 1);
+                       curl_easy_setopt (curl, CURLOPT_COPYPOSTFIELDS, doc.write_to_string().c_str());
+                       CURLcode res = curl_easy_perform (curl);
+                       if (res == CURLE_OK) {
+                               _events.clear ();
+                       }
+                       curl_easy_cleanup (curl);
+                       write ();
+
+               }
+
+               dcpomatic_sleep (60);
+       }
+}
+catch (...) {
+       /* Never mind */
+}
+
 int
 Analytics::successful_dcp_encodes () const
 {
@@ -125,10 +193,9 @@ Analytics::job_state_changed (shared_ptr<Job> job)
        {
                boost::mutex::scoped_lock lm (_mutex);
                _events.push_back (ev);
+               write ();
        }
 
-       write ();
-
        if (successful_dcp_encodes() == 3) {
                emit (
                        boost::bind(
@@ -159,20 +226,26 @@ Analytics::job_state_changed (shared_ptr<Job> job)
        }
 }
 
+/** Must be called with a lock held on _mutex*/
 void
-Analytics::write () const
+Analytics::xmlpp_document (xmlpp::Document& doc) const
 {
-       xmlpp::Document doc;
        xmlpp::Element* root = doc.create_root_node ("Analytics");
 
        root->add_child("Version")->add_child_text(raw_convert<string>(_current_version));
-       boost::mutex::scoped_lock lm (_mutex);
        root->add_child("Id")->add_child_text(_id);
        BOOST_FOREACH (Event e, _events) {
                e.as_xml (root->add_child("Event"));
        }
+}
 
+/** Must be called with a lock held on _mutex */
+void
+Analytics::write () const
+{
        try {
+               xmlpp::Document doc;
+               xmlpp_document (doc);
                doc.write_to_file_formatted(path("analytics.xml").string());
        } catch (xmlpp::exception& e) {
                string s = e.what ();
index 36519ea80e05030e9240f96f48231381280efeca..dbeebf6b514b55a10f80e93aa17c7f90142cd676 100644 (file)
@@ -49,11 +49,11 @@ class Analytics : public State, public Signaller
 {
 public:
        Analytics ();
+       ~Analytics ();
 
-       void job_state_changed (boost::shared_ptr<Job> job);
+       void start ();
 
-       void write () const;
-       void read ();
+       void job_state_changed (boost::shared_ptr<Job> job);
 
        boost::signals2::signal<void (std::string, std::string)> Message;
 
@@ -61,11 +61,16 @@ public:
 
 private:
        int successful_dcp_encodes () const;
+       void xmlpp_document (xmlpp::Document &) const;
+       void write () const;
+       void read ();
+       void thread ();
 
        /** Mutex to protect _id and _events */
        mutable boost::mutex _mutex;
        std::string _id;
        std::list<Event> _events;
+       boost::thread* _thread;
        static Analytics* _instance;
        static int const _current_version;
 };
index fe23f8eafdb0a96af7378ee470854d1a3ba7e446..bec206888fe546243498592d1c8834df91da085b 100644 (file)
@@ -1433,6 +1433,8 @@ private:
                        UpdateChecker::instance()->run ();
                }
 
+               Analytics::instance()->start ();
+
                return true;
        }
        catch (exception& e)