From 84ad40cc8cff2aeba72414da1af36cc8ad3de771 Mon Sep 17 00:00:00 2001 From: Konstantin Dmitriev Date: Dec 13 2019 04:35:51 +0000 Subject: Step 4: Move plugin execution code to studio::Instance::run_plugin(). Remove PluginLauncher class. --- diff --git a/synfig-studio/src/gui/app.cpp b/synfig-studio/src/gui/app.cpp index dab7b58..211ef17 100644 --- a/synfig-studio/src/gui/app.cpp +++ b/synfig-studio/src/gui/app.cpp @@ -4242,3 +4242,26 @@ studio::App::process_all_events(long unsigned int us) Glib::usleep(us); } } + +bool +studio::App::check_python_version(String path) +{ + String command; + String result; + command = path + " --version 2>&1"; + FILE* pipe = popen(command.c_str(), "r"); + if (!pipe) { + return false; + } + char buffer[128]; + while(!feof(pipe)) { + if(fgets(buffer, 128, pipe) != NULL) + result += buffer; + } + pclose(pipe); + // Output is like: "Python 3.3.0" + if (result.substr(7,1) != "3"){ + return false; + } + return true; +} \ No newline at end of file diff --git a/synfig-studio/src/gui/app.h b/synfig-studio/src/gui/app.h index b3251cc..60db59a 100644 --- a/synfig-studio/src/gui/app.h +++ b/synfig-studio/src/gui/app.h @@ -457,6 +457,7 @@ public: static void setup_changed(); static void process_all_events(long unsigned int us = 1); + static bool check_python_version( std::string path); }; // END of class App void delete_widget(Gtk::Widget *widget); diff --git a/synfig-studio/src/gui/instance.cpp b/synfig-studio/src/gui/instance.cpp index f66e3ce..9c4c28a 100644 --- a/synfig-studio/src/gui/instance.cpp +++ b/synfig-studio/src/gui/instance.cpp @@ -294,13 +294,92 @@ studio::Instance::run_plugin(std::string plugin_path) outfile.close(); stream_in.reset(); - bool result=true; + + // ============= EXECUTE START ==================================== + bool result; + int exitcode; + String output; + String command = ""; + + // Path to python binary can be overridden + // with SYNFIG_PYTHON_BINARY env variable: + char* custom_python_binary=getenv("SYNFIG_PYTHON_BINARY"); + if(custom_python_binary) { + command=custom_python_binary; + if (!App::check_python_version(command)) { + output="Error: You need to have Python 3 installed."; + command=""; + } + } else { + // Set path to python binary depending on the os type. + // For Windows case Python binary is expected + // at INSTALL_PREFIX/python/python.exe + std::list< String > binary_choices; + binary_choices.push_back("python"); + binary_choices.push_back("python3"); + std::list< String >::iterator iter; + for(iter=binary_choices.begin();iter!=binary_choices.end();iter++) + { + String python_path; + #ifdef _WIN32 + python_path = "\"" + synfig_root+ETL_DIRECTORY_SEPARATOR+"python"+ETL_DIRECTORY_SEPARATOR+*iter+".exe" + "\""; + #else + python_path = *iter; + #endif + if (App::check_python_version(python_path)) + { + command = python_path; + break; + } + + } + + } + if (command == "") + { + output=_("Error: No Python 3 binary found.\n\nHint: You can set SYNFIG_PYTHON_BINARY environment variable pointing at your custom python installation."); + } else { + synfig::info("Python 3 binary found: "+command); + + + // Construct the full command: + command = command+" \""+plugin_path+"\" \""+filename_processed+"\" 2>&1"; + #ifdef _WIN32 + // This covers the dumb cmd.exe behavior. + // See: http://eli.thegreenplace.net/2011/01/28/on-spaces-in-the-paths-of-programs-and-files-on-windows/ + command = "\"" + command + "\""; + #endif + + FILE* pipe = popen(command.c_str(), "r"); + if (!pipe) { + output = "ERROR: pipe failed!"; + } else { + char buffer[128]; + while(!feof(pipe)) { + if(fgets(buffer, 128, pipe) != NULL) + output += buffer; + } + + if (output != "" ){ + synfig::info(output); + } + + exitcode=pclose(pipe); + + if (0==exitcode){ + result=true; + } + } + } + // =============== EXECUTE END ===================================== + + //result = launcher.execute( plugin_path, App::get_base_path() ); if (!result){ one_moment.hide(); App::dialog_message_1b( "Error", - "", //launcher.get_output(), + output, "details", _("Close")); diff --git a/synfig-studio/src/synfigapp/pluginmanager.cpp b/synfig-studio/src/synfigapp/pluginmanager.cpp index 980665c..08b14b9 100644 --- a/synfig-studio/src/synfigapp/pluginmanager.cpp +++ b/synfig-studio/src/synfigapp/pluginmanager.cpp @@ -62,173 +62,6 @@ using namespace synfigapp; /* === M E T H O D S ======================================================= */ -PluginLauncher::PluginLauncher(synfig::Canvas::Handle canvas) -{ - // Save the original filename - filename_original = canvas->get_file_name(); - if (0) { - String filename_base; - if (is_absolute_path(filename_original)) - { - filename_base = filename_original; - } else { - filename_base = synfigapp::Main::get_user_app_directory()+ETL_DIRECTORY_SEPARATOR+"tmp"+ETL_DIRECTORY_SEPARATOR+filename_original; - } - - // Make random filename and ensure there's no file with such name exist - struct stat buf; - - // Filename to save the file for processing - do { - synfig::GUID guid; - filename_processed = filename_base+"."+guid.get_string().substr(0,8)+".sif"; // without .sif suffix it won't be read back - } while (stat(filename_processed.c_str(), &buf) != -1); - - /* - * The plugin could die with nonzero exit code - * synfig could crash loading the modified file (should not happen) - * having a backup file should protect against both cases - */ - do { - synfig::GUID guid; - filename_backup = filename_base+"-current."+guid.get_string().substr(0,8)+".sif"; - } while (stat(filename_backup.c_str(), &buf) != -1); - - save_canvas(FileSystemNative::instance()->get_identifier(filename_processed),canvas); - - // copy file "filename_processed" -> "filename_backup" - std::ifstream src(filename_processed, std::ios::binary); - std::ofstream dst(filename_backup, std::ios::binary); - dst << src.rdbuf(); - - } - - //canvas=0; - exitcode=-1; - output=""; -} - -bool -PluginLauncher::check_python_version(String path) -{ - String command; - String result; - command = path + " --version 2>&1"; - FILE* pipe = popen(command.c_str(), "r"); - if (!pipe) { - return false; - } - char buffer[128]; - while(!feof(pipe)) { - if(fgets(buffer, 128, pipe) != NULL) - result += buffer; - } - pclose(pipe); - // Output is like: "Python 3.3.0" - if (result.substr(7,1) != "3"){ - return false; - } - return true; -} - -bool -#ifdef _WIN32 -PluginLauncher::execute( std::string script_path, const std::string& synfig_root ) -#else -PluginLauncher::execute( std::string script_path, const std::string& /* synfig_root */ ) -#endif -{ - String command = ""; - - // Path to python binary can be overridden - // with SYNFIG_PYTHON_BINARY env variable: - char* custom_python_binary=getenv("SYNFIG_PYTHON_BINARY"); - if(custom_python_binary) { - command=custom_python_binary; - if (!check_python_version(command)) { - output="Error: You need to have Python 3 installed."; - return false; - } - } else { - // Set path to python binary depending on the os type. - // For Windows case Python binary is expected - // at INSTALL_PREFIX/python/python.exe - std::list< String > binary_choices; - binary_choices.push_back("python"); - binary_choices.push_back("python3"); - std::list< String >::iterator iter; - for(iter=binary_choices.begin();iter!=binary_choices.end();iter++) - { - String python_path; -#ifdef _WIN32 - python_path = "\"" + synfig_root+ETL_DIRECTORY_SEPARATOR+"python"+ETL_DIRECTORY_SEPARATOR+*iter+".exe" + "\""; -#else - python_path = *iter; -#endif - if (check_python_version(python_path)) - { - command = python_path; - break; - } - - } - if (command == "") - { - output=_("Error: No Python 3 binary found.\n\nHint: You can set SYNFIG_PYTHON_BINARY environment variable pointing at your custom python installation."); - return false; - } - } - synfig::info("Python 3 binary found: "+command); - - - // Construct the full command: - command = command+" \""+script_path+"\" \""+filename_processed+"\" 2>&1"; -#ifdef _WIN32 - // This covers the dumb cmd.exe behavior. - // See: http://eli.thegreenplace.net/2011/01/28/on-spaces-in-the-paths-of-programs-and-files-on-windows/ - command = "\"" + command + "\""; -#endif - - FILE* pipe = popen(command.c_str(), "r"); - if (!pipe) { - output = "ERROR: pipe failed!"; - return false; - } - char buffer[128]; - while(!feof(pipe)) { - if(fgets(buffer, 128, pipe) != NULL) - output += buffer; - } - - if (output != "" ){ - synfig::info(output); - } - - exitcode=pclose(pipe); - - if (0==exitcode){ - return true; - } else { - return false; - } -} - -std::string -PluginLauncher::get_result_path() -{ - if (0==exitcode){ - return filename_processed; - } else { - return filename_backup; - } -} - -PluginLauncher::~PluginLauncher() -{ - remove( filename_processed.c_str() ); - remove( filename_backup.c_str() ); -} - PluginManager::PluginManager(): list_() { diff --git a/synfig-studio/src/synfigapp/pluginmanager.h b/synfig-studio/src/synfigapp/pluginmanager.h index 84b634f..d6717be 100644 --- a/synfig-studio/src/synfigapp/pluginmanager.h +++ b/synfig-studio/src/synfigapp/pluginmanager.h @@ -39,40 +39,7 @@ /* === C L A S S E S & S T R U C T S ======================================= */ namespace synfigapp { - -class PluginLauncher -{ - - /* - -- ** -- P R I V A T E D A T A --------------------------------------------- - */ - -private: - std::string filename_original; // location of original file - std::string filename_processed; // processed file - std::string filename_backup; // backup copy - std::string output; - int exitcode; - -protected: - - /* - -- ** -- P U B L I C M E T H O D S ----------------------------------------- - */ - -public: - PluginLauncher( synfig::Canvas::Handle ); - ~PluginLauncher(); - - bool execute( std::string script_path, const std::string& synfig_root ); - bool check_python_version( std::string path); - std::string get_result_path(); - std::string get_original_path() { return filename_original; }; - std::string get_output() { return output; }; - -}; // END class Plugin - class PluginManager { /*