#include #include #include #include #include "filesystem.hpp" #include "functions.hpp" #include "tv_rename.hpp" std::vector parseEpisodeNames( const std::string &season_code, const std::string &language) { std::vector episodes; size_t pos = 0; while( true ) { pos = season_code.find("ge=\"" + language + "\" ", pos); if( pos != std::string::npos ) { if( language == "en" ) pos += 17; else pos += 29; while( isspace(season_code[pos]) ) pos++; auto end = season_code.find("<", pos); end--; while( isspace(season_code[end]) ) end--; end++; episodes.push_back(season_code.substr(pos, end - pos)); } else { break; } } return episodes; } void singleSeason( const std::string &path, const std::string &show, int season, std::string url, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c, std::set const *files) { if( url.empty() ) url = getDefUrl(show, language, c); url += "/seasons/" + std::to_string(season); //get source code of season's page auto season_code = c.execute(url); //remove newlines season_code.erase(std::remove_if(season_code.begin(), season_code.end(), [](char x) {return x == '\r' || x == '\n';}), season_code.end()); //first 900 chars or so are useless to us season_code = season_code.substr(900); //get only the episode names auto pos = season_code.find("\"translations\""); if( pos != std::string::npos ) { season_code = season_code.substr(pos); pos = season_code.find(""); if( pos != std::string::npos ) season_code = season_code.substr(0,pos); else return; } else { return; } auto episodes = parseEpisodeNames(season_code, language); if( episodes.empty() ) return; std::set found_files; std::set renamed_files; std::vector renamed_episodes; renamed_episodes.resize(episodes.size()); if( files == nullptr ) { findSeason(found_files, season, path); files = &found_files; } if( files->empty() ) return; for( const auto &x : *files ) { auto last = x.find_last_of("/"); std::string name; std::string dir; if( last == static_cast(-1) ) { name = x; dir = "."; } else { name = x.substr(last+1); dir = x.substr(0, last); } unsigned long num; // get file's episode number if( searchSpecificSeason(x.c_str(), pos, std::to_string(season)) ) { num = atoi(x.c_str()+pos); } else { continue; } num -= 1; if( num < episodes.size() ) { auto pos = name.find_last_of('.'); // get desired filename name = compilePattern(pattern, season, num+1, name.substr(0, pos), episodes[num], show) + name.substr(pos); // replace characters illegal in windows if desired if( !linux ) { season_code.erase(std::remove_if(name.begin(), name.end(), [](char x) {return x == '?' || x == '"' || x == '\\' || x == '|' || x == '*';}), season_code.end()); size_t max{name.size()}; for( size_t i = 0; i < max ; i++ ) { if( name[i] == '<' ) { name[i] = 'i'; name.insert(i+1, "s less than"); max += 11; } else if ( name[i] == '>' ) { name[i] = 'i'; name.insert(i+1, "s more than"); max += 11; } else if ( name[i] == ':' ) { name[i] = ' '; name.insert(i+1, 1, '-'); max++; } } } renamed_files.insert(dir + "/" + name); renamed_episodes[num] = name; } } for(auto renamed = renamed_files.begin(); renamed != renamed_files.end(); ++renamed) { std::cout << *renamed << std::endl; } if( !trust ) { std::cout << "Does this seem ok? (y/n) "; std::string response; std::cin >> response; std::cin.clear(); std::cin.ignore(1, '\n'); if( response[0] != 'y' && response[0] != 'Y' ) return; } auto orig = files->begin(); for(auto renamed = renamed_files.begin(); renamed != renamed_files.end(); ++renamed) { FSLib::rename(*orig, *renamed); ++orig; } } void multipleSeasons( const std::string &path, const std::string &show, const std::map> &seasons, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) { auto url = getDefUrl(show, language, c); for( const auto &x : seasons ) { singleSeason( path, show, x.first, url, language, pattern, linux, trust, c, &x.second); } } void multipleSeasons( const std::string &path, const std::string &show, const std::set seasons, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) { std::map> season_map; findSeasons(season_map, path, seasons); multipleSeasons(path, show, season_map, language, pattern, linux, trust, c); } void allSeasons( const std::string &path, const std::string &show, const std::string &language, const std::string &pattern, const bool &linux, const bool &trust, Curl &c) { std::map> seasons; //get all season number from this directory and subdirectories iterateFS(seasons, path); multipleSeasons( path, show, seasons, language, pattern, linux, trust, c); }