--- /dev/null
+/*
+ Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <string>
+#include <boost/function.hpp>
+#include <boost/optional.hpp>
+#include <boost/filesystem.hpp>
+#include <curl/curl.h>
+#include <zip.h>
+#include "util.h"
+
+#include "i18n.h"
+
+using std::string;
+using std::stringstream;
+using std::list;
+using boost::optional;
+using boost::function;
+
+static size_t
+get_from_zip_url_data (void* buffer, size_t size, size_t nmemb, void* stream)
+{
+ FILE* f = reinterpret_cast<FILE*> (stream);
+ return fwrite (buffer, size, nmemb, f);
+}
+
+/** @param url URL of ZIP file.
+ * @param file Filename within ZIP file.
+ * @param load Function passed a (temporary) filesystem path of the unpacked file.
+ */
+optional<string>
+get_from_zip_url (string url, string file, function<void (boost::filesystem::path)> load)
+{
+ /* Download the ZIP file to temp_zip */
+ CURL* curl = curl_easy_init ();
+ curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
+
+ ScopedTemporary temp_zip;
+ FILE* f = temp_zip.open ("wb");
+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, get_from_zip_url_data);
+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, f);
+
+ CURLcode const cr = curl_easy_perform (curl);
+
+ temp_zip.close ();
+ curl_easy_cleanup (curl);
+ if (cr != CURLE_OK) {
+ return String::compose (_("Download failed (%1/%2 error %3)"), url, file, cr);
+ }
+
+ /* Open the ZIP file and read `file' out of it */
+
+ struct zip* zip = zip_open (temp_zip.c_str(), 0, 0);
+ if (!zip) {
+ return optional<string> (_("Could not open downloaded ZIP file"));
+ }
+
+ struct zip_file* zip_file = zip_fopen (zip, file.c_str(), 0);
+ if (!zip_file) {
+ return optional<string> (_("Unexpected ZIP file contents"));
+ }
+
+ ScopedTemporary temp_cert;
+ f = temp_cert.open ("wb");
+ char buffer[4096];
+ while (1) {
+ int const N = zip_fread (zip_file, buffer, sizeof (buffer));
+ fwrite (buffer, 1, N, f);
+ if (N < int (sizeof (buffer))) {
+ break;
+ }
+ }
+ temp_cert.close ();
+
+ load (temp_cert.file ());
+ return optional<string> ();
+}
+
+
+static size_t
+ftp_ls_data (void* buffer, size_t size, size_t nmemb, void* data)
+{
+ string* s = reinterpret_cast<string *> (data);
+ uint8_t* b = reinterpret_cast<uint8_t *> (buffer);
+ for (size_t i = 0; i < (size * nmemb); ++i) {
+ *s += b[i];
+ }
+ return nmemb;
+}
+
+list<string>
+ftp_ls (string url)
+{
+ CURL* curl = curl_easy_init ();
+ if (!curl) {
+ return list<string> ();
+ }
+
+ if (url.substr (url.length() - 1, 1) != "/") {
+ url += "/";
+ }
+ curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
+
+ string ls_raw;
+ struct curl_slist* commands = 0;
+ commands = curl_slist_append (commands, "NLST");
+ curl_easy_setopt (curl, CURLOPT_POSTQUOTE, commands);
+ curl_easy_setopt (curl, CURLOPT_WRITEDATA, &ls_raw);
+ curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ftp_ls_data);
+ curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, 0);
+ CURLcode const r = curl_easy_perform (curl);
+ if (r != CURLE_OK) {
+ return list<string> ();
+ }
+
+ stringstream s (ls_raw);
+ string line;
+ list<string> ls;
+ while (s.good ()) {
+ getline (s, line);
+ if (line.length() > 55) {
+ string const file = line.substr (55);
+ if (file != "." && file != "..") {
+ ls.push_back (file);
+ }
+ }
+ }
+
+ curl_easy_cleanup (curl);
+
+ return ls;
+}
--- /dev/null
+/*
+ Copyright (C) 2014 Carl Hetherington <cth@carlh.net>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#include <boost/optional.hpp>
+#include <boost/function.hpp>
+#include <boost/filesystem.hpp>
+
+boost::optional<std::string> get_from_zip_url (std::string url, std::string file, boost::function<void (boost::filesystem::path)> load);
+std::list<std::string> ftp_ls (std::string dir);
ffmpeg_examiner.cc
film.cc
filter.cc
+ internet.cc
image.cc
image_content.cc
image_decoder.cc
*/
+#include <boost/algorithm/string.hpp>
#include <curl/curl.h>
#include "lib/compose.hpp"
+#include "lib/internet.h"
#include "dolby_certificate_dialog.h"
#include "wx_util.h"
using std::list;
using std::string;
+using std::vector;
using std::stringstream;
using std::cout;
+using boost::optional;
+using boost::algorithm::split;
+using boost::algorithm::is_any_of;
DolbyCertificateDialog::DolbyCertificateDialog (wxWindow* parent, boost::function<void (boost::filesystem::path)> load)
: DownloadCertificateDialog (parent, load)
_cinema = add (new wxChoice (this, wxID_ANY));
_cinema->Append (N_("Motion Picture Solutions London Mobile & QC"));
+ add (_("Serial number"), true);
+ _serial = add (new wxChoice (this, wxID_ANY));
+
add_common_widgets ();
_country->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DolbyCertificateDialog::country_selected, this));
_cinema->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DolbyCertificateDialog::cinema_selected, this));
+ _serial->Bind (wxEVT_COMMAND_CHOICE_SELECTED, boost::bind (&DolbyCertificateDialog::serial_selected, this));
Bind (wxEVT_IDLE, boost::bind (&DolbyCertificateDialog::setup_countries, this));
_country->Clear ();
_cinema->Clear ();
}
-static size_t
-ftp_data_ls (void* buffer, size_t size, size_t nmemb, void* data)
-{
- string* s = reinterpret_cast<string *> (data);
- uint8_t* b = reinterpret_cast<uint8_t *> (buffer);
- for (size_t i = 0; i < (size * nmemb); ++i) {
- *s += b[i];
- }
- return nmemb;
-}
-
list<string>
-DolbyCertificateDialog::ftp_ls (string dir) const
+DolbyCertificateDialog::get_dir (string dir) const
{
- CURL* curl = curl_easy_init ();
- if (!curl) {
- _message->SetLabel (N_("Could not set up libcurl"));
- return list<string> ();
- }
-
string url = String::compose ("ftp://dolbyrootcertificates:houro61l@ftp.dolby.co.uk/SHA256/%1", dir);
- if (url.substr (url.length() - 1, 1) != "/") {
- url += "/";
- }
- curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
-
- string ls_raw;
- struct curl_slist* commands = 0;
- commands = curl_slist_append (commands, "NLST");
- curl_easy_setopt (curl, CURLOPT_POSTQUOTE, commands);
- curl_easy_setopt (curl, CURLOPT_WRITEDATA, &ls_raw);
- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ftp_data_ls);
- curl_easy_setopt (curl, CURLOPT_FTP_USE_EPSV, 0);
- CURLcode const r = curl_easy_perform (curl);
- if (r != CURLE_OK) {
- _message->SetLabel (_("Problem occurred when contacting Dolby."));
- return list<string> ();
- }
-
- stringstream s (ls_raw);
- string line;
- list<string> ls;
- while (s.good ()) {
- getline (s, line);
- if (line.length() > 55) {
- string const file = line.substr (55);
- if (file != "." && file != "..") {
- ls.push_back (file);
- }
- }
- }
-
- curl_easy_cleanup (curl);
-
- return ls;
+ return ftp_ls (url);
}
void
_country->SetSelection (0);
run_gui_loop ();
- list<string> const countries = ftp_ls ("");
+ list<string> const countries = get_dir ("");
_country->Clear ();
for (list<string>::const_iterator i = countries.begin(); i != countries.end(); ++i) {
_country->Append (std_to_wx (*i));
_cinema->SetSelection (0);
run_gui_loop ();
- list<string> const cinemas = ftp_ls (wx_to_std (_country->GetStringSelection()));
+ list<string> const cinemas = get_dir (wx_to_std (_country->GetStringSelection()));
_cinema->Clear ();
for (list<string>::const_iterator i = cinemas.begin(); i != cinemas.end(); ++i) {
_cinema->Append (std_to_wx (*i));
void
DolbyCertificateDialog::cinema_selected ()
+{
+ _serial->Clear ();
+ _serial->Append (_("Fetching..."));
+ _serial->SetSelection (0);
+ run_gui_loop ();
+
+ string const dir = String::compose ("%1/%2", wx_to_std (_country->GetStringSelection()), wx_to_std (_cinema->GetStringSelection()));
+ list<string> const zips = get_dir (dir);
+
+ _serial->Clear ();
+ for (list<string>::const_iterator i = zips.begin(); i != zips.end(); ++i) {
+ vector<string> a;
+ split (a, *i, is_any_of ("-_"));
+ if (a.size() >= 4) {
+ _serial->Append (std_to_wx (a[3]), new wxStringClientData (std_to_wx (*i)));
+ }
+ }
+}
+
+void
+DolbyCertificateDialog::serial_selected ()
{
_download->Enable (true);
}
void
DolbyCertificateDialog::download ()
{
+ _message->SetLabel (_("Downloading certificate"));
+ run_gui_loop ();
+
+ string const zip = string_client_data (_serial->GetClientObject (_serial->GetSelection ()));
+
+ string const file = String::compose (
+ "%1/%2/%3",
+ wx_to_std (_country->GetStringSelection()),
+ wx_to_std (_cinema->GetStringSelection()),
+ zip
+ );
+
+ /* Work out the certificate file name inside the zip */
+ vector<string> b;
+ split (b, zip, is_any_of ("_"));
+ if (b.size() < 2) {
+ _message->SetLabel (_("Unexpected certificate filename form"));
+ return;
+ }
+ string const cert = b[0] + "_" + b[1] + ".pem.crt";
+
+ optional<string> error = get_from_zip_url (file, cert, _load);
+ if (error) {
+ error_dialog (this, std_to_wx (error.get ()));
+ }
+ _message->SetLabel (wxT (""));
}
void setup_countries ();
void country_selected ();
void cinema_selected ();
- std::list<std::string> ftp_ls (std::string) const;
+ void serial_selected ();
+ std::list<std::string> get_dir (std::string) const;
wxChoice* _country;
wxChoice* _cinema;
+ wxChoice* _serial;
};
#include <zip.h>
#include "lib/compose.hpp"
#include "lib/util.h"
+#include "lib/internet.h"
#include "doremi_certificate_dialog.h"
#include "wx_util.h"
using std::string;
using boost::function;
+using boost::optional;
DoremiCertificateDialog::DoremiCertificateDialog (wxWindow* parent, function<void (boost::filesystem::path)> load)
: DownloadCertificateDialog (parent, load)
add_common_widgets ();
}
-
-
-static size_t
-ftp_data (void* buffer, size_t size, size_t nmemb, void* stream)
-{
- FILE* f = reinterpret_cast<FILE*> (stream);
- return fwrite (buffer, size, nmemb, f);
-}
-
void
DoremiCertificateDialog::download ()
{
string const serial = wx_to_std (_serial->GetValue ());
if (serial.length() != 6) {
- _message->SetLabel (_("Doremi serial numbers must have 6 digits"));
- return;
- }
-
- CURL* curl = curl_easy_init ();
- if (!curl) {
- _message->SetLabel (N_("Could not set up libcurl"));
+ error_dialog (this, _("Doremi serial numbers must have 6 digits"));
return;
}
-
- string const url = String::compose (
- "ftp://service:t3chn1c1an@ftp.doremilabs.com/Certificates/%1xxx/dcp2000-%2.dcicerts.zip",
- serial.substr(0, 3), serial
- );
-
- curl_easy_setopt (curl, CURLOPT_URL, url.c_str ());
-
- ScopedTemporary temp_zip;
- FILE* f = temp_zip.open ("wb");
- curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, ftp_data);
- curl_easy_setopt (curl, CURLOPT_WRITEDATA, f);
- _message->SetLabel (_("Downloading certificate from Doremi"));
- run_gui_loop ();
+ _message->SetLabel (_("Downloading certificate"));
- CURLcode const cr = curl_easy_perform (curl);
+ optional<string> error = get_from_zip_url (
+ String::compose (
+ "ftp://service:t3chn1c1an@ftp.doremilabs.com/Certificates/%1xxx/dcp2000-%2.dcicerts.zip",
+ serial.substr(0, 3), serial
+ ),
+ String::compose ("dcp2000-%1.cert.sha256.pem", serial),
+ _load
+ );
- _gauge->SetValue (50);
- run_gui_loop ();
-
- temp_zip.close ();
- curl_easy_cleanup (curl);
- if (cr != CURLE_OK) {
- _message->SetLabel (wxString::Format (_("Certificate download failed (%d)"), cr));
- return;
- }
-
- _message->SetLabel (_("Unpacking"));
- run_gui_loop ();
-
- struct zip* zip = zip_open (temp_zip.c_str(), 0, 0);
- if (!zip) {
- _message->SetLabel (N_("Could not open certificate ZIP file"));
- return;
- }
-
- string const name_in_zip = String::compose ("dcp2000-%1.cert.sha256.pem", serial);
- struct zip_file* zip_file = zip_fopen (zip, name_in_zip.c_str(), 0);
- if (!zip_file) {
- _message->SetLabel (N_("Could not find certificate in ZIP file"));
- return;
- }
-
- ScopedTemporary temp_cert;
- f = temp_cert.open ("wb");
- char buffer[4096];
- while (1) {
- int const N = zip_fread (zip_file, buffer, sizeof (buffer));
- fwrite (buffer, 1, N, f);
- if (N < int (sizeof (buffer))) {
- break;
- }
+ if (error) {
+ error_dialog (this, std_to_wx (error.get ()));
+ } else {
+ _message->SetLabel (wxT (""));
}
- temp_cert.close ();
-
- _gauge->SetValue (100);
- _message->SetLabel (_("OK"));
- _load (temp_cert.file ());
}
add_spacer ();
_download = add (new wxButton (this, wxID_ANY, _("Download")));
- add_spacer ();
- _gauge = add (new wxGauge (this, wxID_ANY, 100));
-
add_spacer ();
_message = add (new wxStaticText (this, wxID_ANY, wxT ("")));
+
+ wxFont font = _message->GetFont();
+ font.SetStyle (wxFONTSTYLE_ITALIC);
+ font.SetPointSize (font.GetPointSize() - 1);
+ _message->SetFont (font);
_download->Bind (wxEVT_COMMAND_BUTTON_CLICKED, boost::bind (&DownloadCertificateDialog::download, this));
_download->Enable (false);
boost::function<void (boost::filesystem::path)> _load;
wxSizer* _overall_sizer;
- wxGauge* _gauge;
wxStaticText* _message;
wxButton* _download;