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