#include "programManager.h" ProgramManager::ProgramManager() { } ProgramManager::~ProgramManager() { } int ProgramManager::start(Settings *settings) { pageManager.setProxy(settings->proxy_ip, settings->proxy_port); pageManager.setCookieFilePath(settings->cookieFilePath); pageManager.setDebugMode(settings->debugMode); switch (settings->modus) { case Modus::DEFAULT_MODUS: return defaultModus(settings); case Modus::DIRECT_LINK_MODUS: return directLinkModus(settings); case Modus::Search_MODUS: return searchModus(settings); default: return -1; } } int ProgramManager::defaultModus(Settings *settings) { AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath); //Wenn kein Name mit -n Angegeben wurde: if(settings->name == "") { if(settings->default_checkDirPath != "") { if(settings->default_checkDirPath[settings->default_checkDirPath.length()-1] == settings->pathSymbol) settings->default_checkDirPath.pop_back(); size_t pos = settings->default_checkDirPath.find_last_of(std::string(1, settings->pathSymbol)); if( pos != std::string::npos) { settings->name = settings->default_checkDirPath.substr(pos + 1); if(settings->debugMode) std::cout << " > Use Path for Name: " << settings->default_checkDirPath << " -> " << settings->name << std::endl; } } if(settings->name == "") { std::cout << " => Error: Kein Name angegeben." << std::endl; std::cout << "Aufruf: " << getProgramName(settings->argv0.c_str()) << " default [PARAMETER]" << std::endl; std::cout << "„" << getProgramName(settings->argv0.c_str()) << " default --help“ liefert weitere Informationen." << std::endl; return 27; } } //Überprüfe ob ein Muster existiert: if(settings->default_Searchmuster == "") { std::cout << " => Error: [-m]: Kein Muster angegeben." << std::endl; return 31; } //Liste alle Dateien in dem Ornder von -C auf und speichere diese std::string dirFiles; if(settings->default_checkDirPath != "") if(listDir(dirFiles, settings->default_checkDirPath, settings->default_maxDirs ) != 0) return 28; //Entferne von der liste das \n am ende if(dirFiles.length() > 0) dirFiles.pop_back(); //Wenn Debug Mode, gib die Liste aus if(settings->debugMode && settings->default_checkDirPath != "") std::cout << " > [-C] Files:\n" << dirFiles << std::endl; //Führe Function aus, die überprüft ob die serie existiert std::string nameInUrl =pageManager.checkName(settings->name); if(nameInUrl == "-1") { //Wenn nicht, dann fühe noch eine Suche nach ähnlichen durch. searchModus(settings); return 25; } //Sonst melde sich bei s.to an und speicher cookies. else if (pageManager.login(accountManager.getNextAccount()) != 0) return 29; pageManager.writeToFile(settings->outputFilePath, "Name: " + settings->name); //Finde die anzahl der staffel heraus: //download html von der startpage einer serie Reply tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl); if(tmp_reply.html == "-1") return 32; //speicher zahl -1, ab da wo /staffel-x nicht mehr vorkommt int maxStaffel = pageManager.counterContains(tmp_reply.html, "/staffel-%i"); if(settings->debugMode) std::cout << " > Die Serie " << settings->name << " hat " << maxStaffel << " Staffeln." << std::endl; //For every season for (int staffel = settings->startSeason; staffel <= maxStaffel; ++staffel) { //Find out number of all episodes tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel)); if(tmp_reply.html == "-1") return 40; int maxFolge = pageManager.counterContains(tmp_reply.html, "/episode-%i"); if(settings->debugMode) std::cout << " > Die Staffel " << staffel << " hat " << maxFolge << " Folgen." << std::endl; //for every episode for (int folge = settings->startEpisode; folge <= maxFolge; ++folge) { //Überprüfe ob, wenn -C vorhanden, die Folge in dem Ordner bereits vorkommt. if(settings->default_checkDirPath != "") { if(dirFiles.find(pageManager.replace( pageManager.replace( settings->default_Searchmuster, "%Staffel%", ((staffel < 10) ? "0" : "") + std::to_string(staffel) ), "%Folge%", ((folge < 10) ? "0" : "") + std::to_string(folge) ) ) != std::string::npos) { if(settings->debugMode) std::cout << " > Skippe Folge: S" << staffel << "E" << folge << std::endl; continue; } } tmp_reply =pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel) + "/episode-" + std::to_string(folge)); if(tmp_reply.html == "-1") return 47; std::string allLinks = pageManager.getLinks(tmp_reply.html); std::string Link = pageManager.chooseHosterLink(allLinks, settings->genaueHoster, settings->languages); if(settings->debugMode) std::cout << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://s.to") << Link << ( (Link == "") ? "" : "'\n" ); if(convertLink(Link, &accountManager, settings, staffel, folge, allLinks) != 0) return 51; if(folge == settings->stopEpisode && settings->stopSeason < 1) // stoppe wenn stopfolge gleich der folge ist und stopstaffel nicht gesetzt wurde. return 0; else if ( folge == settings->stopEpisode && staffel == settings->stopSeason) // stoppe wenn stopfolge = folge && stopstaffel == staffel return 0; } //Setzte Startepisode zurück für nächste Staffel settings->startEpisode = 1; if(staffel == settings->stopSeason) { if(settings->debugMode) std::cout << " > Stoppe, weil Staffel: " << staffel << " == StopStaffel " << settings->stopSeason << std::endl; break; } } std::cout << " > Fertig" << std::endl; return 0; } int ProgramManager::directLinkModus(Settings *settings) { AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath); if(settings->name == "") { std::cout << " => Error: Kein(e) Link(s) angegeben." << std::endl; std::cout << "Aufruf: " << getProgramName(settings->argv0.c_str()) << " url [PARAMETER]" << std::endl; std::cout << "„" << getProgramName(settings->argv0.c_str()) << " url --help“ liefert weitere Informationen." << std::endl; return 76; } std::istringstream iStrStream( pageManager.replace( settings->name, ",", "\n" ) + "\n" ); std::string line; if(pageManager.login(accountManager.getNextAccount()) != 0) return 71; while (getline(iStrStream, line).good()) { if(line.find("https://s.to/redirect/") == std::string::npos) { std::cout << " => Error: Invalid Redirect Link: '" << line << "'" << std::endl; continue; } else if(convertLink(pageManager.replace(line, "https://s.to", ""), &accountManager, settings) != 0) return 78; } return 0; } int ProgramManager::searchModus(Settings *settings) { if(settings->search_wantUpdate) { int res = searchModus_update(settings) ; if( res == 0) std::cout << "Erfolgreich geupdatet: Die Serienliste ist nun auf dem neusten Stand." << std::endl; else std::cout << "Error: Das updaten der Serienliste ist fehlgeschlagen." << std::endl; return res; } else if(settings->name == "") { std::cout << " => Error: Kein Name angegeben." << std::endl; std::cout << "Aufruf: " << getProgramName(settings->argv0.c_str()) << " search [PARAMETER]" << std::endl; std::cout << "„" << getProgramName(settings->argv0.c_str()) << " search --help“ liefert weitere Informationen." << std::endl; return 27; } std::ifstream ifs(settings->serienListPath); if(!ifs.is_open()) { std::cout << "Keine SerienListe vorhanden. Erstelle eine neue..." << std::endl; if(searchModus_update(settings) != 0) return 354; else { ifs.open(settings->serienListPath); if(!ifs.is_open()) { perror(" => Error: Couldn't open SerienList file after update again."); return 434; } std::cout << "Erfolgreich gedownloadet." << std::endl; } } //Save file in string: std::string serienListe((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); //Suche alle Möglichkeiten std::string finds = pageManager.grep(serienListe, settings->name, settings->search_IgnoreUpperLower); serienListe.clear(); // Speicher freigeben //Text mit Farben versehen if(!settings->colorless) { for (size_t pos = pageManager.upper_string( finds ).find( pageManager.upper_string( settings->name ), 0); pos != std::string::npos; pos = pageManager.upper_string( finds ).find( pageManager.upper_string( settings->name ), pos + settings->name.length() + strlen("\033[37m\033[0m"))) finds.insert(pos, ( (finds.find(settings->name, pos) == pos) ? "\033[32m" : "\033[36m" ) ).insert(pos + settings->name.length() + strlen("\033[37m"), "\033[0m"); } //Ausgabe if(finds == "") { std::cout << " => Für '" << settings->name << "' wurde(n) keine Serie(n) gefunden." << std::endl; return 0; } std::stringstream strstream(finds); std::string line; std::cout << " => Für '" << settings->name << "' wurde(n) folgende Serie(n) gefunden: " << std::endl; while (getline(strstream, line)) { std::cout << " > " << line.substr(line.find("|", line.find("/")) + 1, line.length() - line.find("|", line.find("/")) -1 ) << "\t[" << line.substr(line.find("/") + 1, line.find("|", line.find("/")) - line.find("/") - 1) << "]" << ( (line[0] == '|') ? "" : "\t( " + line.substr(0, line.find("|")) + " )" ) << std::endl; } return 0; } int ProgramManager::searchModus_update(Settings *settings) { Reply reply = pageManager.getServerRequest("https://s.to/serien"); if(reply.html == "-1") return 21; else if(reply.html.find("") == std::string::npos ) { std::cout << " => Error: Konnte in searchModus_update() nicht finden." << std::endl; return 22; } std::string serienListe = pageManager.replace( pageManager.grep( reply.html, "data-alternative-title" ), "", "\n" ); if(reply.html.find("\" href=\"") == std::string::npos || reply.html.find("
  • ") == std::string::npos) return 51; //...\n
  • 2012 - Das Jahr Null\n... serienListe = pageManager.replace(serienListe, "
  • 2012 - Das Jahr Null\n... serienListe = pageManager.replace(serienListe, "\" href=\"", "|"); //...\n|/serie/stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null\n... serienListe = pageManager.replace(serienListe, "|/serie/stream/", "|/"); std::stringstream strstream(serienListe); std::string line; serienListe.clear(); while (getline(strstream, line)) { if(line.find(" title=\"") == std::string::npos) continue; line.erase(line.find(" title="), line.find(">") - line.find(" title=")); //...\n|/serie/stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null\n... line = pageManager.replace(line, "\">", "|"); //...\n|/serie/stream/2012-das-jahr-null|2012 - Das Jahr Null\n... line = pageManager.replace(line, "", ""); //...\n|/serie/stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null|\n... serienListe += line + "\n"; } if(serienListe.length() > 0) serienListe.pop_back(); //Anzahl der Serien/Zeilen vorher: ssize_t countBef = 0; std::ifstream myFileBef(settings->serienListPath); if(myFileBef.is_open()) for(countBef = 0; std::getline(myFileBef,line); countBef++); myFileBef.close(); //Schreibe die Liste in das TextFile std::ofstream ofs(settings->serienListPath, std::ios::trunc); if(!ofs.is_open()) { perror("Konnte SerienListe-Datei nicht öffnen"); return 111; } ofs << serienListe << std::endl; ofs.close(); //Anzahl der Zeile nachher ssize_t countAf = 0; std::ifstream myFileAf(settings->serienListPath); if(myFileAf.is_open()) for(countAf = 0; std::getline(myFileAf,line); countAf++); myFileAf.close(); std::cout << "Serienunterschied: " << ( ((countAf - countBef) > 0) ? "+" : "") << countAf - countBef << " Serien." << std::endl; return 0; } int ProgramManager::listDir(std::string &list,std::string path, int maxDepth) { if(maxDepth == 0) return 0; else if(!dirExists(path)) { std::cout << " => Error: Verzeichnis '" << path << "' existiert nicht oder ist kein Ordner." << std::endl; return -1; } else maxDepth--; if(path[path.length()-1] != '/') path.push_back('/'); DIR* dirp = opendir(path.c_str()); if(!dirp) { perror(std::string(" => Error: Konnte Verzeichnis nicht öffnen: " + path).c_str()); return -1; } struct dirent * dp; while ((dp = readdir(dirp)) != nullptr) { if(strcmp( dp->d_name, "." ) == 0 || strcmp ( dp->d_name, ".." ) == 0) continue; else if(dirExists((path + dp->d_name + "/"))) { //if(dp->d_type == DT_DIR) { listDir(list, (path + dp->d_name + "/"), maxDepth); } else list.append( std::string(dp->d_name) + "\n" ); } closedir(dirp); return 0; } int ProgramManager::convertLink(std::string redirectLink, AccountManager * accountManager, Settings * settings, int Staffel, int Folge, std::string allLinks) { std::string folgenID = std::string((Staffel == -1 || Folge == -1 ) ? "" : "S" + std::string( (Staffel < 10) ? "0" : "" ) + std::to_string(Staffel) + "E" + std::string( (Folge < 10) ? "0" : "" ) + std::to_string( Folge ) ); std::string green = ((settings->colorless) ? "" : "\033[32m"), red = ((settings->colorless) ? "" : "\033[31m"), orange =((settings->colorless) ? "" : "\033[33m"), blue = ((settings->colorless) ? "" : "\033[34m"); if(redirectLink == "" && settings->modus == Modus::DEFAULT_MODUS) { if(allLinks == "") { std::cout << " => " << red << "KEINEN Hoster für die Folge " << folgenID << " gefunden." << "\033[0m" << std::endl; if(pageManager.writeToFile(settings->outputFilePath, std::string("KEINEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0) return 130; } else { std::cout << " => " << orange << "Keinen PASSENDEN Hoster für die Folge " << folgenID << " gefunden." << "\033[0m" << std::endl << "Alle Links:" << std::endl << pageManager.replace( pageManager.replace( pageManager.replace( allLinks, "data-lang-key=\"1\"", "language=\"GerDub\"" ), "data-lang-key=\"2\"", "language=\"Eng\"" ), "data-lang-key=\"3\"", "language=\"GerSub\"") << std::endl; if(pageManager.writeToFile(settings->outputFilePath, std::string("Keinen PASSENDEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0) return 138; } return 0; } for (int i = 1; i <= 3; ++i) { std::string newUrl = pageManager.getUrlAfterRedirect("https://s.to" + redirectLink); if (newUrl == "-1") { return 102; } else if(newUrl.find("/s.to/redirect/") != std::string::npos ) { if(settings->debugMode) std::cout << "Warnung: Redirect Link nach umwandlung (Capcha?) --> Neuer Account" << std::endl; if(pageManager.login(accountManager->getNextAccount()) != 0) return -1; continue; } else { std::cout << " => " << folgenID << ( (folgenID == "") ? "" : ": " ) << green << newUrl << "\033[0m" << std::endl; if(settings->outputFilePath != "") if(pageManager.writeToFile(settings->outputFilePath,folgenID + ( (folgenID == "") ? "" : ": " ) + newUrl) != 0) return 108; return 0; } } std::cout << " => " << folgenID << ( (folgenID == "") ? "" : ": " ) << red << "https://s.to" << redirectLink << "\033[0m" << std::endl; if(settings->outputFilePath != "") if(pageManager.writeToFile(settings->outputFilePath, folgenID + ( (folgenID == "") ? "" : ": " ) + redirectLink) != 0) return 114; return 0; }