#include "pageManager.h" PageManager::PageManager(std::string sock5ProxyOnlyAddress, std::string cookieFilePath) : sock5Proxy("socks5://" + sock5ProxyOnlyAddress), cookieFilePath(cookieFilePath) { curl_global_init(CURL_GLOBAL_ALL); } PageManager::~PageManager() { curl_global_cleanup(); } void PageManager::setProxy(std::string ip, int port) { if(!port) { if(debugMode) std::cout << " => INFO: Es wird kein Proxy verwendet." << std::endl; this->sock5Proxy = ""; } else { this->sock5Proxy = "socks5://" + ip + ":" + std::to_string(port); if(debugMode) std::cout << "Proxy: " << ip << ":" << port << std::endl; } } void PageManager::setCookieFilePath(std::string path) { this->cookieFilePath = path; } void PageManager::setDebugMode(bool status) { this->debugMode = status; } //Save reply to string size_t WriteCallback(void *contents, size_t size, size_t nmemb, void *userp) { //Function für CURL static_cast(userp)->append(static_cast(contents),size * nmemb); return size * nmemb; } //Write data to file static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) { size_t written = fwrite(ptr, size, nmemb, reinterpret_cast(stream)); return written; } Reply PageManager::getServerRequest(std::string Url, bool useCookies, std::string data, bool generateCookieFile, bool UrlAfterRedirectOnlyNeeded) { CURL *curl; CURLcode res; std::string readBuffer; char *url; std::string returnUrl; //info ausgabe std::cout << ( "\33[2K\rLade: '" + Url + "'..." + ((debugMode) ? "\n" : "" )) << std::flush; curl = curl_easy_init(); if(!curl) { perror("\33[2K\r => Error: Curl easy init failed"); return Reply("-1"); } //Settings if(sock5Proxy != "") curl_easy_setopt(curl, CURLOPT_PROXY, sock5Proxy.c_str() ); //Sock5Proxy für Curl else if(debugMode) std::cout << "\33[2K\r => INFO: Es wird kein Proxy verwendet." << std::endl; //curl_easy_setopt(curl, CURLOPT_FAILONERROR, true); // html errors to errorcode res //curl_easy_setopt(curl, CURLOPT_NOPROGRESS, false); // Progressausgabe aktivieren curl_easy_setopt(curl, CURLOPT_URL, Url.c_str()); //Url für Curl curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); //follows redirection curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); // Funktion zum Speichern des outputs in einem string curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer); //Legt die Variable readbuffer fest curl_easy_setopt(curl, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0"); if(useCookies) curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookieFilePath.c_str()); if(data != "") curl_easy_setopt (curl, CURLOPT_POSTFIELDS, data.c_str()); if(generateCookieFile) curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookieFilePath.c_str()); int maxTimeout = 10; for (int timeout = 1; timeout <= maxTimeout; ++timeout) { /* Perform the request, res will get the return code */ res = curl_easy_perform(curl); std::cout << "\33[2K\r" << std::flush; if(res != CURLE_OK) { if(timeout == maxTimeout) { perror((std::string("\33[2K\r => Error: curl_easy_perform() failed: ") + curl_easy_strerror(res)).c_str()); return Reply("-1"); } else { //Try to use to (new) url if(UrlAfterRedirectOnlyNeeded) { res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); if( res != CURLE_OK || !url ) { perror((std::string("\33[2K\r => Error: curl_easy_getinfo failed: ") + curl_easy_strerror(res)).c_str()); return Reply("-1"); } else { if(url != Url) { if(debugMode) std::cout << " => WARNING: Use Url after Error getServerRequest, cause it chanced and only url needed" << std::endl; Url = url; // after curl_easy_cleanup(), url (char * ) == invalid curl_easy_cleanup(curl); return Reply("", Url); } else { if(debugMode) std::cout << " => WARNING: Want to Use Url after Error getServerRequest, but url didn't chacnge, too" << std::endl; } } } std::cout << std::string( "\33[2K\r => Warning: Versuch " + std::to_string(timeout) + " von " + std::to_string(maxTimeout) + ": curl_easy_perform() failed: " + curl_easy_strerror(res) )<< std::flush; sleep(1); } } else { break; } } //Get Url res = curl_easy_getinfo(curl, CURLINFO_EFFECTIVE_URL, &url); if( res != CURLE_OK || !url ) { perror((std::string("\33[2K\r => Error: curl_easy_getinfo failed: ") + curl_easy_strerror(res)).c_str()); return Reply("-1"); } else returnUrl=url; /* always cleanup */ /* Mach den Griff zu, schreib die Kekse! */ curl_easy_cleanup(curl); return Reply(readBuffer, returnUrl); } int PageManager::downLoadToFile(std::string filePath, std::string url) { CURL *curl_handle; FILE *pagefile; CURLcode res; /* open the file */ pagefile = fopen(filePath.c_str(), "wb"); // w == write; b == binäre if(!pagefile) { perror("Open File filed"); return 1; } //Info ausgabe std::cout << ( "\33[2K\rDownloade: '" + url + "'..." + ((debugMode) ? "\n" : "" )) << std::flush; /* init the curl session */ curl_handle = curl_easy_init(); if(!curl_handle) { perror("\33[2K\r => Error: Curl easy init failed"); return 2; } /* set URL to get here */ curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); /* Switch on full protocol/debug output while testing */ curl_easy_setopt(curl_handle, CURLOPT_VERBOSE, false); /* disable progress meter, set to 0L to enable and disable debug output */ curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, false); /* send all data to this function */ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data); //Sock5Proxy für Curl if(sock5Proxy != "") curl_easy_setopt(curl_handle, CURLOPT_PROXY, sock5Proxy.c_str() ); //Sock5Proxy für Curl else if(debugMode) std::cout << "\33[2K\r => INFO: Es wird kein Proxy verwendet." << std::endl; //User Agent curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:64.0) Gecko/20100101 Firefox/64.0"); /* write the page body to this file handle */ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, pagefile); //Error 404, for example => not found curl_easy_setopt(curl_handle, CURLOPT_FAILONERROR, true); int maxTimeOut = 5; bool failed = false; for (int timeout = 1; timeout <= maxTimeOut; ++timeout) { /* get it! */ if( (res = curl_easy_perform(curl_handle)) != CURLE_OK ) { //Wenns fehlschlägt error ( + wiederversuchen ) if(timeout == maxTimeOut) { perror((std::string("\33[2K\r => Error: curl_easy_perform() failed: ") + curl_easy_strerror(res)).c_str()); failed = true; } else { std::cout << std::string( "\33[2K\r => Warning: Versuch " + std::to_string(timeout) + " von " + std::to_string(maxTimeOut) + ": curl_easy_perform() failed: " + curl_easy_strerror(res) )<< std::flush; sleep(1); } } else { //Sonst ( wenns functioniert) schleife verlassen break; } } /* close the header file */ if(fclose(pagefile) != 0) { perror(" => Error: fclose failed"); return 4; } /* cleanup curl stuff */ curl_easy_cleanup(curl_handle); return (failed) ? 10 : 0; } int PageManager::login(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 ); std::string html = reply.html; if(html == "" ) return 0; else if (html.find("Das Feld Email muss eine gültige E-Mail-Adresse enthalten.") != std::string::npos) std::cout << " => Error: Login failed: Das Feld Email muss eine gültige E-Mail-Adresse enthalten." << std::endl << " Email: '" << account.Email << "' Passwort: '" << account.Password << "'" << std::endl; else if (html.find("Das Passwort ist nicht korrekt") != std::string::npos) std::cout << " => Error: Login failed: Das Passwort ist nicht korrekt." << std::endl << " Email: '" << account.Email << "' Passwort: '" << account.Password << "'" << std::endl; else if (html.find("Ein Account mit dieser E-Mail Adresse wurde nicht gefunden.") != std::string::npos) std::cout << " => Error: Login failed: Ein Account mit dieser E-Mail Adresse wurde nicht gefunden." << std::endl << " Email: '" << account.Email << "' Passwort: '" << account.Password << "'" << std::endl; else if(html == "-1") return -1; else std::cout << " => Error: Login failed: Keine Weiterleitung bei Login." << std::endl << " Email: '" << account.Email << "' Passwort: '" << account.Password << "'" << std::endl; return -1; } std::string PageManager::getUrlAfterRedirect(std::string Url) { return getServerRequest(Url, true, "", false, true).url; } std::string PageManager::checkName(std::string Name) { std::string name = replace(Name, " ", "-"); 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 => Error: 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 => Error: Ungültiger Name: '" << Name << "'" << std::endl; return "-1"; } else if (html == "-1" || html == "") { return "-2"; } else { std::cout << "\33[2K\r > Name: " << name << std::endl; return name; } } std::string PageManager::getLinks(std::string HTML) { //Entderne alles vor den Links size_t pos = HTML.find("
    "); if(pos == std::string::npos) { std::cout << " => Error: Konnte Position von \"" << "
      " << " nicht finden" < Error: Konnte Position von \"" << "