mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-09-25 09:50:59 +00:00
* build: enable /Zc:lambda for MSVC MSVC keeps its legacy lambda processor under /std:c++17, which rejects reading a constexpr constant inside a lambda that does not capture it (C3493). No other compiler requires that capture, and clang reports it as an unused one, so the two cannot both be satisfied without the flag. /Zc:lambda selects the conforming lambda parser that clang and GCC already use. It is implied by /std:c++20 and /permissive-, so it is only needed while we are on C++17. clang-cl is conforming already and does not take the flag. It requires VS2019 16.8, so build_release_vs.bat now says 16.8+. * build: clear 237 unused lambda capture warnings 236 captures across 81 files, 142 of them `this`. Removing an unused capture changes no behavior; clang does not report a capture whose type has a non-trivial destructor, so nothing held only to extend an object's lifetime is in this set. Nine of them are the second half of the warning, "is not required to be captured for this use", where the capture is a const or constexpr value the body does read. Those depend on the /Zc:lambda change in the previous commit. One of them, in FillRectilinear.cpp, had been worked around with an #ifndef __APPLE__ guard around the capture list, which is now gone. GUI_ObjectTableSettings.cpp captured its reset button only to read it inside #ifdef __WXOSX_MAC__. That branch now takes the button from the event it is already handling. * build: fail configure on MSVC older than 19.28 instead of dropping /Zc:lambda cl.exe answers an unrecognized /Zc: sub-option with warning D9002 and keeps going, so on VS2019 before 16.8 the flag is silently ignored and the build instead dies with C3493 in FillRectilinear.cpp, nowhere near the cause. * fix: delete three locals that are now unused Their only remaining use was the lambda capture this branch removed. The Clang builds set -Wno-unused-variable, so the build never flagged them. --------- Co-authored-by: Rodrigo Faselli <162915171+RF47@users.noreply.github.com>
735 lines
26 KiB
C++
735 lines
26 KiB
C++
#include "HMS.hpp"
|
|
|
|
#include "GUI.hpp"
|
|
#include "GUI_App.hpp"
|
|
#include "DeviceManager.hpp"
|
|
#include "DeviceCore/DevManager.h"
|
|
#include "DeviceCore/DevUtil.h"
|
|
#include "libslic3r/AppConfig.hpp"
|
|
|
|
#include <boost/log/trivial.hpp>
|
|
|
|
static const char* HMS_PATH = "hms";
|
|
static const char* HMS_LOCAL_IMG_PATH = "hms/local_image";
|
|
|
|
// the local HMS info
|
|
// Orca: dev-id-type set trimmed to the devices Orca ships local HMS images for
|
|
static unordered_set<string> package_dev_id_types {"094", "239", "093", "22E"};
|
|
|
|
// Orca: HMS should be disabled when stealth mode is on or networking is not installed
|
|
static bool should_disable_hms()
|
|
{
|
|
Slic3r::AppConfig* config = Slic3r::GUI::wxGetApp().app_config;
|
|
if (!config) return true;
|
|
return config->get_stealth_mode() || !config->get_bool("installed_networking");
|
|
}
|
|
|
|
namespace Slic3r {
|
|
namespace GUI {
|
|
|
|
int get_hms_info_version(std::string& version)
|
|
{
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config)
|
|
return -1;
|
|
if (should_disable_hms())
|
|
return -1;
|
|
std::string hms_host = config->get_hms_host();
|
|
if(hms_host.empty()) {
|
|
BOOST_LOG_TRIVIAL(error) << "hms_host is empty";
|
|
return -1;
|
|
}
|
|
int result = -1;
|
|
version = "";
|
|
std::string lang;
|
|
std::string query_params = HMSQuery::build_query_params(lang);
|
|
std::string url = (boost::format("https://%1%/GetVersion.php?%2%") % hms_host % query_params).str();
|
|
Slic3r::Http http = Slic3r::Http::get(url);
|
|
http.timeout_max(10)
|
|
.on_complete([&version](std::string body, unsigned status){
|
|
try {
|
|
json j = json::parse(body);
|
|
if (j.contains("ver")) {
|
|
version = DevJsonValParser::get_longlong_val(j["ver"]);
|
|
}
|
|
} catch (...) {
|
|
;
|
|
}
|
|
})
|
|
.on_error([&result](std::string body, std::string error, unsigned status) {
|
|
BOOST_LOG_TRIVIAL(error) << "get_hms_info_version: body = " << body << ", status = " << status << ", error = " << error;
|
|
result = -1;
|
|
})
|
|
.perform_sync();
|
|
return result;
|
|
}
|
|
|
|
// Note: Download the hms into receive_json
|
|
int HMSQuery::download_hms_related(const std::string& hms_type, const std::string& dev_id_type, json* receive_json)
|
|
{
|
|
std::string local_version = "0";
|
|
load_from_local(hms_type, dev_id_type, receive_json, local_version);
|
|
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config) return -1;
|
|
if (should_disable_hms()) return -1;
|
|
|
|
std::string hms_host = wxGetApp().app_config->get_hms_host();
|
|
std::string lang;
|
|
std::string query_params = HMSQuery::build_query_params(lang);
|
|
std::string url;
|
|
if (hms_type.compare(QUERY_HMS_INFO) == 0) {
|
|
url = (boost::format("https://%1%/query.php?%2%") % hms_host % query_params).str();
|
|
}
|
|
else if (hms_type.compare(QUERY_HMS_ACTION) == 0) {
|
|
url = (boost::format("https://%1%/hms/GetActionImage.php?") % hms_host).str();
|
|
}
|
|
|
|
if (!local_version.empty()) { url += (url.find('?') != std::string::npos ? "&" : "?") + (boost::format("v=%1%") % local_version).str(); }
|
|
|
|
if (!dev_id_type.empty()) { url += (url.find('?') != std::string::npos ? "&" : "?") + (boost::format("d=%1%") % dev_id_type).str(); }
|
|
|
|
|
|
bool to_save_local = false;
|
|
json j;
|
|
|
|
BOOST_LOG_TRIVIAL(info) << "hms: download url = " << url;
|
|
Slic3r::Http http = Slic3r::Http::get(url);
|
|
http.on_complete([receive_json, hms_type, &to_save_local, &j, & local_version](std::string body, unsigned status) {
|
|
try {
|
|
j = json::parse(body);
|
|
if (j.contains("result")) {
|
|
if (j["result"] == 0 && j.contains("data")) {
|
|
|
|
if (!j.contains("ver"))
|
|
{
|
|
return;
|
|
}
|
|
|
|
const std::string& remote_ver = DevJsonValParser::get_longlong_val(j["ver"]);
|
|
if (remote_ver <= local_version)
|
|
{
|
|
return;
|
|
}
|
|
(*receive_json)["version"] = remote_ver;
|
|
|
|
if (hms_type.compare(QUERY_HMS_INFO) == 0)
|
|
{
|
|
(*receive_json) = j["data"];
|
|
to_save_local = true;
|
|
}
|
|
else if (hms_type.compare(QUERY_HMS_ACTION) == 0)
|
|
{
|
|
(*receive_json)["data"] = j["data"];
|
|
to_save_local = true;
|
|
}
|
|
} else if (j["result"] == 201){
|
|
BOOST_LOG_TRIVIAL(info) << "HMSQuery: HMS info is the latest version";
|
|
}else{
|
|
BOOST_LOG_TRIVIAL(info) << "HMSQuery: update hms info error = " << j["result"].get<int>();
|
|
}
|
|
}
|
|
} catch (...) {
|
|
;
|
|
}
|
|
})
|
|
.timeout_max(20)
|
|
.on_error([](std::string body, std::string error, unsigned status) {
|
|
BOOST_LOG_TRIVIAL(error) << "HMSQuery: update hms info error = " << error << ", body = " << body << ", status = " << status;
|
|
}).perform_sync();
|
|
|
|
if (to_save_local && !receive_json->empty()) {
|
|
save_to_local(lang, hms_type, dev_id_type, j);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
static void
|
|
_copy_dir(const fs::path& from_dir, const fs::path& to_dir) /* copy and override with local files*/
|
|
{
|
|
try
|
|
{
|
|
if (!fs::exists(from_dir))
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!fs::exists(to_dir))
|
|
{
|
|
fs::create_directory(to_dir);
|
|
}
|
|
|
|
for (const auto &entry : fs::directory_iterator(from_dir))
|
|
{
|
|
const fs::path &source_path = entry.path();
|
|
const fs::path &relative_path = fs::relative(source_path, from_dir);
|
|
const fs::path &dest_path = to_dir / relative_path;
|
|
|
|
if (fs::is_regular_file(source_path))
|
|
{
|
|
if (fs::exists(dest_path))
|
|
{
|
|
fs::remove(dest_path);
|
|
}
|
|
|
|
copy_file(source_path, dest_path);
|
|
}
|
|
else if (fs::is_directory(source_path))
|
|
{
|
|
_copy_dir(source_path, dest_path);
|
|
}
|
|
}
|
|
}
|
|
catch (...)
|
|
{
|
|
|
|
}
|
|
}
|
|
|
|
void HMSQuery::copy_from_data_dir_to_local()
|
|
{
|
|
const fs::path& from_dir = fs::path(Slic3r::resources_dir()) / HMS_PATH;
|
|
const fs::path& to_dir = fs::path(Slic3r::data_dir()) / HMS_PATH;
|
|
_copy_dir(from_dir, to_dir);
|
|
}
|
|
|
|
int HMSQuery::load_from_local(const std::string& hms_type, const std::string& dev_id_type, json* load_json, std::string& load_version)
|
|
{
|
|
if (data_dir().empty()) {
|
|
load_version = "0";
|
|
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local, data_dir() is empty";
|
|
return -1;
|
|
}
|
|
std::string filename = get_hms_file(hms_type, HMSQuery::hms_language_code(), dev_id_type);
|
|
auto hms_folder = (boost::filesystem::path(data_dir()) / "hms");
|
|
if (!fs::exists(hms_folder))
|
|
fs::create_directory(hms_folder);
|
|
|
|
std::string dir_str = (hms_folder / filename).make_preferred().string();
|
|
std::ifstream json_file(encode_path(dir_str.c_str()));
|
|
try {
|
|
if (json_file.is_open())
|
|
{
|
|
const json &j = json::parse(json_file);
|
|
if (hms_type.compare(QUERY_HMS_INFO) == 0) {
|
|
if (j.contains("data")) { (*load_json) = j["data"]; }
|
|
} else if (hms_type.compare(QUERY_HMS_ACTION) == 0) {
|
|
if (j.contains("data")) { (*load_json)["data"] = j["data"]; }
|
|
}
|
|
|
|
if (j.contains("version")) {
|
|
load_version = DevJsonValParser::get_longlong_val(j["version"]);
|
|
}
|
|
else if (j.contains("ver")) {
|
|
load_version = DevJsonValParser::get_longlong_val(j["ver"]);
|
|
}
|
|
else
|
|
{
|
|
BOOST_LOG_TRIVIAL(warning) << "HMS: load_from_local, no version info";
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
} catch(...) {
|
|
load_version = "0";
|
|
BOOST_LOG_TRIVIAL(error) << "HMS: load_from_local failed";
|
|
return -1;
|
|
}
|
|
load_version = "0";
|
|
return 0;
|
|
}
|
|
|
|
int HMSQuery::save_to_local(std::string lang, std::string hms_type, std::string dev_id_type, json save_json)
|
|
{
|
|
if (data_dir().empty()) {
|
|
BOOST_LOG_TRIVIAL(error) << "HMS: save_to_local, data_dir() is empty";
|
|
return -1;
|
|
}
|
|
std::string filename = get_hms_file(hms_type,lang, dev_id_type);
|
|
auto hms_folder = (boost::filesystem::path(data_dir()) / "hms");
|
|
if (!fs::exists(hms_folder))
|
|
fs::create_directory(hms_folder);
|
|
std::string dir_str = (hms_folder / filename).make_preferred().string();
|
|
std::ofstream json_file(encode_path(dir_str.c_str()));
|
|
if (json_file.is_open()) {
|
|
json_file << save_json.dump(1, '\t') << std::endl; // Orca: tab-indented dump
|
|
json_file.close();
|
|
return 0;
|
|
}
|
|
BOOST_LOG_TRIVIAL(error) << "HMS: save_to_local failed";
|
|
return -1;
|
|
}
|
|
|
|
std::string HMSQuery::hms_language_code()
|
|
{
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config)
|
|
// set language code to en by default
|
|
return "en";
|
|
std::string lang_code = wxGetApp().app_config->get_language_code();
|
|
// Orca: the HMS host ships no catalog for these locales, so fall back to english to avoid empty texts + retries
|
|
if (lang_code.compare("uk") == 0
|
|
|| lang_code.compare("cs") == 0
|
|
|| lang_code.compare("ru") == 0
|
|
|| lang_code.compare("tr") == 0
|
|
|| lang_code.compare("pt") == 0
|
|
|| lang_code.compare("ko") == 0
|
|
)
|
|
{
|
|
BOOST_LOG_TRIVIAL(info) << "HMS: using english for lang_code = " << lang_code;
|
|
return "en";
|
|
}
|
|
else if (lang_code.empty()) {
|
|
// set language code to en by default
|
|
return "en";
|
|
}
|
|
return lang_code;
|
|
}
|
|
|
|
std::string HMSQuery::build_query_params(std::string& lang)
|
|
{
|
|
std::string lang_code = HMSQuery::hms_language_code();
|
|
lang = lang_code;
|
|
std::string query_params = (boost::format("lang=%1%") % lang_code).str();
|
|
return query_params;
|
|
}
|
|
|
|
std::string HMSQuery::get_hms_file(std::string hms_type, std::string lang, std::string dev_id_type)
|
|
{
|
|
//return hms action filename
|
|
if (hms_type.compare(QUERY_HMS_ACTION) == 0) {
|
|
return (boost::format("hms_action_%1%.json") % dev_id_type).str();
|
|
}
|
|
//return hms filename
|
|
return (boost::format("hms_%1%_%2%.json") % lang % dev_id_type).str();
|
|
}
|
|
|
|
wxString HMSQuery::query_hms_msg(const MachineObject* obj, const std::string& long_error_code)
|
|
{
|
|
if (!obj)
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config) return wxEmptyString;
|
|
const std::string& lang_code = HMSQuery::hms_language_code();
|
|
return _query_hms_msg(get_dev_id_type(obj),long_error_code, lang_code);
|
|
}
|
|
|
|
wxString HMSQuery::query_hms_msg(const std::string& dev_id, const std::string& long_error_code)
|
|
{
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config) return wxEmptyString;
|
|
const std::string& lang_code = HMSQuery::hms_language_code();
|
|
return _query_hms_msg(dev_id.substr(0, 3), long_error_code, lang_code);
|
|
}
|
|
|
|
string HMSQuery::get_dev_id_type(const MachineObject* obj) const
|
|
{
|
|
if (obj)
|
|
{
|
|
return obj->get_dev_id().substr(0, 3);
|
|
}
|
|
|
|
return string();
|
|
}
|
|
|
|
wxString HMSQuery::_query_hms_msg(const string& dev_id_type, const string& long_error_code, const string& lang_code)
|
|
{
|
|
if (long_error_code.empty())
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
init_hms_info(dev_id_type);
|
|
auto iter = m_hms_info_jsons.find(dev_id_type);
|
|
if (iter == m_hms_info_jsons.end())
|
|
{
|
|
BOOST_LOG_TRIVIAL(error) << "there are no hms info for the device";
|
|
return wxEmptyString;
|
|
}
|
|
|
|
const json& m_hms_info_json = iter->second;
|
|
if (!m_hms_info_json.is_object())
|
|
{
|
|
BOOST_LOG_TRIVIAL(error) << "the hms info is not a valid json object";
|
|
return wxEmptyString;
|
|
}
|
|
|
|
const json& device_hms_json = m_hms_info_json.value("device_hms", json());
|
|
if (device_hms_json.is_null() || !device_hms_json.is_object())
|
|
{
|
|
BOOST_LOG_TRIVIAL(error) << "there are no valid json object named device_hms";
|
|
return wxEmptyString;
|
|
}
|
|
|
|
const json& device_hms_msg_json = device_hms_json.value(lang_code, json());
|
|
if (device_hms_msg_json.is_null())
|
|
{
|
|
BOOST_LOG_TRIVIAL(error) << "hms: query_hms_msg, do not contains lang_code = " << lang_code;
|
|
if (lang_code.empty()) /*traverse all if lang_code is empty*/
|
|
{
|
|
for (const auto& lang_item : device_hms_json)
|
|
{
|
|
for (const auto& msg_item : lang_item)
|
|
{
|
|
if (msg_item.is_object())
|
|
{
|
|
const std::string& error_code = msg_item.value("ecode", json()).get<std::string>();
|
|
if (boost::to_upper_copy(error_code) == long_error_code && msg_item.contains("intro"))
|
|
{
|
|
BOOST_LOG_TRIVIAL(info) << "retry without lang_code successed.";
|
|
return wxString::FromUTF8(msg_item["intro"].get<std::string>());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return wxEmptyString;
|
|
}
|
|
|
|
for (const auto& item : device_hms_msg_json)
|
|
{
|
|
if (item.is_object())
|
|
{
|
|
const std::string& error_code = item.value("ecode", json()).get<std::string>();
|
|
if (boost::to_upper_copy(error_code) == long_error_code && item.contains("intro"))
|
|
{
|
|
return wxString::FromUTF8(item["intro"].get<std::string>());
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOST_LOG_TRIVIAL(error) << "hms: query_hms_msg, do not contains valid message, lang_code = " << lang_code << " long_error_code = " << long_error_code;
|
|
return wxEmptyString;
|
|
}
|
|
|
|
bool HMSQuery::_is_internal_error(const string &dev_id_type,
|
|
const string &error_code,
|
|
const string &lang_code)
|
|
{
|
|
init_hms_info(dev_id_type);
|
|
auto iter = m_hms_info_jsons.find(dev_id_type);
|
|
if (iter == m_hms_info_jsons.end()) { return false; }
|
|
|
|
const json &m_hms_info_json = iter->second;
|
|
if (m_hms_info_json.contains("device_error")) {
|
|
if (m_hms_info_json["device_error"].contains(lang_code)) {
|
|
for (auto item = m_hms_info_json["device_error"][lang_code].begin(); item != m_hms_info_json["device_error"][lang_code].end(); item++) {
|
|
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
|
|
if (item->contains("intro")) { return wxString::FromUTF8((*item)["intro"].get<std::string>()).IsEmpty(); }
|
|
}
|
|
}
|
|
} else {
|
|
// return first language
|
|
if (!m_hms_info_json["device_error"].empty()) {
|
|
for (auto lang : m_hms_info_json["device_error"]) {
|
|
for (auto item = lang.begin(); item != lang.end(); item++) {
|
|
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
|
|
if (item->contains("intro")) { return wxString::FromUTF8((*item)["intro"].get<std::string>()).IsEmpty(); }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
wxString HMSQuery::_query_error_msg(const std::string &dev_id_type,
|
|
const std::string& error_code,
|
|
const std::string& lang_code)
|
|
{
|
|
init_hms_info(dev_id_type);
|
|
auto iter = m_hms_info_jsons.find(dev_id_type);
|
|
if (iter == m_hms_info_jsons.end())
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
const json& m_hms_info_json = iter->second;
|
|
if (m_hms_info_json.contains("device_error")) {
|
|
if (m_hms_info_json["device_error"].contains(lang_code)) {
|
|
for (auto item = m_hms_info_json["device_error"][lang_code].begin(); item != m_hms_info_json["device_error"][lang_code].end(); item++) {
|
|
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
|
|
if (item->contains("intro")) {
|
|
return wxString::FromUTF8((*item)["intro"].get<std::string>());
|
|
}
|
|
}
|
|
}
|
|
BOOST_LOG_TRIVIAL(info) << "hms: query_error_msg, not found error_code = " << error_code;
|
|
} else {
|
|
BOOST_LOG_TRIVIAL(error) << "hms: query_error_msg, do not contains lang_code = " << lang_code;
|
|
// return first language
|
|
if (!m_hms_info_json["device_error"].empty()) {
|
|
for (auto lang : m_hms_info_json["device_error"]) {
|
|
for (auto item = lang.begin(); item != lang.end(); item++) {
|
|
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == error_code) {
|
|
if (item->contains("intro")) {
|
|
return wxString::FromUTF8((*item)["intro"].get<std::string>());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
BOOST_LOG_TRIVIAL(info) << "device_error is not exists";
|
|
return wxEmptyString;
|
|
}
|
|
|
|
return wxEmptyString;
|
|
}
|
|
|
|
wxString HMSQuery::_query_error_image_action(const std::string& dev_id_type, const std::string& long_error_code, std::vector<int>& button_action)
|
|
{
|
|
init_hms_info(dev_id_type);
|
|
|
|
auto iter = m_hms_action_jsons.find(dev_id_type);
|
|
if (iter == m_hms_action_jsons.end())
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
const json& m_hms_action_json = iter->second;
|
|
if (m_hms_action_json.contains("data")) {
|
|
for (auto item = m_hms_action_json["data"].begin(); item != m_hms_action_json["data"].end(); item++) {
|
|
if (item->contains("ecode") && boost::to_upper_copy((*item)["ecode"].get<std::string>()) == long_error_code) {
|
|
if (item->contains("device") && (boost::to_upper_copy((*item)["device"].get<std::string>()) == dev_id_type ||
|
|
(*item)["device"].get<std::string>() == "default")) {
|
|
if (item->contains("actions")) {
|
|
for (auto item_actions = (*item)["actions"].begin(); item_actions != (*item)["actions"].end(); item_actions++) {
|
|
button_action.emplace_back(item_actions->get<int>());
|
|
}
|
|
}
|
|
if (item->contains("image")) {
|
|
return wxString::FromUTF8((*item)["image"].get<std::string>());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
BOOST_LOG_TRIVIAL(info) << "data is not exists";
|
|
return wxEmptyString;
|
|
}
|
|
return wxEmptyString;
|
|
}
|
|
|
|
|
|
bool HMSQuery::is_internal_error(const MachineObject *obj, int print_error)
|
|
{
|
|
char buf[32];
|
|
::sprintf(buf, "%08X", print_error);
|
|
std::string lang_code = HMSQuery::hms_language_code();
|
|
return _is_internal_error(get_dev_id_type(obj), std::string(buf), lang_code);
|
|
}
|
|
|
|
wxString HMSQuery::query_print_error_msg(const MachineObject *obj, int print_error)
|
|
{
|
|
if (!obj)
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
char buf[32];
|
|
::sprintf(buf, "%08X", print_error);
|
|
std::string lang_code = HMSQuery::hms_language_code();
|
|
return _query_error_msg(get_dev_id_type(obj), std::string(buf), lang_code);
|
|
}
|
|
|
|
wxString HMSQuery::query_print_error_msg(const std::string& dev_id, int print_error)
|
|
{
|
|
char buf[32];
|
|
::sprintf(buf, "%08X", print_error);
|
|
std::string lang_code = HMSQuery::hms_language_code();
|
|
return _query_error_msg(dev_id.substr(0, 3), std::string(buf), lang_code);
|
|
}
|
|
|
|
|
|
wxString HMSQuery::query_print_image_action(const MachineObject* obj, int print_error, std::vector<int>& button_action)
|
|
{
|
|
if (!obj)
|
|
{
|
|
return wxEmptyString;
|
|
}
|
|
|
|
char buf[32];
|
|
::sprintf(buf, "%08X", print_error);
|
|
//The first three digits of SN number
|
|
const auto result = _query_error_image_action(get_dev_id_type(obj),std::string(buf), button_action);
|
|
if (should_disable_hms() && result.Contains("http")) {
|
|
return wxEmptyString;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
wxImage HMSQuery::query_image_from_local(const wxString& image_name)
|
|
{
|
|
if (image_name.empty() || image_name.Contains("http"))
|
|
{
|
|
return wxImage();
|
|
}
|
|
|
|
if (m_hms_local_images.empty())
|
|
{
|
|
const fs::path& local_img_dir = fs::path(Slic3r::data_dir()) / HMS_LOCAL_IMG_PATH;
|
|
if (fs::exists(local_img_dir))
|
|
{
|
|
for (const auto &entry : fs::directory_iterator(local_img_dir))
|
|
{
|
|
const fs::path& image_path = entry.path();
|
|
const fs::path& image_name = fs::relative(image_path, local_img_dir);
|
|
// Orca: from_path() for correct UTF-8 path encoding
|
|
m_hms_local_images[from_path(image_name)] = wxImage(from_path(image_path));
|
|
}
|
|
}
|
|
}
|
|
|
|
auto iter = m_hms_local_images.find(image_name);
|
|
if (iter != m_hms_local_images.end())
|
|
{
|
|
return iter->second;
|
|
}
|
|
|
|
return wxImage();
|
|
}
|
|
|
|
void HMSQuery::clear_hms_info()
|
|
{
|
|
std::unique_lock unique_lock(m_hms_mutex);
|
|
m_hms_info_jsons.clear();
|
|
m_hms_action_jsons.clear();
|
|
m_cloud_hms_last_update_time.clear();
|
|
}
|
|
|
|
void HMSQuery::init_hms_info(const std::string& dev_type_id)
|
|
{
|
|
std::unique_lock unique_lock(m_hms_mutex);
|
|
if (package_dev_id_types.count(dev_type_id) != 0)
|
|
{
|
|
/*the local one only load once*/
|
|
if (m_hms_info_jsons.count(dev_type_id) == 0) {
|
|
|
|
std::string load_version;
|
|
load_from_local(QUERY_HMS_INFO, dev_type_id, &m_hms_info_jsons[dev_type_id], load_version);/*load from local first*/
|
|
if (load_version.empty() || load_version == "0") {
|
|
copy_from_data_dir_to_local(); // STUDIO-9512
|
|
load_from_local(QUERY_HMS_INFO, dev_type_id, &m_hms_info_jsons[dev_type_id], load_version);/*copy files to local, and retry load*/
|
|
}
|
|
}
|
|
|
|
if (m_hms_action_jsons.count(dev_type_id) == 0) {
|
|
std::string load_version;
|
|
load_from_local(QUERY_HMS_ACTION, dev_type_id, &m_hms_action_jsons[dev_type_id], load_version);/*load from local first*/
|
|
if (load_version.empty() || load_version == "0") {
|
|
copy_from_data_dir_to_local(); // STUDIO-9512
|
|
load_from_local(QUERY_HMS_ACTION, dev_type_id, &m_hms_action_jsons[dev_type_id], load_version);/*copy files to local, and retry load*/
|
|
}
|
|
}
|
|
}
|
|
|
|
/*download from cloud*/
|
|
time_t info_last_update_time = m_cloud_hms_last_update_time[dev_type_id];
|
|
|
|
/* check hms is valid or not */
|
|
bool retry = false;
|
|
if(m_hms_info_jsons[dev_type_id].empty() || m_hms_action_jsons[dev_type_id].empty()){
|
|
retry =time(nullptr) - info_last_update_time > (60 * 1); // retry after 1 minute
|
|
}
|
|
|
|
if (time(nullptr) - info_last_update_time > (60 * 60 * 24) || retry)/*do not update in one day to reduce waiting*/
|
|
{
|
|
download_hms_related(QUERY_HMS_INFO, dev_type_id, &m_hms_info_jsons[dev_type_id]);
|
|
download_hms_related(QUERY_HMS_ACTION, dev_type_id, &m_hms_action_jsons[dev_type_id]);
|
|
m_cloud_hms_last_update_time[dev_type_id] = time(nullptr);
|
|
}
|
|
}
|
|
|
|
std::string get_hms_wiki_url(std::string error_code)
|
|
{
|
|
AppConfig* config = wxGetApp().app_config;
|
|
if (!config) return "";
|
|
if (should_disable_hms()) return "";
|
|
|
|
std::string hms_host = wxGetApp().app_config->get_hms_host();
|
|
std::string lang_code = HMSQuery::hms_language_code();
|
|
std::string url = (boost::format("https://%1%/index.php?e=%2%&s=device_hms&lang=%3%")
|
|
% hms_host
|
|
% error_code
|
|
% lang_code).str();
|
|
|
|
DeviceManager* dev = Slic3r::GUI::wxGetApp().getDeviceManager();
|
|
if (!dev) return url;
|
|
MachineObject* obj = dev->get_selected_machine();
|
|
if (!obj) return url;
|
|
|
|
if (!obj->get_dev_id().empty()) {
|
|
url = (boost::format("https://%1%/index.php?e=%2%&d=%3%&s=device_hms&lang=%4%")
|
|
% hms_host
|
|
% error_code
|
|
% obj->get_dev_id()
|
|
% lang_code).str();
|
|
}
|
|
return url;
|
|
}
|
|
|
|
std::string get_error_message(int error_code)
|
|
{
|
|
if (should_disable_hms()) return "";
|
|
|
|
char buf[64];
|
|
std::string result_str = "";
|
|
std::sprintf(buf,"%08X",error_code);
|
|
std::string hms_host = wxGetApp().app_config->get_hms_host();
|
|
std::string get_lang = wxGetApp().app_config->get_language_code();
|
|
|
|
std::string url = (boost::format("https://%1%/query.php?lang=%2%&e=%3%")
|
|
%hms_host
|
|
%get_lang
|
|
%buf).str();
|
|
|
|
Slic3r::Http http = Slic3r::Http::get(url);
|
|
http.header("accept", "application/json")
|
|
.timeout_max(10)
|
|
.on_complete([get_lang, &result_str](std::string body, unsigned status) {
|
|
try {
|
|
json j = json::parse(body);
|
|
if (j.contains("result")) {
|
|
if (j["result"].get<int>() == 0) {
|
|
if (j.contains("data")) {
|
|
json jj = j["data"];
|
|
if (jj.contains("device_error")) {
|
|
if (jj["device_error"].contains(get_lang)) {
|
|
if (jj["device_error"][get_lang].size() > 0) {
|
|
if (!jj["device_error"][get_lang][0]["intro"].empty() || !jj["device_error"][get_lang][0]["ecode"].empty()) {
|
|
std::string error_info = jj["device_error"][get_lang][0]["intro"].get<std::string>();
|
|
std::string error_code = jj["device_error"][get_lang][0]["ecode"].get<std::string>();
|
|
error_code.insert(4, " ");
|
|
result_str = from_u8(error_info).ToStdString() + "[" + error_code + "]";
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} catch (...) {
|
|
;
|
|
}
|
|
})
|
|
.on_error([](std::string body, std::string error, unsigned status) {
|
|
BOOST_LOG_TRIVIAL(info) << boost::format("[BBL ErrorMessage]: status=%1%, error=%2%, body=%3%") % status % error % body;
|
|
}).perform_sync();
|
|
|
|
return result_str;
|
|
}
|
|
|
|
}
|
|
}
|