diff --git a/src/accountManager.cpp b/src/accountManager.cpp index 3d36858..8380472 100644 --- a/src/accountManager.cpp +++ b/src/accountManager.cpp @@ -1,13 +1,14 @@ #include "accountManager.h" -AccountManager::AccountManager(std::string pathToFile, std::string pathToAccountNumberFile) - : pathToAccountNumberFile(pathToAccountNumberFile) +AccountManager::AccountManager(std::string pathToFil, std::string pathToAccountNumberFile, PAGE page) + : pathToAccountNumberFile(pathToAccountNumberFile + "_" + page.name_id), pageInUse(page) { - std::ifstream ifs(pathToFile); + std::string pathToAccountsFile = pathToFil + "_" + page.name_id; + std::ifstream ifs(pathToAccountsFile); if(!ifs.is_open()) { - if(writeDefault(pathToFile) != 0) + if(writeDefault(pathToAccountsFile) != 0) exit(12); - ifs.open(pathToFile); + ifs.open(pathToAccountsFile); if(!ifs.is_open()) { std::cout << " => Error: Konnte Account File nicht öffnen" << std::endl; exit(13); @@ -66,98 +67,113 @@ int AccountManager::writeDefault(std::string path) std::cout << " => Erstelle Datei mit Accounts unter: " << path << "..." < WARNUNG: Keine standart Accounts für die Url '" << pageInUse.url << "' vorhanden." < #include + + +#include "parameterManager.h" + + + struct Account { std::string Email, Password; @@ -14,13 +20,14 @@ struct Account { class AccountManager { public: - AccountManager(std::string pathToFile, std::string pathToAccountNumberFile); + AccountManager(std::string pathToFile, std::string pathToAccountNumberFile, PAGE page); Account getNextAccount(); size_t getLastAccountNumber(); private: std::vector accounts; std::string pathToAccountNumberFile; + PAGE pageInUse; int setLastAccountNumber(size_t number); int writeDefault(std::string path); diff --git a/src/pageManager.cpp b/src/pageManager.cpp index 214afb6..335303e 100644 --- a/src/pageManager.cpp +++ b/src/pageManager.cpp @@ -1,14 +1,18 @@ #include "pageManager.h" -PageManager::PageManager(std::string sock5ProxyOnlyAddress, std::string cookieFilePath) - : sock5Proxy("socks5://" + sock5ProxyOnlyAddress), cookieFilePath(cookieFilePath) +PageManager::PageManager(std::string sock5ProxyOnlyAddress) + : sock5Proxy("socks5://" + sock5ProxyOnlyAddress) { curl_global_init(CURL_GLOBAL_ALL); + if(false) + std::cout << "PageManager()" << std::endl; } PageManager::~PageManager() { curl_global_cleanup(); + if(false) + std::cout << "~PageManager()" << std::endl; } void PageManager::setProxy(std::string ip, int port) @@ -24,10 +28,7 @@ void PageManager::setProxy(std::string ip, int port) } } -void PageManager::setCookieFilePath(std::string path) -{ - this->cookieFilePath = path; -} + void PageManager::setDebugMode(bool status) { @@ -64,8 +65,8 @@ void PageManager::get_terminal_size(int& width) { #if defined(_WIN32) CONSOLE_SCREEN_BUFFER_INFO csbi; if( GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi) == 0 ) { - if ( debugMode ) - std::cout << " => WARNING: GetConsoleScreenBufferInfo failed => Use 9999 as max Msg-Length" << std::endl; + //if ( debugMode ) + //std::cout << " => WARNING: GetConsoleScreenBufferInfo failed => Use 9999 as max Msg-Length" << std::endl; return; } @@ -77,7 +78,7 @@ void PageManager::get_terminal_size(int& width) { #endif // Windows/Linux } -Reply PageManager::getServerRequest(std::string Url, bool useCookies, std::string data, bool generateCookieFile, bool UrlAfterRedirectOnlyNeeded) +Reply PageManager::getServerRequest(std::string Url, bool useCookies, std::string data, bool generateCookieFile, bool UrlAfterRedirectOnlyNeeded, std::string cookieFilePath) { CURL *curl; CURLcode res; @@ -258,12 +259,12 @@ int PageManager::downLoadToFile(std::string filePath, std::string url) return (failed) ? 10 : 0; } -int PageManager::login(Account account) +int PageManager::login(PAGE page, Account account) { if(debugMode) std::cout << " > Melde mit neuem Account an: Email: " << account.Email << " Passowort: " << account.Password << std::endl; - auto reply = getServerRequest("https://serienstream.sx/login", false, std::string("email=" + account.Email + "&password=" + account.Password), true ); + auto reply = getServerRequest("https://" + page.url + "/login", false, std::string("email=" + account.Email + "&password=" + account.Password), true ); std::string html = reply.html; if(html == "" ) @@ -285,29 +286,66 @@ int PageManager::login(Account account) return -1; } -std::string PageManager::getUrlAfterRedirect(std::string Url) +Reply PageManager::getUrlAfterRedirect(std::string Url, std::string cookieFilePath) { - return getServerRequest(Url, true, "", false, true).url; + return getServerRequest(Url, true, "", false, true, cookieFilePath); } -std::string PageManager::checkName(std::string Name) +checkNameRply PageManager::checkName(std::vector pages, std::string Name, bool useFirstPage) { - std::string name = replace(Name, " ", "-"); + if(pages.size() < 1) { + std::cout << " => Error Keine Internet Seiten vorhanden." << std::endl; + return checkNameRply("", PAGE(), checkNameRply::FAILED); + } - std::string html = getServerRequest("https://serienstream.sx/serie/stream/" + name).html; - if(html.find("Die gewünschte Serie wurde nicht gefunden oder ist im Moment deaktiviert.") != std::string::npos) { - std::cout << "\33[2K\r => Die gewünschte Serie wurde nicht gefunden oder ist im Moment deaktiviert: '" << Name << "'" << std::endl; - return "-1"; - } else if (html.find("404 - Seite nicht gefunden") != std::string::npos) { - std::cout << "\33[2K\r => Ungültiger Name: '" << Name << "'" << std::endl; - return "-1"; - } else if (html == "-1" || html == "") { - return "-2"; + //überprüfe, auf welchen seite die serie existiert, wenn parameter + //für automatisch erste Seite aktiv ist, dann wähl aus, sonst manuel auswahl + + int count = 0; + std::string name = replace(Name, " ", "-"); + std::string pagesonExist; + PAGE Page; + + //für jede Seite + for ( const auto &p : pages ) { + + std::string html = getServerRequest("https://" + p.url + p.UrlDir + name).html; + if(html.find("Die gewünschte Serie wurde nicht gefunden oder ist im Moment deaktiviert.") != std::string::npos) { + continue; + + } else if (html.find("404 - Seite nicht gefunden") != std::string::npos) { + std::cout << "\33[2K\r => Ungültiger Name: '" << Name << "'" << std::endl; + return checkNameRply("", PAGE(), checkNameRply::NOTHING_FOUND); + + } else if (html == "-1" || html == "") { + return checkNameRply("", PAGE(), checkNameRply::FAILED); + + } + else { + count ++; + pagesonExist += p.url + " "; + Page = p; + + if(useFirstPage) { + if(debugMode) + std::cerr << "Nimm gleiche diese Seite, da useFirstPage auf true ist" << std::endl; + break; // nimm gleich das erste + } + } } - else { + + // + if( count == 1 ) { std::cout << "\33[2K\r > Name: " << name << std::endl; - return name; + return checkNameRply(name, Page, checkNameRply::SUCCESS);; + } else if ( count > 1) { + std::cout << "\33[2K\r => Die Serie existiert auf mehreren Seiten " << name << ": '" << pagesonExist << "'" << std::endl; + return checkNameRply("", PAGE(), checkNameRply::NOTHING_FOUND); //MULTIPLE OPTIONS FOUND!!!! + } else { + std::cout << "\33[2K\r => Die gewünschte Serie wurde nicht gefunden oder ist im Moment deaktiviert: '" << Name << "'" << std::endl; + return checkNameRply("", PAGE(), checkNameRply::NOTHING_FOUND); } + } std::string PageManager::getLinks(std::string HTML) @@ -507,7 +545,7 @@ int PageManager::writeToFile(std::vector paths, std::string text) if(paths.size() == 0) return 0; std::ofstream of; - for(auto path : paths) { + for(const auto &path : paths) { of.open(path, std::ios::out | std::ios::app); if(!of.is_open()) { perror((" => Error: Konnte Output: '" + path + "' Datei nicht öffnen").c_str()); diff --git a/src/pageManager.h b/src/pageManager.h index b8777b0..0673ad2 100644 --- a/src/pageManager.h +++ b/src/pageManager.h @@ -1,10 +1,15 @@ #ifndef MANAGEPAGE_H #define MANAGEPAGE_H + #include "accountManager.h" #include "curl/curl.h" #include "parameterManager.h" // for isNumber +#ifdef _WIN32 +#include +#endif + #include #include // sleep #include @@ -19,25 +24,33 @@ struct Reply { std::string html, url; }; +struct checkNameRply { + std::string name; + PAGE pageInUse; + enum STATUS { SUCCESS, FAILED, NOTHING_FOUND } status; + + checkNameRply(const std::string &name, const PAGE &p, const checkNameRply::STATUS &s ) + : name(name), pageInUse(p), status(s) {} +}; + class PageManager { public: - PageManager(std::string sock5ProxyOnlyAddress = "127.0.0.1:9150", std::string cookieFilePath = "/tmp/S_New4_cookies"); + PageManager(std::string sock5ProxyOnlyAddress = "127.0.0.1:9150"); ~PageManager(); void setProxy(std::string ip, int port); - void setCookieFilePath(std::string path); void setDebugMode(bool status); void get_terminal_size(int& width); - Reply getServerRequest(std::string Url, bool useCookies = false, std::string data = "", bool generateCookieFile = false, bool UrlAfterRedirectOnlyNeeded = false); + Reply getServerRequest(std::string Url, bool useCookies = false, std::string data = "", bool generateCookieFile = false, bool UrlAfterRedirectOnlyNeeded = false, std::string cookieFilePath = ""); int downLoadToFile(std::string filePath, std::string url); - int login(Account account); - std::string getUrlAfterRedirect(std::string Url); - std::string checkName(std::string Name); + int login(PAGE page, Account account); + Reply getUrlAfterRedirect(std::string Url, std::string cookieFilePath); + checkNameRply checkName(std::vector pages, std::string Name, bool useFirstPage); std::string getLinks(std::string HTML); std::string chooseHosterLink(std::string HosterList, std::string Hoster_with_Highst_Priority_at_First, std::string languages_with_highst_priority_at_first, bool withWarnMsg); std::string getLinkAfterHosterBasedOperation(std::string url); @@ -52,10 +65,8 @@ public: int writeToFile(std::vector paths, std::string text); - const std::string UrlPraefix = "https://serienstream.sx/serie/stream/"; std::string sock5Proxy; private: - std::string cookieFilePath; bool debugMode = false; }; diff --git a/src/parameterManager.cpp b/src/parameterManager.cpp index 1a066ff..95c4d54 100644 --- a/src/parameterManager.cpp +++ b/src/parameterManager.cpp @@ -192,13 +192,22 @@ int loadDefaulOptions(Settings &settings) ofs << "#OutputFile=/tmp/b" << std::endl; ofs << "# -> Log-to-LogFile: Speichere Ausgabe im LogFile - LogFile u.a. beim" << std::endl; ofs << "# JD2-Renamer Skript nötig. Auch anderer Pfad möglich." << std::endl; - ofs << "OutputFile=" << settings.logFilePath<< std::endl << std::endl; + ofs << "OutputFile=" << settings.logFilePath << std::endl << std::endl; + ofs << "# -> Standart Wert für Parameter: -i, --internet-pages:" << std::endl; + ofs << "# -> Internetseiten, auf denen die die Serie gesucht wird. " << std::endl; + ofs << "# (anicloud.ion/serienstream.sx) - Der Priorität nach angeben!" << std::endl; + ofs << "Internetseiten=anicloud.io,serienstream.sx" << std::endl << std::endl; + + ofs << "# -> Standart Wert für Parameter: -f, --use-first:" << std::endl; + ofs << "# -> Benutze sofort die erste Seite, wenn die Serie dort existiert." << std::endl; + ofs << "# Wenn deaktiviert, manuelle auswahl der Seiten nötig!" << std::endl; + ofs << "#UseFirstPage=false" << std::endl << std::endl; ofs << "#" << std::endl << "# -> Einstellungen für default Modus:" << std::endl << "#" << std::endl << std::endl; ofs << "# -> Standart Wert für Parameter: -g, --genaue-hoster:" << std::endl; - ofs << "default_GenaueHoster=UpStream,Vidoza,Vivo,GoUnlimited" << std::endl << std::endl; + ofs << "default_GenaueHoster=UpStream,Vidoza,GoUnlimited" << std::endl << std::endl; ofs << "# -> Standart Wert für Parameter: -l, --languages:" << std::endl; ofs << "#default_Sprachen=GerDub,GerSub,Eng" << std::endl << std::endl; @@ -341,6 +350,22 @@ int loadDefaulOptions(Settings &settings) if(settings.debugMode) std::cout << " > Defaults: search_UpdateWarnungNachTagen: " << settings.updateWarningDays << std::endl; + } else if (what == "Internetseiten") { + if(setUpInternetPages(settings, data) != 0) + return 1233; + + } else if (what == "UseFirstPage") { + if(data == "true") + settings.useFirstPage=true; + else if (data == "false") + settings.useFirstPage=false; + else { + std::cout << " => Error_Defaults: sUseFirstPage: Ungültiger Wert für 'true/false': " << data << std::endl; + return 245; + } + if(settings.debugMode) + std::cout << " > Defaults: UseFirstPage: " << settings.useFirstPage << std::endl; + } else if (what == "test") { //test @@ -360,7 +385,7 @@ int unterOption_help(Settings &settings) << " -> Mit diesem Programm kann man die Download-Urls" << std::endl << " oder Informationen von Serien bekommen." << std::endl << " -> Mit diesem Programm kann man Redirect-Links von" << std::endl - << " serienstream.sx umwandeln." << std::endl + << " serienstream.sx und anicloud.io umwandeln." << std::endl << std::endl; std::cout << "Unteroptionen:" << std::endl @@ -376,7 +401,7 @@ int unterOption_help(Settings &settings) << "\t\"search\"\tModus um Serien zu suchen." << std::endl << "\t\"info\"\t\tModus um Infos einer Serien zu bekommen." << std::endl << "\t\"clean\"\t\tModus um Cookie-Files zu löschen." << std::endl - << "\t\"news\"\t\tModus um neusten 75 Folgen auf serienstream.sx zu sehen." << std::endl + << "\t\"news\"\t\tModus um neusten 75 Folgen zu sehen." << std::endl << "\t\"log\"\t\tModus um Log Datei zu sehen / leeren." << std::endl << std::endl; @@ -413,16 +438,19 @@ int unterOption_default(Settings *settings, int argc, char ** argv) {"check-max-dirs", required_argument, nullptr, 'D'}, {"threads", required_argument, nullptr, 't'}, + {"internet-pages", required_argument, nullptr, 'i'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, + {"use-first-page", no_argument, nullptr, 'f'}, {nullptr, no_argument, nullptr, 0} }; - while( ( c = getopt_long (argc, argv, "p:g:l:o:e:E:s:S:C:m:D:t:hcd", long_opts, nullptr) ) != -1 ) { + + while( ( c = getopt_long (argc, argv, "p:g:l:o:e:E:s:S:C:m:D:t:i:fhcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0) @@ -528,6 +556,18 @@ int unterOption_default(Settings *settings, int argc, char ** argv) break; + case 'i': + if(!optarg) + break; + if(setUpInternetPages(*settings, optarg) != 0) + return 4356; + + break; + case 'f': + settings->useFirstPage = true; + if(settings->debugMode) + std::cout << "useFirstPage: " << settings->useFirstPage << std::endl; + break; case 'C': if(!optarg) break; @@ -585,7 +625,23 @@ void unterOption_default_help(std::string programName) std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man die Downloadlinks von Serien bekommen." << std::endl << std::endl; - std::cout << "HOSTEROPTIONEN:" << std::endl + + std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl + << " -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl + << " Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl + << " nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl + << " Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl + << " Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl + << " Standart: anicloud.io,serienstream.sx" << std::endl + << " -f, --use-first-page" << std::endl + << " Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl + << " auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl + << " Priorität nach; siehe -i, --internet-pages)" << std::endl + << " Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl + << " wenn diese Serie auf mehreren Seiten existiert!" << std::endl + << " Parameter kann auch im Default File als standart festgelegt werden!" << std::endl + << " Standart: Überprüfe alle Seiten" << std::endl << std::endl + << "HOSTER OPTIONEN:" << std::endl << " -g [Hoster1,Hoster2,...], --genaue-hoster [Hoster1,Hoster2,...]" << std::endl << " Mit dieser Option kann man die Hoster angeben, von denen" << std::endl << " man die Downloadlinks will. Die Auswahl der Hoster geht" << std::endl @@ -600,7 +656,7 @@ void unterOption_default_help(std::string programName) << " denen man die Downloadlinks will. Die Beste als erstes" << std::endl << " die 2t-Beste als 2tes,..." << std::endl << " Standart: GerDub,GerSub,Eng" << std::endl << std::endl - << "DURCHLAUFOPTIONEN:" << std::endl + << "DURCHLAUF OPTIONEN:" << std::endl << " -e [Folge], --start-episode [Folge]" << std::endl << " Mit dieser Option kann man festlegen, mit welcher Folge" << std::endl << " das Programm startet." << std::endl << std::endl @@ -629,7 +685,7 @@ void unterOption_default_help(std::string programName) << " -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl << " Mit dieser Option kann man den Socks5Proxy ändern." << std::endl << " Standart: 127.0.0.1:9050 - Port 0 um Proxy zu deaktivieren." << std::endl << std::endl - << "AUSGABEOPTIONEN:" << std::endl + << "AUSGABE OPTIONEN:" << std::endl << " -o [Pfad], --output-file [Pfad]" << std::endl << " Mit diere Option kann man eine (nichtvorhandene) Text-Datei" << std::endl << " angeben, inwelche die umgewandelten Redirect-Links geschrieben" << std::endl @@ -640,7 +696,7 @@ void unterOption_default_help(std::string programName) << " -d, --debug-mode" << std::endl << " Mit dieser Option kann man den Debug-Modus einschalten." << std::endl << " Dabei werden vielmehr Infos ausgegeben." << std::endl << std::endl - << "SELEKTOROPTIONEN:" << std::endl + << "SELEKTOR OPTIONEN:" << std::endl << " -C [PfadZuOrdner], --check [PfadZuOrdner]" << std::endl << " Mit dieser Option kann man einen Ordner festlegen, in dem" << std::endl << " und dessen Unterordnern ( Beachte -D ) das Programm erst" << std::endl @@ -691,16 +747,20 @@ int unterOption_url(Settings *settings, int argc, char **argv) const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"output-file", required_argument, nullptr, 'o'}, + {"standart-page", required_argument, nullptr, 's'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, + {"use-first-page", no_argument, nullptr, 'f'}, {nullptr, no_argument, nullptr, 0} }; - while( ( c = getopt_long (argc, argv, "p:o:hcd", long_opts, nullptr) ) != -1 ) { + + + while( ( c = getopt_long (argc, argv, "p:o:s:fhcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0) @@ -712,11 +772,35 @@ int unterOption_url(Settings *settings, int argc, char **argv) if(settings->debugMode) std::cout << "Pfad zu Output-Datei: " << settings->outputFilePaths.back() << std::endl; break; + case 'f': + settings->useFirstPage = true; + if(settings->debugMode) + std::cout << "useFirstPage: " << settings->useFirstPage << std::endl; + break; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; break; + case 's': + if(!optarg) + break; + if( std::string(optarg) == settings->sto.url || std::string(optarg) == "s.to" ) { + settings->direktLink_explizitPage = settings->sto; + if(settings->debugMode) + std::cout << " > Defaults: Standart-Page-für-direkt-link-mode: " << settings->sto.url << std::endl; + + } else if ( std::string(optarg) == settings->anicio.url ) { + settings->direktLink_explizitPage = settings->anicio; + if(settings->debugMode) + std::cout << " > Defaults: Standart-Page-für-direkt-link-mode: " << settings->anicio.url << std::endl; + + } else { + std::cout << " Error_Defaults: Standart-Page-für-direkt-link-mode : Unbekannte Seite: " << optarg << std::endl; + return 2154; + } + + break; case 'd': settings->debugMode = true; if(settings->debugMode) @@ -762,7 +846,20 @@ void unterOption_url_help(std::string programName) << " Der Link kann folgen Aussehen: {[*]serienstream.sx}/redirect/[*]." << std::endl << " Standartwerte können im Defaultfile geändert werden." << std::endl << std::endl; - std::cout << "OPTIONEN:" << std::endl + std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl + << " -f, --use-first-page" << std::endl + << " Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl + << " auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl + << " Priorität nach; siehe -i, --internet-pages)" << std::endl + << " Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl + << " wenn diese Serie auf mehreren Seiten existiert!" << std::endl + << " Parameter kann auch im Default File als standart festgelegt werden!" << std::endl + << " Standart: Überprüfe alle Seiten" << std::endl + << " -s [url], --standart-page [url]" << std::endl + << " Mit dieser Option kann man festlegen, welche Seite für unvollständige" << std::endl + << " Redirect Links ( z.B. /redirect/xyz ) verwendet werden soll." << std::endl + << " Default: deaktiviert" << std::endl << std::endl; + std::cout << "OPTIONEN:" << std::endl << " -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl << " Mit dieser Option kann man den Socks5Proxy ändern." << std::endl << " Standart: 127.0.0.1:9050 - Port 0 um Proxy zu deaktivieren." << std::endl << std::endl @@ -786,6 +883,7 @@ int unterOption_search(Settings *settings, int argc, char **argv) int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, + {"internet-pages", required_argument, nullptr, 'i'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, @@ -798,12 +896,19 @@ int unterOption_search(Settings *settings, int argc, char **argv) }; - while( ( c = getopt_long (argc, argv, "p:hcdeul", long_opts, nullptr) ) != -1 ) { + + while( ( c = getopt_long (argc, argv, "p:i:hcdeul", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; + case 'i': + if(!optarg) + break; + if(setUpInternetPages(*settings, optarg) != 0) + return 4356; + break; case 'h': unterOption_search_help(settings->programName); return -1; @@ -862,6 +967,7 @@ void unterOption_search_help(std::string programName) << " " << programName << " search [OPTION]... [{-u, --update}&|/{-l, --last-update}]" << std::endl << " " << programName << " search [OPTION]... [{-u, --update}&|/{-l, --last-update}] [Name]" << std::endl << std::endl; + std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion des Programms kann man Serien auf serienstream.sx suchen." << std::endl << " Tipp: Falls deine Serie nicht gefunden wird, entferne einen Teil" << std::endl @@ -880,6 +986,14 @@ void unterOption_search_help(std::string programName) << " nach wie vielen Tagen du an das Updaten erinert wirst." << std::endl << " Default: 10 Tage." << std::endl << std::endl; + std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl + << " -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl + << " Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl + << " nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl + << " Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl + << " Das Aktualisieren der Liste kann damit nicht beeinflusst werden." << std::endl + << " Standart: anicloud.io,serienstream.sx" << std::endl << std::endl; + std::cout << "OPTIONEN:" << std::endl << " -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl << " Mit dieser Option kann man den Socks5Proxy ändern." << std::endl @@ -907,7 +1021,9 @@ int unterOption_info(Settings *settings, int argc, char **argv) const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"output-file", required_argument, nullptr, 'o'}, + {"internet-pages", required_argument, nullptr, 'i'}, + {"use-first-page", no_argument, nullptr, 'f'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, @@ -917,7 +1033,7 @@ int unterOption_info(Settings *settings, int argc, char **argv) }; - while( ( c = getopt_long (argc, argv, "p:o:hcds", long_opts, nullptr) ) != -1 ) { + while( ( c = getopt_long (argc, argv, "p:o:i:fhcds", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0) @@ -929,6 +1045,17 @@ int unterOption_info(Settings *settings, int argc, char **argv) if(settings->debugMode) std::cout << "Pfad zu Output-Datei: " << settings->outputFilePaths.back() << std::endl; break; + case 'i': + if(!optarg) + break; + if(setUpInternetPages(*settings, optarg) != 0) + return 4356; + break; + case 'f': + settings->useFirstPage = true; + if(settings->debugMode) + std::cout << "useFirstPage: " << settings->useFirstPage << std::endl; + break; case 'h': unterOption_info_help(settings->programName); return -1; @@ -978,6 +1105,22 @@ void unterOption_info_help(std::string programName) std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man Informationen zu einer Serie bekommen." << std::endl << std::endl; + std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl + << " -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl + << " Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl + << " nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl + << " Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl + << " Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl + << " Standart: anicloud.io,serienstream.sx" << std::endl + << " -f, --use-first-page" << std::endl + << " Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl + << " auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl + << " Priorität nach; siehe -i, --internet-pages)" << std::endl + << " Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl + << " wenn diese Serie auf mehreren Seiten existiert!" << std::endl + << " Parameter kann auch im Default File als standart festgelegt werden!" << std::endl + << " Standart: Überprüfe alle Seiten" << std::endl << std::endl; + std::cout << "OPTIONEN:" << std::endl << " -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl << " Mit dieser Option kann man den Socks5Proxy ändern." << std::endl @@ -1007,6 +1150,7 @@ void unterOption_clean(Settings * settings, int argc, char **argv) return; } + //Um altes zeug zu löschen unsigned count = 0; if(fileExists(settings->cookieFilePath)) { if(remove(settings->cookieFilePath.c_str()) != 0) { @@ -1024,6 +1168,27 @@ void unterOption_clean(Settings * settings, int argc, char **argv) ++count; } } + //UM sachen nach multipage update zu löschen + for ( const auto &p : settings->pages ) { + if(fileExists(settings->cookieFilePath + "_" + p.name_id)) { + if(remove((settings->cookieFilePath + "_" + p.name_id).c_str()) != 0) { + perror(( " => Error: Das löschen von " + settings->cookieFilePath + "_" + p.name_id + " ist fehlgeschlagen: ").c_str()); + return; + } else + ++count; + } + + for (unsigned i = 0; i < UINT_MAX && fileExists(settings->cookieFilePath + "_" + p.name_id + std::to_string(i)); ++i) { + if(remove( (settings->cookieFilePath + "_" + p.name_id + std::to_string(i)).c_str() ) != 0) { + perror((" => Error: Das löschen von " + settings->cookieFilePath + "_" + p.name_id + std::to_string(i) + " ist fehlgeschlagen: ").c_str()); + return; + } else { + ++count; + } + } + } + + if(count == 0) std::cout << " => Nichts zu tun: Keine Cookies vorhanden." << std::endl; @@ -1190,7 +1355,9 @@ int unterOption_news(Settings *settings, int argc, char **argv) int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, + {"use-first-page", no_argument, nullptr, 'f'}, + {"internet-pages", required_argument, nullptr, 'i'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, @@ -1199,12 +1366,23 @@ int unterOption_news(Settings *settings, int argc, char **argv) }; - while( ( c = getopt_long (argc, argv, "p:hcd", long_opts, nullptr) ) != -1 ) { + while( ( c = getopt_long (argc, argv, "p:i:fhcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(!optarg || setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; + case 'i': + if(!optarg) + break; + if(setUpInternetPages(*settings, optarg) != 0) + return 4356; + break; + case 'f': + settings->useFirstPage = true; + if(settings->debugMode) + std::cout << "useFirstPage: " << settings->useFirstPage << std::endl; + break; case 'h': unterOption_news_help(settings->programName); return -1; @@ -1239,6 +1417,21 @@ void unterOption_news_help(std::string programName) std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man die neuesten 75 Folgen auf serienstream.sx sehen." << std::endl << std::endl; + std::cout << "INTERNETSEITEN OPTIONEN:" << std::endl + << " -i [Url1,Url2], --internet-pages [Url1,Url2]" << std::endl + << " Mit dieser Option kann man die Seiten angeben, auf denen" << std::endl + << " nach Serien gesucht werden soll. (Nur Seiten aus Default Wert möglich)" << std::endl + << " Die Seiten Kommagetrennt nach Priorität angeben. (Höchste am Anfang)" << std::endl + << " Gut Kombinierbar mit --use-first-page kombenierbar!" << std::endl + << " Standart: anicloud.io,serienstream.sx" << std::endl + << " -f, --use-first-page" << std::endl + << " Mit dieser Option kann man festlegen, dass direkt die erste Seite," << std::endl + << " auf der die Serie vorhanden ist, verwendet wird. ( Reihenfolge der" << std::endl + << " Priorität nach; siehe -i, --internet-pages)" << std::endl + << " Ohne diesem Parameter ist eine manuelle auswahl nötig," << std::endl + << " wenn diese Serie auf mehreren Seiten existiert!" << std::endl + << " Parameter kann auch im Default File als standart festgelegt werden!" << std::endl + << " Standart: Überprüfe alle Seiten" << std::endl << std::endl; std::cout << "OPTIONEN:" << std::endl << " -p [ip:port/ip/port], --socks5-proxy [ip:port/ip/port]" << std::endl << " Mit dieser Option kann man den Socks5Proxy ändern." << std::endl @@ -1324,7 +1517,7 @@ void unterOption_update_help(std::string programName) } -bool removeDirIsOk(std::string path, Settings *settings) +bool removeDirIsOk(std::string path, Settings *settings, bool askForDelete) { if(path == "") { std::cout << " => Error: Ungültiger Pfad: '" << path << "'." << std::endl; @@ -1332,10 +1525,11 @@ bool removeDirIsOk(std::string path, Settings *settings) } else if(path.back() != settings->pathSymbol ) path.push_back(settings->pathSymbol); - if(settings->askForEveryDir) { + if(askForDelete) { std::cout << "Zur Bestätigung des Löschens des Ordners: '" << path << "'," << std::endl << "geben sie 'OK' ein: " << std::flush; std::string input; + std::cin.clear(); std::getline(std::cin, input); if(input != "OK") { std::cout << "Abbruch..." << std::endl; @@ -1344,7 +1538,6 @@ bool removeDirIsOk(std::string path, Settings *settings) } - DIR* dirp = nullptr; if( (dirp = opendir( path.c_str() )) == nullptr ) { perror(std::string(" => Error: Konnte Verzeichnis nicht öffnen: '" + path + "'").c_str()); @@ -1356,7 +1549,7 @@ bool removeDirIsOk(std::string path, Settings *settings) if(strcmp( dp->d_name, "." ) == 0 || strcmp ( dp->d_name, ".." ) == 0) continue; else if(dirExists((path + dp->d_name + settings->pathSymbol ))) { //if(dp->d_type == DT_DIR) { - if( ! removeDirIsOk(path + dp->d_name + settings->pathSymbol , settings)) { + if( ! removeDirIsOk(path + dp->d_name + settings->pathSymbol , settings, false/*askForDelete*/)) { if(settings->debugMode) std::cout << " => Error im Unterordner: '" << path + dp->d_name << "'" << std::endl; return false; @@ -1578,3 +1771,36 @@ std::string replace(std::string str, std::string substr1, std::string substr2) str.replace(index, substr1.length(), substr2); return str; } + +int setUpInternetPages(Settings &settings, std::string optarg) +{ + //Lösche default + settings.pages.clear(); + + std::istringstream ss(optarg + ","); + std::string value; + + while(std::getline(ss, value, ',')) { + if(value == "") + continue; + if( value == settings.sto.url || value == "s.to" ) { + settings.pages.push_back(settings.sto); + if(settings.debugMode) + std::cout << " > : Internetseiten pusback: " << settings.sto.url << std::endl; + + } else if ( value == settings.anicio.url ) { + settings.pages.push_back(settings.anicio); + if(settings.debugMode) + std::cout << " > : Internetseiten pusback: " << settings.anicio.url << std::endl; + + } else { + std::cout << " => Error: Unbekannte Internetseiten: " << value << " - Bitte überprüfen sie ihr Default File oder ggf. Parameter -i" << std::endl; + return 2154; + } + } + if(settings.pages.size() < 1) { + std::cout << " => Keine Internetseiten angegeben! " << std::endl; + return 1236; + } + return 0; +} diff --git a/src/parameterManager.h b/src/parameterManager.h index af1cb4c..7d15d72 100644 --- a/src/parameterManager.h +++ b/src/parameterManager.h @@ -7,6 +7,7 @@ #endif #endif + #include #include #include // strlen @@ -19,17 +20,19 @@ #include // readlink() #include -#include "logger.h" -#ifdef _WIN32 -#include -#endif + +#include "logger.h" #define UpdaterCloudUrlWithPath "https://cloud.obermui.de/s/tXz7SWdaPJ7TacZ/download?path=%2F&files=" #define SecondUpdaterCloudUrlWithPath "https://snew4.obermui.de/download?path=%2F&files=" #define VERSION "4.3.7" +//default, anime, normal, +//suche: für jede katego. eine +//zu beginn, erst eiunmal serie suchen + enum Modus { EXIT = -1, @@ -44,10 +47,34 @@ enum Modus { }; +struct PAGE { + PAGE() {} + PAGE( std::string url, std::string nameID, std::string urlAphabetSerienList, std::string urlDir ) + : name_id(nameID), url(url), urlAlphabetSerienList(urlAphabetSerienList), UrlDir(urlDir) + { + + } + std::string name_id, url, urlAlphabetSerienList, UrlDir; +}; + struct Settings { - Settings() {} - Settings(std::string name) : name(name) {} + const std::string programName = "S_New4"; + PAGE sto = PAGE( "serienstream.sx", "Normale_Serien", "/serien-alphabet", "/serie/stream/"); + PAGE anicio = PAGE( "anicloud.io", "Animes", "/animes-alphabet", "/anime/stream/"); + PAGE pagesALL[2] = { sto, anicio }; + + + std::vector pages; // Priority sorted + bool useFirstPage = false; + + PAGE direktLink_explizitPage; + + + Settings() { + pages.push_back( sto ); + pages.push_back( anicio ); + } // Wenn das Betriebsystem x86 ist: #if defined (_X86_) || defined (__amd64__) || defined (_M_IX86) @@ -81,11 +108,14 @@ struct Settings { #endif #endif + + std::string name, - accountFilePath = "", - accountNumberPath= "", - cookieFilePath = "", - serienListPath = "", + accountFilePath = "", + accountNumberPath= "", + cookieFilePath = "", + serienListPath = "", + lastUpdateDateFilePath = "", configDir="", cacheDir="", @@ -96,12 +126,13 @@ struct Settings { languages = "GerDub,GerSub,Eng,", genaueHoster = "", version = VERSION, - defaultFileVersion="1.8", + defaultFileVersion="2.0", default_checkPath = "", default_Searchmuster = "S%Staffel%E%Folge%"; std::vector outputFilePaths; + Modus modus = Modus::EXIT; bool colorless = false, debugMode = false, @@ -139,7 +170,7 @@ bool nothingExists(std::string path); bool createDirIsOk(std::string path); bool makePathIsOk(std::string path); -bool removeDirIsOk(std::string path, Settings *settings); +bool removeDirIsOk(std::string path, Settings *settings, bool askForDelete); int unterOption_help(Settings &settings); void unterOption_printVersion(Settings &settings); @@ -171,7 +202,7 @@ int unterOption_printLogFile(Settings * settings, int argc, char **argv); void unterOption_printLogFile(std::string programName); int setS5ProxytoSettings(Settings &settings, std::string optarg); - +int setUpInternetPages(Settings &settings, std::string optarg); diff --git a/src/programManager.cpp b/src/programManager.cpp index b78b76d..4c9352c 100644 --- a/src/programManager.cpp +++ b/src/programManager.cpp @@ -20,7 +20,6 @@ int ProgramManager::start(Settings *settings) { pageManager.setDebugMode(settings->debugMode); pageManager.setProxy(settings->proxy_ip, settings->proxy_port); - pageManager.setCookieFilePath(settings->cookieFilePath); if(dirExists(settings->cookieFilePath)) { std::cout << " => Error: Kann Cokkie-File nicht erstellen: Es existiert bereits ein Ordner mit diesem Namen: \n '" << settings->cookieFilePath << "'." << std::endl; @@ -48,13 +47,14 @@ int ProgramManager::start(Settings *settings) } } + void * threadFunction(void * data) { ThreadData * myThreadData = reinterpret_cast(data); myThreadData->returnValue=""; myThreadData->exitState=0; - Reply tmp_reply = myThreadData->pageManager->getServerRequest(myThreadData->pageManager->UrlPraefix + myThreadData->nameInUrl + Reply tmp_reply = myThreadData->pageManager->getServerRequest( "https://" + myThreadData->page.url + myThreadData->page.UrlDir + myThreadData->nameInUrl + "/staffel-" + std::to_string(myThreadData->staffel) + "/episode-" + std::to_string(myThreadData->folge)); if(tmp_reply.html == "-1") { if(myThreadData->settings->debugMode) @@ -65,7 +65,7 @@ void * threadFunction(void * data) { std::string Link = myThreadData->pageManager->chooseHosterLink(allLinks, myThreadData->settings->genaueHoster, myThreadData->settings->languages, myThreadData->settings->debugMode); if(myThreadData->settings->debugMode) - std::cout << " > Thread " << myThreadData->id << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://serienstream.sx") << Link << ( (Link == "") ? "" : "'\n" ); + std::cout << " > Thread " << myThreadData->id << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://" + myThreadData->page.url) << Link << ( (Link == "") ? "" : "'\n" ); @@ -111,17 +111,23 @@ void * threadFunction(void * data) { } for (int i = 1; i <= 3; ++i) { - std::string newUrl = myThreadData->pageManager->getUrlAfterRedirect("https://serienstream.sx" + Link); + auto REPLy = myThreadData->pageManager->getUrlAfterRedirect("https://" + myThreadData->page.url + Link, myThreadData->settings->cookieFilePath + "_" + myThreadData->page.name_id); + std::string newUrl = REPLy.url; if (newUrl == "-1") { if(myThreadData->settings->debugMode) std::cerr << " => Debug: In Thread: "<< myThreadData->id << ": getUrlAfterRedirect Function failed: returned -1." << std::endl; return myThreadData->setState(16); // Get redirect link after getUrlAfterRedirect function - } else if(newUrl.find("/serienstream.sx/redirect/") != std::string::npos ) { + } else if (newUrl == "https://s.to" || newUrl == "https://" + myThreadData->page.url || REPLy.html.find("404 - Seite nicht gefunden") != std::string::npos || REPLy.html.find("403 Forbidden") != std::string::npos) { + if(myThreadData->settings->debugMode) + std::cerr << " => Debug: In Thread: "<< myThreadData->id << ": getUrlAfterRedirect Function failed: 404 - Seite nicht gefunden oder 403 Forbidden." << std::endl; + return myThreadData->setState(404); + + } else if(newUrl.find("/" + myThreadData->page.url + "/redirect/") != std::string::npos ) { if(myThreadData->settings->debugMode) std::cout << " > Thread " << myThreadData->id << "Warnung: Redirect Link nach umwandlung (Capcha?) --> Neuer Account" << std::endl; - if(myThreadData->pageManager->login(myThreadData->accountManager->getNextAccount()) != 0) { + if(myThreadData->pageManager->login(myThreadData->page, myThreadData->accountManager->getNextAccount()) != 0) { if(myThreadData->settings->debugMode) std::cerr << " => Debug: In Thread: "<< myThreadData->id << ": login Function failed." << std::endl; return myThreadData->setState(17); @@ -129,7 +135,7 @@ void * threadFunction(void * data) { continue; // get NO-Redirect Link after getUrlAfterRedirect Function - } else { + } else { if( (newUrl = myThreadData->pageManager->getLinkAfterHosterBasedOperation(newUrl)) == "") { if(myThreadData->settings->debugMode) std::cout << " => Error in getLinkAfterHosterBasedOperation() -> exit threadFunction()" << std::endl; @@ -151,7 +157,7 @@ void * threadFunction(void * data) { } //error at 3 time - myThreadData->returnValue = " => " + replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + red + "https://serienstream.sx" + Link + clearColor; + myThreadData->returnValue = " => " + replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + red + "https://" + myThreadData->page.url + Link + clearColor; if(myThreadData->settings->outputFilePaths.size() != 0) if(myThreadData->pageManager->writeToFile(myThreadData->settings->outputFilePaths, replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + Link) != 0) { if(myThreadData->settings->debugMode) @@ -183,9 +189,16 @@ int ProgramManager::waitForThreads() return 0; } -int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageManager, std::string &newName) +int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageManager, checkNameRply &newNameAndPage) { std::string finds; + std::string gewollteSeitenUrl; + + if(settings->pages.size() < 1) { + std::cout << " => Error Keine Internet Seiten vorhanden." << std::endl; + return 1290; + } + //Führe unterfunction zum suchen von Serien aus, aber ohne suche auszugeben und speichere datein in variable if(searchModus(settings, &finds, true) != 0) { if(settings->debugMode) @@ -207,16 +220,30 @@ int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageMana std::string line; std::cout << "\nWähle eine der folgenden Serien, oder nur [Enter] um Forgang abzubrechen." << std::endl; + std::string lastPage = ""; for (unsigned i = 1; std::getline(myStrStream, line).good() ; ++i) { if(line.find_last_of("|") == std::string::npos) { std::cout << " => Error: Invalid Line: " << line << std::endl; return -21; } - std::cout << i << ": " << line.substr(line.find_last_of("|") + 1) << ( (line[0] != '|') ? " ( " + line.substr(0, line.find("|")) + " )" : "" ) << std::endl; + + std::string pageUrl = line.substr( line.find_last_of('|') + 1); + //gib neue Internet seite aus, wenn sie noch nicht ausgegeben wurde + if( lastPage != pageUrl) { + std::cout << "\n-> Auf '" << pageUrl << "':" << std::endl; + lastPage = pageUrl; + } + line.erase(line.find_last_of('|')); + + if(line.find_last_of("|") == std::string::npos) { + std::cout << " => Error: Invalid Line: " << line << std::endl; + return -21; + } + std::cout << "[" << i << "]: " << line.substr(line.find_last_of("|") + 1) << ( (line[0] != '|') ? " ( " + line.substr(0, line.find("|")) + " )" : "" ) << std::endl; } //Lass Benutzer Zeile auswählen: - std::cout << "Zeile: " << std::flush; + std::cout << "\nNummer: " << std::flush; std::string input; std::getline(std::cin, input); @@ -239,11 +266,17 @@ int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageMana // Wenn die Zeile gleich der ausgewählten ist: } else if(static_cast(i) == atoi(input.c_str()) ) { + //entferne und speichere PageUrl; + gewollteSeitenUrl = line.substr(line.find_last_of('|') + 1); + line.erase(line.find_last_of('|')); + //Speichere den Namen der Serie und setzte hasName auf true und brich schleife ab if ( (finds = line.substr( line.find("|/") + 2, // beginn: nach dem |/ line.find("|", line.find("|/") + 2) // Bis zu dem | ab dem ende von |/ - line.find("|/") -2) ) == "" ) { // wegen nicht bi sondern länge, suptrahiere Pos 1 std::cout << " => Error: Konnte den Namen aus der zurückgegebenen Zeile nicht extrahieren. In ausWahlVariante" << std::endl; + + if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": Return value from searchModus.subStr(pos(/)-> next |, after /) is ''." << std::endl; return 48; @@ -260,6 +293,9 @@ int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageMana //Wenn nur 1 Serie gefunden wurde: } else { + //entferne und speichere PageUrl; + gewollteSeitenUrl = finds.substr(finds.find_last_of('|') + 1); + finds.erase(finds.find_last_of('|')); //Frag den User ob das die Richtige Serie ist: std::cout << " -> Ist das deine gewünschte Serie: '" @@ -287,18 +323,42 @@ int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageMana } + //suche Seite aus sucheregbnis in settings... + bool found = false; + for ( const auto & page : settings->pages ) { + if( page.name_id == gewollteSeitenUrl || page.url == gewollteSeitenUrl) { + newNameAndPage.pageInUse = page; + found = true; + } + } + if( !found ) { + std::cout << " => Error: Konnte '" << gewollteSeitenUrl << "' nicht als Valide Seite erkennen!" << std::endl; + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ":failed to search url in pagesList from setings object" << std::endl; + return 45; + } + + //Überprüfe ob es die serie gibt wenn ja speicher ihn in newname und beende Function - newName = pageManager.checkName(finds); - if(newName == "-2") + //test jetzt nicht mehr alle seiten, sondern die die ausgewählt wurde!!!!! + std::vector pages; + pages.push_back( newNameAndPage.pageInUse ); + + auto ret = pageManager.checkName( pages /*settings->pages dann glaub + ich immer fehler, wenn serie auf 2 seiten excistiert*/, + finds, settings->useFirstPage); + if(ret.status == ret.FAILED) return 23; - else if( newName == "-1" ) { + else if( ret.status == ret.NOTHING_FOUND ) { std::cout << " => Error: Konnte die von der Suche vorgeschlagene Serie nicht finden." << std::endl; if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": Extracted Name from searchModus is invalid." << std::endl; return 47; } else { + //speichere neuen Namen in übergebenen ref var + newNameAndPage.name = ret.name; if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": Use new SerienName: '" << newName << "'." << std::endl; + std::cerr << ">>> Debug In " << __FUNCTION__ << ": Use new SerienName: '" << ret.name << "'." << std::endl; return 0; } } @@ -314,10 +374,25 @@ int ProgramManager::checkLastUpdate(Settings *settings, ssize_t *days = nullptr) std::ifstream ifs(settings->lastUpdateDateFilePath); if(!ifs.is_open()) { - perror(("Konnte die Datei '" + settings->lastUpdateDateFilePath + "' nicht öffnen").c_str()); - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": Failed to open Last Update Date File:'" << settings->lastUpdateDateFilePath << "'." << std::endl; - return 1; + std::ofstream ofs2(settings->lastUpdateDateFilePath); + if(!ofs2.is_open()) { + perror(("Konnte die Datei '" + settings->lastUpdateDateFilePath + "' nicht öffnen").c_str()); + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": Failed to create Last Update Date File:'" << settings->lastUpdateDateFilePath << "'." << std::endl; + return 1; + } else { + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": Ordfolgreich LastUpdateTime Save File erstellt:'" << settings->lastUpdateDateFilePath << "'." << std::endl; + ofs2 << "0" << std::endl; + ofs2.close(); + ifs.open(settings->lastUpdateDateFilePath); + if(!ifs.is_open()) { + perror(("Konnte die Datei '" + settings->lastUpdateDateFilePath + "' nicht öffnen").c_str()); + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": Failed to open Last Update Date File:'" << settings->lastUpdateDateFilePath << "'." << std::endl; + return 4545; + } + } } std::string line; ssize_t difDays = 0; @@ -345,7 +420,6 @@ int ProgramManager::checkLastUpdate(Settings *settings, ssize_t *days = nullptr) int ProgramManager::defaultModus(Settings *settings) { - AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath); //Wenn kein Name mit -n Angegeben wurde: if(settings->name == "") { @@ -391,41 +465,49 @@ int ProgramManager::defaultModus(Settings *settings) if(dirFiles.length() > 0) //Entferne von der liste das \n am ende dirFiles.pop_back(); + + //Führe Function aus, die überprüft ob die serie existiert - std::string nameInUrl =pageManager.checkName(settings->name); - if(nameInUrl == "-2") + auto retVal = pageManager.checkName(settings->pages, settings->name, settings->useFirstPage); + + if(retVal.status == retVal.FAILED) return 67; - else if(nameInUrl == "-1") { + else if(retVal.status == retVal.NOTHING_FOUND) { //Wenn nicht, dann fühe noch eine Suche nach ähnlichen durch && Wenn nur 1ne dacnn frag ob es diese ist. int res = 0; - if( ( res = sucheNach_1_Serien(settings, pageManager, nameInUrl) ) != 0) { + if( ( res = sucheNach_1_Serien(settings, pageManager, retVal) ) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": sucheNach_1_Serien failed or found more options." << std::endl; return (res == -10101) ? 0 : 202; } } + std::string nameInUrl = retVal.name; + PAGE page = retVal.pageInUse; + AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath, page); + + /* Wenn multihtreading seaktiviert ist, normal login sonst bereite threads vor if(settings->maxThreads == 0) { - // melde bei serienstream.sx an und speicher cookies. + // melde bei seriens tream.sx an und speicher cookies. if (pageManager.login(accountManager.getNextAccount()) != 0) //---------------------------------------- return 29; }*/ if(settings->maxThreads > 0) { for (unsigned i = 0; i < settings->maxThreads; ++i) { - if(dirExists(settings->cookieFilePath + std::to_string( i ))) { + if(dirExists(settings->cookieFilePath + "_" + page.name_id + std::to_string( i ))) { std::cout << " => Error: Kann Cokkie-File nicht erstellen: Es existiert bereits ein Ordner mit diesem Namen: \n '" - << settings->cookieFilePath + std::to_string( i ) << "'." << std::endl; + << settings->cookieFilePath + "_" + page.name_id + std::to_string( i ) << "'." << std::endl; return 174; } - PageManager * pm = new PageManager(settings->proxy_ip + ":" + std::to_string(settings->proxy_port), settings->cookieFilePath + std::to_string( i )); + PageManager * pm = new PageManager(settings->proxy_ip + ":" + std::to_string(settings->proxy_port)); pm->setDebugMode(settings->debugMode); //pm->setProxy(settings->proxy_ip, settings->proxy_port); - //pm->setCookieFilePath(settings->cookieFilePath + std::to_string( i )); + //pm->setCookieFile Path(settings->cookieFile Path + std::to_string( i )); - ThreadData * newThreadData = new ThreadData(i, 0, nameInUrl, -1, settings, &accountManager, pm); + ThreadData * newThreadData = new ThreadData(i, 0, nameInUrl, -1, settings, &accountManager, pm, page); threadList.push_back(newThreadData); } } @@ -440,7 +522,7 @@ int ProgramManager::defaultModus(Settings *settings) //Finde die anzahl der staffel heraus: //download html von der startpage einer serie - Reply tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl); + Reply tmp_reply = pageManager.getServerRequest("https://" + page.url + page.UrlDir + nameInUrl); if(tmp_reply.html == "-1" || tmp_reply.html == "") { std::cerr << " => Error: Konnte Seitenquelltext nicht herunterladen." << std::endl; return 32; @@ -472,7 +554,7 @@ int ProgramManager::defaultModus(Settings *settings) } //Find out number of all episodes - if( (tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel))).html == "-1") { + if( (tmp_reply = pageManager.getServerRequest("https://" + page.url + page.UrlDir + nameInUrl + "/staffel-" + std::to_string(staffel))).html == "-1") { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest failed when download season page." << std::endl; return 40; @@ -549,7 +631,7 @@ int ProgramManager::defaultModus(Settings *settings) // Default Mode } else { - tmp_reply =pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel) + "/episode-" + std::to_string(folge)); + tmp_reply =pageManager.getServerRequest( "https://" + page.url + page.UrlDir + nameInUrl + "/staffel-" + std::to_string(staffel) + "/episode-" + std::to_string(folge)); if(tmp_reply.html == "-1") { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest failed when download episoden page." << std::endl; @@ -570,7 +652,7 @@ int ProgramManager::defaultModus(Settings *settings) } else line.erase(0, pos); line.erase(line.find("\"")); - if(convertLink(line, &accountManager, settings, staffel, folge, allLinks) != 0) { + if(convertLink(page, line, &accountManager, settings, staffel, folge, allLinks) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": convertLink failed." << std::endl; return 51; @@ -585,8 +667,8 @@ int ProgramManager::defaultModus(Settings *settings) std::string Link = pageManager.chooseHosterLink(allLinks, settings->genaueHoster, settings->languages, settings->debugMode); if(settings->debugMode) - std::cout << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://serienstream.sx") << Link << ( (Link == "") ? "" : "'\n" ); - if(convertLink(Link, &accountManager, settings, staffel, folge, allLinks) != 0) { + std::cout << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://" + page.url) << Link << ( (Link == "") ? "" : "'\n" ); + if(convertLink(page, Link, &accountManager, settings, staffel, folge, allLinks) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": convert Link failed." << std::endl; return 51; @@ -613,7 +695,6 @@ int ProgramManager::defaultModus(Settings *settings) int ProgramManager::directLinkModus(Settings *settings) { - AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath); if(settings->name == "") { std::cout << " => Kein(e) Link(s) angegeben." << std::endl; @@ -629,15 +710,50 @@ int ProgramManager::directLinkModus(Settings *settings) // return 71; while (getline(iStrStream, line).good()) { + //extrahiere redirekt und page + std::string redL; + PAGE page; + if(line.find("/redirect/") == std::string::npos) { std::cout << " => Error: Invalid Redirect Link: '" << line << "'" << std::endl; continue; - } else if(convertLink(line.erase(0, line.find("/redirect/") ), &accountManager, settings) != 0) { + } else if(line.find("://") == std::string::npos) { + if(settings->direktLink_explizitPage.url == "") { + std::cout << " => Kann '://' bei '" << line << "' die Internetseite nicht finden: Benutze -s [url], --standart-page [url]," << std::endl + << " um /redirect/xyz Links für die Internetseite (z.B. anicloud.io) umzuwandel.n" << std::endl; + continue; + } + redL = line.erase(0, line.find("/redirect/")); + page = settings->direktLink_explizitPage; + + + } else { + line.erase(0, line.find("://") + 3); // remove http(s):// + std::string url = line.substr(0, line.find("/redirect/")); + bool found = false; + for( const auto &p : settings->pages ) { + if(p.url == url) { + found = true; + page = p; + break; + } + } + if( !found ) { + std::cout << " => Error: Unbekannte Seite: '" << url << "'" << std::endl; + continue; + } + redL = line.erase(0, line.find("/redirect/")); + } + + AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath, page); + + if(convertLink(page, redL, &accountManager, settings) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": convert Link failed." << std::endl; return 78; - } + + } } if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": Success." << std::endl; @@ -646,8 +762,8 @@ int ProgramManager::directLinkModus(Settings *settings) int ProgramManager::searchModus(Settings *settings, std::string *saveTo, bool noPrint) { + ssize_t dayddiff; if(settings->showLastUpdate) { - ssize_t dayddiff; if(checkLastUpdate(settings, &dayddiff) != 0) { std::cout << " => Error: CheckLasUpdate-Funktion gab einen Error zurück." << std::endl; return -1; @@ -684,6 +800,14 @@ int ProgramManager::searchModus(Settings *settings, std::string *saveTo, bool no return 0; } + //Check for last Update.. (glaub hier nocghmal die funktion, um datei zu erstellen, auch wenn ausgabe deaktiviert is, kann aber auch sein dass der teil ghier weg gehört) + if(checkLastUpdate(settings) != 0) { + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": checkLastUpdate function failed." << std::endl; + return -1; + } + + std::ifstream ifs(settings->serienListPath); if(!ifs.is_open()) { std::cout << " => Keine SerienListe vorhanden. Erstelle eine neue..." << std::endl; @@ -702,18 +826,12 @@ int ProgramManager::searchModus(Settings *settings, std::string *saveTo, bool no } } - //Check for last Update.. - if(checkLastUpdate(settings) != 0) { - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": checkLastUpdate function failed." << std::endl; - return -1; - } //Save file in string: - std::string serienListe((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); + std::string serienListe = std::string((std::istreambuf_iterator(ifs)), std::istreambuf_iterator()); //Suche alle Möglichkeiten - std::string finds = pageManager.grep(serienListe, settings->name, settings->search_IgnoreUpperLower); + std::string fullList = pageManager.grep(serienListe, settings->name, settings->search_IgnoreUpperLower); serienListe.clear(); // Speicher freigeben /*//Text mit Farben versehen @@ -724,6 +842,24 @@ int ProgramManager::searchModus(Settings *settings, std::string *saveTo, bool no finds.insert(pos, ( (finds.find(settings->name, pos) == pos) ? "\033[32m" : "\033[36m" ) ).insert(pos + settings->name.length() + strlen("\033[37m"), "\033[0m"); }*/ + std::string finds; + + //------------------------------------------------> Extrahiere alle Zeilen raus, die aus den Aktivierten Seiten sind + std::istringstream ifS(fullList + "\n"); + std::string l, allUrls; + for( const auto &p : settings->pages ) + allUrls += ((allUrls == "") ? "" : ",") + p.url; + + while (std::getline(ifS, l)) { + if( l.find_last_of('|') == std::string::npos ) { + std::cout << "Invalid Line: '" << l << "'" << std::endl; + continue; + } else if( allUrls.find( l.substr(l.find_last_of('|') + 1) ) != std::string::npos ) + finds += l + "\n"; + } if(finds.size() >= 1) + finds.pop_back(); + //------------------------------------------- + if(saveTo) { //Save List to Variable if set *saveTo=finds; @@ -749,11 +885,38 @@ int ProgramManager::searchModus(Settings *settings, std::string *saveTo, bool no std::stringstream strstream(finds); std::string line; std::cout << " => Für '" << settings->name << "' wurde(n) folgende Serie(n) gefunden: " << std::endl; + + std::string lastPageUrl; while (getline(strstream, line)) { - std::cout << " > " << line.substr(line.find_last_of('|') + 1, std::string::npos ) - << "\t[" << line.substr(line.find("|/") + 2, line.find("|", line.find("|/") + 2) - line.find("|/") - 2) << "]" - << ( (line[0] == '|') ? "" : "\t( " + line.substr(0, line.find("|")) + " )" ) << std::endl; - } + + //splitting + ///Nadia The Secret, Fushigi no Nadia|/nadia-zauberstein|Nadia und Zauberstein|seriento + // into Vector + + std::vector parts; + std::istringstream f(line + "|"); + std::string p; + while (getline(f, p, '|').good()) + parts.push_back(p); + if(parts.size() != 4) { + std::cout << " => Error: Invalid SerienListeEintrag: '" << line << "'" << parts.size() << std::endl; + continue; + } + + if( lastPageUrl != parts.at(3) ) { + std::cout << ((settings->colorless) ? "" : "\033[93m") << "Auf '" << parts.at(3) << "'..." << ((settings->colorless) ? "" : "\033[0m") << std::endl; + lastPageUrl = parts.at(3); + } + + std::cout << " > " << parts.at(2) << "\t[" << parts.at(1).erase(0, 1) << "]" + << ( (line[0] == '|') ? "" : "\t( " + parts.at(0) + " )" ) << std::endl; + //zähne hoch!! + + ///That Time I Got Reincarnated as a Slime|/tensei-shitara-slime-datta-ken|Tensei Shitara Slime Datta Ken|ANIME + } /// > Tensei Shitara Slime Datta Ken [tensei-shitara-slime-datta-ken] ( That Time I Got Reincarnated as a Slime ) + + + if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": success." << std::endl; return 0; @@ -769,18 +932,21 @@ int ProgramManager::infoModus(Settings *settings) } //Führe Function aus, die überprüft ob die serie existiert - std::string nameInUrl = pageManager.checkName(settings->name); - if(nameInUrl == "-2") + auto retV = pageManager.checkName(settings->pages, settings->name, settings->useFirstPage); + if(retV.status == retV.FAILED) return 145; - else if(nameInUrl == "-1") { + else if(retV.status == retV.NOTHING_FOUND) { //Wenn nicht, dann fühe noch eine Suche nach ähnlichen durch. int res = 0; - if( ( res = sucheNach_1_Serien(settings, pageManager, nameInUrl) ) != 0) { + if( ( res = sucheNach_1_Serien(settings, pageManager, retV) ) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": sucheNach_1_Serien function failed." << std::endl; - return (res = -10101) ? 0 : 28; + return (res == -10101) ? 0 : 28; } } + std::string nameInUrl = retV.name; + PAGE page = retV.pageInUse; + //write Name to file if(pageManager.writeToFile(settings->outputFilePaths, "\n\nSerie: " + settings->name + " (" + nameInUrl + ")") != 0) @@ -792,7 +958,7 @@ int ProgramManager::infoModus(Settings *settings) //Finde Anzahl der Staffel heraus: - Reply tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl); + Reply tmp_reply = pageManager.getServerRequest( "https://" + page.url + page.UrlDir + nameInUrl); if(tmp_reply.html == "-1") { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed: at homepage." << std::endl; @@ -816,7 +982,7 @@ int ProgramManager::infoModus(Settings *settings) //Um namen der Folge für jede Staffel zu bekommen for (int staffel = 1; staffel <= maxStaffel; ++staffel) { - Reply tmpReply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel)); + Reply tmpReply = pageManager.getServerRequest( "https://" + page.url + page.UrlDir + nameInUrl + "/staffel-" + std::to_string(staffel)); if(tmpReply.html == "-1") { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed: at season page." << std::endl; @@ -1044,65 +1210,81 @@ int ProgramManager::infoModus(Settings *settings) int ProgramManager::newsModus(Settings *settings) { - size_t pos = 0; - std::string html = pageManager.getServerRequest("https://serienstream.sx/neue-episoden").html; - if(html == "-1") { - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed." << std::endl; - return 1; + if(settings->pages.size() < 1) { + std::cout << " => Error Keine Internet Seiten vorhanden." << std::endl; + return -12; } - if( (pos = html.find("
")) == std::string::npos ) { - std::cout << " => Error: Konnte Position von '
'' nicht finden" <
")) == std::string::npos ) { - std::cout << " => Error: Konnte Position von '
' nicht finden" <pages ) { + std::cout << ((settings->colorless) ? "" : "\033[93m") << "Auf '" << page.url << "'..." << ((settings->colorless) ? "" : "\033[0m") << std::endl; - html = replace(html, "\n", ""); - html = replace(html, "class=\"row\"", "\n"); - - std::stringstream strstream(html + "\n"); - html.clear(); - std::string line; - while (std::getline(strstream, line).good()) { - - size_t pos = line.find(""); - size_t pos2 = line.find(""); - if(pos == std::string::npos) { - std::cout << " => Error: Konnte Position von '' nicht finden" < Error: Konnte Position von '' nicht finden" <debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed." << std::endl; + return 1; } - std::string name = line.substr(pos + 8, pos2 - pos - 8); - if( (pos = line.find("blue2\">")) == std::string::npos) { - std::cout << " => Error: Konnte Position von 'blue2\">' nicht finden" <", pos)) == std::string::npos) { - std::cout << " => Error: Konnte Position von '' nicht finden" <")) == std::string::npos ) { + std::cout << " => Error: Konnte Position von '
'' nicht finden" <
")) == std::string::npos ) { + std::cout << " => Error: Konnte Position von '
' nicht finden" <"); + size_t pos2 = line.find(""); + if(pos == std::string::npos) { + std::cout << " => Error: Konnte Position von '' nicht finden" < Error: Konnte Position von '' nicht finden" <")) == std::string::npos) { + std::cout << " => Error: Konnte Position von 'blue2\">' nicht finden" <", pos)) == std::string::npos) { + std::cout << " => Error: Konnte Position von '' nicht finden" <")) == std::string::npos) { + std::cout << " => Error: Konnte Position von 'Right\">' nicht finden" <", pos)) == std::string::npos) { + std::cout << " => Error: Konnte Position von '' nicht finden" < " << ((settings->colorless) ? "" : "\033[97m") << date << ((settings->colorless) ? "" : "\033[0m") << ": " + << ((settings->colorless) ? "" : "\033[96m") << name << ((settings->colorless) ? "" : "\033[0m") << ": " + << ((settings->colorless) ? "" : "\033[92m") << id << ((settings->colorless) ? "" : "\033[0m") << std::endl; } - std::string id = replace( line.substr(pos + 7, pos2 - pos - 7), " ", ""); - if( (pos = line.find("Right\">")) == std::string::npos) { - std::cout << " => Error: Konnte Position von 'Right\">' nicht finden" <", pos)) == std::string::npos) { - std::cout << " => Error: Konnte Position von '' nicht finden" < " << ((settings->colorless) ? "" : "\033[97m") << date << ((settings->colorless) ? "" : "\033[0m") << ": " - << ((settings->colorless) ? "" : "\033[96m") << name << ((settings->colorless) ? "" : "\033[0m") << ": " - << ((settings->colorless) ? "" : "\033[92m") << id << ((settings->colorless) ? "" : "\033[0m") << std::endl; + if(settings->useFirstPage) + break; + else + std::cout << std::endl; + } return 0; @@ -1331,7 +1513,7 @@ int ProgramManager::cleanUpSettingsAndCache(Settings *settings) //setting dir if(settings->name == "SETTINGS" || settings->name == "ALL") { - if( ! removeDirIsOk(settings->configDir, settings)) { + if( ! removeDirIsOk(settings->configDir, settings, settings->askForEveryDir)) { std::cout << " => Error: Das löschen des Settings-Ordners ist fehlgeschlagen." << std::endl; return 1; } @@ -1339,8 +1521,9 @@ int ProgramManager::cleanUpSettingsAndCache(Settings *settings) } //Cache Dir - else if (settings->name == "CACHE" || settings->name == "ALL") { - if( ! removeDirIsOk(settings->cacheDir, settings)) { + + if (settings->name == "CACHE" || settings->name == "ALL") { + if( ! removeDirIsOk(settings->cacheDir, settings, settings->askForEveryDir)) { std::cout << " => Error: Das löschen des Cache-Ordners ist fehlgeschlagen." << std::endl; return 2; } @@ -1361,82 +1544,98 @@ int ProgramManager::cleanUpSettingsAndCache(Settings *settings) int ProgramManager::searchModus_update(Settings *settings) { - Reply reply = pageManager.getServerRequest("https://serienstream.sx/serien-alphabet"); - if(reply.html == "-1") { - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed." << std::endl; - 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 = replace( pageManager.grep( reply.html, "data-alternative-title" ), "", "\n" ); - - std::string tests[] = {"\" href=\"", "
  • ", }; - for ( auto t : tests ) { - if(reply.html.find( t ) == std::string::npos) { - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": hatml doesnt contain:'" << t << "' after preparing." << std::endl; - return 51; - } - } - - - - //...\n
  • 2012 - Das Jahr Null\n... - serienListe = replace(serienListe, "
  • 2012 - Das Jahr Null\n... - serienListe = replace(serienListe, "\" href=\"", "|"); - //...\n|/serie/stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null\n... - serienListe = replace(serienListe, "|/serie/stream/", "|/"); - - std::stringstream strstream(serienListe); + std::string list; 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 = replace(line, "\">", "|"); - //...\n|/serie/stream/2012-das-jahr-null|2012 - Das Jahr Null\n... - line = replace(line, "", ""); - //...\n|/serie/stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null|\n... - - serienListe += line + "\n"; + if(settings->pages.size() < 1) { + std::cout << " => Error Keine Internet Seiten vorhanden." << std::endl; + return 1290; } - if(serienListe.length() > 0) - serienListe.pop_back(); - - //Entferne Html Sonderzeichen - serienListe = replace(serienListe, "&quot;", "\""); // - - serienListe = replace(serienListe, "&", "&"); // - serienListe = replace(serienListe, "<", "<"); // - serienListe = replace(serienListe, ">", ">"); // - - serienListe = replace(serienListe, "
    ", " "); // - serienListe = replace(serienListe, """, "\""); // - serienListe = replace(serienListe, "'", "'"); // + //darf nicht weniger werden!! + + for ( const auto &page : settings->pagesALL ) { + std::cout << " -> Updating '" << page.name_id << "'..." << std::endl; + + Reply reply = pageManager.getServerRequest("https://" + page.url + page.urlAlphabetSerienList); + + + if(reply.html == "-1") { + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": getServerRequest function failed." << std::endl; + 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 = replace( pageManager.grep( reply.html, "data-alternative-title" ), "
  • ", "\n" ); + + std::string tests[] = {"\" href=\"", "
  • ", }; + for ( auto t : tests ) { + if(reply.html.find( t ) == std::string::npos) { + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": hatml doesnt contain:'" << t << "' after preparing." << std::endl; + return 51; + } + } + + //...\n
  • 2012 - Das Jahr Null\n... + serienListe = replace(serienListe, "
  • 2012 - Das Jahr Null\n... + serienListe = replace(serienListe, "\" href=\"", "|"); + //...\n|/serie /stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null\n... + serienListe = replace(serienListe, "|" + page.UrlDir, "|/"); + + std::stringstream strstream(serienListe); + 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 = replace(line, "\">", "|"); + //...\n|/serie/ stream/2012-das-jahr-null|2012 - Das Jahr Null\n... + line = replace(line, "", ""); + //...\n|/serie/ stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null|\n... + + ///Nadia The Secret, Fushigi no Nadia|/nadia-zauberstein|Nadia und Zauberstein|seriento + serienListe += line + "|" + page.url + "\n"; + } + if(serienListe.length() > 0) + serienListe.pop_back(); + + //Entferne Html Sonderzeichen + serienListe = replace(serienListe, "&quot;", "\""); // + + serienListe = replace(serienListe, "&", "&"); // + serienListe = replace(serienListe, "<", "<"); // + serienListe = replace(serienListe, ">", ">"); // + + serienListe = replace(serienListe, "
    ", " "); // + serienListe = replace(serienListe, """, "\""); // + serienListe = replace(serienListe, "'", "'"); // + + list += serienListe; + + } //Anzahl der Serien/Zeilen vorher: ssize_t countBef = 0; - std::ifstream myFileBef(settings->serienListPath); + std::ifstream myFileBef(settings->serienListPath ); std::string alteListe; if(myFileBef.is_open()) { - for(countBef = 0; std::getline(myFileBef,line); ++countBef) { + for(countBef = 0; std::getline(myFileBef, line); ++countBef) { //Speicher alteListe für verglkeich nach Update alteListe.append(line + "\n"); //Vergeliche neue und alte list => entfernte Serien - if(line != "" && serienListe.find(line) == std::string::npos) { - std::cout << ((settings->colorless) ? "" : "\033[91m") << "Entfernt: '" << line.substr(line.find_last_of("|") + 1) << "'" << ((settings->colorless) ? "" : "\033[0m") + if(line != "" && list.find(line) == std::string::npos) { + std::string tmp = std::string(line).erase(line.find_last_of('|')); + std::cout << ((settings->colorless) ? "" : "\033[91m") << "Entfernt: '" << tmp.substr(tmp.find_last_of("|") + 1) << "'" << ((settings->colorless) ? "" : "\033[0m") << std::endl; } } @@ -1444,24 +1643,25 @@ int ProgramManager::searchModus_update(Settings *settings) } //Schreibe die Liste in das TextFile - std::ofstream ofs(settings->serienListPath, std::ios::trunc); + std::ofstream ofs(settings->serienListPath , std::ios::trunc); if(!ofs.is_open()) { perror("Konnte SerienListe-Datei nicht öffnen"); return 111; } else { //Schreibe Liste in das TextFile - ofs << serienListe << std::endl; + ofs << list << std::endl; ofs.close(); } //Anzahl der Zeile nachher ssize_t countAf = 0; - std::ifstream myFileAf(settings->serienListPath); + std::ifstream myFileAf(settings->serienListPath ); if(myFileAf.is_open()) { for(countAf = 0; std::getline(myFileAf,line); ++countAf) { //Vergeliche neu mit Alt => gib neue Serien aus if(line != "" && alteListe.find(line) == std::string::npos) { - std::cout << ((settings->colorless) ? "" : "\033[92m") << "Neu: '" << line.substr(line.find_last_of("|") + 1) << "'" << ((settings->colorless) ? "" : "\033[0m") + std::string tmp = std::string(line).erase(line.find_last_of('|')); + std::cout << ((settings->colorless) ? "" : "\033[92m") << "Neu: '" << tmp.substr(tmp.find_last_of("|") + 1) << "'" << ((settings->colorless) ? "" : "\033[0m") << std::endl; } } @@ -1473,7 +1673,11 @@ int ProgramManager::searchModus_update(Settings *settings) std::cout << ((settings->colorless) ? "" : "\033[93m") << "Serienunterschied: " << ( ((countAf - countBef) > 0) ? "+" : "") << countAf - countBef << " Serien." << "\033[0m" << std::endl; - //Speicher Dateim des Updates... + + + + + //Speicher Datum des Updates... ofs.open(settings->lastUpdateDateFilePath, std::ios::trunc); if(!ofs.is_open()) { perror("Konnte UpdateDate-Datei nicht öffnen"); @@ -1484,7 +1688,6 @@ int ProgramManager::searchModus_update(Settings *settings) ofs.close(); } - return 0; } @@ -1561,7 +1764,7 @@ int ProgramManager::listDir(std::string &list,std::string path, int maxDepth, bo return 0; } -int ProgramManager::convertLink(std::string redirectLink, AccountManager * accountManager, +int ProgramManager::convertLink(PAGE page, 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) @@ -1594,36 +1797,39 @@ int ProgramManager::convertLink(std::string redirectLink, AccountManager * accou } for (int i = 1; i <= 3; ++i) { - std::string newUrl = pageManager.getUrlAfterRedirect("https://serienstream.sx" + redirectLink); + auto rEply = pageManager.getUrlAfterRedirect("https://" + page.url + redirectLink, settings->cookieFilePath + "_" + page.name_id); + std::string newUrl = rEply.url; + std::cout << "URL NACH UMWANDLUNG:" << newUrl << "\n\n" << rEply.html << std::endl; + + //wenn function fehl schlug beende das Programm if (newUrl == "-1") { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": getUrlAfterRedirect f() failed." << std::endl; return 102; - // wenn nach der Umwandlung immern och ein redirect vorhanden ist, also wenn z.B.: account gewechselt werden muss - } else if(newUrl.find("/serienstream.sx/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) { - if(settings->debugMode) - std::cerr << ">>> Debug In " << __FUNCTION__ << ": login f() failed." << std::endl; - return -1; - } - continue; - - //wenn nach der Umwandlung https://serienstream.sx/ vorhanden ist, die ist wenn der Link Ungültig war: - } else if (newUrl == "https://serienstream.sx/") { - std::cout << " => " << red << replace(folgenID, "E", " E") << ( (folgenID == "") ? "" : ": " ) << "Ungültige Url: 'https://serienstream.sx" << redirectLink << "'" + //wenn nach der Umwandlung https://seriens tream.sx/ vorhanden ist, die ist wenn der Link Ungültig war: + } else if (newUrl == "https://s.to" || newUrl == "https://" + page.url || rEply.html.find("404 - Seite nicht gefunden") != std::string::npos || rEply.html.find("403 Forbidden") != std::string::npos) { + std::cout << " => " << red << replace(folgenID, "E", " E") << ( (folgenID == "") ? "" : ": " ) << "Ungültige Url: 'https://" + page.url << redirectLink << "'" << ((settings->colorless) ? "" : "\033[0m") << std::endl; if(settings->outputFilePaths.size() != 0) - if(pageManager.writeToFile(settings->outputFilePaths, replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + "Ungültige Url: https://serienstream.sx" + redirectLink) != 0) { + if(pageManager.writeToFile(settings->outputFilePaths, replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + "Ungültige Url: https://" + page.url + redirectLink) != 0) { if(settings->debugMode) std::cerr << ">>> Debug In " << __FUNCTION__ << ": writeToFile f() failed." << std::endl; return 108; } return 0; - //sonst war die umwandlung erfolgreich + // wenn nach der Umwandlung immern och ein redirect vorhanden ist, also wenn z.B.: account gewechselt werden muss + } else if(newUrl.find("/" + page.url + "/redirect/") != std::string::npos ) { + if(settings->debugMode) + std::cout << "Warnung: Redirect Link nach umwandlung (Capcha?) --> Neuer Account" << std::endl; + if(pageManager.login(page, accountManager->getNextAccount()) != 0) { + if(settings->debugMode) + std::cerr << ">>> Debug In " << __FUNCTION__ << ": login f() failed." << std::endl; + return -1; + } + continue; + //alles ok } else { if( (newUrl = pageManager.getLinkAfterHosterBasedOperation(newUrl)) == "") { if(settings->debugMode) @@ -1643,7 +1849,7 @@ int ProgramManager::convertLink(std::string redirectLink, AccountManager * accou } //nach 3temn Versuch gib error aus: - std::cout << " => " << replace(folgenID, "E", " E") << ( (folgenID == "") ? "" : ": " ) << red << "https://serienstream.sx" << redirectLink << ((settings->colorless) ? "" : "\033[0m") << std::endl; + std::cout << " => " << replace(folgenID, "E", " E") << ( (folgenID == "") ? "" : ": " ) << red << "https://" + page.url << redirectLink << ((settings->colorless) ? "" : "\033[0m") << std::endl; if(settings->outputFilePaths.size() != 0) { if(pageManager.writeToFile(settings->outputFilePaths, replace(folgenID, "E", " E") + ( (folgenID == "") ? "" : ": " ) + redirectLink) != 0) { if(settings->debugMode) diff --git a/src/programManager.h b/src/programManager.h index 985abcb..5034393 100644 --- a/src/programManager.h +++ b/src/programManager.h @@ -1,6 +1,7 @@ #ifndef MANAGEPROGRAM_H #define MANAGEPROGRAM_H + #include "pageManager.h" #include "parameterManager.h" #include "accountManager.h" @@ -11,10 +12,11 @@ struct ThreadData { - ThreadData(unsigned id, pthread_t init, std::string nameinUrl,int exitStateInit, Settings * settings, AccountManager * accountMg, PageManager * pM) - : id(id), thread(init), nameInUrl(nameinUrl), exitState(exitStateInit), settings(settings), accountManager(accountMg), pageManager(pM) {} + ThreadData(unsigned id, pthread_t init, std::string nameinUrl,int exitStateInit, Settings * settings, AccountManager * accountMg, PageManager * pM, PAGE p) + : id(id), page(p), thread(init), nameInUrl(nameinUrl), exitState(exitStateInit), settings(settings), accountManager(accountMg), pageManager(pM) {} unsigned id; + PAGE page; pthread_t thread; std::string nameInUrl, returnValue; int staffel, folge, exitState; @@ -54,10 +56,10 @@ private: std::vector threadList; unsigned nextThread; - int convertLink(std::string redirectLink, AccountManager *accountManager, Settings * settings, int Staffel = -1, int Folge = -1, std::string allLinks = "NOT_EMPTY"); + int convertLink(PAGE page, std::string redirectLink, AccountManager *accountManager, Settings * settings, int Staffel = -1, int Folge = -1, std::string allLinks = "NOT_EMPTY"); int searchModus_update(Settings * settings); int waitForThreads(); - int sucheNach_1_Serien(Settings *settings, PageManager &pageManager, std::string &newName); + int sucheNach_1_Serien(Settings *settings, PageManager &pageManager, checkNameRply &newNameAndPage); int checkLastUpdate(Settings * settings, ssize_t *days);