TuttleOFX
1
|
00001 #include <sam/common/utility.hpp> 00002 #include <sam/common/options.hpp> 00003 00004 #include <boost/filesystem/operations.hpp> 00005 #include <boost/filesystem/exception.hpp> 00006 #include <boost/exception/diagnostic_information.hpp> 00007 #include <boost/foreach.hpp> 00008 #include <boost/algorithm/string.hpp> 00009 #include <boost/algorithm/string/split.hpp> 00010 #include <boost/program_options.hpp> 00011 #include <boost/shared_ptr.hpp> 00012 00013 #include <detector.hpp> 00014 00015 #include <algorithm> 00016 #include <iterator> 00017 00018 namespace bpo = boost::program_options; 00019 namespace bfs = boost::filesystem; 00020 namespace bal = boost::algorithm; 00021 00022 00023 namespace sam 00024 { 00025 bool wasSthgDumped = false; 00026 } 00027 00028 // A helper function to simplify the main part. 00029 template<class T> 00030 std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) 00031 { 00032 copy(v.begin(), v.end(), std::ostream_iterator<T>(std::cout, " ")); 00033 return os; 00034 } 00035 00036 template<class T> 00037 void coutVec( const boost::ptr_vector<T>& v ) 00038 { 00039 BOOST_FOREACH( const T& f, v ) 00040 { 00041 TUTTLE_LOG_INFO( f ); 00042 sam::wasSthgDumped = true; 00043 } 00044 } 00045 00046 00047 int main( int argc, char** argv ) 00048 { 00049 signal(SIGINT, signal_callback_handler); 00050 00051 using namespace tuttle::common; 00052 using namespace sam; 00053 00054 boost::shared_ptr<formatters::Formatter> formatter( formatters::Formatter::get() ); 00055 boost::shared_ptr<Color> color( Color::get() ); 00056 00057 sequenceParser::EMaskType researchMask = sequenceParser::eMaskTypeDirectory | sequenceParser::eMaskTypeFile | sequenceParser::eMaskTypeSequence ; // by default show directories, files and sequences 00058 sequenceParser::EMaskOptions descriptionMask = sequenceParser::eMaskOptionsNone; // by default show nothing 00059 bool recursiveListing = false; 00060 bool script = false; 00061 std::string availableExtensions; 00062 std::vector<std::string> paths; 00063 std::vector<std::string> filters; 00064 00065 formatter->init_logging(); 00066 00067 // Declare the supported options. 00068 bpo::options_description mainOptions; 00069 mainOptions.add_options() 00070 (kAllOptionString , kAllOptionMessage) 00071 (kDirectoriesOptionString , kDirectoriesOptionMessage) 00072 (kExpressionOptionString , bpo::value<std::string>(), kExpressionOptionMessage) 00073 (kFilesOptionString , kFilesOptionMessage ) 00074 (kHelpOptionString , kHelpOptionMessage) 00075 (kLongListingOptionString , kLongListingOptionMessage) 00076 (kRelativePathOptionString , kRelativePathOptionMessage) 00077 (kRecursiveOptionString , kRecursiveOptionMessage) 00078 (kPathOptionString , kPathOptionMessage) 00079 (kSequencesOptionString , kSequencesOptionMessage) 00080 (kColorOptionString , kColorOptionMessage) 00081 (kFullDisplayOptionString , kFullDisplayOptionMessage ) 00082 (kScriptOptionString , kScriptOptionMessage) 00083 (kBriefOptionString , kBriefOptionMessage) 00084 ; 00085 00086 // describe hidden options 00087 bpo::options_description hidden; 00088 hidden.add_options() 00089 (kInputDirOptionString, bpo::value< std::vector<std::string> >(), kInputDirOptionMessage) 00090 (kEnableColorOptionString, bpo::value<std::string>(), kEnableColorOptionMessage) 00091 ; 00092 00093 // define default options 00094 bpo::positional_options_description pod; 00095 pod.add(kInputDirOptionLongName, -1); 00096 00097 bpo::options_description cmdline_options; 00098 cmdline_options.add(mainOptions).add(hidden); 00099 00100 bpo::positional_options_description pd; 00101 pd.add("", -1); 00102 00103 bpo::variables_map vm; 00104 00105 try 00106 { 00107 //parse the command line, and put the result in vm 00108 bpo::store(bpo::command_line_parser(argc, argv).options(cmdline_options).positional(pod).run(), vm); 00109 00110 // get environment options and parse them 00111 if( const char* env_ls_options = std::getenv("SAM_LS_OPTIONS") ) 00112 { 00113 const std::vector<std::string> vecOptions = bpo::split_unix( env_ls_options, " " ); 00114 bpo::store(bpo::command_line_parser(vecOptions).options(cmdline_options).positional(pod).run(), vm); 00115 } 00116 if( const char* env_ls_options = std::getenv("SAM_OPTIONS") ) 00117 { 00118 const std::vector<std::string> vecOptions = bpo::split_unix( env_ls_options, " " ); 00119 bpo::store(bpo::command_line_parser(vecOptions).options(cmdline_options).positional(pod).run(), vm); 00120 } 00121 bpo::notify(vm); 00122 } 00123 catch( const bpo::error& e) 00124 { 00125 TUTTLE_LOG_ERROR("sam-ls: command line error: " << e.what() ); 00126 exit( 254 ); 00127 } 00128 catch(...) 00129 { 00130 TUTTLE_LOG_ERROR("sam-ls: unknown error in command line."); 00131 exit( 254 ); 00132 } 00133 00134 if ( vm.count(kScriptOptionLongName) ) 00135 { 00136 // disable color, disable directory printing and set relative path by default 00137 script = true; 00138 descriptionMask |= sequenceParser::eMaskOptionsAbsolutePath; 00139 } 00140 00141 if ( vm.count(kColorOptionLongName) && !script ) 00142 { 00143 color->enable(); 00144 descriptionMask |= sequenceParser::eMaskOptionsColor; 00145 } 00146 if ( vm.count(kEnableColorOptionLongName) && !script ) 00147 { 00148 const std::string str = vm[kEnableColorOptionLongName].as<std::string>(); 00149 if( string_to_boolean( str ) ) 00150 { 00151 color->enable(); 00152 descriptionMask |= sequenceParser::eMaskOptionsColor; 00153 } 00154 else 00155 { 00156 color->disable(); 00157 remove( descriptionMask, sequenceParser::eMaskOptionsColor ); 00158 } 00159 } 00160 00161 if (vm.count(kHelpOptionLongName)) 00162 { 00163 TUTTLE_LOG_INFO( color->_blue << "TuttleOFX project [" << kUrlTuttleofxProject << "]" << color->_std ); 00164 TUTTLE_LOG_INFO( "" ); 00165 TUTTLE_LOG_INFO( color->_blue << "NAME" << color->_std ); 00166 TUTTLE_LOG_INFO( color->_green << "\tsam-ls - list directory contents" << color->_std ); 00167 TUTTLE_LOG_INFO( "" ); 00168 TUTTLE_LOG_INFO( color->_blue << "SYNOPSIS" << color->_std ); 00169 TUTTLE_LOG_INFO( color->_green << "\tsam-ls [options] [directories]" << color->_std ); 00170 TUTTLE_LOG_INFO( "" ); 00171 TUTTLE_LOG_INFO( color->_blue << "DESCRIPTION" << color->_std ); 00172 TUTTLE_LOG_INFO( "" ); 00173 TUTTLE_LOG_INFO( "List information about the sequences, files and folders." ); 00174 TUTTLE_LOG_INFO( "List the current directory by default, and only sequences." ); 00175 TUTTLE_LOG_INFO( "The script option disable color, disable directory printing (in multi-directory case or recursive) and set relative path by default." ); 00176 TUTTLE_LOG_INFO( "" ); 00177 TUTTLE_LOG_INFO( color->_blue << "OPTIONS" << color->_std ); 00178 TUTTLE_LOG_INFO( "" ); 00179 TUTTLE_LOG_INFO( mainOptions ); 00180 return 0; 00181 } 00182 00183 if ( vm.count(kBriefOptionLongName) ) 00184 { 00185 TUTTLE_LOG_INFO( color->_green << "list directory contents" << color->_std ); 00186 return 0; 00187 } 00188 00189 if (vm.count(kExpressionOptionLongName)) 00190 { 00191 TUTTLE_LOG_WARNING( "Expression: " << vm["expression"].as<std::string>() ); 00192 bal::split( filters, vm["expression"].as<std::string>(), bal::is_any_of(",")); 00193 } 00194 00195 if( vm.count(kDirectoriesOptionLongName ) | vm.count(kFilesOptionLongName) | vm.count(kSequencesOptionLongName) ) 00196 { 00197 researchMask &= ~sequenceParser::eMaskTypeDirectory; 00198 researchMask &= ~sequenceParser::eMaskTypeFile; 00199 researchMask &= ~sequenceParser::eMaskTypeSequence; 00200 } 00201 00202 if( vm.count(kDirectoriesOptionLongName ) ) 00203 { 00204 researchMask |= sequenceParser::eMaskTypeDirectory; 00205 } 00206 if (vm.count(kFilesOptionLongName)) 00207 { 00208 researchMask |= sequenceParser::eMaskTypeFile; 00209 } 00210 if (vm.count(kSequencesOptionLongName)) 00211 { 00212 researchMask |= sequenceParser::eMaskTypeSequence; 00213 } 00214 00215 if (vm.count(kFullDisplayOptionLongName)) 00216 { 00217 researchMask |= sequenceParser::eMaskTypeDirectory; 00218 researchMask |= sequenceParser::eMaskTypeFile; 00219 researchMask |= sequenceParser::eMaskTypeSequence; 00220 } 00221 00222 if (vm.count(kAllOptionLongName)) 00223 { 00224 // add .* files 00225 descriptionMask |= sequenceParser::eMaskOptionsDotFile; 00226 } 00227 00228 if (vm.count(kLongListingOptionLongName)) 00229 { 00230 descriptionMask |= sequenceParser::eMaskOptionsProperties; 00231 } 00232 00233 if (vm.count(kRelativePathOptionLongName) ) 00234 { 00235 descriptionMask |= sequenceParser::eMaskOptionsPath; 00236 } 00237 00238 if(vm.count(kPathOptionLongName)) 00239 { 00240 descriptionMask |= sequenceParser::eMaskOptionsAbsolutePath; 00241 } 00242 00243 // defines paths, but if no directory specify in command line, we add the current path 00244 if (vm.count(kInputDirOptionLongName)) 00245 { 00246 paths = vm[kInputDirOptionLongName].as< std::vector<std::string> >(); 00247 } 00248 else 00249 { 00250 paths.push_back( "./" ); 00251 } 00252 00253 if (vm.count(kRecursiveOptionLongName)) 00254 { 00255 recursiveListing = true; 00256 } 00257 00258 00259 // for(uint i=0; i<filters.size(); i++) 00260 // TUTTLE_LOG_TRACE( "filters = " << filters.at(i) ); 00261 // TUTTLE_LOG_TRACE( "research mask = " << researchMask ); 00262 // TUTTLE_LOG_TRACE( "options mask = " << descriptionMask ); 00263 00264 std::list<boost::shared_ptr<sequenceParser::FileObject> > listing; 00265 try 00266 { 00267 std::size_t index = 0; 00268 BOOST_FOREACH( bfs::path path, paths ) 00269 { 00270 if( path == bfs::path(".") ) 00271 { 00272 path = bfs::path("./"); 00273 } 00274 if( ( paths.size() > 1 || recursiveListing ) && !script ) 00275 { 00276 if( index > 0 ) 00277 { 00278 TUTTLE_LOG_INFO( "" ); 00279 } 00280 TUTTLE_LOG_INFO( path.string() << ":"); 00281 wasSthgDumped = true; 00282 } 00283 00284 coutVec( sequenceParser::fileObjectInDirectory( path.string(), filters, researchMask, descriptionMask ) ); 00285 00286 if(recursiveListing) 00287 { 00288 for ( bfs::recursive_directory_iterator end, dir( path ); dir != end; ++dir ) 00289 { 00290 if( bfs::is_directory( *dir ) ) 00291 { 00292 bfs::path currentPath = (bfs::path)*dir; 00293 if( !script ) 00294 TUTTLE_LOG_INFO( "\n" << currentPath.string() << ":" ); 00295 00296 coutVec( sequenceParser::fileObjectInDirectory( currentPath.string(), filters, researchMask, descriptionMask ) ); 00297 00298 } 00299 } 00300 } 00301 ++index; 00302 } 00303 } 00304 catch ( const bfs::filesystem_error& ex) 00305 { 00306 TUTTLE_LOG_ERROR( ex.what() ); 00307 } 00308 catch( ... ) 00309 { 00310 TUTTLE_LOG_ERROR( boost::current_exception_diagnostic_information() ); 00311 } 00312 00313 if(!wasSthgDumped) 00314 { 00315 TUTTLE_LOG_ERROR( "No sequence found here." ); 00316 } 00317 00318 return 0; 00319 }