From f968fb875135884b0551195edc2315d4be76d5bc Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Tue, 21 Aug 2018 22:36:24 +0100 Subject: [PATCH] Check content for changes on loading a project. --- src/lib/check_content_change_job.cc | 87 +++++++++++++++++++++++++++++ src/lib/check_content_change_job.h | 35 ++++++++++++ src/lib/content.cc | 24 +++++--- src/lib/content.h | 7 +++ src/lib/wscript | 1 + src/tools/dcpomatic.cc | 3 + 6 files changed, 148 insertions(+), 9 deletions(-) create mode 100644 src/lib/check_content_change_job.cc create mode 100644 src/lib/check_content_change_job.h diff --git a/src/lib/check_content_change_job.cc b/src/lib/check_content_change_job.cc new file mode 100644 index 000000000..0862ab085 --- /dev/null +++ b/src/lib/check_content_change_job.cc @@ -0,0 +1,87 @@ +/* + Copyright (C) 2018 Carl Hetherington + + 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 . + +*/ + +#include "check_content_change_job.h" +#include "job_manager.h" +#include "examine_content_job.h" +#include "content.h" +#include "film.h" +#include +#include + +#include "i18n.h" + +using std::string; +using std::list; +using std::cout; +using boost::shared_ptr; + +CheckContentChangeJob::CheckContentChangeJob (shared_ptr film) + : Job (film) +{ + +} + +string +CheckContentChangeJob::name () const +{ + return _("Check content for changes"); +} + +string +CheckContentChangeJob::json_name () const +{ + return N_("check_content_change"); +} + +void +CheckContentChangeJob::run () +{ + set_progress_unknown (); + + list > changed; + + BOOST_FOREACH (shared_ptr i, _film->content()) { + bool ic = false; + for (size_t j = 0; j < i->number_of_paths(); ++j) { + cout << boost::filesystem::last_write_time(i->path(j)) << " " << i->last_write_time(j) << "\n"; + if (boost::filesystem::last_write_time(i->path(j)) != i->last_write_time(j)) { + cout << "last write differs.\n"; + ic = true; + break; + } + } + if (!ic && i->calculate_digest() != i->digest()) { + cout << "digest differs.\n"; + ic = true; + } + if (ic) { + cout << i->path(0) << " changed.\n"; + changed.push_back (i); + } + } + + BOOST_FOREACH (shared_ptr i, changed) { + JobManager::instance()->add(shared_ptr(new ExamineContentJob(_film, i))); + } + + set_progress (1); + set_state (FINISHED_OK); +} diff --git a/src/lib/check_content_change_job.h b/src/lib/check_content_change_job.h new file mode 100644 index 000000000..4ae3ed1e9 --- /dev/null +++ b/src/lib/check_content_change_job.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2018 Carl Hetherington + + 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 . + +*/ + +#include "job.h" + +/** @class CheckContentChangeJob + * @brief A job to check whether content has changed since it was added to the film. + */ + +class CheckContentChangeJob : public Job +{ +public: + CheckContentChangeJob (boost::shared_ptr); + + std::string name () const; + std::string json_name () const; + void run (); +}; diff --git a/src/lib/content.cc b/src/lib/content.cc index 4e77831ac..69dcbc139 100644 --- a/src/lib/content.cc +++ b/src/lib/content.cc @@ -97,7 +97,7 @@ Content::Content (shared_ptr film, cxml::ConstNodePtr node) list path_children = node->node_children ("Path"); BOOST_FOREACH (cxml::NodePtr i, path_children) { _paths.push_back (i->content()); - optional const mod = i->optional_number_child("mtime"); + optional const mod = i->optional_number_attribute("mtime"); if (mod) { _last_write_times.push_back (*mod); } else if (boost::filesystem::exists(i->content())) { @@ -169,13 +169,9 @@ Content::as_xml (xmlpp::Node* node, bool with_paths) const } } -void -Content::examine (shared_ptr job) +string +Content::calculate_digest () const { - if (job) { - job->sub (_("Computing digest")); - } - boost::mutex::scoped_lock lm (_mutex); vector p = _paths; lm.unlock (); @@ -184,9 +180,19 @@ Content::examine (shared_ptr job) digest here: a digest of the first and last 1e6 bytes with the size of the first file tacked on the end as a string. */ - string const d = digest_head_tail (p, 1000000) + raw_convert (boost::filesystem::file_size (p.front ())); + return digest_head_tail(p, 1000000) + raw_convert(boost::filesystem::file_size(p.front())); +} - lm.lock (); +void +Content::examine (shared_ptr job) +{ + if (job) { + job->sub (_("Computing digest")); + } + + string const d = calculate_digest (); + + boost::mutex::scoped_lock lm (_mutex); _digest = d; } diff --git a/src/lib/content.h b/src/lib/content.h index 3ab272c16..2eaa738d2 100644 --- a/src/lib/content.h +++ b/src/lib/content.h @@ -118,6 +118,11 @@ public: return _paths[i]; } + std::time_t last_write_time (size_t i) const { + boost::mutex::scoped_lock lm (_mutex); + return _last_write_times[i]; + } + bool paths_valid () const; /** @return Digest of the content's file(s). Note: this is @@ -178,6 +183,8 @@ public: std::list user_properties () const; + std::string calculate_digest () const; + /* CHANGE_PENDING and CHANGE_CANCELLED may be emitted from any thread; CHANGE_DONE always from GUI thread */ boost::signals2::signal, int, bool)> Change; diff --git a/src/lib/wscript b/src/lib/wscript index 0cc3d7823..a85ce1f26 100644 --- a/src/lib/wscript +++ b/src/lib/wscript @@ -41,6 +41,7 @@ sources = """ text_content.cc text_decoder.cc case_insensitive_sorter.cc + check_content_change_job.cc cinema.cc cinema_kdms.cc cinema_sound_processor.cc diff --git a/src/tools/dcpomatic.cc b/src/tools/dcpomatic.cc index 7ae6b1c72..0af65bd26 100644 --- a/src/tools/dcpomatic.cc +++ b/src/tools/dcpomatic.cc @@ -71,6 +71,7 @@ #include "lib/transcode_job.h" #include "lib/dkdm_wrapper.h" #include "lib/audio_content.h" +#include "lib/check_content_change_job.h" #include "lib/text_content.h" #include #include @@ -414,6 +415,8 @@ public: } set_film (film); + + JobManager::instance()->add(shared_ptr(new CheckContentChangeJob(film))); } catch (std::exception& e) { wxString p = std_to_wx (file.string ()); -- 2.30.2