From: Carl Hetherington Date: Mon, 11 Feb 2013 23:56:33 +0000 (+0000) Subject: Check for a DCP before offering to copy it to a TMS. X-Git-Tag: v2.0.48~1337^2~682 X-Git-Url: https://git.carlh.net/gitweb/?a=commitdiff_plain;h=106c8fb2d471cb0b01da3b6b09e743304a869f4b;p=dcpomatic.git Check for a DCP before offering to copy it to a TMS. --- diff --git a/src/lib/film.cc b/src/lib/film.cc index ff4d3b8f5..36ebe7199 100644 --- a/src/lib/film.cc +++ b/src/lib/film.cc @@ -63,7 +63,6 @@ using std::ofstream; using std::setfill; using std::min; using std::make_pair; -using std::cout; using boost::shared_ptr; using boost::lexical_cast; using boost::to_upper_copy; @@ -104,6 +103,8 @@ Film::Film (string d, bool must_exist) , _frames_per_second (0) , _dirty (false) { + set_dci_date_today (); + /* Make state.directory a complete path without ..s (where possible) (Code swiped from Adam Bowen on stackoverflow) */ @@ -139,7 +140,6 @@ Film::Film (string d, bool must_exist) } _log = new FileLog (file ("log")); - set_dci_date_today (); } Film::Film (Film const & o) @@ -171,6 +171,7 @@ Film::Film (Film const & o) , _colour_lut (o._colour_lut) , _j2k_bandwidth (o._j2k_bandwidth) , _dci_metadata (o._dci_metadata) + , _dci_date (o._dci_date) , _size (o._size) , _length (o._length) , _dcp_intrinsic_duration (o._dcp_intrinsic_duration) @@ -409,6 +410,7 @@ Film::write_metadata () const f << "colour_lut " << _colour_lut << "\n"; f << "j2k_bandwidth " << _j2k_bandwidth << "\n"; _dci_metadata.write (f); + f << "dci_date " << boost::gregorian::to_iso_string (_dci_date) << "\n"; f << "width " << _size.width << "\n"; f << "height " << _size.height << "\n"; f << "length " << _length.get_value_or(0) << "\n"; @@ -535,6 +537,8 @@ Film::read_metadata () _colour_lut = atoi (v.c_str ()); } else if (k == "j2k_bandwidth") { _j2k_bandwidth = atoi (v.c_str ()); + } else if (k == "dci_date") { + _dci_date = boost::gregorian::from_undelimited_string (v); } _dci_metadata.read (k, v); @@ -696,7 +700,7 @@ Film::still_duration_in_frames () const /** @return a DCI-compliant name for a DCP of this film */ string -Film::dci_name () const +Film::dci_name (bool if_created_now) const { stringstream d; @@ -764,7 +768,11 @@ Film::dci_name () const d << dm.studio << "_"; } - d << boost::gregorian::to_iso_string (_dci_date) << "_"; + if (if_created_now) { + d << boost::gregorian::to_iso_string (boost::gregorian::day_clock::local_day ()) << "_"; + } else { + d << boost::gregorian::to_iso_string (_dci_date) << "_"; + } if (!dm.facility.empty ()) { d << dm.facility << "_"; @@ -779,10 +787,10 @@ Film::dci_name () const /** @return name to give the DCP */ string -Film::dcp_name () const +Film::dcp_name (bool if_created_now) const { if (use_dci_name()) { - return dci_name (); + return dci_name (if_created_now); } return name(); @@ -1355,4 +1363,20 @@ Film::j2c_path (int f, bool t) const return file (p.string ()); } +/** Make an educated guess as to whether we have a complete DCP + * or not. + * @return true if we do. + */ +bool +Film::have_dcp () const +{ + try { + libdcp::DCP dcp (dir (dcp_name())); + dcp.read (); + } catch (...) { + return false; + } + + return true; +} diff --git a/src/lib/film.h b/src/lib/film.h index 5b65a099d..cc77460db 100644 --- a/src/lib/film.h +++ b/src/lib/film.h @@ -92,8 +92,8 @@ public: void read_metadata (); libdcp::Size cropped_size (libdcp::Size) const; - std::string dci_name () const; - std::string dcp_name () const; + std::string dci_name (bool if_created_now) const; + std::string dcp_name (bool if_created_now = false) const; boost::optional dcp_intrinsic_duration () const { return _dcp_intrinsic_duration; @@ -108,6 +108,8 @@ public: void set_dci_date_today (); + bool have_dcp () const; + /** Identifiers for the parts of our state; used for signalling changes. */ @@ -373,9 +375,6 @@ private: /** Any running ExamineContentJob, or 0 */ boost::shared_ptr _examine_content_job; - /** The date that we should use in a DCI name */ - boost::gregorian::date _dci_date; - void signal_changed (Property); void examine_content_finished (); std::string video_state_identifier () const; @@ -452,6 +451,8 @@ private: /** DCI naming stuff */ DCIMetadata _dci_metadata; + /** The date that we should use in a DCI name */ + boost::gregorian::date _dci_date; /* Data which are cached to speed things up */ @@ -478,6 +479,7 @@ private: mutable boost::mutex _state_mutex; friend class paths_test; + friend class film_metadata_test; }; #endif diff --git a/src/tools/dvdomatic.cc b/src/tools/dvdomatic.cc index 4572678e3..b90f3b07f 100644 --- a/src/tools/dvdomatic.cc +++ b/src/tools/dvdomatic.cc @@ -54,6 +54,7 @@ static FilmViewer* film_viewer = 0; static shared_ptr film; static std::string log_level; static std::string film_to_load; +static wxMenu* jobs_menu = 0; static void set_menu_sensitivity (); @@ -159,19 +160,19 @@ setup_menu (wxMenuBar* m) wxMenu* edit = new wxMenu; add_item (edit, "&Preferences...", ID_edit_preferences, ALWAYS); - wxMenu* jobs = new wxMenu; - add_item (jobs, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); - add_item (jobs, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); - jobs->AppendSeparator (); - add_item (jobs, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); - add_item (jobs, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); + jobs_menu = new wxMenu; + add_item (jobs_menu, "&Make DCP", ID_jobs_make_dcp, NEEDS_FILM); + add_item (jobs_menu, "&Send DCP to TMS", ID_jobs_send_dcp_to_tms, NEEDS_FILM); + jobs_menu->AppendSeparator (); + add_item (jobs_menu, "&Examine content", ID_jobs_examine_content, NEEDS_FILM); + add_item (jobs_menu, "Make DCP from existing &transcode", ID_jobs_make_dcp_from_existing_transcode, NEEDS_FILM); wxMenu* help = new wxMenu; add_item (help, "About", ID_help_about, ALWAYS); m->Append (file, _("&File")); m->Append (edit, _("&Edit")); - m->Append (jobs, _("&Jobs")); + m->Append (jobs_menu, _("&Jobs")); m->Append (help, _("&Help")); } @@ -204,6 +205,8 @@ public: Connect (ID_jobs_make_dcp_from_existing_transcode, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::jobs_make_dcp_from_existing_transcode)); Connect (ID_help_about, wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler (Frame::help_about)); + Connect (wxID_ANY, wxEVT_MENU_OPEN, wxMenuEventHandler (Frame::menu_opened)); + wxPanel* panel = new wxPanel (this); wxSizer* s = new wxBoxSizer (wxHORIZONTAL); s->Add (panel, 1, wxEXPAND); @@ -237,6 +240,18 @@ public: set_film (); } +private: + + void menu_opened (wxMenuEvent& ev) + { + if (ev.GetMenu() != jobs_menu) { + return; + } + + bool const have_dcp = film && film->have_dcp(); + jobs_menu->Enable (ID_jobs_send_dcp_to_tms, have_dcp); + } + void set_film () { film_viewer->set_film (film); diff --git a/src/wx/film_editor.cc b/src/wx/film_editor.cc index 634e417df..956084261 100644 --- a/src/wx/film_editor.cc +++ b/src/wx/film_editor.cc @@ -585,7 +585,7 @@ FilmEditor::film_changed (Film::Property p) } else { checked_set (_format, n); } - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; } case Film::CROP: @@ -608,8 +608,7 @@ FilmEditor::film_changed (Film::Property p) } case Film::NAME: checked_set (_name, _film->name()); - _film->set_dci_date_today (); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::FRAMES_PER_SECOND: s << fixed << setprecision(2) << _film->frames_per_second(); @@ -639,7 +638,7 @@ FilmEditor::film_changed (Film::Property p) break; case Film::DCP_CONTENT_TYPE: checked_set (_dcp_content_type, DCPContentType::as_index (_film->dcp_content_type ())); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::DCP_AB: checked_set (_dcp_ab, _film->dcp_ab ()); @@ -665,7 +664,7 @@ FilmEditor::film_changed (Film::Property p) case Film::WITH_SUBTITLES: checked_set (_with_subtitles, _film->with_subtitles ()); setup_subtitle_control_sensitivity (); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::SUBTITLE_OFFSET: checked_set (_subtitle_offset, _film->subtitle_offset ()); @@ -681,23 +680,23 @@ FilmEditor::film_changed (Film::Property p) break; case Film::USE_DCI_NAME: checked_set (_use_dci_name, _film->use_dci_name ()); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::DCI_METADATA: - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); break; case Film::CONTENT_AUDIO_STREAM: if (_film->content_audio_stream()) { checked_set (_audio_stream, _film->content_audio_stream()->to_string()); } - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); break; case Film::USE_CONTENT_AUDIO: checked_set (_use_content_audio, _film->use_content_audio()); checked_set (_use_external_audio, !_film->use_content_audio()); - _dcp_name->SetLabel (std_to_wx (_film->dcp_name ())); + setup_dcp_name (); setup_audio_details (); setup_audio_control_sensitivity (); break; @@ -1171,3 +1170,9 @@ FilmEditor::external_audio_changed (wxCommandEvent &) _film->set_external_audio (a); } + +void +FilmEditor::setup_dcp_name () +{ + _dcp_name->SetLabel (std_to_wx (_film->dcp_name (true))); +} diff --git a/src/wx/film_editor.h b/src/wx/film_editor.h index 90be752d8..8cb90b481 100644 --- a/src/wx/film_editor.h +++ b/src/wx/film_editor.h @@ -94,6 +94,7 @@ private: void setup_audio_control_sensitivity (); void setup_streams (); void setup_audio_details (); + void setup_dcp_name (); wxControl* video_control (wxControl *); wxControl* still_control (wxControl *); diff --git a/test/metadata.ref b/test/metadata.ref index 4250bdf23..ab40dfe8d 100644 --- a/test/metadata.ref +++ b/test/metadata.ref @@ -31,6 +31,7 @@ rating studio facility package_type +dci_date 20130211 width 0 height 0 length 0 diff --git a/test/test.cc b/test/test.cc index 771ef9992..75199fac7 100644 --- a/test/test.cc +++ b/test/test.cc @@ -21,6 +21,7 @@ #include #include #include +#include #include "format.h" #include "film.h" #include "filter.h" @@ -60,14 +61,25 @@ setup_test_config () Config::instance()->set_default_dci_metadata (DCIMetadata ()); } +boost::filesystem::path +test_film_dir (string name) +{ + boost::filesystem::path p; + p /= "build"; + p /= "test"; + p /= name; + return p; +} + shared_ptr new_test_film (string name) { - string const d = String::compose ("build/test/%1", name); - if (boost::filesystem::exists (d)) { - boost::filesystem::remove_all (d); + boost::filesystem::path p = test_film_dir (name); + if (boost::filesystem::exists (p)) { + boost::filesystem::remove_all (p); } - return shared_ptr (new Film (d, false)); + + return shared_ptr (new Film (p.string(), false)); } @@ -144,6 +156,7 @@ BOOST_AUTO_TEST_CASE (film_metadata_test) BOOST_CHECK_THROW (new Film (test_film, true), OpenFileError); shared_ptr f (new Film (test_film, false)); + f->_dci_date = boost::gregorian::from_undelimited_string ("20130211"); BOOST_CHECK (f->format() == 0); BOOST_CHECK (f->dcp_content_type() == 0); BOOST_CHECK (f->filters ().empty()); @@ -468,6 +481,7 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) film->set_format (Format::from_nickname ("Flat")); film->set_dcp_content_type (DCPContentType::from_pretty_name ("Test")); film->make_dcp (true); + film->write_metadata (); while (JobManager::instance()->work_to_do ()) { dvdomatic_sleep (1); @@ -476,6 +490,19 @@ BOOST_AUTO_TEST_CASE (make_dcp_test) BOOST_CHECK_EQUAL (JobManager::instance()->errors(), false); } +/** Test Film::have_dcp(). Requires the output from make_dcp_test above */ +BOOST_AUTO_TEST_CASE (have_dcp_test) +{ + boost::filesystem::path p = test_film_dir ("make_dcp_test"); + Film f (p.string ()); + BOOST_CHECK (f.have_dcp()); + + p /= f.dcp_name(); + p /= "video.mxf"; + boost::filesystem::remove (p); + BOOST_CHECK (!f.have_dcp ()); +} + BOOST_AUTO_TEST_CASE (make_dcp_with_range_test) { shared_ptr film = new_test_film ("make_dcp_with_range_test");