X-Git-Url: https://main.carlh.net/gitweb/?p=dcpomatic.git;a=blobdiff_plain;f=src%2Flib%2Fconfig.cc;h=a4dea7fd1abb49926a3b709b3f90f1e0bc45209a;hp=4bc4f60f2f5640d6fa264fc9055d55a1e0e9b1b0;hb=HEAD;hpb=00885f610bb9957c602a3aff92fa79066b2b2ef3 diff --git a/src/lib/config.cc b/src/lib/config.cc index 4bc4f60f2..384db5cde 100644 --- a/src/lib/config.cc +++ b/src/lib/config.cc @@ -23,8 +23,8 @@ #include "colour_conversion.h" #include "compose.hpp" #include "config.h" +#include "constants.h" #include "cross.h" -#include "crypto.h" #include "dcp_content_type.h" #include "dkdm_recipient.h" #include "dkdm_wrapper.h" @@ -32,8 +32,7 @@ #include "filter.h" #include "log.h" #include "ratio.h" -#include "types.h" -#include "util.h" +#include "unzipper.h" #include "zipper.h" #include #include @@ -107,7 +106,7 @@ Config::set_defaults () _language = optional (); _default_still_length = 10; _default_dcp_content_type = DCPContentType::from_isdcf_name ("FTR"); - _default_dcp_audio_channels = 6; + _default_dcp_audio_channels = 8; _default_j2k_bandwidth = 150000000; _default_audio_delay = 0; _default_interop = false; @@ -141,9 +140,9 @@ Config::set_defaults () _dkdm_recipients_file = read_path ("dkdm_recipients.xml"); _show_hints_before_make_dcp = true; _confirm_kdm_email = true; - _kdm_container_name_format = dcp::NameFormat ("KDM %f %c"); - _kdm_filename_format = dcp::NameFormat ("KDM %f %c %s"); - _dkdm_filename_format = dcp::NameFormat ("DKDM %f %c %s"); + _kdm_container_name_format = dcp::NameFormat("KDM_%f_%c"); + _kdm_filename_format = dcp::NameFormat("KDM_%f_%c_%s"); + _dkdm_filename_format = dcp::NameFormat("DKDM_%f_%c_%s"); _dcp_metadata_filename_format = dcp::NameFormat ("%t"); _dcp_asset_filename_format = dcp::NameFormat ("%t"); _jump_to_selected = true; @@ -154,6 +153,7 @@ Config::set_defaults () _sound_output = optional (); _last_kdm_write_type = KDM_WRITE_FLAT; _last_dkdm_write_type = DKDM_WRITE_INTERNAL; + _default_add_file_location = DefaultAddFileLocation::SAME_AS_LAST_TIME; /* I think the scaling factor here should be the ratio of the longest frame encode time to the shortest; if the thread count is T, longest time is L @@ -186,7 +186,18 @@ Config::set_defaults () _player_kdm_directory = boost::none; _audio_mapping = boost::none; _custom_languages.clear (); - _add_files_path = boost::none; + _initial_paths.clear(); + _initial_paths["AddFilesPath"] = boost::none; + _initial_paths["AddKDMPath"] = boost::none; + _initial_paths["AddDKDMPath"] = boost::none; + _initial_paths["SelectCertificatePath"] = boost::none; + _initial_paths["AddCombinerInputPath"] = boost::none; + _initial_paths["ExportSubtitlesPath"] = boost::none; + _initial_paths["ExportVideoPath"] = boost::none; + _initial_paths["DebugLogPath"] = boost::none; + _initial_paths["CinemaDatabasePath"] = boost::none; + _initial_paths["ConfigFilePath"] = boost::none; + _initial_paths["Preferences"] = boost::none; _use_isdcf_name_by_default = true; _write_kdms_to_disk = true; _email_kdms = false; @@ -194,6 +205,8 @@ Config::set_defaults () _default_kdm_duration = RoughDuration(1, RoughDuration::Unit::WEEKS); _auto_crop_threshold = 0.1; _last_release_notes_version = boost::none; + _allow_smpte_bv20 = false; + _isdcf_name_part_length = 14; _allowed_dcp_frame_rates.clear (); _allowed_dcp_frame_rates.push_back (24); @@ -285,7 +298,7 @@ Config::read_config() try { cxml::Document f ("Config"); - f.read_file (config_read_file()); + f.read_file(dcp::filesystem::fix_long_path(config_read_file())); auto version = f.optional_number_child ("Version"); if (version && *version < _current_version) { @@ -495,6 +508,7 @@ try case BAD_SIGNER_UTF8_STRINGS: case BAD_SIGNER_INCONSISTENT: case BAD_SIGNER_VALIDITY_TOO_LONG: + case BAD_SIGNER_DN_QUALIFIER: _signer_chain = create_certificate_chain (); break; case BAD_DECRYPTION_INCONSISTENT: @@ -600,7 +614,9 @@ try } catch (std::runtime_error& e) {} } - _add_files_path = f.optional_string_child("AddFilesPath"); + for (auto& initial: _initial_paths) { + initial.second = f.optional_string_child(initial.first); + } _use_isdcf_name_by_default = f.optional_bool_child("UseISDCFNameByDefault").get_value_or(true); _write_kdms_to_disk = f.optional_bool_child("WriteKDMsToDisk").get_value_or(true); _email_kdms = f.optional_bool_child("EmailKDMs").get_value_or(false); @@ -615,6 +631,17 @@ try _main_divider_sash_position = f.optional_number_child("MainDividerSashPosition"); _main_content_divider_sash_position = f.optional_number_child("MainContentDividerSashPosition"); + if (auto loc = f.optional_string_child("DefaultAddFileLocation")) { + if (*loc == "last") { + _default_add_file_location = DefaultAddFileLocation::SAME_AS_LAST_TIME; + } else if (*loc == "project") { + _default_add_file_location = DefaultAddFileLocation::SAME_AS_PROJECT; + } + } + + _allow_smpte_bv20 = f.optional_bool_child("AllowSMPTEBv20").get_value_or(false); + _isdcf_name_part_length = f.optional_number_child("ISDCFNamePartLength").get_value_or(14); + _export.read(f.optional_node_child("Export")); } catch (...) { @@ -635,10 +662,10 @@ catch (...) { void Config::read_cinemas() { - if (boost::filesystem::exists (_cinemas_file)) { + if (dcp::filesystem::exists(_cinemas_file)) { try { cxml::Document f("Cinemas"); - f.read_file(_cinemas_file); + f.read_file(dcp::filesystem::fix_long_path(_cinemas_file)); read_cinemas(f); } catch (...) { backup(); @@ -652,10 +679,10 @@ Config::read_cinemas() void Config::read_dkdm_recipients() { - if (boost::filesystem::exists (_dkdm_recipients_file)) { + if (dcp::filesystem::exists(_dkdm_recipients_file)) { try { cxml::Document f("DKDMRecipients"); - f.read_file(_dkdm_recipients_file); + f.read_file(dcp::filesystem::fix_long_path(_dkdm_recipients_file)); read_dkdm_recipients(f); } catch (...) { backup(); @@ -1024,7 +1051,7 @@ Config::write_config () const } /* [XML] PlayerMode window for a single window, full for full-screen and dual for full screen playback - with controls on another monitor. + with separate (advanced) controls. */ switch (_player_mode) { case PLAYER_MODE_WINDOW: @@ -1072,9 +1099,10 @@ Config::write_config () const for (auto const& i: _custom_languages) { root->add_child("CustomLanguage")->add_child_text(i.to_string()); } - if (_add_files_path) { - /* [XML] AddFilesPath The default path that will be offered in the picker when adding files to a film. */ - root->add_child("AddFilesPath")->add_child_text(_add_files_path->string()); + for (auto const& initial: _initial_paths) { + if (initial.second) { + root->add_child(initial.first)->add_child_text(initial.second->string()); + } } root->add_child("UseISDCFNameByDefault")->add_child_text(_use_isdcf_name_by_default ? "1" : "0"); root->add_child("WriteKDMsToDisk")->add_child_text(_write_kdms_to_disk ? "1" : "0"); @@ -1091,6 +1119,15 @@ Config::write_config () const root->add_child("MainContentDividerSashPosition")->add_child_text(raw_convert(*_main_content_divider_sash_position)); } + root->add_child("DefaultAddFileLocation")->add_child_text( + _default_add_file_location == DefaultAddFileLocation::SAME_AS_LAST_TIME ? "last" : "project" + ); + + /* [XML] AllowSMPTEBv20 1 to allow the user to choose SMPTE (Bv2.0 only) as a standard, otherwise 0 */ + root->add_child("AllowSMPTEBv20")->add_child_text(_allow_smpte_bv20 ? "1" : "0"); + /* [XML] ISDCFNamePartLength Maximum length of the "name" part of an ISDCF name, which should be 14 according to the standard */ + root->add_child("ISDCFNamePartLength")->add_child_text(raw_convert(_isdcf_name_part_length)); + _export.write(root->add_child("Export")); auto target = config_write_file(); @@ -1104,8 +1141,8 @@ Config::write_config () const } f.checked_write(s.c_str(), s.bytes()); f.close(); - boost::filesystem::remove (target); - boost::filesystem::rename (tmp, target); + dcp::filesystem::remove(target); + dcp::filesystem::rename(tmp, target); } catch (xmlpp::exception& e) { string s = e.what (); trim (s); @@ -1128,8 +1165,8 @@ write_file (string root_node, string node, string version, list> t try { doc.write_to_file_formatted (file.string() + ".tmp"); - boost::filesystem::remove (file); - boost::filesystem::rename (file.string() + ".tmp", file); + dcp::filesystem::remove(file); + dcp::filesystem::rename(file.string() + ".tmp", file); } catch (xmlpp::exception& e) { string s = e.what (); trim (s); @@ -1172,7 +1209,7 @@ Config::directory_or (optional dir, boost::filesystem:: } boost::system::error_code ec; - auto const e = boost::filesystem::exists (*dir, ec); + auto const e = dcp::filesystem::exists(*dir, ec); if (ec || !e) { return a; } @@ -1184,7 +1221,7 @@ void Config::drop () { delete _instance; - _instance = 0; + _instance = nullptr; } void @@ -1267,7 +1304,7 @@ Config::add_to_player_history (boost::filesystem::path p) add_to_history_internal (_player_history, p); } -/** Remove non-existant items from the player history */ +/** Remove non-existent items from the player history */ void Config::clean_player_history () { @@ -1295,7 +1332,7 @@ Config::clean_history_internal (vector& h) h.clear (); for (auto i: old) { try { - if (boost::filesystem::is_directory(i)) { + if (dcp::filesystem::is_directory(i)) { h.push_back (i); } } catch (...) { @@ -1308,7 +1345,7 @@ Config::clean_history_internal (vector& h) bool Config::have_existing (string file) { - return boost::filesystem::exists (read_path(file)); + return dcp::filesystem::exists(read_path(file)); } @@ -1335,10 +1372,10 @@ Config::set_cinemas_file (boost::filesystem::path file) _cinemas_file = file; - if (boost::filesystem::exists (_cinemas_file)) { + if (dcp::filesystem::exists(_cinemas_file)) { /* Existing file; read it in */ cxml::Document f ("Cinemas"); - f.read_file (_cinemas_file); + f.read_file(dcp::filesystem::fix_long_path(_cinemas_file)); read_cinemas (f); } @@ -1367,12 +1404,12 @@ Config::save_template (shared_ptr film, string name) const list Config::templates () const { - if (!boost::filesystem::exists(read_path("templates"))) { + if (!dcp::filesystem::exists(read_path("templates"))) { return {}; } list n; - for (auto const& i: boost::filesystem::directory_iterator(read_path("templates"))) { + for (auto const& i: dcp::filesystem::directory_iterator(read_path("templates"))) { n.push_back (i.path().filename().string()); } return n; @@ -1381,7 +1418,7 @@ Config::templates () const bool Config::existing_template (string name) const { - return boost::filesystem::exists (template_read_path(name)); + return dcp::filesystem::exists(template_read_path(name)); } @@ -1402,13 +1439,13 @@ Config::template_write_path (string name) const void Config::rename_template (string old_name, string new_name) const { - boost::filesystem::rename (template_read_path(old_name), template_write_path(new_name)); + dcp::filesystem::rename(template_read_path(old_name), template_write_path(new_name)); } void Config::delete_template (string name) const { - boost::filesystem::remove (template_write_path(name)); + dcp::filesystem::remove(template_write_path(name)); } /** @return Path to the config.xml containing the actual settings, following a link if required */ @@ -1416,14 +1453,14 @@ boost::filesystem::path config_file (boost::filesystem::path main) { cxml::Document f ("Config"); - if (!boost::filesystem::exists (main)) { + if (!dcp::filesystem::exists(main)) { /* It doesn't exist, so there can't be any links; just return it */ return main; } /* See if there's a link */ try { - f.read_file (main); + f.read_file(dcp::filesystem::fix_long_path(main)); auto link = f.optional_string_child("Link"); if (link) { return *link; @@ -1477,7 +1514,7 @@ void Config::copy_and_link (boost::filesystem::path new_file) const { write (); - boost::filesystem::copy_file (config_read_file(), new_file, boost::filesystem::copy_option::overwrite_if_exists); + dcp::filesystem::copy_file(config_read_file(), new_file, boost::filesystem::copy_option::overwrite_if_exists); link (new_file); } @@ -1561,6 +1598,9 @@ Config::check_certificates () const if ((i.not_after().year() - i.not_before().year()) > 15) { bad = BAD_SIGNER_VALIDITY_TOO_LONG; } + if (dcp::escape_digest(i.subject_dn_qualifier()) != dcp::public_key_digest(i.public_key())) { + bad = BAD_SIGNER_DN_QUALIFIER; + } } if (!_signer_chain->chain_valid() || !_signer_chain->private_key_valid()) { @@ -1582,13 +1622,66 @@ save_all_config_as_zip (boost::filesystem::path zip_file) auto config = Config::instance(); zipper.add ("config.xml", dcp::file_to_string(config->config_read_file())); - if (boost::filesystem::exists(config->cinemas_file())) { + if (dcp::filesystem::exists(config->cinemas_file())) { zipper.add ("cinemas.xml", dcp::file_to_string(config->cinemas_file())); } - if (boost::filesystem::exists(config->dkdm_recipients_file())) { + if (dcp::filesystem::exists(config->dkdm_recipients_file())) { zipper.add ("dkdm_recipients.xml", dcp::file_to_string(config->dkdm_recipients_file())); } zipper.close (); } + +void +Config::load_from_zip(boost::filesystem::path zip_file) +{ + Unzipper unzipper(zip_file); + dcp::write_string_to_file(unzipper.get("config.xml"), config_write_file()); + + try { + dcp::write_string_to_file(unzipper.get("cinemas.xml"), cinemas_file()); + dcp::write_string_to_file(unzipper.get("dkdm_recipient.xml"), dkdm_recipients_file()); + } catch (std::runtime_error&) {} + + read(); + + changed(Property::USE_ANY_SERVERS); + changed(Property::SERVERS); + changed(Property::CINEMAS); + changed(Property::DKDM_RECIPIENTS); + changed(Property::SOUND); + changed(Property::SOUND_OUTPUT); + changed(Property::PLAYER_CONTENT_DIRECTORY); + changed(Property::PLAYER_PLAYLIST_DIRECTORY); + changed(Property::PLAYER_DEBUG_LOG); + changed(Property::HISTORY); + changed(Property::SHOW_EXPERIMENTAL_AUDIO_PROCESSORS); + changed(Property::AUDIO_MAPPING); + changed(Property::AUTO_CROP_THRESHOLD); + changed(Property::ALLOW_SMPTE_BV20); + changed(Property::ISDCF_NAME_PART_LENGTH); + changed(Property::OTHER); +} + + +void +Config::set_initial_path(string id, boost::filesystem::path path) +{ + auto iter = _initial_paths.find(id); + DCPOMATIC_ASSERT(iter != _initial_paths.end()); + iter->second = path; + changed(); +} + + +optional +Config::initial_path(string id) const +{ + auto iter = _initial_paths.find(id); + if (iter == _initial_paths.end()) { + return {}; + } + return iter->second; +} +