#include #include #ifdef _WIN32 #include #include #include #else #include #endif #include "filesystem.hpp" #include "functions.hpp" #include "tv_rename.hpp" #ifdef _WIN32 using char_t = wchar_t; using string = std::wstring; #define cerr std::wcerr #define cout std::wcout #define cin std::wcin #else using char_t = char; using string = std::string; #define cerr std::cerr #define cout std::cout #define cin std::cin #define TEXT( a ) a #endif int handleArgument( char_t c, string &show, std::set< int > &seasons_num, bool &change_dir, string &path, bool &trust, bool &linux, string &language, string &pattern, char_t *optional, int &i ) { switch ( c ) { case 's': show = optional; i++; break; case 'n': parseSeasonNumbers( seasons_num, optional ); i++; break; case 'c': change_dir = false; break; case 'p': path = string( optional ); i++; // if path provided, assume it's correct change_dir = false; break; case 't': trust = true; break; case 'x': linux = true; break; case 'l': if ( findLanguage( optional ) ) { language = optional; } else { cerr << "Invalid language choice" << std::endl; printLangs(); return -1; } i++; break; case '0': printLangs(); return 1; case 'h': printHelp(); return 1; case '1': pattern = optional; i++; break; default: return -1; } return 0; } #ifdef _WIN32 string getOptions( const char_t *option ) { if ( option[1] != '-' ) return option + 1; if ( !wcscmp( option, L"--show" ) ) return L"s"; else if ( !wcscmp( option, L"--season" ) ) return L"n"; else if ( !wcscmp( option, L"--correct-path" ) ) return L"c"; else if ( !wcscmp( option, L"--show-path" ) ) return L"p"; else if ( !wcscmp( option, L"--trust" ) ) return L"t"; else if ( !wcscmp( option, L"--linux" ) ) return L"x"; else if ( !wcscmp( option, L"--lang" ) ) return L"l"; else if ( !wcscmp( option, L"--print-langs" ) ) return L"0"; else if ( !wcscmp( option, L"--name-pattern" ) ) return L"1"; else if ( !wcscmp( option, L"--help" ) ) return L"h"; return L""; } // there's no getopt for windows, so just use wcscmp int parseCommandLine( string &show, std::set< int > &seasons_num, string &path, bool &change_dir, string &language, string &pattern, bool &linux, bool &trust, const int argc, char_t **argv ) { for ( auto i = 1; i < argc; i++ ) { auto options = getOptions( argv[i] ); char_t *optional = ( i < argc - 1 ) ? argv[i + 1] : nullptr; for ( const auto &x : options ) { auto res = handleArgument( x, show, seasons_num, change_dir, path, trust, linux, language, pattern, optional, i ); if ( res != 0 ) return res; } } return 0; } #else // parse command line arguments using getopt int parseCommandLine( string &show, std::set< int > &seasons_num, string &path, bool &change_dir, string &language, string &pattern, bool &linux, bool &trust, int argc, char **argv ) { static struct option long_options[] = { { "show", required_argument, 0, 's' }, { "season", required_argument, 0, 'n' }, { "correct-path", no_argument, 0, 'c' }, { "show-path", required_argument, 0, 'p' }, { "trust", no_argument, 0, 't' }, { "linux", no_argument, 0, 'x' }, { "lang", required_argument, 0, 'l' }, { "print-langs", no_argument, 0, '0' }, { "name-pattern", required_argument, 0, '1' }, { "help", no_argument, 0, 'h' } }; int i{}; // this is useless, but needed for handleArgument while ( 1 ) { int option_index{ 0 }; auto c = getopt_long( argc, argv, "s:n:cp:txl:01:h", long_options, &option_index ); if ( c == -1 ) break; auto res = handleArgument( c, show, seasons_num, change_dir, path, trust, linux, language, pattern, optarg, i ); if ( res != 0 ) return res; } return 0; } #endif // windows needs wmain for unicode support #ifdef _WIN32 int wmain #else int main #endif ( int argc, char_t **argv ) { #ifdef _WIN32 // set console to unicode _setmode( _fileno( stdout ), _O_U16TEXT ); #endif string show{}; std::set< int > seasons_num{}; bool change_dir{ true }; bool linux{ false }; bool trust{ false }; string path{ TEXT( "." ) }; string language{ TEXT( "en" ) }; string pattern{ TEXT( "%filename - %epname" ) }; Curl c; { auto tmp = parseCommandLine( show, seasons_num, path, change_dir, language, pattern, linux, trust, argc, argv ); if ( tmp == -1 ) return 1; else if ( tmp == 1 ) return 0; } if ( !FSLib::isDirectory( path ) ) change_dir = true; while ( change_dir ) { if ( !FSLib::isDirectory( path ) ) { cout << "This directory doesn't exist, please insert a correct " "path: " << std::endl; std::getline( cin, path ); continue; } cout << "Is this the right directory? " << FSLib::canonical( path ) << std::endl; string response; cin >> response; cin.ignore( 1, '\n' ); cin.clear(); if ( response[0] == 'y' || response[0] == 'Y' ) { change_dir = false; } else { cout << "Insert correct path:" << std::endl; std::getline( cin, path ); } } if ( show.empty() ) { auto pos = show.find_last_of( '/' ); if ( pos != string::npos ) show = show.substr( ++pos ); cout << "Is this the right show name? " << show << std::endl; string response; cin >> response; cin.ignore( 1, '\n' ); cin.clear(); if ( response[0] != 'y' && response[0] != 'Y' ) { cout << "Insert the correct show name: " << std::endl; std::getline( cin, show ); } } if ( seasons_num.size() == 1 ) { singleSeason( path, show, *seasons_num.begin(), string(), language, pattern, linux, trust, c ); } else if ( seasons_num.size() != 0 ) { multipleSeasons( path, show, seasons_num, language, pattern, linux, trust, c ); } else { allSeasons( path, show, language, pattern, linux, trust, c ); } }