Try more times to connect to batch converter.
[dcpomatic.git] / src / wx / dolby_certificate_panel.cc
1 /*
2     Copyright (C) 2014-2015 Carl Hetherington <cth@carlh.net>
3
4     This program is free software; you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation; either version 2 of the License, or
7     (at your option) any later version.
8
9     This program is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13
14     You should have received a copy of the GNU General Public License
15     along with this program; if not, write to the Free Software
16     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17
18 */
19
20 #include "dolby_certificate_panel.h"
21 #include "download_certificate_dialog.h"
22 #include "wx_util.h"
23 #include "lib/compose.hpp"
24 #include "lib/internet.h"
25 #include "lib/signal_manager.h"
26 #include "lib/util.h"
27 #include <curl/curl.h>
28 #include <boost/algorithm/string.hpp>
29 #include <boost/foreach.hpp>
30 #include <iostream>
31
32 using std::list;
33 using std::string;
34 using std::vector;
35 using std::cout;
36 using boost::optional;
37 using boost::algorithm::split;
38 using boost::algorithm::is_any_of;
39
40 DolbyCertificatePanel::DolbyCertificatePanel (wxWindow* parent, DownloadCertificateDialog* dialog)
41         : DownloadCertificatePanel (parent, dialog)
42 {
43         add_label_to_sizer (_table, this, _("Country"), true);
44         _country = new wxChoice (this, wxID_ANY);
45         _table->Add (_country, 1, wxEXPAND);
46         _country->Append (N_("Hashemite Kingdom of Jordan"));
47
48         add_label_to_sizer (_table, this, _("Cinema"), true);
49         _cinema = new wxChoice (this, wxID_ANY);
50         _table->Add (_cinema, 1, wxEXPAND);
51         _cinema->Append (N_("Motion Picture Solutions London Mobile & QC"));
52
53         add_label_to_sizer (_table, this, _("Serial number"), true);
54         _serial = new wxChoice (this, wxID_ANY);
55         _table->Add (_serial, 1, wxEXPAND);
56
57         layout ();
58
59         _country->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DolbyCertificatePanel::country_selected, this));
60         _cinema->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DolbyCertificatePanel::cinema_selected, this));
61         _serial->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DownloadCertificateDialog::setup_sensitivity, _dialog));
62
63         _country->Clear ();
64         _cinema->Clear ();
65 }
66
67 string
68 DolbyCertificatePanel::url (string path) const
69 {
70         return String::compose ("ftp://dolbyrootcertificates:houro61l@ftp.dolby.co.uk/SHA256/%1", path);
71 }
72
73 list<string>
74 DolbyCertificatePanel::get_dir (string dir) const
75 {
76         return ftp_ls (url (dir), false);
77 }
78
79 void
80 DolbyCertificatePanel::setup_countries ()
81 {
82         if (_country->GetCount() > 0) {
83                 /* Already set up */
84                 return;
85         }
86
87         _country->Append (_("Fetching..."));
88         _country->SetSelection (0);
89
90         /* See DoremiCertificatePanel for discussion about this daft delay */
91         wxMilliSleep (200);
92
93         signal_manager->when_idle (boost::bind (&DolbyCertificatePanel::finish_setup_countries, this));
94 }
95
96 void
97 DolbyCertificatePanel::finish_setup_countries ()
98 {
99         try {
100                 list<string> const c = get_dir ("");
101                 _country->Clear ();
102                 BOOST_FOREACH (string i, c) {
103                         _country->Append (std_to_wx (i));
104                 }
105         } catch (NetworkError& e) {
106                 error_dialog (this, wxString::Format (_("Could not get country list (%s)"), e.what()));
107                 _country->Clear ();
108         }
109 }
110
111 void
112 DolbyCertificatePanel::country_selected ()
113 {
114         _cinema->Clear ();
115         _cinema->Append (_("Fetching..."));
116         _cinema->SetSelection (0);
117
118 #ifdef DCPOMATIC_OSX
119         wxMilliSleep (200);
120 #endif
121         signal_manager->when_idle (boost::bind (&DolbyCertificatePanel::finish_country_selected, this));
122 }
123
124 void
125 DolbyCertificatePanel::finish_country_selected ()
126 {
127         try {
128                 list<string> const c = get_dir (wx_to_std (_country->GetStringSelection()));
129                 _cinema->Clear ();
130                 BOOST_FOREACH (string i, c) {
131                         _cinema->Append (std_to_wx (i));
132                 }
133         } catch (NetworkError& e) {
134                 error_dialog (this, wxString::Format (_("Could not get cinema list (%s)"), e.what ()));
135                 _cinema->Clear ();
136         }
137 }
138
139 void
140 DolbyCertificatePanel::cinema_selected ()
141 {
142         _serial->Clear ();
143         _serial->Append (_("Fetching..."));
144         _serial->SetSelection (0);
145
146 #ifdef DCPOMATIC_OSX
147         wxMilliSleep (200);
148 #endif
149         signal_manager->when_idle (boost::bind (&DolbyCertificatePanel::finish_cinema_selected, this));
150 }
151
152 void
153 DolbyCertificatePanel::finish_cinema_selected ()
154 {
155         try {
156                 list<string> const s = get_dir (String::compose ("%1/%2", wx_to_std (_country->GetStringSelection()), wx_to_std (_cinema->GetStringSelection())));
157                 _serial->Clear ();
158                 BOOST_FOREACH (string i, s) {
159                         vector<string> a;
160                         split (a, i, is_any_of ("-_"));
161                         if (a.size() >= 4) {
162                                 _serial->Append (std_to_wx (a[3]), new wxStringClientData (std_to_wx (i)));
163                         }
164                 }
165         } catch (NetworkError& e) {
166                 error_dialog (this, wxString::Format (_("Could not get screen list (%s)"), e.what()));
167                 _serial->Clear ();
168         }
169 }
170
171 void
172 DolbyCertificatePanel::download (wxStaticText* message)
173 {
174         message->SetLabel (_("Downloading certificate"));
175
176 #ifdef DCPOMATIC_OSX
177         wxMilliSleep (200);
178 #endif
179
180         signal_manager->when_idle (boost::bind (&DolbyCertificatePanel::finish_download, this, message));
181 }
182
183 void
184 DolbyCertificatePanel::finish_download (wxStaticText* message)
185 {
186         string const zip = string_client_data (_serial->GetClientObject (_serial->GetSelection ()));
187
188         string const file = url (
189                 String::compose ("%1/%2/%3",
190                                  wx_to_std (_country->GetStringSelection()),
191                                  wx_to_std (_cinema->GetStringSelection()),
192                                  zip
193                         )
194                 );
195
196         /* Work out the certificate file name inside the zip */
197         vector<string> b;
198         split (b, zip, is_any_of ("_"));
199         if (b.size() < 2) {
200                 message->SetLabel (_("Unexpected certificate filename form"));
201                 return;
202         }
203         string const cert = b[0] + "_" + b[1] + ".pem.crt";
204
205         optional<string> error = get_from_zip_url (file, cert, false, boost::bind (&DownloadCertificatePanel::load, this, _1));
206         if (error) {
207                 message->SetLabel (std_to_wx (error.get ()));
208         } else {
209                 message->SetLabel (_("Certificate downloaded"));
210                 _dialog->setup_sensitivity ();
211         }
212 }
213
214 bool
215 DolbyCertificatePanel::ready_to_download () const
216 {
217         return _country->GetSelection() != -1 && _cinema->GetSelection() != -1 && _serial->GetSelection() != -1;
218 }
219
220 void
221 DolbyCertificatePanel::setup ()
222 {
223         signal_manager->when_idle (boost::bind (&DolbyCertificatePanel::setup_countries, this));
224 }