Fix some spelling mistakes (mostly in comments).
[dcpomatic.git] / src / lib / config.cc
1 /*
2     Copyright (C) 2012-2022 Carl Hetherington <cth@carlh.net>
3
4     This file is part of DCP-o-matic.
5
6     DCP-o-matic is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     DCP-o-matic is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with DCP-o-matic.  If not, see <http://www.gnu.org/licenses/>.
18
19 */
20
21
22 #include "cinema.h"
23 #include "colour_conversion.h"
24 #include "compose.hpp"
25 #include "config.h"
26 #include "cross.h"
27 #include "crypto.h"
28 #include "dcp_content_type.h"
29 #include "dkdm_recipient.h"
30 #include "dkdm_wrapper.h"
31 #include "film.h"
32 #include "filter.h"
33 #include "log.h"
34 #include "ratio.h"
35 #include "types.h"
36 #include "util.h"
37 #include "zipper.h"
38 #include <dcp/certificate_chain.h>
39 #include <dcp/name_format.h>
40 #include <dcp/raw_convert.h>
41 #include <libcxml/cxml.h>
42 #include <glib.h>
43 #include <libxml++/libxml++.h>
44 #include <boost/filesystem.hpp>
45 #include <boost/algorithm/string.hpp>
46 #include <boost/thread.hpp>
47 #include <cstdlib>
48 #include <fstream>
49 #include <iostream>
50
51 #include "i18n.h"
52
53
54 using std::cout;
55 using std::dynamic_pointer_cast;
56 using std::ifstream;
57 using std::list;
58 using std::make_shared;
59 using std::max;
60 using std::min;
61 using std::remove;
62 using std::shared_ptr;
63 using std::string;
64 using std::vector;
65 using boost::algorithm::trim;
66 using boost::optional;
67 using dcp::raw_convert;
68
69
70 Config* Config::_instance = 0;
71 int const Config::_current_version = 3;
72 boost::signals2::signal<void (Config::LoadFailure)> Config::FailedToLoad;
73 boost::signals2::signal<void (string)> Config::Warning;
74 boost::signals2::signal<bool (Config::BadReason)> Config::Bad;
75
76
77 /** Construct default configuration */
78 Config::Config ()
79         /* DKDMs are not considered a thing to reset on set_defaults() */
80         : _dkdms (new DKDMGroup ("root"))
81         , _default_kdm_duration (1, RoughDuration::Unit::WEEKS)
82         , _export(this)
83 {
84         set_defaults ();
85 }
86
87 void
88 Config::set_defaults ()
89 {
90         _master_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
91         _server_encoding_threads = max (2U, boost::thread::hardware_concurrency ());
92         _server_port_base = 6192;
93         _use_any_servers = true;
94         _servers.clear ();
95         _only_servers_encode = false;
96         _tms_protocol = FileTransferProtocol::SCP;
97         _tms_ip = "";
98         _tms_path = ".";
99         _tms_user = "";
100         _tms_password = "";
101         _allow_any_dcp_frame_rate = false;
102         _allow_any_container = false;
103         _allow_96khz_audio = false;
104         _use_all_audio_channels = false;
105         _show_experimental_audio_processors = false;
106         _language = optional<string> ();
107         _default_still_length = 10;
108         _default_container = Ratio::from_id ("185");
109         _default_dcp_content_type = DCPContentType::from_isdcf_name ("FTR");
110         _default_dcp_audio_channels = 6;
111         _default_j2k_bandwidth = 150000000;
112         _default_audio_delay = 0;
113         _default_interop = false;
114         _default_metadata.clear ();
115         _upload_after_make_dcp = false;
116         _mail_server = "";
117         _mail_port = 25;
118         _mail_protocol = EmailProtocol::AUTO;
119         _mail_user = "";
120         _mail_password = "";
121         _kdm_from = "";
122         _kdm_cc.clear ();
123         _kdm_bcc = "";
124         _notification_from = "";
125         _notification_to = "";
126         _notification_cc.clear ();
127         _notification_bcc = "";
128         _check_for_updates = false;
129         _check_for_test_updates = false;
130         _maximum_j2k_bandwidth = 250000000;
131         _log_types = LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR | LogEntry::TYPE_DISK;
132         _analyse_ebur128 = true;
133         _automatic_audio_analysis = false;
134 #ifdef DCPOMATIC_WINDOWS
135         _win32_console = false;
136 #endif
137         /* At the moment we don't write these files anywhere new after a version change, so they will be read from
138          * ~/.config/dcpomatic2 (or equivalent) and written back there.
139          */
140         _cinemas_file = read_path ("cinemas.xml");
141         _dkdm_recipients_file = read_path ("dkdm_recipients.xml");
142         _show_hints_before_make_dcp = true;
143         _confirm_kdm_email = true;
144         _kdm_container_name_format = dcp::NameFormat ("KDM %f %c");
145         _kdm_filename_format = dcp::NameFormat ("KDM %f %c %s");
146         _dkdm_filename_format = dcp::NameFormat ("DKDM %f %c %s");
147         _dcp_metadata_filename_format = dcp::NameFormat ("%t");
148         _dcp_asset_filename_format = dcp::NameFormat ("%t");
149         _jump_to_selected = true;
150         for (int i = 0; i < NAG_COUNT; ++i) {
151                 _nagged[i] = false;
152         }
153         _sound = true;
154         _sound_output = optional<string> ();
155         _last_kdm_write_type = KDM_WRITE_FLAT;
156         _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
157
158         /* I think the scaling factor here should be the ratio of the longest frame
159            encode time to the shortest; if the thread count is T, longest time is L
160            and the shortest time S we could encode L/S frames per thread whilst waiting
161            for the L frame to encode so we might have to store LT/S frames.
162
163            However we don't want to use too much memory, so keep it a bit lower than we'd
164            perhaps like.  A J2K frame is typically about 1Mb so 3 here will mean we could
165            use about 240Mb with 72 encoding threads.
166         */
167         _frames_in_memory_multiplier = 3;
168         _decode_reduction = optional<int>();
169         _default_notify = false;
170         for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
171                 _notification[i] = false;
172         }
173         _barco_username = optional<string>();
174         _barco_password = optional<string>();
175         _christie_username = optional<string>();
176         _christie_password = optional<string>();
177         _gdc_username = optional<string>();
178         _gdc_password = optional<string>();
179         _player_mode = PLAYER_MODE_WINDOW;
180         _image_display = 0;
181         _video_view_type = VIDEO_VIEW_SIMPLE;
182         _respect_kdm_validity_periods = true;
183         _player_debug_log_file = boost::none;
184         _player_content_directory = boost::none;
185         _player_playlist_directory = boost::none;
186         _player_kdm_directory = boost::none;
187         _audio_mapping = boost::none;
188         _custom_languages.clear ();
189         _add_files_path = boost::none;
190         _use_isdcf_name_by_default = true;
191         _write_kdms_to_disk = true;
192         _email_kdms = false;
193         _default_kdm_type = dcp::Formulation::MODIFIED_TRANSITIONAL_1;
194         _default_kdm_duration = RoughDuration(1, RoughDuration::Unit::WEEKS);
195         _auto_crop_threshold = 0.1;
196         _last_release_notes_version = boost::none;
197
198         _allowed_dcp_frame_rates.clear ();
199         _allowed_dcp_frame_rates.push_back (24);
200         _allowed_dcp_frame_rates.push_back (25);
201         _allowed_dcp_frame_rates.push_back (30);
202         _allowed_dcp_frame_rates.push_back (48);
203         _allowed_dcp_frame_rates.push_back (50);
204         _allowed_dcp_frame_rates.push_back (60);
205
206         set_kdm_email_to_default ();
207         set_notification_email_to_default ();
208         set_cover_sheet_to_default ();
209
210         _export.set_defaults();
211 }
212
213 void
214 Config::restore_defaults ()
215 {
216         Config::instance()->set_defaults ();
217         Config::instance()->changed ();
218 }
219
220 shared_ptr<dcp::CertificateChain>
221 Config::create_certificate_chain ()
222 {
223         return make_shared<dcp::CertificateChain> (
224                 openssl_path(),
225                 CERTIFICATE_VALIDITY_PERIOD,
226                 "dcpomatic.com",
227                 "dcpomatic.com",
228                 ".dcpomatic.smpte-430-2.ROOT",
229                 ".dcpomatic.smpte-430-2.INTERMEDIATE",
230                 "CS.dcpomatic.smpte-430-2.LEAF"
231                 );
232 }
233
234 void
235 Config::backup ()
236 {
237         using namespace boost::filesystem;
238
239         auto copy_adding_number = [](path const& path_to_copy) {
240
241                 auto add_number = [](path const& path, int number) {
242                         return String::compose("%1.%2", path, number);
243                 };
244
245                 int n = 1;
246                 while (n < 100 && exists(add_number(path_to_copy, n))) {
247                         ++n;
248                 }
249                 boost::system::error_code ec;
250                 copy_file(path_to_copy, add_number(path_to_copy, n), ec);
251         };
252
253         /* Make a backup copy of any config.xml, cinemas.xml, dkdm_recipients.xml that we might be about
254          * to write over.  This is more intended for the situation where we have a corrupted config.xml,
255          * and decide to overwrite it with a new one (possibly losing important details in the corrupted
256          * file).  But we might as well back up the other files while we're about it.
257          */
258
259         /* This uses the State::write_path stuff so, e.g. for a current version 2.16 we might copy
260          * ~/.config/dcpomatic2/2.16/config.xml to ~/.config/dcpomatic2/2.16/config.xml.1
261          */
262         copy_adding_number (config_write_file());
263
264         /* These do not use State::write_path, so whatever path is in the Config we will copy
265          * adding a number.
266          */
267         copy_adding_number (_cinemas_file);
268         copy_adding_number (_dkdm_recipients_file);
269 }
270
271 void
272 Config::read ()
273 {
274         read_config();
275         read_cinemas();
276         read_dkdm_recipients();
277 }
278
279
280 void
281 Config::read_config()
282 try
283 {
284         cxml::Document f ("Config");
285         f.read_file (config_read_file());
286
287         auto version = f.optional_number_child<int> ("Version");
288         if (version && *version < _current_version) {
289                 /* Back up the old config before we re-write it in a back-incompatible way */
290                 backup ();
291         }
292
293         if (f.optional_number_child<int>("NumLocalEncodingThreads")) {
294                 _master_encoding_threads = _server_encoding_threads = f.optional_number_child<int>("NumLocalEncodingThreads").get();
295         } else {
296                 _master_encoding_threads = f.number_child<int>("MasterEncodingThreads");
297                 _server_encoding_threads = f.number_child<int>("ServerEncodingThreads");
298         }
299
300         _default_directory = f.optional_string_child ("DefaultDirectory");
301         if (_default_directory && _default_directory->empty ()) {
302                 /* We used to store an empty value for this to mean "none set" */
303                 _default_directory = boost::optional<boost::filesystem::path> ();
304         }
305
306         auto b = f.optional_number_child<int> ("ServerPort");
307         if (!b) {
308                 b = f.optional_number_child<int> ("ServerPortBase");
309         }
310         _server_port_base = b.get ();
311
312         auto u = f.optional_bool_child ("UseAnyServers");
313         _use_any_servers = u.get_value_or (true);
314
315         for (auto i: f.node_children("Server")) {
316                 if (i->node_children("HostName").size() == 1) {
317                         _servers.push_back (i->string_child ("HostName"));
318                 } else {
319                         _servers.push_back (i->content ());
320                 }
321         }
322
323         _only_servers_encode = f.optional_bool_child ("OnlyServersEncode").get_value_or (false);
324         _tms_protocol = static_cast<FileTransferProtocol>(f.optional_number_child<int>("TMSProtocol").get_value_or(static_cast<int>(FileTransferProtocol::SCP)));
325         _tms_ip = f.string_child ("TMSIP");
326         _tms_path = f.string_child ("TMSPath");
327         _tms_user = f.string_child ("TMSUser");
328         _tms_password = f.string_child ("TMSPassword");
329
330         _language = f.optional_string_child ("Language");
331
332         auto c = f.optional_string_child ("DefaultContainer");
333         if (c) {
334                 _default_container = Ratio::from_id (c.get ());
335         }
336
337         if (_default_container && !_default_container->used_for_container()) {
338                 Warning (_("Your default container is not valid and has been changed to Flat (1.85:1)"));
339                 _default_container = Ratio::from_id ("185");
340         }
341
342         _default_dcp_content_type = DCPContentType::from_isdcf_name(f.optional_string_child("DefaultDCPContentType").get_value_or("FTR"));
343         _default_dcp_audio_channels = f.optional_number_child<int>("DefaultDCPAudioChannels").get_value_or (6);
344
345         if (f.optional_string_child ("DCPMetadataIssuer")) {
346                 _dcp_issuer = f.string_child ("DCPMetadataIssuer");
347         } else if (f.optional_string_child ("DCPIssuer")) {
348                 _dcp_issuer = f.string_child ("DCPIssuer");
349         }
350
351         auto up = f.optional_bool_child("UploadAfterMakeDCP");
352         if (!up) {
353                 up = f.optional_bool_child("DefaultUploadAfterMakeDCP");
354         }
355         _upload_after_make_dcp = up.get_value_or (false);
356         _dcp_creator = f.optional_string_child ("DCPCreator").get_value_or ("");
357         _dcp_company_name = f.optional_string_child("DCPCompanyName").get_value_or("");
358         _dcp_product_name = f.optional_string_child("DCPProductName").get_value_or("");
359         _dcp_product_version = f.optional_string_child("DCPProductVersion").get_value_or("");
360         _dcp_j2k_comment = f.optional_string_child("DCPJ2KComment").get_value_or("");
361
362         _default_still_length = f.optional_number_child<int>("DefaultStillLength").get_value_or (10);
363         _default_j2k_bandwidth = f.optional_number_child<int>("DefaultJ2KBandwidth").get_value_or (200000000);
364         _default_audio_delay = f.optional_number_child<int>("DefaultAudioDelay").get_value_or (0);
365         _default_interop = f.optional_bool_child("DefaultInterop").get_value_or (false);
366
367         for (auto const& i: f.node_children("DefaultMetadata")) {
368                 _default_metadata[i->string_attribute("key")] = i->content();
369         }
370
371         _default_kdm_directory = f.optional_string_child("DefaultKDMDirectory");
372
373         /* Read any cinemas that are still lying around in the config file
374          * from an old version.
375          */
376         read_cinemas (f);
377
378         _mail_server = f.string_child ("MailServer");
379         _mail_port = f.optional_number_child<int> ("MailPort").get_value_or (25);
380
381         {
382                 /* Make sure this matches the code in write_config */
383                 string const protocol = f.optional_string_child("MailProtocol").get_value_or("Auto");
384                 if (protocol == "Auto") {
385                         _mail_protocol = EmailProtocol::AUTO;
386                 } else if (protocol == "Plain") {
387                         _mail_protocol = EmailProtocol::PLAIN;
388                 } else if (protocol == "STARTTLS") {
389                         _mail_protocol = EmailProtocol::STARTTLS;
390                 } else if (protocol == "SSL") {
391                         _mail_protocol = EmailProtocol::SSL;
392                 }
393         }
394
395         _mail_user = f.optional_string_child("MailUser").get_value_or ("");
396         _mail_password = f.optional_string_child("MailPassword").get_value_or ("");
397
398         _kdm_subject = f.optional_string_child ("KDMSubject").get_value_or (_("KDM delivery: $CPL_NAME"));
399         _kdm_from = f.string_child ("KDMFrom");
400         for (auto i: f.node_children("KDMCC")) {
401                 if (!i->content().empty()) {
402                         _kdm_cc.push_back (i->content ());
403                 }
404         }
405         _kdm_bcc = f.optional_string_child ("KDMBCC").get_value_or ("");
406         _kdm_email = f.string_child ("KDMEmail");
407
408         _notification_subject = f.optional_string_child("NotificationSubject").get_value_or(_("DCP-o-matic notification"));
409         _notification_from = f.optional_string_child("NotificationFrom").get_value_or("");
410         _notification_to = f.optional_string_child("NotificationTo").get_value_or("");
411         for (auto i: f.node_children("NotificationCC")) {
412                 if (!i->content().empty()) {
413                         _notification_cc.push_back (i->content ());
414                 }
415         }
416         _notification_bcc = f.optional_string_child("NotificationBCC").get_value_or("");
417         if (f.optional_string_child("NotificationEmail")) {
418                 _notification_email = f.string_child("NotificationEmail");
419         }
420
421         _check_for_updates = f.optional_bool_child("CheckForUpdates").get_value_or (false);
422         _check_for_test_updates = f.optional_bool_child("CheckForTestUpdates").get_value_or (false);
423
424         _maximum_j2k_bandwidth = f.optional_number_child<int> ("MaximumJ2KBandwidth").get_value_or (250000000);
425         _allow_any_dcp_frame_rate = f.optional_bool_child ("AllowAnyDCPFrameRate").get_value_or (false);
426         _allow_any_container = f.optional_bool_child ("AllowAnyContainer").get_value_or (false);
427         _allow_96khz_audio = f.optional_bool_child("Allow96kHzAudio").get_value_or(false);
428         _use_all_audio_channels = f.optional_bool_child("UseAllAudioChannels").get_value_or(false);
429         _show_experimental_audio_processors = f.optional_bool_child ("ShowExperimentalAudioProcessors").get_value_or (false);
430
431         _log_types = f.optional_number_child<int> ("LogTypes").get_value_or (LogEntry::TYPE_GENERAL | LogEntry::TYPE_WARNING | LogEntry::TYPE_ERROR);
432         _analyse_ebur128 = f.optional_bool_child("AnalyseEBUR128").get_value_or (true);
433         _automatic_audio_analysis = f.optional_bool_child ("AutomaticAudioAnalysis").get_value_or (false);
434 #ifdef DCPOMATIC_WINDOWS
435         _win32_console = f.optional_bool_child ("Win32Console").get_value_or (false);
436 #endif
437
438         for (auto i: f.node_children("History")) {
439                 _history.push_back (i->content ());
440         }
441
442         for (auto i: f.node_children("PlayerHistory")) {
443                 _player_history.push_back (i->content ());
444         }
445
446         auto signer = f.optional_node_child ("Signer");
447         if (signer) {
448                 auto c = make_shared<dcp::CertificateChain>();
449                 /* Read the signing certificates and private key in from the config file */
450                 for (auto i: signer->node_children ("Certificate")) {
451                         c->add (dcp::Certificate (i->content ()));
452                 }
453                 c->set_key (signer->string_child ("PrivateKey"));
454                 _signer_chain = c;
455         } else {
456                 /* Make a new set of signing certificates and key */
457                 _signer_chain = create_certificate_chain ();
458         }
459
460         auto decryption = f.optional_node_child ("Decryption");
461         if (decryption) {
462                 auto c = make_shared<dcp::CertificateChain>();
463                 for (auto i: decryption->node_children ("Certificate")) {
464                         c->add (dcp::Certificate (i->content ()));
465                 }
466                 c->set_key (decryption->string_child ("PrivateKey"));
467                 _decryption_chain = c;
468         } else {
469                 _decryption_chain = create_certificate_chain ();
470         }
471
472         /* These must be done before we call Bad as that might set one
473            of the nags.
474         */
475         for (auto i: f.node_children("Nagged")) {
476                 auto const id = i->number_attribute<int>("Id");
477                 if (id >= 0 && id < NAG_COUNT) {
478                         _nagged[id] = raw_convert<int>(i->content());
479                 }
480         }
481
482         auto bad = check_certificates ();
483         if (bad) {
484                 auto const remake = Bad(*bad);
485                 if (remake && *remake) {
486                         switch (*bad) {
487                         case BAD_SIGNER_UTF8_STRINGS:
488                         case BAD_SIGNER_INCONSISTENT:
489                         case BAD_SIGNER_VALIDITY_TOO_LONG:
490                                 _signer_chain = create_certificate_chain ();
491                                 break;
492                         case BAD_DECRYPTION_INCONSISTENT:
493                                 _decryption_chain = create_certificate_chain ();
494                                 break;
495                         }
496                 }
497         }
498
499         if (f.optional_node_child("DKDMGroup")) {
500                 /* New-style: all DKDMs in a group */
501                 _dkdms = dynamic_pointer_cast<DKDMGroup> (DKDMBase::read (f.node_child("DKDMGroup")));
502         } else {
503                 /* Old-style: one or more DKDM nodes */
504                 _dkdms = make_shared<DKDMGroup>("root");
505                 for (auto i: f.node_children("DKDM")) {
506                         _dkdms->add (DKDMBase::read (i));
507                 }
508         }
509         _cinemas_file = f.optional_string_child("CinemasFile").get_value_or(read_path("cinemas.xml").string());
510         _dkdm_recipients_file = f.optional_string_child("DKDMRecipientsFile").get_value_or(read_path("dkdm_recipients.xml").string());
511         _show_hints_before_make_dcp = f.optional_bool_child("ShowHintsBeforeMakeDCP").get_value_or (true);
512         _confirm_kdm_email = f.optional_bool_child("ConfirmKDMEmail").get_value_or (true);
513         _kdm_container_name_format = dcp::NameFormat (f.optional_string_child("KDMContainerNameFormat").get_value_or ("KDM %f %c"));
514         _kdm_filename_format = dcp::NameFormat (f.optional_string_child("KDMFilenameFormat").get_value_or ("KDM %f %c %s"));
515         _dkdm_filename_format = dcp::NameFormat (f.optional_string_child("DKDMFilenameFormat").get_value_or("DKDM %f %c %s"));
516         _dcp_metadata_filename_format = dcp::NameFormat (f.optional_string_child("DCPMetadataFilenameFormat").get_value_or ("%t"));
517         _dcp_asset_filename_format = dcp::NameFormat (f.optional_string_child("DCPAssetFilenameFormat").get_value_or ("%t"));
518         _jump_to_selected = f.optional_bool_child("JumpToSelected").get_value_or (true);
519         /* The variable was renamed but not the XML tag */
520         _sound = f.optional_bool_child("PreviewSound").get_value_or (true);
521         _sound_output = f.optional_string_child("PreviewSoundOutput");
522         if (f.optional_string_child("CoverSheet")) {
523                 _cover_sheet = f.optional_string_child("CoverSheet").get();
524         }
525         _last_player_load_directory = f.optional_string_child("LastPlayerLoadDirectory");
526         if (f.optional_string_child("LastKDMWriteType")) {
527                 if (f.optional_string_child("LastKDMWriteType").get() == "flat") {
528                         _last_kdm_write_type = KDM_WRITE_FLAT;
529                 } else if (f.optional_string_child("LastKDMWriteType").get() == "folder") {
530                         _last_kdm_write_type = KDM_WRITE_FOLDER;
531                 } else if (f.optional_string_child("LastKDMWriteType").get() == "zip") {
532                         _last_kdm_write_type = KDM_WRITE_ZIP;
533                 }
534         }
535         if (f.optional_string_child("LastDKDMWriteType")) {
536                 if (f.optional_string_child("LastDKDMWriteType").get() == "internal") {
537                         _last_dkdm_write_type = DKDM_WRITE_INTERNAL;
538                 } else if (f.optional_string_child("LastDKDMWriteType").get() == "file") {
539                         _last_dkdm_write_type = DKDM_WRITE_FILE;
540                 }
541         }
542         _frames_in_memory_multiplier = f.optional_number_child<int>("FramesInMemoryMultiplier").get_value_or(3);
543         _decode_reduction = f.optional_number_child<int>("DecodeReduction");
544         _default_notify = f.optional_bool_child("DefaultNotify").get_value_or(false);
545
546         for (auto i: f.node_children("Notification")) {
547                 int const id = i->number_attribute<int>("Id");
548                 if (id >= 0 && id < NOTIFICATION_COUNT) {
549                         _notification[id] = raw_convert<int>(i->content());
550                 }
551         }
552
553         _barco_username = f.optional_string_child("BarcoUsername");
554         _barco_password = f.optional_string_child("BarcoPassword");
555         _christie_username = f.optional_string_child("ChristieUsername");
556         _christie_password = f.optional_string_child("ChristiePassword");
557         _gdc_username = f.optional_string_child("GDCUsername");
558         _gdc_password = f.optional_string_child("GDCPassword");
559
560         auto pm = f.optional_string_child("PlayerMode");
561         if (pm && *pm == "window") {
562                 _player_mode = PLAYER_MODE_WINDOW;
563         } else if (pm && *pm == "full") {
564                 _player_mode = PLAYER_MODE_FULL;
565         } else if (pm && *pm == "dual") {
566                 _player_mode = PLAYER_MODE_DUAL;
567         }
568
569         _image_display = f.optional_number_child<int>("ImageDisplay").get_value_or(0);
570         auto vc = f.optional_string_child("VideoViewType");
571         if (vc && *vc == "opengl") {
572                 _video_view_type = VIDEO_VIEW_OPENGL;
573         } else if (vc && *vc == "simple") {
574                 _video_view_type = VIDEO_VIEW_SIMPLE;
575         }
576         _respect_kdm_validity_periods = f.optional_bool_child("RespectKDMValidityPeriods").get_value_or(true);
577         _player_debug_log_file = f.optional_string_child("PlayerDebugLogFile");
578         _player_content_directory = f.optional_string_child("PlayerContentDirectory");
579         _player_playlist_directory = f.optional_string_child("PlayerPlaylistDirectory");
580         _player_kdm_directory = f.optional_string_child("PlayerKDMDirectory");
581
582         if (f.optional_node_child("AudioMapping")) {
583                 _audio_mapping = AudioMapping (f.node_child("AudioMapping"), Film::current_state_version);
584         }
585
586         for (auto i: f.node_children("CustomLanguage")) {
587                 try {
588                         /* This will fail if it's called before dcp::init() as it won't recognise the
589                          * tag.  That's OK because the Config will be reloaded again later.
590                          */
591                         _custom_languages.push_back (dcp::LanguageTag(i->content()));
592                 } catch (std::runtime_error& e) {}
593         }
594
595         _add_files_path = f.optional_string_child("AddFilesPath");
596         _use_isdcf_name_by_default = f.optional_bool_child("UseISDCFNameByDefault").get_value_or(true);
597         _write_kdms_to_disk = f.optional_bool_child("WriteKDMsToDisk").get_value_or(true);
598         _email_kdms = f.optional_bool_child("EmailKDMs").get_value_or(false);
599         _default_kdm_type = dcp::string_to_formulation(f.optional_string_child("DefaultKDMType").get_value_or("modified-transitional-1"));
600         if (auto duration = f.optional_node_child("DefaultKDMDuration")) {
601                 _default_kdm_duration = RoughDuration(duration);
602         } else {
603                 _default_kdm_duration = RoughDuration(1, RoughDuration::Unit::WEEKS);
604         }
605         _auto_crop_threshold = f.optional_number_child<double>("AutoCropThreshold").get_value_or(0.1);
606         _last_release_notes_version = f.optional_string_child("LastReleaseNotesVersion");
607
608         _export.read(f.optional_node_child("Export"));
609 }
610 catch (...) {
611         if (have_existing("config.xml")) {
612                 backup ();
613                 /* We have a config file but it didn't load */
614                 FailedToLoad(LoadFailure::CONFIG);
615         }
616         set_defaults ();
617         /* Make a new set of signing certificates and key */
618         _signer_chain = create_certificate_chain ();
619         /* And similar for decryption of KDMs */
620         _decryption_chain = create_certificate_chain ();
621         write_config();
622 }
623
624
625 void
626 Config::read_cinemas()
627 {
628         if (boost::filesystem::exists (_cinemas_file)) {
629                 try {
630                         cxml::Document f("Cinemas");
631                         f.read_file(_cinemas_file);
632                         read_cinemas(f);
633                 } catch (...) {
634                         backup();
635                         FailedToLoad(LoadFailure::CINEMAS);
636                         write_cinemas();
637                 }
638         }
639 }
640
641
642 void
643 Config::read_dkdm_recipients()
644 {
645         if (boost::filesystem::exists (_dkdm_recipients_file)) {
646                 try {
647                         cxml::Document f("DKDMRecipients");
648                         f.read_file(_dkdm_recipients_file);
649                         read_dkdm_recipients(f);
650                 } catch (...) {
651                         backup();
652                         FailedToLoad(LoadFailure::DKDM_RECIPIENTS);
653                         write_dkdm_recipients();
654                 }
655         }
656 }
657
658
659 /** @return Singleton instance */
660 Config *
661 Config::instance ()
662 {
663         if (_instance == nullptr) {
664                 _instance = new Config;
665                 _instance->read ();
666         }
667
668         return _instance;
669 }
670
671 /** Write our configuration to disk */
672 void
673 Config::write () const
674 {
675         write_config ();
676         write_cinemas ();
677         write_dkdm_recipients ();
678 }
679
680 void
681 Config::write_config () const
682 {
683         xmlpp::Document doc;
684         auto root = doc.create_root_node ("Config");
685
686         /* [XML] Version The version number of the configuration file format. */
687         root->add_child("Version")->add_child_text (raw_convert<string>(_current_version));
688         /* [XML] MasterEncodingThreads Number of encoding threads to use when running as master. */
689         root->add_child("MasterEncodingThreads")->add_child_text (raw_convert<string> (_master_encoding_threads));
690         /* [XML] ServerEncodingThreads Number of encoding threads to use when running as server. */
691         root->add_child("ServerEncodingThreads")->add_child_text (raw_convert<string> (_server_encoding_threads));
692         if (_default_directory) {
693                 /* [XML:opt] DefaultDirectory Default directory when creating a new film in the GUI. */
694                 root->add_child("DefaultDirectory")->add_child_text (_default_directory->string ());
695         }
696         /* [XML] ServerPortBase Port number to use for frame encoding requests.  <code>ServerPortBase</code> + 1 and
697            <code>ServerPortBase</code> + 2 are used for querying servers.  <code>ServerPortBase</code> + 3 is used
698            by the batch converter to listen for job requests.
699         */
700         root->add_child("ServerPortBase")->add_child_text (raw_convert<string> (_server_port_base));
701         /* [XML] UseAnyServers 1 to broadcast to look for encoding servers to use, 0 to use only those configured. */
702         root->add_child("UseAnyServers")->add_child_text (_use_any_servers ? "1" : "0");
703
704         for (auto i: _servers) {
705                 /* [XML:opt] Server IP address or hostname of an encoding server to use; you can use as many of these tags
706                    as you like.
707                 */
708                 root->add_child("Server")->add_child_text (i);
709         }
710
711         /* [XML] OnlyServersEncode 1 to set the master to do decoding of source content no JPEG2000 encoding; all encoding
712            is done by the encoding servers.  0 to set the master to do some encoding as well as coordinating the job.
713         */
714         root->add_child("OnlyServersEncode")->add_child_text (_only_servers_encode ? "1" : "0");
715         /* [XML] TMSProtocol Protocol to use to copy files to a TMS; 0 to use SCP, 1 for FTP. */
716         root->add_child("TMSProtocol")->add_child_text (raw_convert<string> (static_cast<int> (_tms_protocol)));
717         /* [XML] TMSIP IP address of TMS. */
718         root->add_child("TMSIP")->add_child_text (_tms_ip);
719         /* [XML] TMSPath Path on the TMS to copy files to. */
720         root->add_child("TMSPath")->add_child_text (_tms_path);
721         /* [XML] TMSUser Username to log into the TMS with. */
722         root->add_child("TMSUser")->add_child_text (_tms_user);
723         /* [XML] TMSPassword Password to log into the TMS with. */
724         root->add_child("TMSPassword")->add_child_text (_tms_password);
725         if (_language) {
726                 /* [XML:opt] Language Language to use in the GUI e.g. <code>fr_FR</code>. */
727                 root->add_child("Language")->add_child_text (_language.get());
728         }
729         if (_default_container) {
730                 /* [XML:opt] DefaultContainer ID of default container
731                    to use when creating new films (<code>185</code>,<code>239</code> or
732                    <code>190</code>).
733                 */
734                 root->add_child("DefaultContainer")->add_child_text (_default_container->id ());
735         }
736         if (_default_dcp_content_type) {
737                 /* [XML:opt] DefaultDCPContentType Default content type to use when creating new films (<code>FTR</code>, <code>SHR</code>,
738                    <code>TLR</code>, <code>TST</code>, <code>XSN</code>, <code>RTG</code>, <code>TSR</code>, <code>POL</code>,
739                    <code>PSA</code> or <code>ADV</code>). */
740                 root->add_child("DefaultDCPContentType")->add_child_text (_default_dcp_content_type->isdcf_name ());
741         }
742         /* [XML] DefaultDCPAudioChannels Default number of audio channels to use when creating new films. */
743         root->add_child("DefaultDCPAudioChannels")->add_child_text (raw_convert<string> (_default_dcp_audio_channels));
744         /* [XML] DCPIssuer Issuer text to write into CPL files. */
745         root->add_child("DCPIssuer")->add_child_text (_dcp_issuer);
746         /* [XML] DCPCreator Creator text to write into CPL files. */
747         root->add_child("DCPCreator")->add_child_text (_dcp_creator);
748         /* [XML] Company name to write into MXF files. */
749         root->add_child("DCPCompanyName")->add_child_text (_dcp_company_name);
750         /* [XML] Product name to write into MXF files. */
751         root->add_child("DCPProductName")->add_child_text (_dcp_product_name);
752         /* [XML] Product version to write into MXF files. */
753         root->add_child("DCPProductVersion")->add_child_text (_dcp_product_version);
754         /* [XML] Comment to write into JPEG2000 data. */
755         root->add_child("DCPJ2KComment")->add_child_text (_dcp_j2k_comment);
756         /* [XML] UploadAfterMakeDCP 1 to upload to a TMS after making a DCP, 0 for no upload. */
757         root->add_child("UploadAfterMakeDCP")->add_child_text (_upload_after_make_dcp ? "1" : "0");
758
759         /* [XML] DefaultStillLength Default length (in seconds) for still images in new films. */
760         root->add_child("DefaultStillLength")->add_child_text (raw_convert<string> (_default_still_length));
761         /* [XML] DefaultJ2KBandwidth Default bitrate (in bits per second) for JPEG2000 data in new films. */
762         root->add_child("DefaultJ2KBandwidth")->add_child_text (raw_convert<string> (_default_j2k_bandwidth));
763         /* [XML] DefaultAudioDelay Default delay to apply to audio (positive moves audio later) in milliseconds. */
764         root->add_child("DefaultAudioDelay")->add_child_text (raw_convert<string> (_default_audio_delay));
765         /* [XML] DefaultInterop 1 to default new films to Interop, 0 for SMPTE. */
766         root->add_child("DefaultInterop")->add_child_text (_default_interop ? "1" : "0");
767         for (auto const& i: _default_metadata) {
768                 auto c = root->add_child("DefaultMetadata");
769                 c->set_attribute("key", i.first);
770                 c->add_child_text(i.second);
771         }
772         if (_default_kdm_directory) {
773                 /* [XML:opt] DefaultKDMDirectory Default directory to write KDMs to. */
774                 root->add_child("DefaultKDMDirectory")->add_child_text (_default_kdm_directory->string ());
775         }
776         _default_kdm_duration.as_xml(root->add_child("DefaultKDMDuration"));
777         /* [XML] MailServer Hostname of SMTP server to use. */
778         root->add_child("MailServer")->add_child_text (_mail_server);
779         /* [XML] MailPort Port number to use on SMTP server. */
780         root->add_child("MailPort")->add_child_text (raw_convert<string> (_mail_port));
781         /* [XML] MailProtocol Protocol to use on SMTP server (Auto, Plain, STARTTLS or SSL) */
782         switch (_mail_protocol) {
783         case EmailProtocol::AUTO:
784                 root->add_child("MailProtocol")->add_child_text("Auto");
785                 break;
786         case EmailProtocol::PLAIN:
787                 root->add_child("MailProtocol")->add_child_text("Plain");
788                 break;
789         case EmailProtocol::STARTTLS:
790                 root->add_child("MailProtocol")->add_child_text("STARTTLS");
791                 break;
792         case EmailProtocol::SSL:
793                 root->add_child("MailProtocol")->add_child_text("SSL");
794                 break;
795         }
796         /* [XML] MailUser Username to use on SMTP server. */
797         root->add_child("MailUser")->add_child_text (_mail_user);
798         /* [XML] MailPassword Password to use on SMTP server. */
799         root->add_child("MailPassword")->add_child_text (_mail_password);
800
801         /* [XML] KDMSubject Subject to use for KDM emails. */
802         root->add_child("KDMSubject")->add_child_text (_kdm_subject);
803         /* [XML] KDMFrom From address to use for KDM emails. */
804         root->add_child("KDMFrom")->add_child_text (_kdm_from);
805         for (auto i: _kdm_cc) {
806                 /* [XML] KDMCC CC address to use for KDM emails; you can use as many of these tags as you like. */
807                 root->add_child("KDMCC")->add_child_text (i);
808         }
809         /* [XML] KDMBCC BCC address to use for KDM emails. */
810         root->add_child("KDMBCC")->add_child_text (_kdm_bcc);
811         /* [XML] KDMEmail Text of KDM email. */
812         root->add_child("KDMEmail")->add_child_text (_kdm_email);
813
814         /* [XML] NotificationSubject Subject to use for notification emails. */
815         root->add_child("NotificationSubject")->add_child_text (_notification_subject);
816         /* [XML] NotificationFrom From address to use for notification emails. */
817         root->add_child("NotificationFrom")->add_child_text (_notification_from);
818         /* [XML] NotificationFrom To address to use for notification emails. */
819         root->add_child("NotificationTo")->add_child_text (_notification_to);
820         for (auto i: _notification_cc) {
821                 /* [XML] NotificationCC CC address to use for notification emails; you can use as many of these tags as you like. */
822                 root->add_child("NotificationCC")->add_child_text (i);
823         }
824         /* [XML] NotificationBCC BCC address to use for notification emails. */
825         root->add_child("NotificationBCC")->add_child_text (_notification_bcc);
826         /* [XML] NotificationEmail Text of notification email. */
827         root->add_child("NotificationEmail")->add_child_text (_notification_email);
828
829         /* [XML] CheckForUpdates 1 to check dcpomatic.com for new versions, 0 to check only on request. */
830         root->add_child("CheckForUpdates")->add_child_text (_check_for_updates ? "1" : "0");
831         /* [XML] CheckForUpdates 1 to check dcpomatic.com for new text versions, 0 to check only on request. */
832         root->add_child("CheckForTestUpdates")->add_child_text (_check_for_test_updates ? "1" : "0");
833
834         /* [XML] MaximumJ2KBandwidth Maximum J2K bandwidth (in bits per second) that can be specified in the GUI. */
835         root->add_child("MaximumJ2KBandwidth")->add_child_text (raw_convert<string> (_maximum_j2k_bandwidth));
836         /* [XML] AllowAnyDCPFrameRate 1 to allow users to specify any frame rate when creating DCPs, 0 to limit the GUI to standard rates. */
837         root->add_child("AllowAnyDCPFrameRate")->add_child_text (_allow_any_dcp_frame_rate ? "1" : "0");
838         /* [XML] AllowAnyContainer 1 to allow users to user any container ratio for their DCP, 0 to limit the GUI to DCI Flat/Scope */
839         root->add_child("AllowAnyContainer")->add_child_text (_allow_any_container ? "1" : "0");
840         /* [XML] Allow96kHzAudio 1 to allow users to make DCPs with 96kHz audio, 0 to always make 48kHz DCPs */
841         root->add_child("Allow96kHzAudio")->add_child_text(_allow_96khz_audio ? "1" : "0");
842         /* [XML] UseAllAudioChannels 1 to allow users to map audio to all 16 DCP channels, 0 to limit to the channels used in standard DCPs */
843         root->add_child("UseAllAudioChannels")->add_child_text(_use_all_audio_channels ? "1" : "0");
844         /* [XML] ShowExperimentalAudioProcessors 1 to offer users the (experimental) audio upmixer processors, 0 to hide them */
845         root->add_child("ShowExperimentalAudioProcessors")->add_child_text (_show_experimental_audio_processors ? "1" : "0");
846         /* [XML] LogTypes Types of logging to write; a bitfield where 1 is general notes, 2 warnings, 4 errors, 8 debug information related
847            to 3D, 16 debug information related to encoding, 32 debug information for timing purposes, 64 debug information related
848            to sending email, 128 debug information related to the video view, 256 information about disk writing, 512 debug information
849            related to the player, 1024 debug information related to audio analyses.
850         */
851         root->add_child("LogTypes")->add_child_text (raw_convert<string> (_log_types));
852         /* [XML] AnalyseEBUR128 1 to do EBUR128 analyses when analysing audio, otherwise 0. */
853         root->add_child("AnalyseEBUR128")->add_child_text (_analyse_ebur128 ? "1" : "0");
854         /* [XML] AutomaticAudioAnalysis 1 to run audio analysis automatically when audio content is added to the film, otherwise 0. */
855         root->add_child("AutomaticAudioAnalysis")->add_child_text (_automatic_audio_analysis ? "1" : "0");
856 #ifdef DCPOMATIC_WINDOWS
857         if (_win32_console) {
858                 /* [XML] Win32Console 1 to open a console when running on Windows, otherwise 0.
859                  * We only write this if it's true, which is a bit of a hack to allow unit tests to work
860                  * more easily on Windows (without a platform-specific reference in config_write_utf8_test)
861                  */
862                 root->add_child("Win32Console")->add_child_text ("1");
863         }
864 #endif
865
866         /* [XML] Signer Certificate chain and private key to use when signing DCPs and KDMs.  Should contain <code>&lt;Certificate&gt;</code>
867            tags in order and a <code>&lt;PrivateKey&gt;</code> tag all containing PEM-encoded certificates or private keys as appropriate.
868         */
869         auto signer = root->add_child ("Signer");
870         DCPOMATIC_ASSERT (_signer_chain);
871         for (auto const& i: _signer_chain->unordered()) {
872                 signer->add_child("Certificate")->add_child_text (i.certificate (true));
873         }
874         signer->add_child("PrivateKey")->add_child_text (_signer_chain->key().get ());
875
876         /* [XML] Decryption Certificate chain and private key to use when decrypting KDMs */
877         auto decryption = root->add_child ("Decryption");
878         DCPOMATIC_ASSERT (_decryption_chain);
879         for (auto const& i: _decryption_chain->unordered()) {
880                 decryption->add_child("Certificate")->add_child_text (i.certificate (true));
881         }
882         decryption->add_child("PrivateKey")->add_child_text (_decryption_chain->key().get ());
883
884         /* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the GUI; there can be more than one
885            of these tags.
886         */
887         for (auto i: _history) {
888                 root->add_child("History")->add_child_text (i.string ());
889         }
890
891         /* [XML] History Filename of DCP to present in the <guilabel>File</guilabel> menu of the player; there can be more than one
892            of these tags.
893         */
894         for (auto i: _player_history) {
895                 root->add_child("PlayerHistory")->add_child_text (i.string ());
896         }
897
898         /* [XML] DKDMGroup A group of DKDMs, each with a <code>Name</code> attribute, containing other <code>&lt;DKDMGroup&gt;</code>
899            or <code>&lt;DKDM&gt;</code> tags.
900         */
901         /* [XML] DKDM A DKDM as XML */
902         _dkdms->as_xml (root);
903
904         /* [XML] CinemasFile Filename of cinemas list file. */
905         root->add_child("CinemasFile")->add_child_text (_cinemas_file.string());
906         /* [XML] DKDMRecipientsFile Filename of DKDM recipients list file. */
907         root->add_child("DKDMRecipientsFile")->add_child_text (_dkdm_recipients_file.string());
908         /* [XML] ShowHintsBeforeMakeDCP 1 to show hints in the GUI before making a DCP, otherwise 0. */
909         root->add_child("ShowHintsBeforeMakeDCP")->add_child_text (_show_hints_before_make_dcp ? "1" : "0");
910         /* [XML] ConfirmKDMEmail 1 to confirm before sending KDM emails in the GUI, otherwise 0. */
911         root->add_child("ConfirmKDMEmail")->add_child_text (_confirm_kdm_email ? "1" : "0");
912         /* [XML] KDMFilenameFormat Format for KDM filenames. */
913         root->add_child("KDMFilenameFormat")->add_child_text (_kdm_filename_format.specification ());
914         /* [XML] KDMFilenameFormat Format for DKDM filenames. */
915         root->add_child("DKDMFilenameFormat")->add_child_text(_dkdm_filename_format.specification());
916         /* [XML] KDMContainerNameFormat Format for KDM containers (directories or ZIP files). */
917         root->add_child("KDMContainerNameFormat")->add_child_text (_kdm_container_name_format.specification ());
918         /* [XML] DCPMetadataFilenameFormat Format for DCP metadata filenames. */
919         root->add_child("DCPMetadataFilenameFormat")->add_child_text (_dcp_metadata_filename_format.specification ());
920         /* [XML] DCPAssetFilenameFormat Format for DCP asset filenames. */
921         root->add_child("DCPAssetFilenameFormat")->add_child_text (_dcp_asset_filename_format.specification ());
922         /* [XML] JumpToSelected 1 to make the GUI jump to the start of content when it is selected, otherwise 0. */
923         root->add_child("JumpToSelected")->add_child_text (_jump_to_selected ? "1" : "0");
924         /* [XML] Nagged 1 if a particular nag screen has been shown and should not be shown again, otherwise 0. */
925         for (int i = 0; i < NAG_COUNT; ++i) {
926                 xmlpp::Element* e = root->add_child ("Nagged");
927                 e->set_attribute ("Id", raw_convert<string>(i));
928                 e->add_child_text (_nagged[i] ? "1" : "0");
929         }
930         /* [XML] PreviewSound 1 to use sound in the GUI preview and player, otherwise 0. */
931         root->add_child("PreviewSound")->add_child_text (_sound ? "1" : "0");
932         if (_sound_output) {
933                 /* [XML:opt] PreviewSoundOutput Name of the audio output to use. */
934                 root->add_child("PreviewSoundOutput")->add_child_text (_sound_output.get());
935         }
936         /* [XML] CoverSheet Text of the cover sheet to write when making DCPs. */
937         root->add_child("CoverSheet")->add_child_text (_cover_sheet);
938         if (_last_player_load_directory) {
939                 root->add_child("LastPlayerLoadDirectory")->add_child_text(_last_player_load_directory->string());
940         }
941         /* [XML] LastKDMWriteType Last type of KDM-write: <code>flat</code> for a flat file, <code>folder</code> for a folder or <code>zip</code> for a ZIP file. */
942         if (_last_kdm_write_type) {
943                 switch (_last_kdm_write_type.get()) {
944                 case KDM_WRITE_FLAT:
945                         root->add_child("LastKDMWriteType")->add_child_text("flat");
946                         break;
947                 case KDM_WRITE_FOLDER:
948                         root->add_child("LastKDMWriteType")->add_child_text("folder");
949                         break;
950                 case KDM_WRITE_ZIP:
951                         root->add_child("LastKDMWriteType")->add_child_text("zip");
952                         break;
953                 }
954         }
955         /* [XML] LastDKDMWriteType Last type of DKDM-write: <code>file</code> for a file, <code>internal</code> to add to DCP-o-matic's list. */
956         if (_last_dkdm_write_type) {
957                 switch (_last_dkdm_write_type.get()) {
958                 case DKDM_WRITE_INTERNAL:
959                         root->add_child("LastDKDMWriteType")->add_child_text("internal");
960                         break;
961                 case DKDM_WRITE_FILE:
962                         root->add_child("LastDKDMWriteType")->add_child_text("file");
963                         break;
964                 }
965         }
966         /* [XML] FramesInMemoryMultiplier value to multiply the encoding threads count by to get the maximum number of
967            frames to be held in memory at once.
968         */
969         root->add_child("FramesInMemoryMultiplier")->add_child_text(raw_convert<string>(_frames_in_memory_multiplier));
970
971         /* [XML] DecodeReduction power of 2 to reduce DCP images by before decoding in the player. */
972         if (_decode_reduction) {
973                 root->add_child("DecodeReduction")->add_child_text(raw_convert<string>(_decode_reduction.get()));
974         }
975
976         /* [XML] DefaultNotify 1 to default jobs to notify when complete, otherwise 0. */
977         root->add_child("DefaultNotify")->add_child_text(_default_notify ? "1" : "0");
978
979         /* [XML] Notification 1 if a notification type is enabled, otherwise 0. */
980         for (int i = 0; i < NOTIFICATION_COUNT; ++i) {
981                 xmlpp::Element* e = root->add_child ("Notification");
982                 e->set_attribute ("Id", raw_convert<string>(i));
983                 e->add_child_text (_notification[i] ? "1" : "0");
984         }
985
986         if (_barco_username) {
987                 /* [XML] BarcoUsername Username for logging into Barco's servers when downloading server certificates. */
988                 root->add_child("BarcoUsername")->add_child_text(*_barco_username);
989         }
990         if (_barco_password) {
991                 /* [XML] BarcoPassword Password for logging into Barco's servers when downloading server certificates. */
992                 root->add_child("BarcoPassword")->add_child_text(*_barco_password);
993         }
994
995         if (_christie_username) {
996                 /* [XML] ChristieUsername Username for logging into Christie's servers when downloading server certificates. */
997                 root->add_child("ChristieUsername")->add_child_text(*_christie_username);
998         }
999         if (_christie_password) {
1000                 /* [XML] ChristiePassword Password for logging into Christie's servers when downloading server certificates. */
1001                 root->add_child("ChristiePassword")->add_child_text(*_christie_password);
1002         }
1003
1004         if (_gdc_username) {
1005                 /* [XML] GDCUsername Username for logging into GDC's servers when downloading server certificates. */
1006                 root->add_child("GDCUsername")->add_child_text(*_gdc_username);
1007         }
1008         if (_gdc_password) {
1009                 /* [XML] GDCPassword Password for logging into GDC's servers when downloading server certificates. */
1010                 root->add_child("GDCPassword")->add_child_text(*_gdc_password);
1011         }
1012
1013         /* [XML] PlayerMode <code>window</code> for a single window, <code>full</code> for full-screen and <code>dual</code> for full screen playback
1014            with controls on another monitor.
1015         */
1016         switch (_player_mode) {
1017         case PLAYER_MODE_WINDOW:
1018                 root->add_child("PlayerMode")->add_child_text("window");
1019                 break;
1020         case PLAYER_MODE_FULL:
1021                 root->add_child("PlayerMode")->add_child_text("full");
1022                 break;
1023         case PLAYER_MODE_DUAL:
1024                 root->add_child("PlayerMode")->add_child_text("dual");
1025                 break;
1026         }
1027
1028         /* [XML] ImageDisplay Screen number to put image on in dual-screen player mode. */
1029         root->add_child("ImageDisplay")->add_child_text(raw_convert<string>(_image_display));
1030         switch (_video_view_type) {
1031         case VIDEO_VIEW_SIMPLE:
1032                 root->add_child("VideoViewType")->add_child_text("simple");
1033                 break;
1034         case VIDEO_VIEW_OPENGL:
1035                 root->add_child("VideoViewType")->add_child_text("opengl");
1036                 break;
1037         }
1038         /* [XML] RespectKDMValidityPeriods 1 to refuse to use KDMs that are out of date, 0 to ignore KDM dates. */
1039         root->add_child("RespectKDMValidityPeriods")->add_child_text(_respect_kdm_validity_periods ? "1" : "0");
1040         if (_player_debug_log_file) {
1041                 /* [XML] PlayerLogFile Filename to use for player debug logs. */
1042                 root->add_child("PlayerDebugLogFile")->add_child_text(_player_debug_log_file->string());
1043         }
1044         if (_player_content_directory) {
1045                 /* [XML] PlayerContentDirectory Directory to use for player content in the dual-screen mode. */
1046                 root->add_child("PlayerContentDirectory")->add_child_text(_player_content_directory->string());
1047         }
1048         if (_player_playlist_directory) {
1049                 /* [XML] PlayerPlaylistDirectory Directory to use for player playlists in the dual-screen mode. */
1050                 root->add_child("PlayerPlaylistDirectory")->add_child_text(_player_playlist_directory->string());
1051         }
1052         if (_player_kdm_directory) {
1053                 /* [XML] PlayerKDMDirectory Directory to use for player KDMs in the dual-screen mode. */
1054                 root->add_child("PlayerKDMDirectory")->add_child_text(_player_kdm_directory->string());
1055         }
1056         if (_audio_mapping) {
1057                 _audio_mapping->as_xml (root->add_child("AudioMapping"));
1058         }
1059         for (auto const& i: _custom_languages) {
1060                 root->add_child("CustomLanguage")->add_child_text(i.to_string());
1061         }
1062         if (_add_files_path) {
1063                 /* [XML] AddFilesPath The default path that will be offered in the picker when adding files to a film. */
1064                 root->add_child("AddFilesPath")->add_child_text(_add_files_path->string());
1065         }
1066         root->add_child("UseISDCFNameByDefault")->add_child_text(_use_isdcf_name_by_default ? "1" : "0");
1067         root->add_child("WriteKDMsToDisk")->add_child_text(_write_kdms_to_disk ? "1" : "0");
1068         root->add_child("EmailKDMs")->add_child_text(_email_kdms ? "1" : "0");
1069         root->add_child("DefaultKDMType")->add_child_text(dcp::formulation_to_string(_default_kdm_type));
1070         root->add_child("AutoCropThreshold")->add_child_text(raw_convert<string>(_auto_crop_threshold));
1071         if (_last_release_notes_version) {
1072                 root->add_child("LastReleaseNotesVersion")->add_child_text(*_last_release_notes_version);
1073         }
1074
1075         _export.write(root->add_child("Export"));
1076
1077         auto target = config_write_file();
1078
1079         try {
1080                 auto const s = doc.write_to_string_formatted ();
1081                 boost::filesystem::path tmp (string(target.string()).append(".tmp"));
1082                 dcp::File f(tmp, "w");
1083                 if (!f) {
1084                         throw FileError (_("Could not open file for writing"), tmp);
1085                 }
1086                 f.checked_write(s.c_str(), s.bytes());
1087                 f.close();
1088                 boost::filesystem::remove (target);
1089                 boost::filesystem::rename (tmp, target);
1090         } catch (xmlpp::exception& e) {
1091                 string s = e.what ();
1092                 trim (s);
1093                 throw FileError (s, target);
1094         }
1095 }
1096
1097
1098 template <class T>
1099 void
1100 write_file (string root_node, string node, string version, list<shared_ptr<T>> things, boost::filesystem::path file)
1101 {
1102         xmlpp::Document doc;
1103         auto root = doc.create_root_node (root_node);
1104         root->add_child("Version")->add_child_text(version);
1105
1106         for (auto i: things) {
1107                 i->as_xml (root->add_child(node));
1108         }
1109
1110         try {
1111                 doc.write_to_file_formatted (file.string() + ".tmp");
1112                 boost::filesystem::remove (file);
1113                 boost::filesystem::rename (file.string() + ".tmp", file);
1114         } catch (xmlpp::exception& e) {
1115                 string s = e.what ();
1116                 trim (s);
1117                 throw FileError (s, file);
1118         }
1119 }
1120
1121
1122 void
1123 Config::write_cinemas () const
1124 {
1125         write_file ("Cinemas", "Cinema", "1", _cinemas, _cinemas_file);
1126 }
1127
1128
1129 void
1130 Config::write_dkdm_recipients () const
1131 {
1132         write_file ("DKDMRecipients", "DKDMRecipient", "1", _dkdm_recipients, _dkdm_recipients_file);
1133 }
1134
1135
1136 boost::filesystem::path
1137 Config::default_directory_or (boost::filesystem::path a) const
1138 {
1139         return directory_or (_default_directory, a);
1140 }
1141
1142 boost::filesystem::path
1143 Config::default_kdm_directory_or (boost::filesystem::path a) const
1144 {
1145         return directory_or (_default_kdm_directory, a);
1146 }
1147
1148 boost::filesystem::path
1149 Config::directory_or (optional<boost::filesystem::path> dir, boost::filesystem::path a) const
1150 {
1151         if (!dir) {
1152                 return a;
1153         }
1154
1155         boost::system::error_code ec;
1156         auto const e = boost::filesystem::exists (*dir, ec);
1157         if (ec || !e) {
1158                 return a;
1159         }
1160
1161         return *dir;
1162 }
1163
1164 void
1165 Config::drop ()
1166 {
1167         delete _instance;
1168         _instance = 0;
1169 }
1170
1171 void
1172 Config::changed (Property what)
1173 {
1174         Changed (what);
1175 }
1176
1177 void
1178 Config::set_kdm_email_to_default ()
1179 {
1180         _kdm_subject = _("KDM delivery: $CPL_NAME");
1181
1182         _kdm_email = _(
1183                 "Dear Projectionist\n\n"
1184                 "Please find attached KDMs for $CPL_NAME.\n\n"
1185                 "Cinema: $CINEMA_NAME\n"
1186                 "Screen(s): $SCREENS\n\n"
1187                 "The KDMs are valid from $START_TIME until $END_TIME.\n\n"
1188                 "Best regards,\nDCP-o-matic"
1189                 );
1190 }
1191
1192 void
1193 Config::set_notification_email_to_default ()
1194 {
1195         _notification_subject = _("DCP-o-matic notification");
1196
1197         _notification_email = _(
1198                 "$JOB_NAME: $JOB_STATUS"
1199                 );
1200 }
1201
1202 void
1203 Config::reset_kdm_email ()
1204 {
1205         set_kdm_email_to_default ();
1206         changed ();
1207 }
1208
1209 void
1210 Config::reset_notification_email ()
1211 {
1212         set_notification_email_to_default ();
1213         changed ();
1214 }
1215
1216 void
1217 Config::set_cover_sheet_to_default ()
1218 {
1219         _cover_sheet = _(
1220                 "$CPL_NAME\n\n"
1221                 "CPL Filename: $CPL_FILENAME\n"
1222                 "Type: $TYPE\n"
1223                 "Format: $CONTAINER\n"
1224                 "Audio: $AUDIO\n"
1225                 "Audio Language: $AUDIO_LANGUAGE\n"
1226                 "Subtitle Language: $SUBTITLE_LANGUAGE\n"
1227                 "Length: $LENGTH\n"
1228                 "Size: $SIZE\n"
1229                 );
1230 }
1231
1232 void
1233 Config::add_to_history (boost::filesystem::path p)
1234 {
1235         add_to_history_internal (_history, p);
1236 }
1237
1238 /** Remove non-existent items from the history */
1239 void
1240 Config::clean_history ()
1241 {
1242         clean_history_internal (_history);
1243 }
1244
1245 void
1246 Config::add_to_player_history (boost::filesystem::path p)
1247 {
1248         add_to_history_internal (_player_history, p);
1249 }
1250
1251 /** Remove non-existant items from the player history */
1252 void
1253 Config::clean_player_history ()
1254 {
1255         clean_history_internal (_player_history);
1256 }
1257
1258 void
1259 Config::add_to_history_internal (vector<boost::filesystem::path>& h, boost::filesystem::path p)
1260 {
1261         /* Remove existing instances of this path in the history */
1262         h.erase (remove (h.begin(), h.end(), p), h.end ());
1263
1264         h.insert (h.begin (), p);
1265         if (h.size() > HISTORY_SIZE) {
1266                 h.pop_back ();
1267         }
1268
1269         changed (HISTORY);
1270 }
1271
1272 void
1273 Config::clean_history_internal (vector<boost::filesystem::path>& h)
1274 {
1275         auto old = h;
1276         h.clear ();
1277         for (auto i: old) {
1278                 try {
1279                         if (boost::filesystem::is_directory(i)) {
1280                                 h.push_back (i);
1281                         }
1282                 } catch (...) {
1283                         /* We couldn't find out if it's a directory for some reason; just ignore it */
1284                 }
1285         }
1286 }
1287
1288
1289 bool
1290 Config::have_existing (string file)
1291 {
1292         return boost::filesystem::exists (read_path(file));
1293 }
1294
1295
1296 void
1297 Config::read_cinemas (cxml::Document const & f)
1298 {
1299         _cinemas.clear ();
1300         for (auto i: f.node_children("Cinema")) {
1301                 /* Slightly grotty two-part construction of Cinema here so that we can use
1302                    shared_from_this.
1303                 */
1304                 auto cinema = make_shared<Cinema>(i);
1305                 cinema->read_screens (i);
1306                 _cinemas.push_back (cinema);
1307         }
1308 }
1309
1310 void
1311 Config::set_cinemas_file (boost::filesystem::path file)
1312 {
1313         if (file == _cinemas_file) {
1314                 return;
1315         }
1316
1317         _cinemas_file = file;
1318
1319         if (boost::filesystem::exists (_cinemas_file)) {
1320                 /* Existing file; read it in */
1321                 cxml::Document f ("Cinemas");
1322                 f.read_file (_cinemas_file);
1323                 read_cinemas (f);
1324         }
1325
1326         changed (CINEMAS);
1327         changed (OTHER);
1328 }
1329
1330
1331 void
1332 Config::read_dkdm_recipients (cxml::Document const & f)
1333 {
1334         _dkdm_recipients.clear ();
1335         for (auto i: f.node_children("DKDMRecipient")) {
1336                 _dkdm_recipients.push_back (make_shared<DKDMRecipient>(i));
1337         }
1338 }
1339
1340
1341 void
1342 Config::save_template (shared_ptr<const Film> film, string name) const
1343 {
1344         film->write_template (template_write_path(name));
1345 }
1346
1347
1348 list<string>
1349 Config::templates () const
1350 {
1351         if (!boost::filesystem::exists(read_path("templates"))) {
1352                 return {};
1353         }
1354
1355         list<string> n;
1356         for (auto const& i: boost::filesystem::directory_iterator(read_path("templates"))) {
1357                 n.push_back (i.path().filename().string());
1358         }
1359         return n;
1360 }
1361
1362 bool
1363 Config::existing_template (string name) const
1364 {
1365         return boost::filesystem::exists (template_read_path(name));
1366 }
1367
1368
1369 boost::filesystem::path
1370 Config::template_read_path (string name) const
1371 {
1372         return read_path("templates") / tidy_for_filename (name);
1373 }
1374
1375
1376 boost::filesystem::path
1377 Config::template_write_path (string name) const
1378 {
1379         return write_path("templates") / tidy_for_filename (name);
1380 }
1381
1382
1383 void
1384 Config::rename_template (string old_name, string new_name) const
1385 {
1386         boost::filesystem::rename (template_read_path(old_name), template_write_path(new_name));
1387 }
1388
1389 void
1390 Config::delete_template (string name) const
1391 {
1392         boost::filesystem::remove (template_write_path(name));
1393 }
1394
1395 /** @return Path to the config.xml containing the actual settings, following a link if required */
1396 boost::filesystem::path
1397 config_file (boost::filesystem::path main)
1398 {
1399         cxml::Document f ("Config");
1400         if (!boost::filesystem::exists (main)) {
1401                 /* It doesn't exist, so there can't be any links; just return it */
1402                 return main;
1403         }
1404
1405         /* See if there's a link */
1406         try {
1407                 f.read_file (main);
1408                 auto link = f.optional_string_child("Link");
1409                 if (link) {
1410                         return *link;
1411                 }
1412         } catch (xmlpp::exception& e) {
1413                 /* There as a problem reading the main configuration file,
1414                    so there can't be a link.
1415                 */
1416         }
1417
1418         return main;
1419 }
1420
1421
1422 boost::filesystem::path
1423 Config::config_read_file ()
1424 {
1425         return config_file (read_path("config.xml"));
1426 }
1427
1428
1429 boost::filesystem::path
1430 Config::config_write_file ()
1431 {
1432         return config_file (write_path("config.xml"));
1433 }
1434
1435
1436 void
1437 Config::reset_cover_sheet ()
1438 {
1439         set_cover_sheet_to_default ();
1440         changed ();
1441 }
1442
1443 void
1444 Config::link (boost::filesystem::path new_file) const
1445 {
1446         xmlpp::Document doc;
1447         doc.create_root_node("Config")->add_child("Link")->add_child_text(new_file.string());
1448         try {
1449                 doc.write_to_file_formatted(write_path("config.xml").string());
1450         } catch (xmlpp::exception& e) {
1451                 string s = e.what ();
1452                 trim (s);
1453                 throw FileError (s, write_path("config.xml"));
1454         }
1455 }
1456
1457 void
1458 Config::copy_and_link (boost::filesystem::path new_file) const
1459 {
1460         write ();
1461         boost::filesystem::copy_file (config_read_file(), new_file, boost::filesystem::copy_option::overwrite_if_exists);
1462         link (new_file);
1463 }
1464
1465 bool
1466 Config::have_write_permission () const
1467 {
1468         dcp::File f(config_write_file(), "r+");
1469         return static_cast<bool>(f);
1470 }
1471
1472 /** @param  output_channels Number of output channels in use.
1473  *  @return Audio mapping for this output channel count (may be a default).
1474  */
1475 AudioMapping
1476 Config::audio_mapping (int output_channels)
1477 {
1478         if (!_audio_mapping || _audio_mapping->output_channels() != output_channels) {
1479                 /* Set up a default */
1480                 _audio_mapping = AudioMapping (MAX_DCP_AUDIO_CHANNELS, output_channels);
1481                 if (output_channels == 2) {
1482                         /* Special case for stereo output.
1483                            Map so that Lt = L(-3dB) + Ls(-3dB) + C(-6dB) + Lfe(-10dB)
1484                            Rt = R(-3dB) + Rs(-3dB) + C(-6dB) + Lfe(-10dB)
1485                         */
1486                         _audio_mapping->set (dcp::Channel::LEFT,   0, 1 / sqrt(2));  // L   -> Lt
1487                         _audio_mapping->set (dcp::Channel::RIGHT,  1, 1 / sqrt(2));  // R   -> Rt
1488                         _audio_mapping->set (dcp::Channel::CENTRE, 0, 1 / 2.0);      // C   -> Lt
1489                         _audio_mapping->set (dcp::Channel::CENTRE, 1, 1 / 2.0);      // C   -> Rt
1490                         _audio_mapping->set (dcp::Channel::LFE,    0, 1 / sqrt(10)); // Lfe -> Lt
1491                         _audio_mapping->set (dcp::Channel::LFE,    1, 1 / sqrt(10)); // Lfe -> Rt
1492                         _audio_mapping->set (dcp::Channel::LS,     0, 1 / sqrt(2));  // Ls  -> Lt
1493                         _audio_mapping->set (dcp::Channel::RS,     1, 1 / sqrt(2));  // Rs  -> Rt
1494                 } else {
1495                         /* 1:1 mapping */
1496                         for (int i = 0; i < min (MAX_DCP_AUDIO_CHANNELS, output_channels); ++i) {
1497                                 _audio_mapping->set (i, i, 1);
1498                         }
1499                 }
1500         }
1501
1502         return *_audio_mapping;
1503 }
1504
1505 void
1506 Config::set_audio_mapping (AudioMapping m)
1507 {
1508         _audio_mapping = m;
1509         changed (AUDIO_MAPPING);
1510 }
1511
1512 void
1513 Config::set_audio_mapping_to_default ()
1514 {
1515         DCPOMATIC_ASSERT (_audio_mapping);
1516         auto const ch = _audio_mapping->output_channels ();
1517         _audio_mapping = boost::none;
1518         _audio_mapping = audio_mapping (ch);
1519         changed (AUDIO_MAPPING);
1520 }
1521
1522
1523 void
1524 Config::add_custom_language (dcp::LanguageTag tag)
1525 {
1526         if (find(_custom_languages.begin(), _custom_languages.end(), tag) == _custom_languages.end()) {
1527                 _custom_languages.push_back (tag);
1528                 changed ();
1529         }
1530 }
1531
1532
1533 optional<Config::BadReason>
1534 Config::check_certificates () const
1535 {
1536         optional<BadReason> bad;
1537
1538         for (auto const& i: _signer_chain->unordered()) {
1539                 if (i.has_utf8_strings()) {
1540                         bad = BAD_SIGNER_UTF8_STRINGS;
1541                 }
1542                 if ((i.not_after().year() - i.not_before().year()) > 15) {
1543                         bad = BAD_SIGNER_VALIDITY_TOO_LONG;
1544                 }
1545         }
1546
1547         if (!_signer_chain->chain_valid() || !_signer_chain->private_key_valid()) {
1548                 bad = BAD_SIGNER_INCONSISTENT;
1549         }
1550
1551         if (!_decryption_chain->chain_valid() || !_decryption_chain->private_key_valid()) {
1552                 bad = BAD_DECRYPTION_INCONSISTENT;
1553         }
1554
1555         return bad;
1556 }
1557
1558
1559 void
1560 save_all_config_as_zip (boost::filesystem::path zip_file)
1561 {
1562         Zipper zipper (zip_file);
1563
1564         auto config = Config::instance();
1565         zipper.add ("config.xml", dcp::file_to_string(config->config_read_file()));
1566         if (boost::filesystem::exists(config->cinemas_file())) {
1567                 zipper.add ("cinemas.xml", dcp::file_to_string(config->cinemas_file()));
1568         }
1569         if (boost::filesystem::exists(config->dkdm_recipients_file())) {
1570                 zipper.add ("dkdm_recipients.xml", dcp::file_to_string(config->dkdm_recipients_file()));
1571         }
1572
1573         zipper.close ();
1574 }
1575