Various improvements in robustness / neatness of certificate download stuff.
authorCarl Hetherington <cth@carlh.net>
Tue, 3 Nov 2015 21:27:26 +0000 (21:27 +0000)
committerCarl Hetherington <cth@carlh.net>
Tue, 3 Nov 2015 21:27:26 +0000 (21:27 +0000)
src/lib/internet.cc
src/lib/internet.h
src/lib/signal_manager.h
src/wx/dolby_certificate_dialog.cc
src/wx/doremi_certificate_dialog.cc

index 7bc818717a44737f2719960a8bc8832aff4eec82..2b1e90ca7c030366652ec38cb625bc3cd0798ac9 100644 (file)
 
 */
 
-#include <string>
+#include "scoped_temporary.h"
+#include "compose.hpp"
+#include "safe_stringstream.h"
+#include "exceptions.h"
+#include <curl/curl.h>
+#include <zip.h>
 #include <boost/function.hpp>
 #include <boost/optional.hpp>
 #include <boost/filesystem.hpp>
 #include <boost/algorithm/string.hpp>
-#include <curl/curl.h>
-#include <zip.h>
-#include "scoped_temporary.h"
-#include "compose.hpp"
-#include "safe_stringstream.h"
+#include <string>
 
 #include "i18n.h"
 
@@ -111,11 +112,11 @@ ftp_ls_data (void* buffer, size_t size, size_t nmemb, void* data)
 }
 
 list<string>
-ftp_ls (string url)
+ftp_ls (string url, bool pasv)
 {
        CURL* curl = curl_easy_init ();
        if (!curl) {
-               return list<string> ();
+               throw NetworkError ("could not set up curl");
        }
 
        if (url.substr (url.length() - 1, 1) != "/") {
@@ -132,9 +133,13 @@ ftp_ls (string url)
        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);
+       if (!pasv) {
+               curl_easy_setopt (curl, CURLOPT_FTPPORT, "");
+       }
        CURLcode const r = curl_easy_perform (curl);
        if (r != CURLE_OK) {
-               return list<string> ();
+               curl_easy_cleanup (curl);
+               throw NetworkError (curl_easy_strerror (r));
        }
 
        SafeStringStream s (ls_raw);
index d7427fe48351e04cc736f9467915f9a97858197e..f46abc367de128780a87c390142e73587d4532a1 100644 (file)
@@ -22,4 +22,4 @@
 #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);
+std::list<std::string> ftp_ls (std::string dir, bool pasv = true);
index b8d892c41dc264e527d094e6336c9ebd8697125b..62afacade3139fc965b298887b87c20842ace5d4 100644 (file)
@@ -46,8 +46,8 @@ public:
 
        /** Call this in the UI when it is idle */
        size_t ui_idle () {
-               /* This executes any functors that have been post()ed to _service */
-               return _service.poll ();
+               /* This executes one of the functors that has been post()ed to _service */
+               return _service.poll_one ();
        }
 
        /** This should wake the UI and make it call ui_idle() */
index 58ad73e0d2a25c0635ac7e208e78719a89e893f0..8661cd5f88bd9f5e6b32f4775408bab742bc94c2 100644 (file)
@@ -22,6 +22,7 @@
 #include "lib/compose.hpp"
 #include "lib/internet.h"
 #include "lib/signal_manager.h"
+#include "lib/util.h"
 #include <curl/curl.h>
 #include <boost/algorithm/string.hpp>
 #include <boost/foreach.hpp>
@@ -54,7 +55,7 @@ DolbyCertificateDialog::DolbyCertificateDialog (wxWindow* parent, boost::functio
        _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));
+       signal_manager->when_idle (boost::bind (&DolbyCertificateDialog::setup_countries, this));
 
        _country->Clear ();
        _cinema->Clear ();
@@ -64,7 +65,7 @@ list<string>
 DolbyCertificateDialog::get_dir (string dir) const
 {
        string url = String::compose ("ftp://dolbyrootcertificates:houro61l@ftp.dolby.co.uk/SHA256/%1", dir);
-       return ftp_ls (url);
+       return ftp_ls (url, false);
 }
 
 void
@@ -78,19 +79,24 @@ DolbyCertificateDialog::setup_countries ()
        _country->Append (_("Fetching..."));
        _country->SetSelection (0);
 
-#ifdef DCPOMATIC_OSX
        /* See DoremiCertificateDialog for discussion about this daft delay */
        wxMilliSleep (200);
-#endif
+
        signal_manager->when_idle (boost::bind (&DolbyCertificateDialog::finish_setup_countries, this));
 }
 
 void
 DolbyCertificateDialog::finish_setup_countries ()
 {
-       _country->Clear ();
-       BOOST_FOREACH (string i, get_dir ("")) {
-               _country->Append (std_to_wx (i));
+       try {
+               list<string> const c = get_dir ("");
+               _country->Clear ();
+               BOOST_FOREACH (string i, c) {
+                       _country->Append (std_to_wx (i));
+               }
+       } catch (NetworkError& e) {
+               error_dialog (this, wxString::Format (_("Could not get country list (%s)"), e.what()));
+               _country->Clear ();
        }
 }
 
@@ -110,9 +116,15 @@ DolbyCertificateDialog::country_selected ()
 void
 DolbyCertificateDialog::finish_country_selected ()
 {
-       _cinema->Clear ();
-       BOOST_FOREACH (string i, get_dir (wx_to_std (_country->GetStringSelection()))) {
-               _cinema->Append (std_to_wx (i));
+       try {
+               list<string> const c = get_dir (wx_to_std (_country->GetStringSelection()));
+               _cinema->Clear ();
+               BOOST_FOREACH (string i, c) {
+                       _cinema->Append (std_to_wx (i));
+               }
+       } catch (NetworkError& e) {
+               error_dialog (this, wxString::Format (_("Could not get cinema list (%s)"), e.what ()));
+               _cinema->Clear ();
        }
 }
 
@@ -132,15 +144,19 @@ DolbyCertificateDialog::cinema_selected ()
 void
 DolbyCertificateDialog::finish_cinema_selected ()
 {
-       string const dir = String::compose ("%1/%2", wx_to_std (_country->GetStringSelection()), wx_to_std (_cinema->GetStringSelection()));
-
-       _serial->Clear ();
-       BOOST_FOREACH (string i, get_dir (dir)) {
-               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)));
+       try {
+               list<string> const s = get_dir (String::compose ("%1/%2", wx_to_std (_country->GetStringSelection()), wx_to_std (_cinema->GetStringSelection())));
+               _serial->Clear ();
+               BOOST_FOREACH (string i, s) {
+                       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)));
+                       }
                }
+       } catch (NetworkError& e) {
+               error_dialog (this, wxString::Format (_("Could not get screen list (%s)"), e.what()));
+               _serial->Clear ();
        }
 }
 
index c4c2115f04e6de01e219caaa6ae1e237e33418a8..ffb2a0f99c05f07917cbadd28ac8df970ea48481 100644 (file)
@@ -55,10 +55,8 @@ DoremiCertificateDialog::download ()
        downloaded (false);
        _message->SetLabel (_("Downloading certificate"));
 
-#ifdef DCPOMATIC_OSX
-       /* This is necessary on OS X, otherwise the SetLabel() above has no visible effect */
+       /* Hack: without this the SetLabel() above has no visible effect */
        wxMilliSleep (200);
-#endif
 
        signal_manager->when_idle (boost::bind (&DoremiCertificateDialog::finish_download, this, serial));
 }
@@ -100,6 +98,7 @@ DoremiCertificateDialog::finish_download (string serial)
        }
 
        if (error) {
+               _message->SetLabel (wxT (""));
                error_dialog (this, std_to_wx (error.get ()));
        } else {
                _message->SetLabel (_("Certificate downloaded"));
@@ -112,4 +111,3 @@ DoremiCertificateDialog::set_sensitivity ()
 {
        _download->Enable (!_serial->IsEmpty ());
 }
-