X-Git-Url: https://git.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Ftools%2Fdcpomatic_disk.cc;h=ec5d8e782db122dc4a15814432aa3ddae5bb2f2c;hb=ccacce39c39d16977ab6c1592fcb6e941b05ddff;hp=5ae5cfb927168fb455d7cc8f173395835331c264;hpb=adcf6f9adcd8b33fd6f3cf0e5b00a4a4db183002;p=dcpomatic.git diff --git a/src/tools/dcpomatic_disk.cc b/src/tools/dcpomatic_disk.cc index 5ae5cfb92..ec5d8e782 100644 --- a/src/tools/dcpomatic_disk.cc +++ b/src/tools/dcpomatic_disk.cc @@ -19,24 +19,26 @@ */ -#include "wx/wx_signal_manager.h" -#include "wx/wx_util.h" -#include "wx/job_manager_view.h" +#include "wx/disk_warning_dialog.h" #include "wx/drive_wipe_warning_dialog.h" -#include "wx/try_unmount_dialog.h" +#include "wx/job_manager_view.h" #include "wx/message_dialog.h" -#include "wx/disk_warning_dialog.h" -#include "lib/file_log.h" -#include "lib/dcpomatic_log.h" -#include "lib/util.h" +#include "wx/try_unmount_dialog.h" +#include "wx/wx_util.h" +#include "wx/wx_signal_manager.h" +#include "wx/wx_util.h" #include "lib/config.h" -#include "lib/signal_manager.h" -#include "lib/cross.h" #include "lib/copy_to_drive_job.h" -#include "lib/job_manager.h" +#include "lib/cross.h" +#include "lib/dcpomatic_log.h" #include "lib/disk_writer_messages.h" +#include "lib/file_log.h" +#include "lib/job_manager.h" +#include "lib/signal_manager.h" +#include "lib/util.h" #include "lib/version.h" #include "lib/warnings.h" +#include #include DCPOMATIC_DISABLE_WARNINGS #include @@ -49,11 +51,12 @@ DCPOMATIC_ENABLE_WARNINGS #endif -using std::string; -using std::exception; -using std::cout; using std::cerr; +using std::cout; +using std::exception; +using std::make_shared; using std::shared_ptr; +using std::string; using boost::optional; #if BOOST_VERSION >= 106100 using namespace boost::placeholders; @@ -136,7 +139,7 @@ public: /* XXX: this is a hack, but I expect we'll need logs and I'm not sure if there's * a better place to put them. */ - dcpomatic_log.reset(new FileLog(config_path() / "disk.log")); + dcpomatic_log = make_shared(State::write_path("disk.log")); dcpomatic_log->set_types (dcpomatic_log->types() | LogEntry::TYPE_DISK); LOG_DISK("dcpomatic_disk %1 started", dcpomatic_git_commit); @@ -171,6 +174,21 @@ public: ~DOMFrame () { _nanomsg.send(DISK_WRITER_QUIT "\n", 2000); + /* This seems really horrible but it's suggested by the examples on nanomsg.org, so... + * Without this the quit is not received (at least sometimes) causing #2018. + */ + dcpomatic_sleep_seconds (1); + } + + void set_dcp (boost::filesystem::path dcp) + { + if (!boost::filesystem::exists(dcp / "ASSETMAP") && !boost::filesystem::exists(dcp / "ASSETMAP.xml")) { + error_dialog (nullptr, _("No ASSETMAP or ASSETMAP.xml found in this folder. Please choose a DCP folder.")); + return; + } + + _dcp_path = dcp; + _dcp_name->SetLabel (std_to_wx(dcp.filename().string())); } private: @@ -230,28 +248,49 @@ private: return; } - _dcp_path = path; - _dcp_name->SetLabel (std_to_wx(_dcp_path->filename().string())); + set_dcp (path); setup_sensitivity (); } void copy () { + /* Check that the selected drive still exists and update its properties if so */ + drive_refresh (); + if (_drive->GetSelection() == wxNOT_FOUND) { + error_dialog (this, _("The disk you selected is no longer available. Please choose another.")); + return; + } + DCPOMATIC_ASSERT (_drive->GetSelection() != wxNOT_FOUND); DCPOMATIC_ASSERT (static_cast(_dcp_path)); - bool have_writer = true; - if (!_nanomsg.send(DISK_WRITER_PING "\n", 2000)) { - have_writer = false; - } else { - auto reply = _nanomsg.receive (2000); - if (!reply || *reply != DISK_WRITER_PONG) { - have_writer = false; + auto ping = [this](int attempt) { + if (_nanomsg.send(DISK_WRITER_PING "\n", 1000)) { + auto reply = _nanomsg.receive (1000); + if (reply && *reply == DISK_WRITER_PONG) { + return true; + } else if (reply) { + LOG_DISK("Unexpected response %1 to ping received (attempt %2)", *reply, attempt); + } else { + LOG_DISK("No reply received from ping (attempt %1)", attempt); + } + } else { + LOG_DISK("Could not send ping to writer (attempt %1)", attempt); + } + dcpomatic_sleep_seconds (1); + return false; + }; + + bool have_writer = false; + for (int i = 0; i < 8; ++i) { + if (ping(i + 1)) { + have_writer = true; + break; } } if (!have_writer) { -#ifdef DCPOMATIC_WINDOWS +#if defined(DCPOMATIC_WINDOWS) auto m = new MessageDialog ( this, _("DCP-o-matic Disk Writer"), @@ -260,7 +299,17 @@ private: m->ShowModal (); m->Destroy (); return; +#elif defined(DCPOMATIC_OSX) + auto m = new MessageDialog ( + this, + _("DCP-o-matic Disk Writer"), + _("Did you install the DCP-o-matic Disk Writer.pkg from the .dmg? Please check and try again.") + ); + m->ShowModal (); + m->Destroy (); + return; #else + LOG_DISK_NC ("Failed to ping writer"); throw CommunicationFailedError (); #endif } @@ -276,12 +325,15 @@ private: LOG_DISK("Sending unmount request to disk writer for %1", drive.as_xml()); if (!_nanomsg.send(DISK_WRITER_UNMOUNT "\n", 2000)) { + LOG_DISK_NC("Failed to send unmount request."); throw CommunicationFailedError (); } if (!_nanomsg.send(drive.as_xml(), 2000)) { + LOG_DISK_NC("Failed to send drive for unmount request."); throw CommunicationFailedError (); } - auto reply = _nanomsg.receive (2000); + /* The reply may have to wait for the user to authenticate, so let's wait a while */ + auto reply = _nanomsg.receive (30000); if (!reply || *reply != DISK_WRITER_OK) { auto * m = new MessageDialog ( this, @@ -352,11 +404,18 @@ private: }; +static const wxCmdLineEntryDesc command_line_description[] = { + { wxCMD_LINE_OPTION, "d", "dcp", "DCP to write", wxCMD_LINE_VAL_STRING, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_SWITCH, "s", "sure", "skip alpha test warnings", wxCMD_LINE_VAL_NONE, wxCMD_LINE_PARAM_OPTIONAL }, + { wxCMD_LINE_NONE, "", "", "", wxCmdLineParamType (0), 0 } +}; + + class App : public wxApp { public: App () - : _frame (0) + : _frame (nullptr) {} bool OnInit () @@ -400,18 +459,24 @@ public: */ Config::drop (); - auto warning = new DiskWarningDialog (); - warning->ShowModal (); - if (!warning->confirmed()) { - return false; + if (!_skip_alpha_check) { + auto warning = new DiskWarningDialog (); + warning->ShowModal (); + if (!warning->confirmed()) { + return false; + } + warning->Destroy (); } - warning->Destroy (); _frame = new DOMFrame (_("DCP-o-matic Disk Writer")); SetTopWindow (_frame); _frame->Show (); + if (_dcp_to_write) { + _frame->set_dcp (*_dcp_to_write); + } + signal_manager = new wxSignalManager (this); Bind (wxEVT_IDLE, boost::bind (&App::idle, this, _1)); } @@ -424,6 +489,24 @@ public: return true; } + void OnInitCmdLine (wxCmdLineParser& parser) + { + parser.SetDesc (command_line_description); + parser.SetSwitchChars (wxT ("-")); + } + + bool OnCmdLineParsed (wxCmdLineParser& parser) + { + _skip_alpha_check = parser.Found(wxT("sure")); + + wxString dcp; + if (parser.Found(wxT("dcp"), &dcp)) { + _dcp_to_write = wx_to_std (dcp); + } + + return true; + } + void config_failed_to_load () { message_dialog (_frame, _("The existing configuration failed to load. Default values will be used instead. These may take a short time to create.")); @@ -479,6 +562,8 @@ public: } DOMFrame* _frame; + bool _skip_alpha_check = false; + boost::optional _dcp_to_write; }; IMPLEMENT_APP (App)