2 Copyright (C) 2013-2015 Carl Hetherington <cth@carlh.net>
4 This file is part of DCP-o-matic.
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.
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.
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/>.
21 #include "exceptions.h"
22 #include "cinema_kdms.h"
28 #include "compose.hpp"
31 #include "dcpomatic_log.h"
32 #include <boost/foreach.hpp>
39 using std::runtime_error;
40 using boost::shared_ptr;
41 using boost::function;
44 CinemaKDMs::make_zip_file (boost::filesystem::path zip_file, dcp::NameFormat name_format, dcp::NameFormat::Map name_values) const
46 Zipper zipper (zip_file);
48 name_values['c'] = cinema->name;
50 BOOST_FOREACH (shared_ptr<KDMWithMetadata> i, screen_kdms) {
51 name_values['s'] = i->screen->name;
52 name_values['i'] = i->kdm_id ();
53 string const name = careful_string_filter(name_format.get(name_values, ".xml"));
54 zipper.add (name, i->kdm_as_xml());
60 /** Collect a list of KDMWithMetadatas into a list of CinemaKDMs so that each
61 * CinemaKDM contains the KDMs for its cinema.
64 CinemaKDMs::collect (list<shared_ptr<KDMWithMetadata> > screen_kdms)
66 list<CinemaKDMs> cinema_kdms;
68 while (!screen_kdms.empty ()) {
70 /* Get all the screens from a single cinema */
74 list<shared_ptr<KDMWithMetadata> >::iterator i = screen_kdms.begin ();
75 ck.cinema = (*i)->screen->cinema;
76 ck.screen_kdms.push_back (*i);
77 list<shared_ptr<KDMWithMetadata> >::iterator j = i;
79 screen_kdms.remove (*j);
81 while (i != screen_kdms.end ()) {
82 if ((*i)->screen->cinema == ck.cinema) {
83 ck.screen_kdms.push_back (*i);
84 list<shared_ptr<KDMWithMetadata> >::iterator j = i;
86 screen_kdms.remove (*j);
92 cinema_kdms.push_back (ck);
98 /** Write one directory per cinema into another directory */
100 CinemaKDMs::write_directories (
101 list<CinemaKDMs> cinema_kdms,
102 boost::filesystem::path directory,
103 dcp::NameFormat container_name_format,
104 dcp::NameFormat filename_format,
105 dcp::NameFormat::Map name_values,
106 function<bool (boost::filesystem::path)> confirm_overwrite
109 /* No specific screen */
110 name_values['s'] = "";
114 BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
115 boost::filesystem::path path = directory;
116 name_values['c'] = i.cinema->name;
117 path /= container_name_format.get(name_values, "");
118 if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
119 boost::filesystem::create_directories (path);
120 KDMWithMetadata::write_files (i.screen_kdms, path, filename_format, name_values, confirm_overwrite);
122 written += i.screen_kdms.size();
128 /** Write one ZIP file per cinema into a directory */
130 CinemaKDMs::write_zip_files (
131 list<CinemaKDMs> cinema_kdms,
132 boost::filesystem::path directory,
133 dcp::NameFormat container_name_format,
134 dcp::NameFormat filename_format,
135 dcp::NameFormat::Map name_values,
136 function<bool (boost::filesystem::path)> confirm_overwrite
139 /* No specific screen */
140 name_values['s'] = "";
144 BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
145 boost::filesystem::path path = directory;
146 name_values['c'] = i.cinema->name;
147 path /= container_name_format.get(name_values, ".zip");
148 if (!boost::filesystem::exists (path) || confirm_overwrite (path)) {
149 if (boost::filesystem::exists (path)) {
150 /* Creating a new zip file over an existing one is an error */
151 boost::filesystem::remove (path);
153 i.make_zip_file (path, filename_format, name_values);
154 written += i.screen_kdms.size();
161 /** Email one ZIP file per cinema to the cinema.
162 * @param cinema_kdms KDMS to email.
163 * @param container_name_format Format of folder / ZIP to use.
164 * @param filename_format Format of filenames to use.
165 * @param name_values Values to substitute into \p container_name_format and \p filename_format.
166 * @param cpl_name Name of the CPL that the KDMs are for.
170 list<CinemaKDMs> cinema_kdms,
171 dcp::NameFormat container_name_format,
172 dcp::NameFormat filename_format,
173 dcp::NameFormat::Map name_values,
177 Config* config = Config::instance ();
179 if (config->mail_server().empty()) {
180 throw NetworkError (_("No mail server configured in preferences"));
183 /* No specific screen */
184 name_values['s'] = "";
186 BOOST_FOREACH (CinemaKDMs const & i, cinema_kdms) {
188 if (i.cinema->emails.empty()) {
192 name_values['c'] = i.cinema->name;
194 boost::filesystem::path zip_file = boost::filesystem::temp_directory_path() / boost::filesystem::unique_path();
195 boost::filesystem::create_directories (zip_file);
196 zip_file /= container_name_format.get(name_values, ".zip");
197 i.make_zip_file (zip_file, filename_format, name_values);
199 string subject = config->kdm_subject();
200 boost::algorithm::replace_all (subject, "$CPL_NAME", cpl_name);
201 boost::algorithm::replace_all (subject, "$START_TIME", name_values['b']);
202 boost::algorithm::replace_all (subject, "$END_TIME", name_values['e']);
203 boost::algorithm::replace_all (subject, "$CINEMA_NAME", i.cinema->name);
205 string body = config->kdm_email().c_str();
206 boost::algorithm::replace_all (body, "$CPL_NAME", cpl_name);
207 boost::algorithm::replace_all (body, "$START_TIME", name_values['b']);
208 boost::algorithm::replace_all (body, "$END_TIME", name_values['e']);
209 boost::algorithm::replace_all (body, "$CINEMA_NAME", i.cinema->name);
212 BOOST_FOREACH (shared_ptr<KDMWithMetadata> j, i.screen_kdms) {
213 screens += j->screen->name + ", ";
215 boost::algorithm::replace_all (body, "$SCREENS", screens.substr (0, screens.length() - 2));
217 Emailer email (config->kdm_from(), i.cinema->emails, subject, body);
219 BOOST_FOREACH (string i, config->kdm_cc()) {
222 if (!config->kdm_bcc().empty ()) {
223 email.add_bcc (config->kdm_bcc ());
226 email.add_attachment (zip_file, container_name_format.get(name_values, ".zip"), "application/zip");
228 Config* c = Config::instance ();
231 email.send (c->mail_server(), c->mail_port(), c->mail_protocol(), c->mail_user(), c->mail_password());
233 boost::filesystem::remove (zip_file);
234 dcpomatic_log->log ("Email content follows", LogEntry::TYPE_DEBUG_EMAIL);
235 dcpomatic_log->log (email.email(), LogEntry::TYPE_DEBUG_EMAIL);
236 dcpomatic_log->log ("Email session follows", LogEntry::TYPE_DEBUG_EMAIL);
237 dcpomatic_log->log (email.notes(), LogEntry::TYPE_DEBUG_EMAIL);
241 boost::filesystem::remove (zip_file);
243 dcpomatic_log->log ("Email content follows", LogEntry::TYPE_DEBUG_EMAIL);
244 dcpomatic_log->log (email.email(), LogEntry::TYPE_DEBUG_EMAIL);
245 dcpomatic_log->log ("Email session follows", LogEntry::TYPE_DEBUG_EMAIL);
246 dcpomatic_log->log (email.notes(), LogEntry::TYPE_DEBUG_EMAIL);