Improvements of Archive repo db.

Save repo states to json in config folder.
Use uuid to manage repos.
Check conflicts of ids and other errors.
This commit is contained in:
David Kocik 2024-05-03 09:56:16 +02:00
parent 10638751af
commit 4e5f1dbd29
9 changed files with 377 additions and 95 deletions

View File

@ -624,7 +624,7 @@ PageUpdateManager::PageUpdateManager(ConfigWizard* parent)
btn->SetFont(wxGetApp().bold_font());
wxGetApp().UpdateDarkUI(btn, true);
btn->Bind(wxEVT_BUTTON, [this](wxCommandEvent& event) {
m_manager->set_used_archives();
m_manager->set_selected_repositories();
wizard_p()->set_config_updated_from_archive(true);
});

View File

@ -3162,7 +3162,7 @@ bool GUI_App::run_wizard(ConfigWizard::RunReason reason, ConfigWizard::StartPage
}
#endif // 0
// Do blocking sync on every start of wizard, so user is always offered recent profiles.
preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_archives());
preset_updater->sync_blocking(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid());
// Offer update installation (of already installed profiles) only when run by user.
if (reason == ConfigWizard::RR_USER) {
preset_updater->update_index_db();
@ -3880,7 +3880,7 @@ void GUI_App::start_preset_updater(bool forced)
return;
}
this->preset_updater->cancel_sync();
this->preset_updater->sync(preset_bundle, this, plater()->get_preset_archive_database()->get_archives());
this->preset_updater->sync(preset_bundle, this, plater()->get_preset_archive_database()->get_archive_repositories(), plater()->get_preset_archive_database()->get_selected_repositories_uuid());
m_started_preset_updater = true;
}
} // GUI

View File

@ -994,7 +994,7 @@ Plater::priv::priv(Plater *q, MainFrame *main_frame)
}
this->q->Bind(EVT_PRESET_ARCHIVE_DATABASE_SYNC_DONE, [this](Event<ArchiveRepositorySyncData>& evt) {
preset_archive_database->set_archives(evt.data.json);
preset_archive_database->read_server_manifest(evt.data.json);
wxGetApp().start_preset_updater(evt.data.force_updater);
});

View File

@ -14,8 +14,12 @@
#include <boost/filesystem/fstream.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <cctype>
#include <curl/curl.h>
#include <iostream>
#include <fstream>
namespace pt = boost::property_tree;
namespace fs = boost::filesystem;
@ -69,21 +73,21 @@ bool extract_repository_header(const pt::ptree& ptree, ArchiveRepository::Reposi
if (const auto name = ptree.get_optional<std::string>("name"); name){
data.name = *name;
} else {
BOOST_LOG_TRIVIAL(error) << "Failed to find \"name\" parameter in repository header. Repository is invalid.";
BOOST_LOG_TRIVIAL(error) << "Failed to find \"name\" parameter in repository manifest. Repository is invalid.";
return false;
}
if (const auto id = ptree.get_optional<std::string>("id"); id) {
data.id = *id;
}
else {
BOOST_LOG_TRIVIAL(error) << "Failed to find \"id\" parameter in repository header. Repository is invalid.";
BOOST_LOG_TRIVIAL(error) << "Failed to find \"id\" parameter in repository manifest. Repository is invalid.";
return false;
}
if (const auto url = ptree.get_optional<std::string>("url"); url) {
data.url = *url;
}
else {
BOOST_LOG_TRIVIAL(error) << "Failed to find \"url\" parameter in repository header. Repository is invalid.";
BOOST_LOG_TRIVIAL(error) << "Failed to find \"url\" parameter in repository manifest. Repository is invalid.";
return false;
}
// optional atributes
@ -120,32 +124,33 @@ void delete_path_recursive(const fs::path& path)
}
}
bool extract_local_archive_repository(const fs::path& zip_path, fs::path& unq_tmp_path, ArchiveRepository::RepositoryManifest& header_data)
bool extract_local_archive_repository(const std::string& uuid, const fs::path& zip_path, fs::path& unq_tmp_path, ArchiveRepository::RepositoryManifest& manifest_data)
{
manifest_data.source_path = zip_path;
// Path where data will be unzipped.
header_data.local_path = unq_tmp_path / zip_path.stem();
manifest_data.tmp_path = unq_tmp_path / uuid;
// Delete previous data before unzip.
// We have unique path in temp set for whole run of slicer and in it folder for each repo.
delete_path_recursive(header_data.local_path);
fs::create_directories(header_data.local_path);
delete_path_recursive(manifest_data.tmp_path);
fs::create_directories(manifest_data.tmp_path);
// Unzip repository zip to unique path in temp directory.
if (!unzip_repository(zip_path, header_data.local_path)) {
if (!unzip_repository(zip_path, manifest_data.tmp_path)) {
return false;
}
// Read the header file.
fs::path header_path = header_data.local_path / "header.json";
// Read the manifest file.
fs::path manifest_path = manifest_data.tmp_path / "manifest.json";
try
{
pt::ptree ptree;
pt::read_json(header_path.string(), ptree);
if (!extract_repository_header(ptree, header_data)) {
pt::read_json(manifest_path.string(), ptree);
if (!extract_repository_header(ptree, manifest_data)) {
BOOST_LOG_TRIVIAL(error) << "Failed to load repository: " << zip_path;
return false;
}
}
catch (const std::exception& e)
{
BOOST_LOG_TRIVIAL(error) << "Failed to read repository header JSON " << header_path << ". reason: " << e.what();
BOOST_LOG_TRIVIAL(error) << "Failed to read repository manifest JSON " << manifest_path << ". reason: " << e.what();
return false;
}
return true;
@ -297,18 +302,21 @@ bool LocalArchiveRepository::get_file(const std::string& source_subpath, const f
BOOST_LOG_TRIVIAL(error) << "Error getting file " << source_subpath << ". The repository_id was not matching.";
return false;
}
return get_file_inner(m_data.local_path / source_subpath, target_path);
return get_file_inner(m_data.tmp_path / source_subpath, target_path);
}
bool LocalArchiveRepository::get_ini_no_id(const std::string& source_subpath, const fs::path& target_path) const
{
return get_file_inner(m_data.local_path / source_subpath, target_path);
return get_file_inner(m_data.tmp_path / source_subpath, target_path);
}
bool LocalArchiveRepository::get_archive(const fs::path& target_path) const
{
fs::path source_path = fs::path(m_data.local_path) / "vendor_indices.zip";
fs::path source_path = fs::path(m_data.tmp_path) / "vendor_indices.zip";
return get_file_inner(std::move(source_path), target_path);
}
//-------------------------------------PresetArchiveDatabase-------------------------------------------------------------------------------------------------------------------------
PresetArchiveDatabase::PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler* evt_handler)
: p_evt_handler(evt_handler)
{
@ -317,62 +325,304 @@ PresetArchiveDatabase::PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler
fs::create_directories(m_unq_tmp_path, ec);
assert(!ec);
set_local_archives(app_config);
load_app_manifest_json();
}
void PresetArchiveDatabase::set_used_archives(const std::vector<std::string>& used_ids)
bool PresetArchiveDatabase::set_selected_repositories(const std::vector<std::string>& selected_uuids, std::string& msg)
{
m_used_archive_ids = used_ids;
// Check if some uuids leads to the same id (online vs local conflict)
std::map<std::string, std::string> used_set;
for (const std::string& uuid : selected_uuids) {
std::string id;
std::string name;
for (const auto& archive : m_archive_repositories) {
if (archive->get_uuid() == uuid) {
id = archive->get_manifest().id;
name = archive->get_manifest().name;
break;
}
void PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path)
{
}
void PresetArchiveDatabase::remove_local_archive(const std::string& id)
{
assert(!id.empty());
if (auto it = used_set.find(id); it != used_set.end()) {
msg = GUI::format(_L("Cannot select two repositories with the same id: %1% and %2%"), it->second, name);
return false;
}
used_set.emplace(id, name);
}
// deselect all first
for (auto& pair : m_selected_repositories_uuid) {
pair.second = false;
}
for (const std::string& uuid : selected_uuids) {
m_selected_repositories_uuid[uuid] = true;
}
save_app_manifest_json();
return true;
}
void PresetArchiveDatabase::set_archives(const std::string& json_body)
bool PresetArchiveDatabase::add_local_archive(const boost::filesystem::path path, std::string& msg)
{
m_archives.clear();
// Online repo headers are in json_body.
if (auto it = std::find_if(m_archive_repositories.begin(), m_archive_repositories.end(), [path](const std::unique_ptr<const ArchiveRepository>& ptr) {
return ptr->get_manifest().source_path == path;
}); it != m_archive_repositories.end())
{
msg = GUI::format(_L("Failed to add local archive %1%. Path already used."), path);
BOOST_LOG_TRIVIAL(error) << msg;
return false;
}
std::string uuid = get_next_uuid();
ArchiveRepository::RepositoryManifest header_data;
if (!extract_local_archive_repository(uuid, path, m_unq_tmp_path, header_data)) {
msg = GUI::format(_L("Failed to extract local archive %1%."), path);
BOOST_LOG_TRIVIAL(error) << msg;
return false;
}
// Solve if it can be set true first.
m_selected_repositories_uuid[uuid] = false;
m_archive_repositories.emplace_back(std::make_unique<LocalArchiveRepository>(uuid, std::move(header_data)));
save_app_manifest_json();
return true;
}
void PresetArchiveDatabase::remove_local_archive(const std::string& uuid)
{
auto compare_repo = [uuid](const std::unique_ptr<const ArchiveRepository>& repo) {
return repo->get_uuid() == uuid;
};
auto archives_it = std::find_if(m_archive_repositories.begin(), m_archive_repositories.end(), compare_repo);
assert(archives_it != m_archive_repositories.end());
std::string removed_uuid = archives_it->get()->get_uuid();
m_archive_repositories.erase(archives_it);
auto used_it = m_selected_repositories_uuid.find(removed_uuid);
assert(used_it != m_selected_repositories_uuid.end());
m_selected_repositories_uuid.erase(used_it);
save_app_manifest_json();
}
void PresetArchiveDatabase::load_app_manifest_json()
{
std::string path = get_stored_manifest_path();
std::ifstream file(path);
std::string data;
if (file.is_open()) {
std::string line;
while (getline(file, line)) {
data += line;
}
file.close();
}
else {
assert(true);
BOOST_LOG_TRIVIAL(error) << "Failed to read Archive Repository Manifest at " << path;
}
if (data.empty()) {
return;
}
m_archive_repositories.clear();
try
{
std::stringstream ss(json_body);
std::stringstream ss(data);
pt::ptree ptree;
pt::read_json(ss, ptree);
for (const auto& subtree : ptree) {
ArchiveRepository::RepositoryManifest header;
if (extract_repository_header(subtree.second, header)) {
m_archives.emplace_back(std::make_unique<OnlineArchiveRepository>(std::move(header)));
} else {
BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers.";
// if has tmp_path its local repo else its online repo (manifest is written in its zip, not in our json)
if (const auto source_path = subtree.second.get_optional<std::string>("source_path"); source_path) {
ArchiveRepository::RepositoryManifest manifest;
std::string uuid = get_next_uuid();
if (!extract_local_archive_repository(uuid, *source_path, m_unq_tmp_path, manifest)) {
BOOST_LOG_TRIVIAL(error) << "Local archive repository not extracted: " << *source_path;
continue;
}
if(const auto used = subtree.second.get_optional<bool>("selected"); used) {
m_selected_repositories_uuid[uuid] = *used;
} else {
assert(true);
}
m_archive_repositories.emplace_back(std::make_unique<LocalArchiveRepository>(std::move(uuid), std::move(manifest)));
continue;
}
// online repo
ArchiveRepository::RepositoryManifest manifest;
std::string uuid = get_next_uuid();
if (!extract_repository_header(subtree.second, manifest)) {
assert(true);
BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers.";
continue;
}
auto search = m_selected_repositories_uuid.find(uuid);
assert(search == m_selected_repositories_uuid.end());
if (const auto used = subtree.second.get_optional<bool>("selected"); used) {
m_selected_repositories_uuid[uuid] = *used;
} else {
assert(true);
}
m_archive_repositories.emplace_back(std::make_unique<OnlineArchiveRepository>(std::move(uuid), std::move(manifest)));
}
}
catch (const std::exception& e)
{
BOOST_LOG_TRIVIAL(error) << "Failed to read archives JSON. " << e.what();
}
// Local archives are stored as paths to zip.
// PresetArchiveDatabase has its folder in temp, local archives are extracted there
for (const std::string& archive_opt : m_local_archive_adresses) {
ArchiveRepository::RepositoryManifest header_data;
if (extract_local_archive_repository(archive_opt, m_unq_tmp_path, header_data)) {
m_archives.emplace_back(std::make_unique<LocalArchiveRepository>(std::move(header_data)));
}
void PresetArchiveDatabase::save_app_manifest_json() const
{
/*
[{
"name": "Production",
"description": "Production repository",
"visibility": null,
"id": "prod",
"url": "http://10.24.3.3:8001/v1/repos/prod",
"index_url": "http://10.24.3.3:8001/v1/repos/prod/vendor_indices.zip"
}, {
"name": "Development",
"description": "Production repository",
"visibility": null,
"id": "dev",
"url": "http://10.24.3.3:8001/v1/repos/dev",
"index_url": "http://10.24.3.3:8001/v1/repos/dev/vendor_indices.zip"
}]
*/
std::string data = "[";
for (const auto& archive : m_archive_repositories) {
// local writes only source_path and "selected". Rest is read from zip on source_path.
if (!archive->get_manifest().tmp_path.empty()) {
const ArchiveRepository::RepositoryManifest& man = archive->get_manifest();
std::string line = archive == m_archive_repositories.front() ? std::string() : ",";
line += GUI::format(
"{\"source_path\": \"%1%\","
"\"selected\": %2%}"
, man.source_path.generic_string(), is_selected(archive->get_uuid()) ? "1" : "0");
data += line;
continue;
}
m_used_archive_ids.clear();
m_used_archive_ids.reserve(m_archives.size());
for (const auto& archive : m_archives) {
m_used_archive_ids.emplace_back(archive->get_manifest().id);
// online repo writes whole manifest - in case of offline run, this info is load from here
const ArchiveRepository::RepositoryManifest& man = archive->get_manifest();
std::string line = archive == m_archive_repositories.front() ? std::string() : ",";
line += GUI::format(
"{\"name\": \"%1%\","
"\"description\": \"%2%\","
"\"visibility\": \"%3%\","
"\"id\": \"%4%\","
"\"url\": \"%5%\","
"\"index_url\": \"%6%\","
"\"selected\": %7%}"
, man.name, man.description, man. visibility, man.id, man.url, man.index_url, is_selected(archive->get_uuid()) ? "1" : "0");
data += line;
}
data += "]";
std::string path = get_stored_manifest_path();
std::ofstream file(path);
if (file.is_open()) {
file << data;
file.close();
} else {
assert(true);
BOOST_LOG_TRIVIAL(error) << "Failed to write Archive Repository Manifest to " << path;
}
}
void PresetArchiveDatabase::set_local_archives(AppConfig* app_config)
std::string PresetArchiveDatabase::get_stored_manifest_path() const
{
m_local_archive_adresses.clear();
std::string opt = app_config->get("local_archives");
deserialize_string(opt, m_local_archive_adresses);
return (boost::filesystem::path(Slic3r::data_dir()) / "ArchiveRepositoryManifest.json").make_preferred().string();
}
bool PresetArchiveDatabase::is_selected(const std::string& uuid) const
{
auto search = m_selected_repositories_uuid.find(uuid);
assert(search != m_selected_repositories_uuid.end());
return search->second;
}
void PresetArchiveDatabase::clear_online_repos()
{
auto it = m_archive_repositories.begin();
while (it != m_archive_repositories.end()) {
if ((*it)->get_manifest().tmp_path.empty()) {
it = m_archive_repositories.erase(it);
} else {
++it;
}
}
}
void PresetArchiveDatabase::read_server_manifest(const std::string& json_body)
{
pt::ptree ptree;
try
{
std::stringstream ss(json_body);
pt::read_json(ss, ptree);
}
catch (const std::exception& e)
{
BOOST_LOG_TRIVIAL(error) << "Failed to read archives JSON. " << e.what();
}
// Online repo manifests are in json_body. We already read local manifest and online manifest from last run.
// Keep the local ones and replace the online ones but keep uuid for same id so the selected map is correct.
// Solution: Create id - uuid translate table for online repos.
std::map<std::string, std::string> id_to_uuid;
for (const auto& repo_ptr : m_archive_repositories) {
if (repo_ptr->get_manifest().source_path.empty()){
id_to_uuid[repo_ptr->get_manifest().id] = repo_ptr->get_uuid();
}
}
clear_online_repos();
for (const auto& subtree : ptree) {
ArchiveRepository::RepositoryManifest manifest;
if (!extract_repository_header(subtree.second, manifest)) {
assert(true);
BOOST_LOG_TRIVIAL(error) << "Failed to read one of repository headers.";
continue;
}
auto id_it = id_to_uuid.find(manifest.id);
std::string uuid = (id_it == id_to_uuid.end() ? get_next_uuid() : id_it->second);
// Set default used value to true - its a never before seen repository
if (auto search = m_selected_repositories_uuid.find(uuid); search == m_selected_repositories_uuid.end()) {
m_selected_repositories_uuid[uuid] = true;
}
m_archive_repositories.emplace_back(std::make_unique<OnlineArchiveRepository>(uuid, std::move(manifest)));
}
consolidate_selected_uuids_map();
save_app_manifest_json();
}
void PresetArchiveDatabase::consolidate_selected_uuids_map()
{
//std::vector<std::unique_ptr<const ArchiveRepository>> m_archive_repositories;
//std::map<std::string, bool> m_selected_repositories_uuid;
auto it = m_selected_repositories_uuid.begin();
while (it != m_selected_repositories_uuid.end()) {
bool found = false;
for (const auto& repo_ptr : m_archive_repositories) {
if (repo_ptr->get_uuid() == it->first) {
found = true;
break;
}
}
if (!found) {
it = m_selected_repositories_uuid.erase(it);
} else {
++it;
}
}
}
std::string PresetArchiveDatabase::get_next_uuid()
{
boost::uuids::uuid uuid = m_uuid_generator();
return boost::uuids::to_string(uuid);
}
namespace {
@ -419,7 +669,7 @@ void PresetArchiveDatabase::sync_blocking()
std::string manifest;
if (!sync_inner(manifest))
return;
set_archives(std::move(manifest));
read_server_manifest(std::move(manifest));
}
}} // Slic3r::GUI

View File

@ -3,6 +3,8 @@
#include "Event.hpp"
#include <boost/uuid/uuid_generators.hpp>
#include <string>
#include <vector>
#include <memory>
@ -43,11 +45,12 @@ public:
std::string description;
std::string visibility;
// not read from manifest json
boost::filesystem::path local_path;
boost::filesystem::path tmp_path; // Where archive is unzziped. Created each app run.
boost::filesystem::path source_path; // Path given by user. Stored between app runs.
bool m_secret { false };
};
// Use std::move when calling constructor.
ArchiveRepository(RepositoryManifest&& data) : m_data(std::move(data)) {}
ArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : m_data(std::move(data)), m_uuid(uuid) {}
virtual ~ArchiveRepository() {}
// Gets vendor_indices.zip to target_path
virtual bool get_archive(const boost::filesystem::path& target_path) const = 0;
@ -57,16 +60,16 @@ public:
// Gets file without id check - for not yet encountered vendors only!
virtual bool get_ini_no_id(const std::string& source_subpath, const boost::filesystem::path& target_path) const = 0;
const RepositoryManifest& get_manifest() const { return m_data; }
std::string get_uuid() const { return m_uuid; }
protected:
RepositoryManifest m_data;
std::string m_uuid;
};
typedef std::vector<std::unique_ptr<const ArchiveRepository>> ArchiveRepositoryVector;
class OnlineArchiveRepository : public ArchiveRepository
{
public:
OnlineArchiveRepository(RepositoryManifest&& data) : ArchiveRepository(std::move(data))
OnlineArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : ArchiveRepository(uuid, std::move(data))
{
if (m_data.url.back() != '/') {
m_data.url += "/";
@ -87,7 +90,7 @@ private:
class LocalArchiveRepository : public ArchiveRepository
{
public:
LocalArchiveRepository(RepositoryManifest&& data) : ArchiveRepository(std::move(data)) {}
LocalArchiveRepository(const std::string& uuid, RepositoryManifest&& data) : ArchiveRepository(uuid, std::move(data)) {}
// Gets vendor_indices.zip to target_path.
bool get_archive(const boost::filesystem::path& target_path) const override;
// Gets file if repository_id arg matches m_id.
@ -99,29 +102,39 @@ public:
private:
bool get_file_inner(const boost::filesystem::path& source_path, const boost::filesystem::path& target_path) const;
};
typedef std::vector<std::unique_ptr<const ArchiveRepository>> ArchiveRepositoryVector;
class PresetArchiveDatabase
{
public:
PresetArchiveDatabase(AppConfig* app_config, wxEvtHandler* evt_handler);
~PresetArchiveDatabase() {}
const ArchiveRepositoryVector& get_archives() const { return m_archives; }
const ArchiveRepositoryVector& get_archive_repositories() const { return m_archive_repositories; }
void sync();
void sync_blocking();
void set_token(const std::string token) { m_token = token; }
void set_local_archives(AppConfig* app_config);
void set_archives(const std::string& json_body);
const std::vector<std::string>& get_used_archives() const { return m_used_archive_ids; }
void set_used_archives(const std::vector<std::string>& used_ids);
void add_local_archive(const boost::filesystem::path path);
void remove_local_archive(const std::string& id);
//void set_local_archives(AppConfig* app_config);
void read_server_manifest(const std::string& json_body);
const std::map<std::string, bool>& get_selected_repositories_uuid() const { assert(m_selected_repositories_uuid.size() == m_archive_repositories.size()); return m_selected_repositories_uuid; }
bool set_selected_repositories(const std::vector<std::string>& used_uuids, std::string& msg);
bool add_local_archive(const boost::filesystem::path path, std::string& msg);
void remove_local_archive(const std::string& uuid);
private:
void load_app_manifest_json();
void save_app_manifest_json() const;
void clear_online_repos();
bool is_selected(const std::string& id) const;
std::string get_stored_manifest_path() const;
void consolidate_selected_uuids_map();
std::string get_next_uuid();
wxEvtHandler* p_evt_handler;
boost::filesystem::path m_unq_tmp_path;
ArchiveRepositoryVector m_archives;
std::vector<std::string> m_used_archive_ids;
std::vector<std::string> m_local_archive_adresses;
ArchiveRepositoryVector m_archive_repositories;
std::map<std::string, bool> m_selected_repositories_uuid;
std::string m_token;
boost::uuids::random_generator m_uuid_generator;
};
}} // Slic3r::GUI

View File

@ -60,20 +60,24 @@ void UIManager::fill_entries()
m_online_entries.clear();
m_offline_entries.clear();
const ArchiveRepositoryVector& archs = m_pad->get_archives();
const std::vector<std::string>& used_archs = m_pad->get_used_archives();
const ArchiveRepositoryVector& archs = m_pad->get_archive_repositories();
const std::map<std::string, bool>& selected_repos = m_pad->get_selected_repositories_uuid();
for (const auto& archive : archs) {
const auto& data = archive->get_manifest();
if (data.local_path.empty()) {
if (data.source_path.empty()) {
// online repo
bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end();
m_online_entries.push_back({is_used, data.id, data.name, data.description, data.visibility });
auto selected_it = selected_repos.find(archive->get_uuid());
assert(selected_it != selected_repos.end());
bool is_selected = selected_it->second;
m_online_entries.push_back({is_selected, archive->get_uuid(), data.name, data.description, data.visibility });
}
else {
// offline repo
bool is_used = std::find(used_archs.begin(), used_archs.end(), data.id) != used_archs.end();
m_offline_entries.push_back({is_used, data.id, data.name, data.description, data.local_path.filename().string(), fs::exists(data.local_path)});
auto selected_it = selected_repos.find(archive->get_uuid());
assert(selected_it != selected_repos.end());
bool is_selected = selected_it->second;
m_offline_entries.push_back({is_selected, archive->get_uuid(), data.name, data.description, data.source_path.filename().string(), fs::exists(data.source_path)});
}
}
@ -143,13 +147,13 @@ void UIManager::fill_grids()
// header
for (const wxString& l : std::initializer_list<wxString>{ _L("Use"), _L("Name"), _L("Descrition"), "", _L("Sourse file"), "" }) {
for (const wxString& l : std::initializer_list<wxString>{ _L("Use"), _L("Name"), _L("Descrition"), "", _L("Source file"), "" }) {
auto text = new wxStaticText(m_parent, wxID_ANY, l);
text->SetFont(wxGetApp().bold_font());
add(text);
}
// data
// data1
for (const auto& entry : m_offline_entries)
{
@ -226,7 +230,11 @@ void UIManager::load_offline_repos()
std::string input_file = into_u8(input_files.Item(i));
try {
fs::path input_path = fs::path(input_file);
m_pad->add_local_archive(input_path);
std::string msg;
if (!m_pad->add_local_archive(input_path, msg))
{
// Finish me.
}
}
catch (fs::filesystem_error const& e) {
std::cerr << e.what() << '\n';
@ -236,7 +244,7 @@ void UIManager::load_offline_repos()
update();
}
void UIManager::set_used_archives()
void UIManager::set_selected_repositories()
{
std::vector<std::string> used_ids;
for (const std::string& id : m_online_selections)
@ -244,7 +252,10 @@ void UIManager::set_used_archives()
for (const std::string& id : m_offline_selections)
used_ids.push_back(id);
m_pad->set_used_archives(used_ids);
std::string msg;
if (!m_pad->set_selected_repositories(used_ids, msg)) {
// Finish me.
}
}
@ -286,7 +297,7 @@ void ManageUpdatesDialog::onCloseDialog(wxEvent &)
void ManageUpdatesDialog::onOkDialog(wxEvent&)
{
m_manager->set_used_archives();
m_manager->set_selected_repositories();
this->EndModal(wxID_CLOSE);
}

View File

@ -67,7 +67,7 @@ public:
~UIManager() {}
wxSizer* get_sizer() { return m_main_sizer; }
void set_used_archives();
void set_selected_repositories();
};
class ManageUpdatesDialog : public DPIDialog

View File

@ -1142,16 +1142,20 @@ PresetUpdater::~PresetUpdater()
}
}
void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories)
void PresetUpdater::sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map<std::string, bool>& selected_repo_uuids)
{
p->set_download_prefs(GUI::wxGetApp().app_config);
if (!p->enabled_config_update) { return; }
p->thread = std::thread([this, &vendors = preset_bundle->vendors, &repositories, evt_handler]() {
p->thread = std::thread([this, &vendors = preset_bundle->vendors, &repositories, &selected_repo_uuids, evt_handler]() {
this->p->prune_tmps();
for(const auto& archive : repositories) {
auto it = selected_repo_uuids.find(archive->get_uuid());
assert(it != selected_repo_uuids.end());
if (it->second) {
this->p->sync_config(vendors, *archive);
}
}
wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE);
evt_handler->QueueEvent(evt);
});
@ -1168,15 +1172,19 @@ void PresetUpdater::cancel_sync()
p->cancel = false;
}
void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories)
void PresetUpdater::sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map<std::string, bool>& selected_repo_uuids)
{
p->set_download_prefs(GUI::wxGetApp().app_config);
if (!p->enabled_config_update) { return; }
this->p->prune_tmps();
for (const auto& archive : repositories) {
auto it = selected_repo_uuids.find(archive->get_uuid());
assert(it != selected_repo_uuids.end());
if (it->second) {
this->p->sync_config(preset_bundle->vendors, *archive);
}
}
wxCommandEvent* evt = new wxCommandEvent(EVT_CONFIG_UPDATER_SYNC_DONE);
evt_handler->QueueEvent(evt);
}

View File

@ -34,10 +34,10 @@ public:
~PresetUpdater();
// If either version check or config updating is enabled, get the appropriate data in the background and cache it.
void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories);
void sync(const PresetBundle *preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map<std::string, bool>& selected_repo_uuids);
void cancel_sync();
void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories);
void sync_blocking(const PresetBundle* preset_bundle, wxEvtHandler* evt_handler, const ArchiveRepositoryVector& repositories, const std::map<std::string, bool>& selected_repo_uuids);
// If version check is enabled, check if chaced online slic3r version is newer, notify if so.
void slic3r_update_notify();