TuttleOFX
1
|
00001 #include <sam/common/options.hpp> 00002 #include <sam/common/utility.hpp> 00003 00004 #include <tuttle/host/Core.hpp> 00005 #include <tuttle/host/ofx/OfxhImageEffectPlugin.hpp> 00006 00007 #include <boost/filesystem/operations.hpp> 00008 #include <boost/filesystem/exception.hpp> 00009 #include <boost/exception/diagnostic_information.hpp> 00010 #include <boost/foreach.hpp> 00011 #include <boost/program_options.hpp> 00012 #include <boost/regex.hpp> 00013 #include <boost/algorithm/string.hpp> 00014 #include <boost/algorithm/string/split.hpp> 00015 00016 00017 namespace bpo = boost::program_options; 00018 namespace bal = boost::algorithm; 00019 namespace tth = tuttle::host; 00020 00021 bool properties = false; 00022 bool clips = false; 00023 bool parameters = false; 00024 00025 /// get defaults values of plugin properties 00026 std::string getDefaultValues(const tth::ofx::property::OfxhProperty& prop) 00027 { 00028 std::string s; 00029 if( !(prop.getType() == 3) ) // if Pointer, we don't have _value and _defaultValue properties 00030 { 00031 int n = 0; 00032 for( ; n < (int)( prop.getDimension() ) - 1; ++n ) 00033 { 00034 s += prop.getStringValue( n ); 00035 s += ", "; 00036 } 00037 if( prop.getDimension() > 0 ) 00038 { 00039 s += prop.getStringValue( n ); 00040 } 00041 } 00042 return s; 00043 } 00044 00045 void printProperties( const tth::ofx::property::OfxhSet properties, std::string context="" ) 00046 { 00047 signal(SIGINT, signal_callback_handler); 00048 00049 using namespace tuttle::common; 00050 boost::shared_ptr<Color> color( Color::get() ); 00051 if( context.size() == 0 ) 00052 { 00053 TUTTLE_LOG_INFO( color->_red << "Number of properties : " << properties.getSize() << color->_std ); 00054 } 00055 else 00056 { 00057 TUTTLE_LOG_INFO( color->_red << "Number of properties for \"" << context << "\": " << properties.getSize() << color->_std ); 00058 } 00059 00060 std::string propertyId = "Property Name"; 00061 propertyId.resize( 50, ' ' ); 00062 TUTTLE_LOG_INFO( 00063 color->_red << "RW" << color->_std << " " << 00064 color->_red << "ModifiedBy" << color->_std << "\t" << 00065 color->_red << "Type" << color->_std << "\t" << 00066 color->_red << "Size" << color->_std << "\t" << 00067 color->_red << propertyId << color->_std << "\t" << 00068 color->_red << "Default Values" << color->_std ); 00069 00070 tth::ofx::property::PropertyMap propMap = properties.getMap(); 00071 for( tth::ofx::property::PropertyMap::const_iterator itProperty = propMap.begin(); itProperty != propMap.end(); ++itProperty ) 00072 { 00073 const tth::ofx::property::OfxhProperty& prop = *( itProperty->second ); 00074 std::string propertyLabel = itProperty->first; 00075 propertyLabel.resize( 50, ' ' ); 00076 00077 TUTTLE_LOG_INFO( 00078 color->_green << 00079 ( prop.getPluginReadOnly() ? (color->_green + "r-" + color->_std + " ") : (color->_green + "rw" + color->_std + " " ) ) << 00080 ( prop.getModifiedBy() == tth::ofx::property::eModifiedByHost ? ( color->_green + "host" + color->_std + " \t" ) : ( color->_green + "plugin" + color->_std + "\t" ) ) << 00081 color->_green << ( tth::ofx::property::mapTypeEnumToString( prop.getType() ) ) << color->_std << "\t" << color->_green << "[" << 00082 prop.getDimension() << "]" << color->_std << "\t" << 00083 color->_blue << propertyLabel << color->_std << "\t" << color->_green << "{ " << 00084 getDefaultValues(prop) << " }" << color->_std 00085 ); 00086 } 00087 } 00088 00089 00090 void getPluginProperties( const std::string& plugName ) 00091 { 00092 using namespace tuttle::common; 00093 boost::shared_ptr<Color> color( Color::get() ); 00094 tth::ofx::imageEffect::OfxhImageEffectPlugin* plug = tth::core().getImageEffectPluginById( plugName ); 00095 00096 if( !plug ) 00097 { 00098 TUTTLE_LOG_ERROR( color->_red << "no plugin match to: " << plugName << color->_std ); 00099 return; 00100 } 00101 00102 plug->loadAndDescribeActions(); 00103 TUTTLE_LOG_INFO("Identifier:\t\t" << plug->getIdentifier() ); 00104 TUTTLE_LOG_INFO("Raw identifier:\t\t" << plug->getRawIdentifier() ); 00105 TUTTLE_LOG_INFO("Minor version:\t\t" << plug->getVersionMinor() ); 00106 TUTTLE_LOG_INFO("Major version:\t\t" << plug->getVersionMajor() ); 00107 TUTTLE_LOG_INFO("API version:\t\t" << plug->getApiVersion() ); 00108 00109 // list contexts of plugin 00110 TUTTLE_LOG_INFO( color->_green << "Contexts:" << color->_std ); 00111 00112 tth::ofx::imageEffect::OfxhImageEffectPlugin::ContextSet contexts = plug->getContexts(); 00113 tth::ofx::imageEffect::OfxhImageEffectPlugin::ContextSet::iterator itContext; 00114 std::string strContexts; 00115 for( itContext = contexts.begin(); itContext != contexts.end(); ++itContext ) 00116 { 00117 strContexts += *itContext + ", "; 00118 } 00119 strContexts.erase(strContexts.size()-2, 2); 00120 TUTTLE_LOG_INFO( "[ " << strContexts << " ]" ); 00121 itContext = contexts.begin(); 00122 00123 // list properties of plugin for the first context 00124 if( properties ) 00125 { 00126 TUTTLE_LOG_INFO( std::endl << color->_red << "Properties" << color->_std ); 00127 00128 const tth::ofx::property::OfxhSet properties = plug->getDescriptorInContext( *itContext ).getProperties(); 00129 printProperties( properties ); 00130 } 00131 tth::ofx::imageEffect::OfxhImageEffectNode* plugInst = NULL; 00132 if( clips | parameters ) 00133 { 00134 if( plug->supportsContext( kOfxImageEffectContextReader ) ) 00135 { 00136 plugInst = plug->createInstance( kOfxImageEffectContextReader ); 00137 } 00138 else if( plug->supportsContext( kOfxImageEffectContextWriter ) ) 00139 { 00140 plugInst = plug->createInstance( kOfxImageEffectContextWriter ); 00141 } 00142 else if( plug->supportsContext( kOfxImageEffectContextGenerator ) ) 00143 { 00144 plugInst = plug->createInstance( kOfxImageEffectContextGenerator ); 00145 } 00146 else if( plug->supportsContext( kOfxImageEffectContextFilter ) ) 00147 { 00148 plugInst = plug->createInstance( kOfxImageEffectContextFilter ); 00149 } 00150 else if( plug->supportsContext( kOfxImageEffectContextGeneral ) ) 00151 { 00152 plugInst = plug->createInstance( kOfxImageEffectContextGeneral ); 00153 } 00154 else 00155 { 00156 TUTTLE_LOG_ERROR( "Plugin contexts not supported by the host. (" + plugName + ")" ); 00157 return; 00158 } 00159 } 00160 if( clips ) 00161 { 00162 TUTTLE_LOG_INFO( "" ); 00163 TUTTLE_LOG_INFO( std::endl << color->_red << "Clips" << color->_std ); 00164 00165 typedef std::map<std::string, tth::ofx::attribute::OfxhClipImageDescriptor*> ContextMap; 00166 00167 // get contexts 00168 ContextMap::const_iterator it = plugInst->getDescriptor().getClips().begin(); 00169 std::string strClipContexts; 00170 for( ; it != plugInst->getDescriptor().getClips().end(); ++it ) 00171 { 00172 strClipContexts += (*it).first + ", " ; 00173 } 00174 strClipContexts.erase( strClipContexts.size()-2, 2 ); 00175 00176 TUTTLE_LOG_INFO( color->_green << "[ " << strClipContexts << " ]" << color->_std ); 00177 00178 00179 // get propeties in each context 00180 ContextMap::const_iterator it2 = plugInst->getDescriptor().getClips().begin(); 00181 for( ; it2 != plugInst->getDescriptor().getClips().end(); ++it2 ) 00182 { 00183 printProperties( (*it2).second->getProperties(), (*it2).first ); 00184 } 00185 } 00186 00187 if( parameters ) 00188 { 00189 TUTTLE_LOG_INFO( "" ); 00190 TUTTLE_LOG_INFO( color->_red << "Parameters" << color->_std ); 00191 00192 typedef std::map<std::string, tth::ofx::attribute::OfxhParamDescriptor*> ParamDescriptorMap; 00193 00194 // get contexts 00195 ParamDescriptorMap::const_iterator it = plugInst->getDescriptor().getParams().begin(); 00196 std::string strParamsContexts; 00197 for( ; it != plugInst->getDescriptor().getParams().end(); ++it ) 00198 { 00199 strParamsContexts += (*it).first + ", "; 00200 } 00201 strParamsContexts.erase( strParamsContexts.size()-2, 2 ); 00202 00203 TUTTLE_LOG_INFO( color->_green << "[ " << strParamsContexts << " ]" << color->_std ); 00204 00205 // get propeties in each context 00206 ParamDescriptorMap::const_iterator it2 = plugInst->getDescriptor().getParams().begin(); 00207 for( ; it2 != plugInst->getDescriptor().getParams().end(); it2++ ) 00208 { 00209 printProperties( (*it2).second->getProperties(), (*it2).first ); 00210 } 00211 /* 00212 const tth::ofx::property::OfxhSet paramProperties = plugInst->getDescriptor().getParamList().front().getProperties(); 00213 printProperties( paramProperties, "" ); 00214 */ 00215 } 00216 } 00217 00218 bool isNotFiltered( std::string plugName, std::vector<std::string>& filters) 00219 { 00220 if( filters.size() == 0 ) 00221 return true; 00222 00223 for( std::size_t i = 0; i < filters.size(); ++i ) 00224 { 00225 std::string filter(filters.at(i)); 00226 filter = boost::regex_replace( filter, boost::regex( "\\*" ), "(.*)" ); 00227 filter = boost::regex_replace( filter, boost::regex( "\\?" ), "(.)" ); 00228 00229 if( regex_match( plugName, boost::regex(filter) ) ) 00230 return true; 00231 } 00232 return false; 00233 } 00234 00235 int main( int argc, char** argv ) 00236 { 00237 using namespace tuttle::common; 00238 using namespace sam; 00239 00240 boost::shared_ptr<formatters::Formatter> formatter( formatters::Formatter::get() ); 00241 boost::shared_ptr<Color> color( Color::get() ); 00242 00243 std::vector<std::string> plugins; 00244 std::vector<std::string> foundPlugins; 00245 std::vector<std::string> filters; 00246 00247 formatter->init_logging(); 00248 00249 // Declare the supported options. 00250 bpo::options_description mainOptions; 00251 mainOptions.add_options() 00252 ( kHelpOptionString , kHelpOptionMessage ) 00253 ( kAllOptionString , kAllOptionMessage ) 00254 ( kFilterOptionString , bpo::value<std::string>(), kFilterOptionMessage ) 00255 ( kColorOptionString , kColorOptionMessage ) 00256 ( kPropertiesOptionString , kPropertiesOptionMessage ) 00257 ( kClipsOptionString , kClipsOptionMessage ) 00258 ( kParametersOptionString , kParametersOptionMessage ) 00259 ( kBriefOptionString , kBriefOptionMessage ) 00260 ; 00261 00262 // describe hidden options 00263 bpo::options_description hidden; 00264 hidden.add_options() 00265 ( kInputDirOptionString, bpo::value< std::vector<std::string> >(), kInputDirOptionMessage ) 00266 ( kEnableColorOptionString, bpo::value<std::string>(), kEnableColorOptionMessage ); 00267 00268 // define default options 00269 bpo::positional_options_description pod; 00270 pod.add(kInputDirOptionLongName, -1); 00271 00272 bpo::options_description cmdline_options; 00273 cmdline_options.add(mainOptions).add(hidden); 00274 00275 //parse the command line, and put the result in vm 00276 bpo::variables_map vm; 00277 try 00278 { 00279 bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).positional(pod).run(), vm); 00280 00281 // get environnement options and parse them 00282 if( const char* env_plugins_options = std::getenv("SAM_PLUGINS_OPTIONS") ) 00283 { 00284 const std::vector<std::string> vecOptions = bpo::split_unix( env_plugins_options, " " ); 00285 bpo::store(bpo::command_line_parser(vecOptions).options(cmdline_options).positional(pod).run(), vm); 00286 } 00287 if( const char* env_options = std::getenv("SAM_OPTIONS") ) 00288 { 00289 const std::vector<std::string> vecOptions = bpo::split_unix( env_options, " " ); 00290 bpo::store(bpo::command_line_parser(vecOptions).options(cmdline_options).positional(pod).run(), vm); 00291 } 00292 bpo::notify(vm); 00293 } 00294 catch( const bpo::error& e) 00295 { 00296 TUTTLE_LOG_ERROR( "sam-plugins: command line error: " << e.what() ); 00297 exit( 254 ); 00298 } 00299 catch(...) 00300 { 00301 TUTTLE_LOG_ERROR( "sam-plugins: unknown error in command line."); 00302 exit( 254 ); 00303 } 00304 00305 if( vm.count( kColorOptionLongName ) ) 00306 { 00307 color->enable(); 00308 } 00309 00310 if( vm.count( kEnableColorOptionLongName ) ) 00311 { 00312 const std::string str = vm[kEnableColorOptionLongName].as<std::string>(); 00313 if( string_to_boolean(str) ) 00314 { 00315 color->enable(); 00316 } 00317 else 00318 { 00319 color->disable(); 00320 } 00321 } 00322 00323 if( vm.count(kHelpOptionLongName) ) 00324 { 00325 TUTTLE_LOG_INFO( color->_blue << "TuttleOFX project [" << kUrlTuttleofxProject << "]" << color->_std ); 00326 TUTTLE_LOG_INFO( "" ); 00327 TUTTLE_LOG_INFO( color->_blue << "NAME" << color->_std ); 00328 TUTTLE_LOG_INFO( color->_green << "\tsam-plugins - show informations about OpenFX plugins" << color->_std ); 00329 TUTTLE_LOG_INFO( "" ); 00330 TUTTLE_LOG_INFO( color->_blue << "SYNOPSIS" << color->_std ); 00331 TUTTLE_LOG_INFO( color->_green << "\tsam-plugins [options] [specific_OpenFX_plugin]" << color->_std ); 00332 TUTTLE_LOG_INFO( "" ); 00333 TUTTLE_LOG_INFO( color->_blue << "DESCRIPTION" << color->_std ); 00334 TUTTLE_LOG_INFO( "List OpenFX in OFX_PLUGIN_PATH by default."); 00335 TUTTLE_LOG_INFO( "And could print properties, parameters and clips for each plugins" ); 00336 TUTTLE_LOG_INFO( "" ); 00337 TUTTLE_LOG_INFO( color->_blue << "OPTIONS" << color->_std ); 00338 TUTTLE_LOG_INFO( mainOptions ); 00339 return 0; 00340 } 00341 00342 if ( vm.count(kBriefOptionLongName) ) 00343 { 00344 TUTTLE_LOG_INFO( color->_green << "show informations about OpenFX plugins" << color->_std ); 00345 return 0; 00346 } 00347 00348 // defines plugins 00349 if( vm.count(kInputDirOptionLongName) ) 00350 { 00351 plugins = vm[kInputDirOptionLongName].as< std::vector<std::string> >(); 00352 } 00353 00354 if( vm.count(kFilterOptionLongName) ) 00355 { 00356 bal::split( filters, vm[kFilterOptionLongName].as<std::string>(), bal::is_any_of(",")); 00357 } 00358 00359 if( vm.count(kAllOptionLongName) | (plugins.size() == 0) ) 00360 { 00361 tth::core().preload(); 00362 const std::vector<tth::ofx::imageEffect::OfxhImageEffectPlugin*> plugs = tth::core().getImageEffectPluginCache().getPlugins(); 00363 00364 for( std::size_t i = 0; i < plugs.size(); ++i ) 00365 { 00366 const std::string plugName = plugs.at(i)->getRawIdentifier(); 00367 if( isNotFiltered( plugName, filters) ) 00368 { 00369 TUTTLE_LOG_INFO( plugName ); 00370 } 00371 } 00372 return 0; 00373 } 00374 00375 00376 if (vm.count(kPropertiesOptionLongName)) 00377 { 00378 properties = true; 00379 } 00380 00381 if (vm.count(kClipsOptionLongName)) 00382 { 00383 clips = true; 00384 } 00385 00386 if (vm.count(kParametersOptionLongName)) 00387 { 00388 parameters = true; 00389 } 00390 // for(unsigned int i=0; i< plugins.size(); i++) 00391 // TUTTLE_LOG_TRACE( plugins.at(i) ); 00392 00393 try 00394 { 00395 tth::core().preload(); 00396 // get the plugins names for research partials names (rawreader need to make reference to the plug tuttle.reader) 00397 const std::vector<tth::ofx::imageEffect::OfxhImageEffectPlugin*> plugs = tth::core().getImageEffectPluginCache().getPlugins(); 00398 00399 unsigned int founded; 00400 BOOST_FOREACH( const std::string& plugin, plugins ) 00401 { 00402 std::vector< std::string > termsPlugin; 00403 bal::split( termsPlugin, plugin, bal::is_any_of(".")); 00404 00405 for( std::size_t i=0; i<plugs.size(); i++ ) 00406 { 00407 founded = 0; 00408 for( std::size_t t=0; t<termsPlugin.size(); t++ ) 00409 { 00410 std::size_t found1 = plugs.at(i)->getRawIdentifier().find( "."+termsPlugin.at(t) ); 00411 std::size_t found2 = plugs.at(i)->getRawIdentifier().find( termsPlugin.at(t)+"." ); 00412 if( ( found1 == std::string::npos ) && ( found2 == std::string::npos ) ) 00413 { 00414 break; 00415 } 00416 ++founded; 00417 if( founded == termsPlugin.size() ) 00418 { 00419 /*TUTTLE_LOG_TRACE("plug is " << plugs.at(i)->getRawIdentifier() );*/ 00420 foundPlugins.push_back( plugs.at(i)->getRawIdentifier() ); 00421 } 00422 } 00423 } 00424 } 00425 00426 TUTTLE_LOG_INFO( color->_red << "################################################################################" << color->_std ); 00427 00428 BOOST_FOREACH( const std::string& plugin, foundPlugins ) 00429 { 00430 TUTTLE_LOG_INFO(color->_blue << "PLUGIN DESCRIPTION" << color->_std ); 00431 getPluginProperties( plugin ); 00432 TUTTLE_LOG_INFO( color->_red << "################################################################################" << color->_std ); 00433 } 00434 } 00435 catch( ... ) 00436 { 00437 TUTTLE_LOG_ERROR( color->_red << boost::current_exception_diagnostic_information() << color->_std ); 00438 } 00439 00440 return 0; 00441 } 00442