38#include <wx/progdlg.h>
40#include <wx/statline.h>
43#include "catalog_mgr.h"
44#include "download_mgr.h"
45#include "expand_icon.h"
46#include "model/downloader.h"
47#include "OCPNPlatform.h"
50#include "model/plugin_cache.h"
51#include "pluginmanager.h"
52#include "model/semantic_vers.h"
64wxDEFINE_EVENT(EVT_PLUGINS_RELOAD, wxCommandEvent);
69static bool checksum_ok(
const std::string& path,
71 wxLogDebug(
"Checksum test on %s", metadata.name.c_str());
72 if (metadata.checksum ==
"") {
73 wxLogDebug(
"No metadata checksum, aborting check,");
76 const size_t pos = metadata.checksum.find(
':');
77 std::string checksum(metadata.checksum);
78 if (pos == std::string::npos) {
79 checksum = std::string(
"sha256:") + checksum;
81 std::ifstream f(path, std::ios::binary);
82 picosha2::hash256_one_by_one hasher;
85 f.read(buff,
sizeof(buff));
86 const std::string
block(buff, f.gcount());
90 std::string tarball_hash =
91 std::string(
"sha256:") + picosha2::get_hash_hex_string(hasher);
93 if (tarball_hash == checksum) {
94 wxLogDebug(
"Checksum ok: %s", tarball_hash.c_str());
97 wxLogMessage(
"Checksum fail on %s, tarball: %s, metadata: %s",
98 metadata.name.c_str(), tarball_hash.c_str(), checksum.c_str());
106static ssize_t PlugInIxByName(
const std::string name,
107 const ArrayOfPlugIns* plugins) {
108 for (
unsigned i = 0; i < plugins->GetCount(); i += 1) {
109 if (name == plugins->Item(i)->m_common_name.Lower().ToStdString()) {
124std::string GuiDownloader::run(wxWindow* parent,
bool remove_current) {
126 bool downloaded =
false;
130 std::string label(_(
"Downloading "));
133 new wxProgressDialog(_(
"Downloading"), label.c_str(), size, parent,
134 wxPD_AUTO_HIDE | wxPD_APP_MODAL | wxPD_CAN_ABORT);
135#ifdef __OCPN__ANDROID__
136 m_dialog->SetBackgroundColour(wxColour(0x7c, 0xb0, 0xe9));
139 g_Platform->HideBusySpinner();
143 showErrorDialog(
"Download error");
149 showErrorDialog(
"Download aborted");
154 if (!checksum_ok(path, m_plugin)) {
155 showErrorDialog(
"Checksum error");
163 if (remove_current) {
164 wxLogMessage(
"Uninstalling %s", m_plugin.name.c_str());
165 pluginHandler->Uninstall(m_plugin.name);
167 ok = pluginHandler->InstallPlugin(m_plugin, path);
169 showErrorDialog(
"Installation error");
175 wxURI uri(wxString(m_plugin.tarball_url.c_str()));
176 wxFileName fn(uri.GetPath());
177 auto basename = fn.GetFullName().ToStdString();
179 wxLogMessage(
"Copied %s to local cache at %s", path.c_str(),
184 wxMessageDialog* dlg =
new wxMessageDialog(
186 m_plugin.name +
" " + m_plugin.version + _(
" successfully installed"),
187 _(
"Installation complete"), wxOK | wxCENTRE | wxICON_INFORMATION);
194 m_downloaded += bytes;
195 if (m_dialog && !m_dialog->Update(m_downloaded)) {
202void GuiDownloader::showErrorDialog(
const char* msg) {
203 auto dlg =
new wxMessageDialog(m_parent,
"", _(
"Installation error"),
204 wxOK | wxICON_ERROR);
206 std::string text = msg;
207 if (last_error_msg !=
"") {
208 text = text +
": " + error_msg;
210 text = text +
"\nPlease check system log for more info.";
211 dlg->SetMessage(text);
Handle downloading of files from remote urls.
bool download(std::ostream *stream)
Download url into stream, return false on errors.
long get_filesize()
Try to get remote filesize, return 0 on failure.
std::string last_error()
Last Curl error message.
virtual void on_chunk(const char *buff, unsigned bytes)
Called when given bytes has been transferred from remote.
void on_chunk(const char *buff, unsigned bytes) override
Called when given bytes has been transferred from remote.
GuiDownloader(wxWindow *parent, PluginMetadata plugin)
Add progress and final message dialogs to the basic Downloader.
static PluginHandler * GetInstance()
Singleton factory.
std::string lookup_tarball(const char *uri)
Get path to tarball in cache for given filename.
bool store_tarball(const char *path, const char *basename)
Store a tarball in tarball cache, return success/fail.
PLugin remote repositories installation and Uninstall/list operations.
Runtime representation of a plugin block.