#include "parameterManager.h" int setPaths(Settings &settings) { //Path settings std::string CacheDir, SettingsDir; #ifdef __linux__ CacheDir = std::string(getenv("HOME")) + "/.cache/S_New4/"; SettingsDir = std::string( getenv("HOME") ) + "/.config/S_New4/"; settings.pathSymbol = '/'; #endif #ifdef _WIN32 CacheDir = std::string(getenv("LOCALAPPDATA")) + "\\S_New4\\"; // C:\Users\{username}\AppData\Local SettingsDir = std::string( getenv("APPDATA") ) + "\\S_New4\\"; // C:\Users\{username}\AppData\Roaming settings.pathSymbol = '\\'; #endif if(CacheDir == "" || SettingsDir == "") { std::cout << " => Error: PfadVariablen sind nicht gesetzt." << std::endl; return -1; } else if(!dirExists(CacheDir)) { if(!makePathIsOk(CacheDir)) { std::cout << " => Error: Konnte Ordner nicht erstellen: " << CacheDir << std::endl; return -1; } else std::cout << " > Erfolgreich Ordner '" << CacheDir << "' erstellt." << std::endl; } if(!dirExists(SettingsDir)) { if(!makePathIsOk(SettingsDir)) { std::cout << " => Error: Konnte Ordner nicht erstellen: " << SettingsDir << std::endl; return -1; } else std::cout << " > Erfolgreich Ordner '" << SettingsDir << "' erstellt." << std::endl; } settings.cookieFilePath = CacheDir + "S_New4_cookies"; settings.accountNumberPath = CacheDir + "Account_Number"; settings.lastUpdateDateFilePath = CacheDir + "LastUpdateDate"; settings.accountFilePath = SettingsDir + "Accounts"; settings.serienListPath = SettingsDir + "SerienListe"; settings.defaultsFilePath = SettingsDir + "Defaults"; return 0; } int manageParameter(Settings &settings, int argc, char **argv) { //Path settings if(setPaths(settings) != 0) return -1; if(loadDefaulOptions(settings) != 0) return 28; if(argc < 2) { std::cout << " => Error: Keine Unteroption angegeben." << std::endl; std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]" << std::endl; std::cout << "\"" << settings.programName << " --help\" liefert weitere Informationen." << std::endl; return 1; } std::vector res = compare("--help\ndefault\nurl\n--version\nsearch\ninfo\nclean\nnews", argv[1]); if(res.size() != 1) { if(res.size() == 0) std::cout << " => Error: Keine Unteroption für " << argv[1] << " gefunden." << std::endl; else if(res.size() > 1) { std::cout << " => Error: Mehrere Unteroptionen für '" << argv[1] << "' gefunden:" << std::endl; for (auto &e : res) std::cout << " > '" << argv[1] << "' =? " << e << std::endl; } std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]" << std::endl; std::cout << "\"" << settings.programName << " --help\" liefert weitere Informationen." << std::endl; return 2; } res.clear(); if(strncmp(argv[1], "--help", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_help(settings); } else if (strncmp(argv[1], "default", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_default(&settings, argc, argv); } else if (strncmp(argv[1], "url", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_url(&settings, argc, argv); } else if (strncmp(argv[1], "--version", strlen(argv[1])) == 0) { std::cout << "Programinfos:" << std::endl << " > Program Version: " << settings.version << std::endl << " > Defaults Datei Version: " << settings.defaultFileVersion << std::endl << " > C++ Standart: "; if(__cplusplus == 1) std::cout << "C++_Pre_C++98" << std::endl; else if (__cplusplus == 199711) std::cout << "C++98" << std::endl; else if (__cplusplus == 201103) std::cout << "C++11" << std::endl; else if (__cplusplus == 201402) std::cout << "C++14" << std::endl; else if (__cplusplus == 201703) std::cout << "C++17" << std::endl; else std::cout << "C++_Newer_C++17" << std::endl; std::cout << " > " << sizeof (void *) * 8 << " Bit Version" << std::endl; return -1; } else if (strncmp(argv[1], "search", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_search(&settings, argc, argv); } else if (strncmp(argv[1], "info", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_info(&settings, argc, argv); } else if (strncmp(argv[1], "clean", strlen(argv[1])) == 0) { argv[1][0] = '\0'; unterOption_clean(&settings, argc, argv); return -1; } else if (strncmp(argv[1], "news", strlen(argv[1])) == 0) { argv[1][0] = '\0'; return unterOption_news(&settings, argc, argv); } else { std::cout << " => Error: Invalid option " << argv[1] << ", but not detected in compare-Function" << std::endl; return 3; } } int loadDefaulOptions(Settings &settings) { std::fstream ifs(settings.defaultsFilePath); if(!ifs.is_open()) { std::ofstream ofs(settings.defaultsFilePath); if(!ofs.is_open()) { perror((" => Error: Konnte Defaults-Datei nicht öffnen: " + settings.defaultsFilePath).c_str()); return 89; } else { std::cout << " => Erstelle Defaults-Datei: " << settings.defaultsFilePath << std::endl; ofs << "# -> Mit # kann man eine Zeile deaktivieren." << std::endl; ofs << "DefaultFileVersion="<< settings.defaultFileVersion << std::endl << std::endl; ofs << "#" << std::endl << "# -> Globale Einstellungen:" << std::endl << "#" << std::endl << std::endl; ofs << "# -> Einstellung gleicht dem Parameter -d, --debug-mode:" << std::endl; ofs << "#DebugModus=false" << std::endl << std::endl; ofs << "# -> Einstellung gleicht dem Parameter -p, --socks5-proxy:" << std::endl; ofs << "#Socks5Proxy=127.0.0.1:9050" << std::endl << std::endl; ofs << "# -> Einstellung gleicht dem Parameter -c, --colorless:" << std::endl; ofs << "#FarbloseAusgabe=false" << std::endl << std::endl; ofs << "# -> Einstellung gleicht dem Parameter -o [Pfad], --output-file," << std::endl; ofs << "# falls dieser in der ausgeführeten Unterfunktion vorhanden ist:" << std::endl; ofs << "#OutputFile=/tmp/a" << 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=Vivo,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; ofs << "# -> Standart Wert für Parameter: -m, --check-muster:" << std::endl; ofs << "#default_CheckSuchMuster=S%Staffel%E%Folge%" << std::endl << std::endl; ofs << "# -> Standart Wert für Parameter: -D, --check-max-dirs:" << std::endl; ofs << "#default_CheckMaxDirs=20" << std::endl << std::endl; ofs << "# -> Standart Wert für Parameter: -t, --threads:" << std::endl; ofs << "#default_maxThreads=0" << std::endl << std::endl; ofs << "#" << std::endl << "# -> Einstellungen für search Modus:" << std::endl << "#" << std::endl << std::endl; ofs << "# -> Standart Wert für Parameter: -e, --exactly-writing:" << std::endl; ofs << "#search-AchteAufGroßUndKleinschreibung=false" << std::endl << std::endl; ofs << "# -> Mit 0 Können Sie die Warnung deaktivieren:" << std::endl; ofs << "#search-UpdateWarnungNachTagen=10" << std::endl << std::endl; ofs.close(); } ifs.open(settings.defaultsFilePath); if(!ifs.is_open()) { perror((" => Error: Konnte Defaults-Datei nach dem erstellen nicht öffnen: " + settings.defaultsFilePath).c_str()); return 97; } } std::string line; while (std::getline(ifs, line).good()) { if(line.find("#") != std::string::npos || line == "") continue; else if ( line.find("=") == std::string::npos ) { std::cout << " => Warnung: Bitte Info-Texte mit '#' am Anfang: Ungültige Option '" << line << "'." << std::endl; continue; } std::string what = line.substr(0, line.find("=")), data = line.substr(line.find("=") + 1, line.length() - line.find("=") -1); if(what == "") { } else if (what == "Socks5Proxy") { if(setS5ProxytoSettings(settings, data) != 0) return 2; } else if (what == "DefaultFileVersion") { if(data != settings.defaultFileVersion) std::cout << " => Warnung: Veraltetes Defaults-File. Löschen sie die Datei, um die neuste Version zu bekommen." << std::endl; } else if (what == "DebugModus") { if(data == "true") settings.debugMode=true; else if (data == "false") settings.debugMode=false; else { std::cout << " => Error_Defaults: DebugModus: Ungültiger Wert für 'true/false': " << data << std::endl; return 161; } if(settings.debugMode) std::cout << " > Defaults: DebugMode: true" << std::endl; } else if (what == "default_GenaueHoster") { settings.genaueHoster=data; if(settings.debugMode) std::cout << " > Defaults: GenaueHoster: " << settings.genaueHoster << std::endl; } else if (what == "default_Sprachen") { settings.languages=data; if(settings.debugMode) std::cout << " > Defaults: Sprachen: " << settings.languages << std::endl; } else if (what == "default_CheckSuchMuster") { settings.default_Searchmuster=data; if(settings.debugMode) std::cout << " > Defaults: SuchMuster: " << settings.default_Searchmuster << std::endl; } else if (what == "default_CheckMaxDirs") { settings.default_maxDirs = atoi(data.c_str()); if(!isNumber(data) ) { std::cout << " => Error_Defaults: default_CheckMaxDirs: Ungültige Zahl: " << data << std::endl; return 18; } if(settings.debugMode) std::cout << " > Defaults: default_CheckMaxDirs: " << settings.default_maxDirs << std::endl; } else if (what == "default_maxThreads") { settings.maxThreads = static_cast(atoi(data.c_str())); if(!isNumber(data) ) { std::cout << " => Error_Defaults: Thread-Max Ungültige Zahl: " << data << std::endl; return 18; } else if (settings.maxThreads > 10) { std::cout << " => Error_Defaults: Thread-Max: Zahl größer 10: " << data << std::endl; return 19; } if(settings.debugMode) std::cout << " > Defaults: MaxThreads: " << settings.maxThreads << std::endl; } else if (what == "FarbloseAusgabe") { if(data == "true") settings.colorless=true; else if (data == "false") settings.colorless=false; else { std::cout << " => Error_Defaults: FarbloseAusgabe: Ungültiger Wert für 'true/false': " << data << std::endl; return 207; } if(settings.debugMode) std::cout << " > Defaults: FarbloseAusgabe: " << settings.colorless << std::endl; } else if (what == "search-AchteAufGroßUndKleinschreibung") { if(data == "true") settings.search_IgnoreUpperLower=false; else if (data == "false") settings.search_IgnoreUpperLower=true; else { std::cout << " => Error_Defaults: search-AchteAufGroßUndKleinschreibung: Ungültiger Wert für 'true/false': " << data << std::endl; return 227; } if(settings.debugMode) std::cout << " > Defaults: search-AchteAufGroßUndKleinschreibung: " << settings.search_IgnoreUpperLower << std::endl; } else if (what == "OutputFile") { settings.outputFilePath = data; if(settings.debugMode) std::cout << " > Defaults: OutputFile: " << settings.outputFilePath << std::endl; } else if (what == "search-UpdateWarnungNachTagen") { if(!isNumber(data)) { std::cout << " Error_Defaults: search-UpdateWarnungNachTagen: Wert ist keine Zahl." << std::endl; return 228; } else { settings.updateWarningDays = atoi(data.c_str()); } if(settings.debugMode) std::cout << " > Defaults: search-UpdateWarnungNachTagen: " << settings.updateWarningDays << std::endl; } else if (what == "") { } else if (what == "") { } else if (what == "") { } else { std::cout << " => Warnung: Unbekannte Default-Option: '" << what << "'." << std::endl; } } ifs.close(); return 0; } int unterOption_help(Settings &settings) { std::cout << "Aufruf: " << settings.programName << " [Unteroption] [PARAMETER]..." << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " -> 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 << " s.to umwandeln." << std::endl << std::endl; std::cout << "Unteroptionen:" << std::endl << "\t\"--help\"\tGibt dieses Helpmenue aus." << std::endl << "\t\"--version\"\tGibt die Version des Programmes aus." << std::endl << "\t\"url\"\t\tModus um eigene Redirect-Links umzuwandeln." << std::endl << "\t\"default\"\tModus um Links von Serien zu bekommen." << std::endl << "\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 s.to zu sehen." << std::endl << std::endl; std::cout << "Verzeichnisse:" << std::endl << "\tOrdner zum zwischenspeichern der Cookies und der AccountNummer:" << std::endl << "\t > '" << settings.cookieFilePath << "'" << std::endl << "\tOrdner zum speichern der Accounts und Default-Einstellungen:" << std::endl << "\t > '" << settings.defaultsFilePath << "'" << std::endl; return -1; } int unterOption_default(Settings *settings, int argc, char ** argv) { settings->modus = Modus::DEFAULT_MODUS; int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"genaue-hoster", required_argument, nullptr, 'g'}, {"languages", required_argument, nullptr, 'l'}, {"output-file", required_argument, nullptr, 'o'}, {"start-episode", required_argument, nullptr, 'e'}, {"stop-episode", required_argument, nullptr, 'E'}, {"start-season", required_argument, nullptr, 's'}, {"stop-season", required_argument, nullptr, 'S'}, {"check", required_argument, nullptr, 'C'}, {"check-muster", required_argument, nullptr, 'm'}, {"check-max-dirs", required_argument, nullptr, 'D'}, {"threads", required_argument, nullptr, 't'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, {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 ) { switch(c) { case 'p': if(optarg && setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; case 'g': if(optarg) settings->genaueHoster =+ optarg + std::string(","); if(settings->debugMode) std::cout << "Hosterreihenfolge: " << settings->genaueHoster << std::endl; break; case 'l': if(optarg) settings->languages =+ optarg + std::string(","); if(settings->debugMode) std::cout << "Sprachenreihenfolge: " << settings->languages << std::endl; break; case 'o': if(optarg) settings->outputFilePath = optarg; if(settings->debugMode) std::cout << "Pfad zu Output-Datei: " << settings->outputFilePath << std::endl; break; case 'e': if(!optarg) break; settings->startEpisode = atoi(optarg); if (!isNumber(optarg)) { std::cout << " => Error: -e [Folge]: '" << optarg << "' ist keine Zahl." << std::endl; return 11; } else if (settings->startEpisode <= 0) { std::cout << " => Error: -e [Folge]: StartEpisode " << settings->startEpisode << " ist kleiner gleich 0." << std::endl; return 13; } if(settings->debugMode) std::cout << "StartEpisode: " << settings->startEpisode << std::endl; break; case 'E': if(!optarg) break; settings->stopEpisode = atoi(optarg); if (!isNumber(optarg)) { std::cout << " => Error: -E [Folge]: '" << optarg << "' ist keine Zahl." << std::endl; return 14; } else if (settings->debugMode) std::cout << "StopEpisode: " << settings->stopEpisode << std::endl; break; case 's': if(!optarg) break; settings->startSeason = atoi(optarg); if (!isNumber(optarg)) { std::cout << " => Error: -s [Staffel]: '" << optarg << "' ist keine Zahl." << std::endl; return 15; } else if (settings->startSeason < 0) { std::cout << " => Error: -s [Staffel]: StartStaffel " << settings->startSeason << " ist kleiner 0." << std::endl; return 17; } else if(settings->debugMode) std::cout << "StartStaffel: " << settings->startSeason << std::endl; break; case 'S': if(!optarg) break; settings->stopSeason = atoi(optarg); if (!isNumber(optarg)) { std::cout << " => Error: -S [Staffel]: '" << optarg << "' ist keine Zahl." << std::endl; return 18; } else if(settings->debugMode) std::cout << "StopSeason: " << settings->stopSeason << std::endl; break; case 'm': if(optarg) settings->default_Searchmuster = optarg; if(settings->debugMode) std::cout << " SearchMuster: " << settings->default_Searchmuster << std::endl; break; case 'D': if(!optarg) break; settings->default_maxDirs = atoi(optarg); if(!isNumber(optarg)) { std::cout << " => Error: [-D]: Ungültige Zahl: " << optarg << std::endl; return 18; } if(settings->debugMode) std::cout << "CheckMaxDirs: " << settings->default_maxDirs << std::endl; break; case 't': if(!optarg) break; settings->maxThreads = static_cast(atoi(optarg)); if(!isNumber(optarg)) { std::cout << " => Error: [-t]: Thread-Max: Ungültige Zahl: " << optarg << std::endl; return 18; } else if (settings->maxThreads > 10 && !settings->debugMode) { std::cout << " => Error: [-t]: Thread-Max: Zahl ist größer 10: " << optarg << std::endl; return 19; } if(settings->debugMode) std::cout << "MaxThreads: " << settings->maxThreads << std::endl; break; case 'C': if(!optarg) break; settings->default_checkPath = optarg; if(settings->debugMode) std::cout << "To check Dir/File: " << settings->default_checkPath << std::endl; break; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; if(argc > optind) if(argv[optind][0] != '-' && std::string(argv[optind]).find(settings->pathSymbol) != std::string::npos) { std::cout << " => Upps: Hast du -c (--colorless) mit -C (--check-dir) verwechselt?" << std::endl << " (Hat \"Argument\" mit \""<< settings->pathSymbol << "\": '-c " << std::string(argv[optind]) << "')." << std::endl; return -1; } break; case 'd': settings->debugMode = true; if(settings->debugMode) std::cout << "Debug Modus: true" << std::endl; break; case 'h': unterOption_default_help(settings->programName); return -1; default: std::cout << "Aufruf: " << settings->programName << " default [OPTION]... [NAME]..." << std::endl; std::cout << "\"" << settings->programName << " default --help\" liefert weitere Informationen." << std::endl; return -1; } } //Alle nicht verwendeten Parameter == Name while (optind < argc) { if(argv[optind][0]) { settings->name.append(argv[optind++]).append(" "); // optind++ gives the value before ++ back } else ++optind; } if(settings->name.length() > 0) settings->name.pop_back(); if(settings->debugMode) { std::cout << "Name: " << settings->name << std::endl; std::cout << "Modus: DEFAULT_MODUS" << std::endl; } return 0; } void unterOption_default_help(std::string programName) { std::cout << "Aufruf: " << programName << " default [OPTION]... [NAME]" << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man die Downloadlinks von Serien bekommen." << std::endl << std::endl; std::cout << "HOSTEROPTIONEN:" << 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 << " der Reihe nach: Der als erstes angegebene Hoster wird als" << std::endl << " erstes verwendet, wenn er für die Folge vorhanden ist, sonst" << std::endl << " versuche 2ten Hoster,..." << std::endl << " Beachte verwendug mit -l: Die Reihenfolge ist:" << std::endl << " 1.Angegebene Sprache, 1. Angegebener Hoster; 1.Sprache, 2.Hoster,..." << std::endl << " 2.Sprache, 1.Hoster,..." << std::endl << std::endl << " -l [GerDub/GerSub/Eng,...], --languages [GerDub/GerSub/Eng,...]" << std::endl << " Mit dieser Option kann man die Sprachen angeben, von" << std::endl << " 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 << " -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 << " Standart: 1" << std::endl << " -s [Staffel], --start-season [Staffel]" << std::endl << " Mit dieser Option kann man festlegen, mit welcher Staffel das" << std::endl << " Programm startet. Verwende 0 um mit der letzten Staffel zu starten." << std::endl << " Standart: 1" << std::endl << std::endl << " -E [Folge], --stop-episode [Folge]" << std::endl << " Mit dieser Option kann man festlegen, mit welcher Folge" << std::endl << " das Programm stopt. Verwende 0 um die Option zu deaktiviern." << std::endl << " Beachte:" << std::endl << " -> Wenn -S nicht verwendet wird, stopt das Programm" << std::endl << " sobald die angegebene Folge erreicht wurde." << std::endl << " -> Wenn -S auch verwendet wird, stop das Programm" << std::endl << " 1. sobald die angegebene Folge und die angegebene Staffel erreicht" << std::endl << " wurden," << std::endl << " 2. wenn die angegebene Staffel von -S vollendet wurde." << std::endl << " Standert: 0" << std::endl << std::endl << " -S [Staffel], --stop-season [Staffel]" << std::endl << " Mit dieser Option kann man festlegen, mit welcher Staffel" << std::endl << " das Programm stopt. Verwende 0 um die Option zu deaktivieren." << std::endl << " Beachte verwendung mit -E." << std::endl << " Standart: 0" << std::endl << std::endl << "SOCK5PROXY:" << 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" << std::endl << std::endl << "AUSGABEOPTIONEN:" << std::endl << " -o [Pfad], --output-file [Pfad]" << std::endl << " Mit diere Option kann man ein (nichtvorhandenes) Text-Datei" << std::endl << " angeben, inwelches die umgewandelten Redirect-Links geschrieben" << std::endl << " werden. Beachte: Wenn die Datei von -C existiert, dann" << std::endl << " schreibt das Programm kein 'Name: ...' in die Datei." << std::endl << " -c, --colorless" << std::endl << " Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl << " -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 << " -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 << " überprüft, ob eine Datei mit einem bestimmten Muster" << std::endl << " ( Beachte -m ) vorkommt. Wenn diese vorkommt, wird die Folge" << std::endl << " übersprungen." << std::endl << std::endl << " -C [PfadZuTextDatei], --check [PfadZuTextDatei]" << std::endl << " Mit dieser Option kann man eine Textdatei angeben, in der" << std::endl << " bei jedem Durchlauf überprüft wird, ob ein bestimmtes Muster " << std::endl << " vorkommt ( Beachte -m ). Wenn ja, wird die Folge übersprungen." << std::endl << " Tipp: Mit -o zu der gleichen Datei kann verwendet werden, um" << std::endl << " nur neue Folgen einer Serie zu downloaden." << std::endl << " Beachte: Bei verwendung dieser Option, wird kein" << std::endl << " 'Name: ...' in die Datei geschrieben, wenn die" << std::endl << " Datei beim überprüfen existiert." << std::endl << std::endl << " -m [Muster], --check-muster [Muster]" << std::endl << " Mit dieser Option kann man das Muster verändern, das bei" << std::endl << " der Option -C verwendet wird." << std::endl << " %Staffel% kann als Platzhalter für die Staffel im Durch-" << std::endl << " lauf verwendet werde." << std::endl << " %Folge% als Platzhalter für die jeweilige Folge." << std::endl << " Beachte: Bei den Platzhaltern: 01,02,..,09,10,11,..." << std::endl << " Standart: S%Staffel%E%Folge%" << std::endl << std::endl << " -D [AnzahlAnOrdnern], --check-max-dirs [AnzahlAnOrdnern]" << std::endl << " Mit dieser Option kann man die maximale Anzahl an Ordnern" << std::endl << " angeben, die Durchsucht werden sollen." << std::endl << " Standart: 20" << std::endl << std::endl << "MULTITHEADING:" << std::endl << " -t [ThreadAnzahl], --threads [ThreadAnzahl]" << std::endl << " Mit dieser Option kann man das Multihreading aktivieren." << std::endl << " Das Programm startet dann für jede Folge einen neuen" << std::endl << " Thread, bis die angegebene Anzahl an Threads erreicht" << std::endl << " wurde. Dannm wartet es auf das Enden der Threads und" << std::endl << " beginnt von vorne. Verwende 0 um das Multihreading zu" << std::endl << " deaktivieren. Maximal 10 Threads." << std::endl << " Standart: 0" << std::endl << std::endl << "HELPMENUE:" << std::endl << " -h, --help" << std::endl << " Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl; } int unterOption_url(Settings *settings, int argc, char **argv) { settings->modus = Modus::DIRECT_LINK_MODUS; int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"output-file", required_argument, nullptr, 'o'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, {nullptr, no_argument, nullptr, 0} }; while( ( c = getopt_long (argc, argv, "p:o:hcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(optarg && setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; case 'o': if(optarg) settings->outputFilePath = optarg; if(settings->debugMode) std::cout << "Pfad zu Output-Datei: " << settings->outputFilePath << std::endl; break; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; break; case 'd': settings->debugMode = true; if(settings->debugMode) std::cout << "Debug Modus: true" << std::endl; break; case 'h': unterOption_url_help(settings->programName); return -1; default: std::cout << "Aufruf: " << settings->programName << " url [OPTION]... [URL]..." << std::endl; std::cout << "\"" << settings->programName << " url --help\" liefert weitere Informationen." << std::endl; return 21; } } //Alle nicht verwendeten Parameter == Name while (optind < argc) { if(argv[optind][0]) { settings->name.append(argv[optind++]).append(","); } else ++optind; } if(settings->name.length() > 0) settings->name.pop_back(); if(settings->debugMode) { std::cout << "Urls: " << settings->name << std::endl; std::cout << "Modus: DIRECT_LINK_MODUS" << std::endl; } return 0; } void unterOption_url_help(std::string programName) { std::cout << "Aufruf: " << programName << " url [OPTION]... [URL]..." << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunction von " << programName << " können eigene" << std::endl << " Redirect-Links umgewandelt werden. Beispiel:" << std::endl << " https://s.to/redirect/4449825 -> http://vivo.sx/d20b111ade" << std::endl << " Achtung: Achte, dass Url mit https:// nicht mit http:// beginnt." << std::endl << " Standartwerte können im Defaultfile geändert werden." << 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" << std::endl << std::endl << " -o [Pfad], --output-file [Pfad]" << std::endl << " Mit diere Option kann man ein (nichtvorhandenes) Text-Datei angeben," << std::endl << " inwelches die umgewandelten Redirect-Links geschrieben werden." << std::endl << std::endl << " -c, --colorless" << std::endl << " Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl << " -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 << " -h, --help" << std::endl << " Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl; } int unterOption_search(Settings *settings, int argc, char **argv) { settings->modus = Modus::SEARCH_MODUS; int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, {"exactly-writing", no_argument, nullptr, 'e'}, {"update", no_argument, nullptr, 'u'}, {nullptr, no_argument, nullptr, 0} }; while( ( c = getopt_long (argc, argv, "p:hcdeu", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(optarg && setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; case 'h': unterOption_search_help(settings->programName); return -1; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; break; case 'd': settings->debugMode = true; if(settings->debugMode) std::cout << "Debug Modus: true" << std::endl; break; case 'e': settings->search_IgnoreUpperLower = false; if(settings->debugMode) std::cout << "Achte auf Groß und Kleinschreibung: true" << std::endl; break; case 'u': settings->search_wantUpdate = true; if(settings->debugMode) std::cout << "Update die Liste: true" << std::endl; break; default: std::cout << "Aufruf: " << settings->programName << " search [OPTION]... [NAME]..." << std::endl; std::cout << "\"" << settings->programName << " search --help\" liefert weitere Informationen." << std::endl; return 21; } } //Alle nicht verwendeten Parameter == Name while (optind < argc) { if(argv[optind][0]) { settings->name.append(argv[optind++]).append(" "); } else ++optind; } if(settings->name.length() > 0) settings->name.pop_back(); if(settings->debugMode) { std::cout << "Name: " << settings->name << std::endl; std::cout << "Modus: Search_MODUS" << std::endl; } return 0; } void unterOption_search_help(std::string programName) { std::cout << "Aufruf: " << programName << " search [OPTION]... [NAME]" << std::endl << " " << programName << " search [-u, --update] [OPTION]... [NAME]" << std::endl << " " << programName << " search [-u, --update]" << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion des Programms kann man Serien auf s.to suchen." << std::endl << " Tipp: Falls deine Serie nicht gefunden wird, entferne einen Teil" << std::endl << " am Ende deines SuchNamens und wiederhole die Suche." << std::endl << " Tipp: Wenn deine Serie sehr neu auf s.to ist, und deshalb nicht gefunden" << std::endl << " wird, verwende die Option -u, um die Liste zu aktualisieren." << std::endl << std::endl; std::cout << "AKTUALISIERUNG:" << std::endl << " -u, --update" << std::endl << " Mit dieser Option wird die Liste der Serien, die bei der" << std::endl << " Suche durchsucht wird, aktualisiert." << std::endl << std::endl; std::cout << "AKTUALISIERUNGSWARNUNG:" << std::endl << " In der Defaults Datei findest du die Einstellung" << std::endl << " 'search-UpdateWarnungNachTagen' mit der du festlegen kannst," << std::endl << " nach wie vielen Tagen du an das Updaten erinert wirst." << std::endl << " Default: 10 Tage." << 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" << std::endl << std::endl << " -e, --exactly-writing" << std::endl << " Mit dieser Option achtet das Programm auf Groß- und Kleinschreibung." << std::endl << std::endl << " -c, --colorless" << std::endl << " Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl << " -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 << " -h, --help" << std::endl << " Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl << std::endl; } int unterOption_info(Settings *settings, int argc, char **argv) { settings->modus = Modus::INFO_MODUS; int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, {nullptr, no_argument, nullptr, 0} }; while( ( c = getopt_long (argc, argv, "p:hcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(optarg && setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; case 'h': unterOption_info_help(settings->programName); return -1; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; break; case 'd': settings->debugMode = true; if(settings->debugMode) std::cout << "Debug Modus: true" << std::endl; break; default: std::cout << "Aufruf: " << settings->programName << " info [OPTION]... [NAME]..." << std::endl; std::cout << "\"" << settings->programName << " info --help\" liefert weitere Informationen." << std::endl; return 21; } } //Alle nicht verwendeten Parameter == Name while (optind < argc) { if(argv[optind][0]) { settings->name.append(argv[optind++]).append(" "); } else ++optind; } if(settings->name.length() > 0) settings->name.pop_back(); if(settings->debugMode) { std::cout << "Name: " << settings->name << std::endl; std::cout << "Modus: Search_MODUS" << std::endl; } return 0; } void unterOption_info_help(std::string programName) { std::cout << "Aufruf: " << programName << " info [OPTION]... [NAME]" << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man Informationen zu einer Serie bekommen." << 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" << std::endl << std::endl << " -c, --colorless" << std::endl << " Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl << " -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 << " -h, --help" << std::endl << " Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl; } void unterOption_clean(Settings * settings, int argc, char **argv) { if(argc > 2) if(strncmp("--help", argv[2], strlen(argv[2])) == 0) { std::cout << "Aufruf: " << settings->programName << " clean\n " << settings->programName << " clean --help" << std::endl << std::endl << "Beschreibung:" << std::endl << " Mit dieser Unterfunction kann man die Cookie-Dateien löschen." << std::endl << std::endl; return; } unsigned count = 0; if(fileExists(settings->cookieFilePath)) { if(remove(settings->cookieFilePath.c_str()) != 0) { perror(( " => Error: Das löschen von " + settings->cookieFilePath + " ist fehlgeschlagen: ").c_str()); return; } else ++count; } for (unsigned i = 0; i < UINT_MAX && fileExists(settings->cookieFilePath + std::to_string(i)); ++i) { if(remove( (settings->cookieFilePath + std::to_string(i)).c_str() ) != 0) { perror((" => Error: Das löschen von " + settings->cookieFilePath + std::to_string(i) + " ist fehlgeschlagen: ").c_str()); return; } else { ++count; } } if(count == 0) std::cout << " => Nichts zu tun: Keine Cookies vorhanden." << std::endl; else std::cout << " => " << count << " Cookie-File(s) gelöscht." << std::endl; return; } std::vector compare(std::string All_Options_with_komma_between, std::string input) { std::istringstream iStrStream( All_Options_with_komma_between + "\n"); std::vector allFounds; std::string line; while (getline(iStrStream, line).good()) if(strncmp(line.c_str(), input.c_str(), input.length()) == 0) allFounds.push_back(line); return allFounds; } bool dirExists(std::string dir) { struct stat sb; return (stat(dir.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) ? true : false; } bool fileExists (const std::string& name) { struct stat buffer; return (stat (name.c_str(), &buffer) == 0 && S_ISREG(buffer.st_mode)); } bool nothingExists(std::string path) { struct stat buffer; return (stat(path.c_str(), &buffer) == 0) ? false : true; } bool isNumber(std::string number) { bool hasRemovedZero = false; for (size_t i = 0; i < number.length(); ++i) if( number[i] == '0') { number.erase(i, 1); i--; hasRemovedZero=true; } if(hasRemovedZero && number == "") number="0"; return (std::to_string(atoll(number.c_str())) == number) ? true : false; } int setS5ProxytoSettings(Settings &settings, std::string Optarg) { std::string optarg = Optarg; //Ersetze localhost mit 127.0.0.1 if(optarg.find("localhost") != std::string::npos) optarg.insert(optarg.find("localhost"), "127.0.0.1").erase(optarg.find("localhost"), 9); //Wenn optarg keine vollständige Addresse ( ip:port ) ist: if(optarg.find(":") == std::string::npos) { //Wenn optarg eine Zahl ist, also Port: if(isNumber(optarg)) { settings.proxy_port = atoi(optarg.c_str()); //Wenn es scheint eine Ip zu sein, also mit '.': } else if (optarg.find(".") != std::string::npos) { settings.proxy_ip = optarg; // Sonst error: } else { std::cout << " => Error: Ungültige Socks5 Proxy Addresse: '" << Optarg << "'." << std::endl; return 1; } // Wenn vollständige Addr: } else { //setze schein Ip: settings.proxy_ip = optarg.substr(0, optarg.find(":")); //setze Port, falls dieser eine Zahl ist: std::string tmpPort = optarg.substr(optarg.find(":") + 1, optarg.length() - optarg.find(":")); if(isNumber(tmpPort)) settings.proxy_port = atoi(optarg.substr(optarg.find(":") + 1, optarg.length() - optarg.find(":")).c_str()); else { std::cout << " => Error: Ungültiger Socks5 Proxy Port: '" << tmpPort << "'."<< std::endl; return 2; } } //Überprüfe ob Ip aus 3 * '.' besteht und dann eine Zahl ist: std::string tmpIp = settings.proxy_ip; for (int i = 0; i < 3; ++i) { if(tmpIp.find(".") != std::string::npos) { tmpIp.erase(static_cast(tmpIp.find(".")), 1); } else { std::cout << " => Error: Ungültige Socks5 Proxy Ip Addresse: '" << settings.proxy_ip << "'." << std::endl; return 3; } } if(!isNumber(tmpIp)) { std::cout << " => Error: Ungültige Socks5 Proxy Ip Addresse: '" << settings.proxy_ip << "'." << std::endl; return 4; // Überprüfe ob Port Positiv oder 0 und kliner als 2 Byte ist: } else if (settings.proxy_port < 0 || settings.proxy_port > 65535) { std::cout << " => Error: Ungültiger Socks5 Proxy Port ( 0 bis 65535): " << settings.proxy_port << std::endl; return 5; //Debug Nachricht: } else if(settings.debugMode) std::cout << " > Defaults: Proxy Addresse: "<< settings.proxy_ip << ":" << settings.proxy_port << std::endl; return 0; } bool makePathIsOk(std::string path) { if(path == "") { std::cout << " => Error: Üngültiger Pfad: ''." << std::endl; return false; } else if (path[path.length()-1] == '/' || path[path.length()-1] == '\\') path.pop_back(); if(createDirIsOk(path)) return true; else if(errno == ENOENT) { size_t pos = path.find_last_of("/\\"); if (pos == static_cast(std::string::npos)) return false; else if (!makePathIsOk( path.substr(0, pos) )) return false; // now, try to create again return createDirIsOk(path); } else if (errno == EEXIST) { return dirExists(path); } else { perror((" => Error: Erstellen von '" + path +"' ist fehlgeschlagen").c_str()); return false; } } bool createDirIsOk(std::string path) { #ifdef __linux__ if(mkdir(path.c_str(), 0777) != 0) { #endif #ifdef _WIN32 if(mkdir(path.c_str()) != 0) { #endif //perror((" => Error: Erstellen von dem Ordner '" + path + "' ist fehlgeschlagen").c_str()); return false; } else return dirExists(path); } int unterOption_news(Settings *settings, int argc, char **argv) { settings->modus = Modus::NEWS_MODUS; int c = 0; const option long_opts[] = { {"socks5-proxy", required_argument, nullptr, 'p'}, {"help", no_argument, nullptr, 'h'}, {"colorless", no_argument, nullptr, 'c'}, {"debug-mode", no_argument, nullptr, 'd'}, {nullptr, no_argument, nullptr, 0} }; while( ( c = getopt_long (argc, argv, "p:hcd", long_opts, nullptr) ) != -1 ) { switch(c) { case 'p': if(optarg && setS5ProxytoSettings(*settings, optarg) != 0) return 2; break; case 'h': unterOption_news_help(settings->programName); return -1; case 'c': settings->colorless = true; if(settings->debugMode) std::cout << "Farblos: true" << std::endl; break; case 'd': settings->debugMode = true; if(settings->debugMode) std::cout << "Debug Modus: true" << std::endl; break; default: std::cout << "Aufruf: " << settings->programName << " info [OPTION]... [NAME]..." << std::endl; std::cout << "\"" << settings->programName << " info --help\" liefert weitere Informationen." << std::endl; return 21; } } if(settings->debugMode) std::cout << "Modus: Search_MODUS" << std::endl; return 0; } void unterOption_news_help(std::string programName) { std::cout << "Aufruf: " << programName << " news [OPTION]..." << std::endl << std::endl; std::cout << "Beschreibung:" << std::endl << " Mit dieser Unterfunktion kann man die neuesten Folgen auf s.to sehen." << 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" << std::endl << std::endl << " -c, --colorless" << std::endl << " Mit dieser Option kann man die farbige Ausgabe ausstellen." << std::endl << std::endl << " -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 << " -h, --help" << std::endl << " Mit dieser Option wird dieses Helpmenue ausgegeben." << std::endl; }