forked from markus/S_New4
827 lines
36 KiB
C++
827 lines
36 KiB
C++
#include "programManager.h"
|
|
|
|
|
|
ProgramManager::ProgramManager()
|
|
: nextThread(0)
|
|
{
|
|
|
|
}
|
|
|
|
ProgramManager::~ProgramManager()
|
|
{
|
|
for(auto e : threadList) {
|
|
delete e->pageManager;
|
|
delete e;
|
|
e = nullptr;
|
|
}
|
|
}
|
|
|
|
int ProgramManager::start(Settings *settings)
|
|
{
|
|
pageManager.setProxy(settings->proxy_ip, settings->proxy_port);
|
|
pageManager.setDebugMode(settings->debugMode);
|
|
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;
|
|
return 174;
|
|
}
|
|
|
|
switch (settings->modus) {
|
|
case Modus::DEFAULT_MODUS:
|
|
return defaultModus(settings);
|
|
case Modus::DIRECT_LINK_MODUS:
|
|
return directLinkModus(settings);
|
|
case Modus::SEARCH_MODUS:
|
|
return searchModus(settings);
|
|
case Modus::INFO_MODUS:
|
|
return infoModus(settings);
|
|
default:
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
void * threadFunction(void * data) {
|
|
ThreadData * myThreadData = reinterpret_cast<struct ThreadData*>(data);
|
|
myThreadData->returnValue="";
|
|
myThreadData->exitState=0;
|
|
|
|
|
|
Reply tmp_reply = myThreadData->pageManager->getServerRequest(myThreadData->pageManager->UrlPraefix + myThreadData->nameInUrl
|
|
+ "/staffel-" + std::to_string(myThreadData->staffel) + "/episode-" + std::to_string(myThreadData->folge));
|
|
if(tmp_reply.html == "-1")
|
|
return myThreadData->setState(10);
|
|
std::string allLinks = myThreadData->pageManager->getLinks(tmp_reply.html);
|
|
std::string Link = myThreadData->pageManager->chooseHosterLink(allLinks, myThreadData->settings->genaueHoster, myThreadData->settings->languages);
|
|
|
|
if(myThreadData->settings->debugMode)
|
|
std::cout << " > Thread " << myThreadData->id << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://s.to") << Link << ( (Link == "") ? "" : "'\n" );
|
|
|
|
|
|
|
|
|
|
std::string folgenID = std::string((myThreadData->staffel == -1 || myThreadData->folge == -1 ) ? "" : "S" + std::string( (myThreadData->staffel < 10) ? "0" : "" ) + std::to_string(myThreadData->staffel)
|
|
+ "E" + std::string( (myThreadData->folge < 10) ? "0" : "" ) + std::to_string( myThreadData->folge ) );
|
|
std::string green = ((myThreadData->settings->colorless) ? "" : "\033[32m"),
|
|
red = ((myThreadData->settings->colorless) ? "" : "\033[31m"),
|
|
orange =((myThreadData->settings->colorless) ? "" : "\033[33m"),
|
|
blue = ((myThreadData->settings->colorless) ? "" : "\033[34m");
|
|
|
|
if(Link == "") {
|
|
if(allLinks == "") {
|
|
myThreadData->returnValue = " => " + red + "KEINEN Hoster für die Folge " + folgenID + " gefunden." + "\033[0m";
|
|
if(myThreadData->pageManager->writeToFile(myThreadData->settings->outputFilePath, std::string("KEINEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0)
|
|
return myThreadData->setState(14);
|
|
}
|
|
else {
|
|
myThreadData->returnValue = " => " + orange + "Keinen PASSENDEN Hoster für die Folge " + folgenID + " gefunden." + "\033[0m" + "\n"
|
|
+ "Alle Links:" + "\n"
|
|
+ myThreadData->pageManager->replace( myThreadData->pageManager->replace( myThreadData->pageManager->replace( allLinks, "data-lang-key=\"1\"", "language=\"GerDub\"" ),
|
|
"data-lang-key=\"2\"", "language=\"Eng\"" ), "data-lang-key=\"3\"", "language=\"GerSub\"");
|
|
if(myThreadData->pageManager->writeToFile(myThreadData->settings->outputFilePath, std::string("Keinen PASSENDEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0)
|
|
return myThreadData->setState(15);
|
|
}
|
|
return myThreadData->setState(0);
|
|
}
|
|
|
|
for (int i = 1; i <= 3; ++i) {
|
|
std::string newUrl = myThreadData->pageManager->getUrlAfterRedirect("https://s.to" + Link);
|
|
if (newUrl == "-1") {
|
|
return myThreadData->setState(16);
|
|
} else if(newUrl.find("/s.to/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)
|
|
return myThreadData->setState(17);
|
|
continue;
|
|
|
|
} else {
|
|
myThreadData->returnValue = " => " + folgenID + ( (folgenID == "") ? "" : ": " ) + green + newUrl + "\033[0m";
|
|
if(myThreadData->settings->outputFilePath != "")
|
|
if(myThreadData->pageManager->writeToFile(myThreadData->settings->outputFilePath,folgenID + ( (folgenID == "") ? "" : ": " ) + newUrl) != 0)
|
|
return myThreadData->setState(18);
|
|
return myThreadData->setState(0);
|
|
}
|
|
}
|
|
myThreadData->returnValue = " => " + folgenID + ( (folgenID == "") ? "" : ": " ) + red + "https://s.to" + Link + "\033[0m";
|
|
if(myThreadData->settings->outputFilePath != "")
|
|
if(myThreadData->pageManager->writeToFile(myThreadData->settings->outputFilePath, folgenID + ( (folgenID == "") ? "" : ": " ) + Link) != 0)
|
|
return myThreadData->setState(19);
|
|
return myThreadData->setState(0);
|
|
|
|
}
|
|
|
|
int ProgramManager::waitForThreads()
|
|
{
|
|
for( auto &e : threadList) {
|
|
if( e->exitState != -1 && pthread_join(e->thread, nullptr) == 0) {
|
|
if(e->exitState != 0) {
|
|
std::cout << "\33[2K\r => Error: Thread gab error zurück." << std::endl;
|
|
return e->exitState;
|
|
} else
|
|
if(e->returnValue != "")
|
|
std::cout << ("\33[2K\r(T" + std::to_string(e->id) + ")" + e->returnValue ) << std::endl;
|
|
}
|
|
e->exitState = -1;
|
|
e->returnValue = "";
|
|
e->setData(0, 0);
|
|
e->thread = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::sucheNach_1_Serien(Settings *settings, PageManager &pageManager, std::string &newName)
|
|
{
|
|
std::string finds;
|
|
if(searchModus(settings, &finds) != 0)
|
|
return 24;
|
|
else if(finds.find("/") == std::string::npos || finds.find("|") == std::string::npos || finds.find("\n") != std::string::npos)
|
|
return 45;
|
|
else if ( (finds = finds.substr( finds.find("/") + 1, finds.find("|", finds.find("/")) - finds.find("/") -1) ) == "" ) {
|
|
std::cout << " => Error: Konnte den Namen aus der zurückgegebenen Zeile nicht extrahieren." << std::endl;
|
|
return 46;
|
|
} else if ( (newName = pageManager.checkName(finds)) == "-1") {
|
|
std::cout << " => Error: Konnte die von der Suche vorgeschlagene Serie nicht finden." << std::endl;
|
|
return 47;
|
|
}
|
|
std::cout << "Ist das deine gewünschte Serie? Drücke nur Enter um fortzufahren: " << std::flush;
|
|
std::getline(std::cin, finds);
|
|
if ( finds != "") {
|
|
std::cout << " => Abbruch..." << std::endl;
|
|
return 48;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::defaultModus(Settings *settings)
|
|
{
|
|
AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath);
|
|
|
|
//Wenn kein Name mit -n Angegeben wurde:
|
|
if(settings->name == "") {
|
|
if(settings->default_checkPath != "") {
|
|
if(settings->default_checkPath[settings->default_checkPath.length()-1] == settings->pathSymbol)
|
|
settings->default_checkPath.pop_back();
|
|
size_t pos = settings->default_checkPath.find_last_of(std::string(1, settings->pathSymbol));
|
|
if( pos != std::string::npos) {
|
|
settings->name = settings->default_checkPath.substr(pos + 1);
|
|
if(settings->debugMode)
|
|
std::cout << " > Use Path from -C for Name: " << settings->default_checkPath << " -> " << settings->name << std::endl;
|
|
}
|
|
} if(settings->name == "") {
|
|
std::cout << " => Error: Kein Name angegeben." << std::endl;
|
|
std::cout << "Aufruf: " << getProgramName() << " default [OPTION]... [NAME]..." << std::endl;
|
|
std::cout << "\"" << getProgramName() << " default --help\" liefert weitere Informationen." << std::endl;
|
|
return 27;
|
|
}
|
|
}
|
|
|
|
//Überprüfe ob ein Muster existiert:
|
|
if(settings->default_checkPath != "" && settings->default_Searchmuster == "") {
|
|
std::cout << " => Error: [-m]: Kein Muster angegeben." << std::endl;
|
|
return 31;
|
|
}
|
|
|
|
|
|
//Liste alle Dateien in dem Ornder von -C auf und speichere diese
|
|
std::string dirFiles;
|
|
if(settings->default_checkPath != "")
|
|
if(listDir(dirFiles, settings->default_checkPath, settings->default_maxDirs ) != 0)
|
|
return 28;
|
|
if(dirFiles.length() > 0) //Entferne von der liste das \n am ende
|
|
dirFiles.pop_back();
|
|
if(settings->debugMode && settings->default_checkPath != "") //Wenn Debug Mode, gib die Liste aus
|
|
std::cout << " > [-C] Files:\n" << dirFiles << std::endl;
|
|
|
|
|
|
//Führe Function aus, die überprüft ob die serie existiert
|
|
std::string nameInUrl =pageManager.checkName(settings->name);
|
|
if(nameInUrl == "-1") {
|
|
//Wenn nicht, dann fühe noch eine Suche nach ähnlichen durch && Wenn nur 1ne dacnn frag ob es diese ist.
|
|
if( sucheNach_1_Serien(settings, pageManager, nameInUrl) != 0)
|
|
return 202;
|
|
}
|
|
|
|
/* Wenn multihtreading seaktiviert ist, normal login sonst bereite threads vor
|
|
if(settings->maxThreads == 0) {
|
|
// melde bei s.to 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 ))) {
|
|
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;
|
|
return 174;
|
|
}
|
|
PageManager * pm = new PageManager(settings->proxy_ip + ":" + std::to_string(settings->proxy_port), settings->cookieFilePath + std::to_string( i ));
|
|
pm->setDebugMode(settings->debugMode);
|
|
|
|
//pm->setProxy(settings->proxy_ip, settings->proxy_port);
|
|
//pm->setCookieFilePath(settings->cookieFilePath + std::to_string( i ));
|
|
|
|
ThreadData * newThreadData = new ThreadData(i, 0, nameInUrl, -1, settings, &accountManager, pm);
|
|
threadList.push_back(newThreadData);
|
|
}
|
|
}
|
|
|
|
//Write Name to File if -o is set und kein TXT-FILE angegeben wird
|
|
if(settings->outputFilePath != "" && !fileExists( settings->default_checkPath ))
|
|
if(pageManager.writeToFile(settings->outputFilePath, "Name: " + settings->name) != 0)
|
|
return 31;
|
|
|
|
//Finde die anzahl der staffel heraus:
|
|
//download html von der startpage einer serie
|
|
Reply tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl);
|
|
if(tmp_reply.html == "-1")
|
|
return 32;
|
|
//speicher zahl -1, ab da wo /staffel-x nicht mehr vorkommt
|
|
int maxStaffel = pageManager.counterContains(tmp_reply.html, "/staffel-%i");
|
|
|
|
if(settings->debugMode)
|
|
std::cout << " > Die Serie " << settings->name << " hat " << maxStaffel << " Staffeln." << std::endl;
|
|
|
|
//For every season
|
|
if(settings->startSeason == 0)
|
|
settings->startSeason = maxStaffel;
|
|
for (int staffel = settings->startSeason; staffel <= maxStaffel; ++staffel) {
|
|
//Test for stopping Program caused -E, -S
|
|
if(staffel > settings->stopSeason && settings->stopSeason > 0) {
|
|
if(settings->debugMode)
|
|
std::cout << " > Stoppe, weil Staffel: " << staffel << " > StopStaffel " << settings->stopSeason << std::endl;
|
|
std::cout << " > Fertig, da Staffel " << staffel << " größer ist als StopStaffel " << settings->stopSeason << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
//Find out number of all episodes
|
|
tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel));
|
|
if(tmp_reply.html == "-1")
|
|
return 40;
|
|
int maxFolge = pageManager.counterContains(tmp_reply.html, "/episode-%i");
|
|
|
|
if(settings->debugMode)
|
|
std::cout << " > Die Staffel " << staffel << " hat " << maxFolge << " Folgen." << std::endl;
|
|
|
|
//for every episode
|
|
for (int folge = settings->startEpisode; folge <= maxFolge; ++folge) {
|
|
// stoppe wenn stopfolge größer der folge ist und stopstaffel nicht gesetzt wurde. und stopepisode gröser 0, also aktiv ist
|
|
if(folge > settings->stopEpisode && settings->stopSeason < 1 && settings->stopEpisode > 0) {
|
|
if(settings->maxThreads != 0)
|
|
if(waitForThreads() != 0)
|
|
return 261;
|
|
std::cout << " > Fertig, da Folge " << folge << " größer ist als Stopfolge " << settings->stopEpisode << "."<< std::endl;
|
|
return 0;
|
|
|
|
} else if ( folge > settings->stopEpisode && staffel >= settings->stopSeason && settings->stopEpisode > 0) { // stoppe wenn stopfolge > folge && stopstaffel >= staffel und stopepisode gröser 0, also aktiv ist
|
|
if(settings->maxThreads != 0)
|
|
if(waitForThreads() != 0)
|
|
return 267;
|
|
std::cout << " > Fertig, da Folge " << folge << " größer ist als Stopfolge " << settings->stopEpisode << std::endl
|
|
<< " und Staffel " << staffel << " größer gleich Stopstaffel " << settings->stopSeason << " ist." << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
//Überprüfe ob, wenn -C vorhanden, die Folge in dem Ordner bereits vorkommt.
|
|
if(settings->default_checkPath != "") {
|
|
if(dirFiles.find(pageManager.replace( pageManager.replace( settings->default_Searchmuster, "%Staffel%", ((staffel < 10) ? "0" : "") + std::to_string(staffel) ),
|
|
"%Folge%", ((folge < 10) ? "0" : "") + std::to_string(folge) ) ) != std::string::npos) {
|
|
if(settings->debugMode)
|
|
std::cout << " > Skippe Folge: S" << staffel << "E" << folge << std::endl;
|
|
continue;
|
|
}
|
|
}
|
|
|
|
//Multihreading Mode
|
|
if(settings->maxThreads > 0) {
|
|
//Wenn nex Thread noch in den Vector passt(weniger Threads als Max), dann Starte neuen mit data aus dem Vector...
|
|
if(nextThread < threadList.size()) {
|
|
threadList[nextThread]->exitState = 0;
|
|
threadList[nextThread]->setData(staffel, folge);
|
|
if(pthread_create(&threadList[nextThread]->thread, nullptr, threadFunction, reinterpret_cast<void*>(threadList[nextThread])) != 0 ) {
|
|
perror("pthread_creat failed");
|
|
return 48;
|
|
}
|
|
nextThread++;
|
|
} else { // Sonnst warte bis alle Fertig sind und restarte die Folge
|
|
if(waitForThreads() != 0)
|
|
return 231;
|
|
nextThread=0;
|
|
folge--;
|
|
continue;
|
|
}
|
|
|
|
} else { // Default Mode
|
|
tmp_reply =pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl + "/staffel-" + std::to_string(staffel) + "/episode-" + std::to_string(folge));
|
|
if(tmp_reply.html == "-1")
|
|
return 50;
|
|
std::string allLinks = pageManager.getLinks(tmp_reply.html);
|
|
std::string Link = pageManager.chooseHosterLink(allLinks, settings->genaueHoster, settings->languages);
|
|
|
|
if(settings->debugMode)
|
|
std::cout << allLinks << std::endl << ( (Link == "") ? "" : " -> Link: 'https://s.to") << Link << ( (Link == "") ? "" : "'\n" );
|
|
if(convertLink(Link, &accountManager, settings, staffel, folge, allLinks) != 0)
|
|
return 51;
|
|
|
|
}
|
|
}
|
|
//Setzte Startepisode zurück für nächste Staffel
|
|
settings->startEpisode = 1;
|
|
}
|
|
|
|
if(settings->maxThreads != 0)
|
|
if(waitForThreads() != 0)
|
|
return 292;
|
|
|
|
std::cout << " > Fertig" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::directLinkModus(Settings *settings)
|
|
{
|
|
AccountManager accountManager(settings->accountFilePath, settings->accountNumberPath);
|
|
|
|
if(settings->name == "") {
|
|
std::cout << " => Error: Kein(e) Link(s) angegeben." << std::endl;
|
|
std::cout << "Aufruf: " << getProgramName() << " url [OPTION]... [URL]..." << std::endl;
|
|
std::cout << "\"" << getProgramName() << " url --help\" liefert weitere Informationen." << std::endl;
|
|
return 76;
|
|
}
|
|
|
|
std::istringstream iStrStream( pageManager.replace( settings->name, ",", "\n" ) + "\n" );
|
|
std::string line;
|
|
|
|
//if(pageManager.login(accountManager.getNextAccount()) != 0)
|
|
// return 71;
|
|
|
|
while (getline(iStrStream, line).good()) {
|
|
if(line.find("https://s.to/redirect/") == std::string::npos) {
|
|
std::cout << " => Error: Invalid Redirect Link: '" << line << "'" << std::endl;
|
|
continue;
|
|
}
|
|
else if(convertLink(pageManager.replace(line, "https://s.to", ""), &accountManager, settings) != 0)
|
|
return 78;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::searchModus(Settings *settings, std::string *saveTo)
|
|
{
|
|
if(settings->search_wantUpdate) {
|
|
int res = searchModus_update(settings) ;
|
|
if( res == 0)
|
|
std::cout << "Erfolgreich geupdatet: Die Serienliste ist nun auf dem neusten Stand." << std::endl;
|
|
else
|
|
std::cout << " => Error: Das updaten der Serienliste ist fehlgeschlagen." << std::endl;
|
|
return res;
|
|
|
|
} else if(settings->name == "") {
|
|
std::cout << " => Error: Kein Name angegeben." << std::endl;
|
|
std::cout << "Aufruf: " << getProgramName() << " search [OPTION]... [NAME]..." << std::endl;
|
|
std::cout << "\"" << getProgramName() << " search --help\" liefert weitere Informationen." << std::endl;
|
|
return 27;
|
|
}
|
|
|
|
std::ifstream ifs(settings->serienListPath);
|
|
if(!ifs.is_open()) {
|
|
std::cout << "Keine SerienListe vorhanden. Erstelle eine neue..." << std::endl;
|
|
if(searchModus_update(settings) != 0)
|
|
return 354;
|
|
else {
|
|
ifs.open(settings->serienListPath);
|
|
if(!ifs.is_open()) {
|
|
perror(" => Error: Couldn't open SerienList file after update again.");
|
|
return 434;
|
|
}
|
|
std::cout << "Erfolgreich gedownloadet." << std::endl;
|
|
}
|
|
}
|
|
|
|
//Save file in string:
|
|
std::string serienListe((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
|
|
|
|
//Suche alle Möglichkeiten
|
|
std::string finds = pageManager.grep(serienListe, settings->name, settings->search_IgnoreUpperLower);
|
|
serienListe.clear(); // Speicher freigeben
|
|
|
|
/*//Text mit Farben versehen
|
|
if(!settings->colorless) {
|
|
for (size_t pos = pageManager.upper_string( finds ).find( pageManager.upper_string( settings->name ), 0);
|
|
pos != std::string::npos;
|
|
pos = pageManager.upper_string( finds ).find( pageManager.upper_string( settings->name ), pos + settings->name.length() + strlen("\033[37m\033[0m")))
|
|
finds.insert(pos, ( (finds.find(settings->name, pos) == pos) ? "\033[32m" : "\033[36m" ) ).insert(pos + settings->name.length() + strlen("\033[37m"), "\033[0m");
|
|
}*/
|
|
|
|
if(saveTo) {
|
|
//Save List to Variable if set
|
|
*saveTo=finds;
|
|
}
|
|
|
|
//Text mit Farben versehen
|
|
if(!settings->colorless) {
|
|
std::string UpperFinds = pageManager.upper_string( finds );
|
|
std::string UpperName = pageManager.upper_string( settings->name );
|
|
for (size_t pos = UpperFinds.find( UpperName, 0); pos != std::string::npos; pos = UpperFinds.find( UpperName, pos + settings->name.length() + strlen("\033[37m\033[0m"))) {
|
|
bool exaktGeschrieben = (finds.find(settings->name, pos) == pos);
|
|
finds.insert(pos, ( (exaktGeschrieben) ? "\033[32m" : "\033[36m" ) ).insert(pos + settings->name.length() + strlen("\033[37m"), "\033[0m");
|
|
UpperFinds.insert(pos, ( (exaktGeschrieben ) ? "\033[32m" : "\033[36m" ) ).insert(pos + settings->name.length() + strlen("\033[37m"), "\033[0m");
|
|
}
|
|
}
|
|
//Ausgabe
|
|
if(finds == "") {
|
|
std::cout << " => Für '" << settings->name << "' wurde(n) keine Serie(n) gefunden." << std::endl;
|
|
return 0;
|
|
}
|
|
std::stringstream strstream(finds);
|
|
std::string line;
|
|
std::cout << " => Für '" << settings->name << "' wurde(n) folgende Serie(n) gefunden: " << std::endl;
|
|
while (getline(strstream, line)) {
|
|
std::cout << " > " << line.substr(line.find("|", line.find("/")) + 1, line.length() - line.find("|", line.find("/")) -1 )
|
|
<< "\t[" << line.substr(line.find("/") + 1, line.find("|", line.find("/")) - line.find("/") - 1) << "]"
|
|
<< ( (line[0] == '|') ? "" : "\t( " + line.substr(0, line.find("|")) + " )" ) << std::endl;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::infoModus(Settings *settings)
|
|
{
|
|
if(settings->name == "") {
|
|
std::cout << " => Error: Kein Name angegeben." << std::endl;
|
|
std::cout << "Aufruf: " << getProgramName() << " info [OPTION]... [NAME]..." << std::endl;
|
|
std::cout << "\"" << getProgramName() << " info --help\" liefert weitere Informationen." << std::endl;
|
|
return 27;
|
|
}
|
|
|
|
//Führe Function aus, die überprüft ob die serie existiert
|
|
std::string nameInUrl = pageManager.checkName(settings->name);
|
|
if(nameInUrl == "-1") {
|
|
//Wenn nicht, dann fühe noch eine Suche nach ähnlichen durch.
|
|
if( sucheNach_1_Serien(settings, pageManager, nameInUrl) != 0)
|
|
return 28;
|
|
}
|
|
|
|
//Finde Anzahl der Staffel heraus:
|
|
Reply tmp_reply = pageManager.getServerRequest(pageManager.UrlPraefix + nameInUrl);
|
|
if(tmp_reply.html == "-1")
|
|
return 32;
|
|
|
|
//speicher (zahl -1), ab da wo /staffel-x nicht mehr vorkommt
|
|
int maxStaffel = pageManager.counterContains(tmp_reply.html, "/staffel-%i");
|
|
|
|
//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));
|
|
if(tmpReply.html == "-1")
|
|
return 40;
|
|
std::cout << "Die Staffel " << staffel << " hat " << pageManager.counterContains(tmpReply.html, "/episode-%i") << " Folge(n)." << std::endl;
|
|
|
|
std::string html = tmpReply.html;
|
|
size_t pos = 0;
|
|
if( (pos = html.find("<tr ")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '<tr ' nicht finden." << std::endl;
|
|
return 41;
|
|
} else
|
|
html.erase(0, pos);
|
|
if( (pos = html.find("</tbody>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '</tbody>' nicht finden." << std::endl;
|
|
return 42;
|
|
} else
|
|
html.erase(pos, std::string::npos);
|
|
|
|
html = pageManager.replace(html, "\n", "");
|
|
html = pageManager.replace(html, "</tr>", "\n");
|
|
|
|
std::stringstream folgenListe(html);
|
|
std::string line;
|
|
while (std::getline(folgenListe, line).good()) {
|
|
std::string titel;
|
|
|
|
if( (pos = line.find("\"> Folge")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '\"> Folge' nicht finden." << std::endl;
|
|
return 43;
|
|
} else
|
|
line.erase(0, pos + 3);
|
|
if( (pos = line.find(" </a>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von ' </a>' nicht finden." << std::endl;
|
|
return 44;
|
|
}
|
|
std::cout << " Staffel " << staffel << " " << line.substr(0, pos) << ":" <<std::endl;
|
|
|
|
if( (pos = line.find("<strong>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '<strong>' nicht finden." << std::endl;
|
|
return 43;
|
|
} else
|
|
line.erase(0, pos + 8);
|
|
if( (pos = line.find("</strong>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '</strong>' nicht finden." << std::endl;
|
|
return 44;
|
|
}
|
|
titel = line.substr(0, pos);
|
|
if(titel != "")
|
|
std::cout << " > Titel1: " << titel << std::endl;
|
|
|
|
if( (pos = line.find("<span>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '<span>' nicht finden." << std::endl;
|
|
return 43;
|
|
} else
|
|
line.erase(0, pos + 6);
|
|
if( (pos = line.find("</span>")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte Position von '</span>' nicht finden." << std::endl;
|
|
return 44;
|
|
}
|
|
titel = line.substr(0, pos);
|
|
if(titel != "")
|
|
std::cout << " > Titel2: " << titel << std::endl;
|
|
}
|
|
|
|
}
|
|
|
|
//Datum & FSK
|
|
std::string line = pageManager.grep(tmp_reply.html, "<small> (<span itemprop=\"startDate\"><a");
|
|
if(line == "") {
|
|
std::cout << " => Error: Konnte '<small> (<span itemprop=\"startDate\"><a' nicht finden." << std::endl;
|
|
return 83;
|
|
}
|
|
|
|
std::string startStopDates[2];
|
|
size_t pos = 0, pos2 = 0;
|
|
|
|
//Date
|
|
for (int i = 0; i < 2; ++i) {
|
|
if( (pos = line.find("href=")) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte 'href=' nicht finden." << std::endl;
|
|
return 84;
|
|
} else
|
|
line.erase(0, pos + 5);
|
|
|
|
if( (pos = line.find(">")) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte '>' nicht finden." << std::endl;
|
|
return 85;
|
|
} else if ((pos2 = line.find("</a>")) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte '</a>' nicht finden." << std::endl;
|
|
return 86;
|
|
}
|
|
startStopDates[i] = line.substr(pos + 1, pos2 - pos -1);
|
|
}
|
|
|
|
//FSK
|
|
if( (pos = line.find("data-fsk=\"")) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte 'data-fsk=\"' nicht finden." << std::endl;
|
|
return 87;
|
|
} else if ((pos2 = line.find("\" class=\"fsk")) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte '\" class=\"fsk' nicht finden." << std::endl;
|
|
return 86;
|
|
}
|
|
std::string fsk = line.substr(pos + 10, pos2 -pos - 10);
|
|
|
|
//Deskription
|
|
if( (pos = tmp_reply.html.find("data-full-description=")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte 'data-full-description=' nicht finden." << std::endl;
|
|
return 83;
|
|
} else if ((pos2 = tmp_reply.html.find("\">", pos)) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte '\">' nicht finden." << std::endl;
|
|
return 86;
|
|
}
|
|
std::string description = pageManager.replace( pageManager.replace( tmp_reply.html.substr(pos + 23, pos2 - pos - 23), "\n", "" ), "<br />", "" );
|
|
|
|
//Genres
|
|
std::vector<std::string> genres;
|
|
line = pageManager.grep(tmp_reply.html, "\"genre\">");
|
|
if(line == "") {
|
|
std::cout << " => Error: Konnte '\"genre\">' nicht finden." << std::endl;
|
|
return 87;
|
|
}
|
|
for (pos = line.find("\"genre\">"); pos != std::string::npos; pos = line.find("\"genre\">", pos + 7)) {
|
|
if( (pos2 = line.find("</a>", pos)) == std::string::npos) {
|
|
std::cout << " => Error: Konnte '</a>' nicht finden." << std::endl;
|
|
return 89;
|
|
}
|
|
genres.push_back(line.substr(pos + 8, pos2 - pos - 8));
|
|
}
|
|
|
|
//CoverLink
|
|
line = pageManager.grep(tmp_reply.html, "title=\"Cover");
|
|
if( (pos = line.find("data-src=\"")) == std::string::npos) {
|
|
std::cout << " => Error: Konnte 'data-src=\"' nicht finden." << std::endl;
|
|
return 90;
|
|
} else if ((pos2 = line.find("\"", pos + 10)) == std::string::npos ) {
|
|
std::cout << " => Error: Konnte '\"' nicht finden." << std::endl;
|
|
return 86;
|
|
}
|
|
std::string coverLink = line.substr(pos + 10, pos2 - pos -10);
|
|
|
|
|
|
|
|
|
|
std::cout << "Produktion von " << startStopDates[0] << " bis " << startStopDates[1] << std::endl
|
|
<< "FSK: " << fsk << std::endl
|
|
<< "Cover Bild: " << coverLink << std::endl
|
|
<< "Genre(s): " << std::flush;
|
|
for( const auto &e : genres)
|
|
std::cout << e << " ";
|
|
|
|
std::cout << std::endl << "\nBeschreibung: " << description << std::endl;
|
|
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::searchModus_update(Settings *settings)
|
|
{
|
|
Reply reply = pageManager.getServerRequest("https://s.to/serien");
|
|
if(reply.html == "-1")
|
|
return 21;
|
|
else if(reply.html.find("</html>") == std::string::npos ) {
|
|
std::cout << " => Error: Konnte </html> in searchModus_update() nicht finden." << std::endl;
|
|
return 22;
|
|
}
|
|
|
|
std::string serienListe = pageManager.replace( pageManager.grep( reply.html, "data-alternative-title" ), "</li>", "\n" );
|
|
|
|
if(reply.html.find("\" href=\"") == std::string::npos ||
|
|
reply.html.find("<li><a data-alternative-title=\"") == std::string::npos ||
|
|
reply.html.find("/serie/stream/") == std::string::npos ||
|
|
reply.html.find("</a>") == std::string::npos)
|
|
return 51;
|
|
|
|
//...\n<li><a data-alternative-title="" href="/serie/stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null</a>\n...
|
|
serienListe = pageManager.replace(serienListe, "<li><a data-alternative-title=\"", "");
|
|
//...\n" href="/serie/stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null</a>\n...
|
|
serienListe = pageManager.replace(serienListe, "\" href=\"", "|");
|
|
//...\n|/serie/stream/2012-das-jahr-null" title="2012 - Das Jahr Null Stream anschauen">2012 - Das Jahr Null</a>\n...
|
|
serienListe = pageManager.replace(serienListe, "|/serie/stream/", "|/");
|
|
|
|
std::stringstream strstream(serienListe);
|
|
std::string line;
|
|
serienListe.clear();
|
|
|
|
while (getline(strstream, line)) {
|
|
if(line.find(" title=\"") == std::string::npos)
|
|
continue;
|
|
line.erase(line.find(" title="), line.find(">") - line.find(" title="));
|
|
//...\n|/serie/stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null</a>\n...
|
|
line = pageManager.replace(line, "\">", "|");
|
|
//...\n|/serie/stream/2012-das-jahr-null|2012 - Das Jahr Null</a>\n...
|
|
line = pageManager.replace(line, "</a>", "");
|
|
//...\n|/serie/stream/2012-das-jahr-null"_weg_>2012 - Das Jahr Null|\n...
|
|
|
|
serienListe += line + "\n";
|
|
}
|
|
if(serienListe.length() > 0)
|
|
serienListe.pop_back();
|
|
|
|
//Anzahl der Serien/Zeilen vorher:
|
|
ssize_t countBef = 0;
|
|
std::ifstream myFileBef(settings->serienListPath);
|
|
if(myFileBef.is_open())
|
|
for(countBef = 0; std::getline(myFileBef,line); countBef++);
|
|
myFileBef.close();
|
|
|
|
//Schreibe die Liste in das TextFile
|
|
std::ofstream ofs(settings->serienListPath, std::ios::trunc);
|
|
if(!ofs.is_open()) {
|
|
perror("Konnte SerienListe-Datei nicht öffnen");
|
|
return 111;
|
|
}
|
|
ofs << serienListe << std::endl;
|
|
ofs.close();
|
|
|
|
//Anzahl der Zeile nachher
|
|
ssize_t countAf = 0;
|
|
std::ifstream myFileAf(settings->serienListPath);
|
|
if(myFileAf.is_open())
|
|
for(countAf = 0; std::getline(myFileAf,line); countAf++);
|
|
myFileAf.close();
|
|
|
|
std::cout << "Serienunterschied: " << ( ((countAf - countBef) > 0) ? "+" : "") << countAf - countBef << " Serien." << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::listDir(std::string &list,std::string path, int maxDepth)
|
|
{
|
|
//Wenn Pfad zu einem TextFile geht
|
|
if(fileExists(path)) {
|
|
std::ifstream ifs(path);
|
|
if(!ifs.is_open()) {
|
|
perror(" => Error: Konnte Textdatei nicht öffnen.");
|
|
return -1;
|
|
}
|
|
list = std::string((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
|
|
return 0;
|
|
|
|
} // Sonst normal Ordner listen
|
|
else if(maxDepth <= 0)
|
|
return 0;
|
|
else if(nothingExists(path)) {
|
|
std::cout << " => Warnug: Datei oder Verzeichnis existiert nicht: '" << path << "'" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
//verkleiner varibable um 1, um zu verhindern, das endlose schleife entsteht
|
|
maxDepth--;
|
|
|
|
if(path[path.length()-1] != '/')
|
|
path.push_back('/');
|
|
|
|
DIR* dirp = opendir(path.c_str());
|
|
if(!dirp) {
|
|
perror(std::string(" => Error: Konnte Verzeichnis nicht öffnen: " + path).c_str());
|
|
return -1;
|
|
}
|
|
|
|
struct dirent * dp;
|
|
while ((dp = readdir(dirp)) != nullptr) {
|
|
if(strcmp( dp->d_name, "." ) == 0 || strcmp ( dp->d_name, ".." ) == 0)
|
|
continue;
|
|
|
|
else if(dirExists((path + dp->d_name + "/"))) { //if(dp->d_type == DT_DIR) {
|
|
listDir(list, (path + dp->d_name + "/"), maxDepth);
|
|
} else
|
|
list.append( std::string(dp->d_name) + "\n" );
|
|
}
|
|
closedir(dirp);
|
|
return 0;
|
|
}
|
|
|
|
int ProgramManager::convertLink(std::string redirectLink, AccountManager * accountManager,
|
|
Settings * settings, int Staffel, int Folge, std::string allLinks)
|
|
{
|
|
std::string folgenID = std::string((Staffel == -1 || Folge == -1 ) ? "" : "S" + std::string( (Staffel < 10) ? "0" : "" ) + std::to_string(Staffel)
|
|
+ "E" + std::string( (Folge < 10) ? "0" : "" ) + std::to_string( Folge ) );
|
|
std::string green = ((settings->colorless) ? "" : "\033[32m"),
|
|
red = ((settings->colorless) ? "" : "\033[31m"),
|
|
orange =((settings->colorless) ? "" : "\033[33m");
|
|
|
|
if(redirectLink == "" && settings->modus == Modus::DEFAULT_MODUS) {
|
|
if(allLinks == "") {
|
|
std::cout << " => " << red << "KEINEN Hoster für die Folge " << folgenID << " gefunden." << "\033[0m" << std::endl;
|
|
if(pageManager.writeToFile(settings->outputFilePath, std::string("KEINEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0)
|
|
return 130;
|
|
}
|
|
else {
|
|
std::cout << " => " << orange << "Keinen PASSENDEN Hoster für die Folge " << folgenID << " gefunden." << "\033[0m" << std::endl
|
|
<< "Alle Links:" << std::endl
|
|
<< pageManager.replace( pageManager.replace( pageManager.replace( allLinks, "data-lang-key=\"1\"", "language=\"GerDub\"" ),
|
|
"data-lang-key=\"2\"", "language=\"Eng\"" ), "data-lang-key=\"3\"", "language=\"GerSub\"") << std::endl;
|
|
if(pageManager.writeToFile(settings->outputFilePath, std::string("Keinen PASSENDEN Hoster für die Folge ") + folgenID + std::string(" gefunden.")) != 0)
|
|
return 138;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
for (int i = 1; i <= 3; ++i) {
|
|
std::string newUrl = pageManager.getUrlAfterRedirect("https://s.to" + redirectLink);
|
|
if (newUrl == "-1") {
|
|
return 102;
|
|
} else if(newUrl.find("/s.to/redirect/") != std::string::npos ) {
|
|
if(settings->debugMode)
|
|
std::cout << "Warnung: Redirect Link nach umwandlung (Capcha?) --> Neuer Account" << std::endl;
|
|
if(pageManager.login(accountManager->getNextAccount()) != 0)
|
|
return -1;
|
|
continue;
|
|
|
|
} else {
|
|
std::cout << " => " << folgenID << ( (folgenID == "") ? "" : ": " ) << green << newUrl << "\033[0m" << std::endl;
|
|
if(settings->outputFilePath != "")
|
|
if(pageManager.writeToFile(settings->outputFilePath,folgenID + ( (folgenID == "") ? "" : ": " ) + newUrl) != 0)
|
|
return 108;
|
|
return 0;
|
|
}
|
|
}
|
|
std::cout << " => " << folgenID << ( (folgenID == "") ? "" : ": " ) << red << "https://s.to" << redirectLink << "\033[0m" << std::endl;
|
|
if(settings->outputFilePath != "")
|
|
if(pageManager.writeToFile(settings->outputFilePath, folgenID + ( (folgenID == "") ? "" : ": " ) + redirectLink) != 0)
|
|
return 114;
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|