Cookie: Added Support For Chromium Based Browser

Created 'cookie' class to handle cookies easier. The 'cookie' class
contains a name, value, and length. The 'cookie' class also has
functions for getting values for an sqlite database and decrypting chrome cookies.
This commit is contained in:
Moss 2022-09-29 22:42:45 -04:00
parent 1f0d1b8baf
commit 5c86f201cd
8 changed files with 363 additions and 263 deletions

View File

@ -22,7 +22,7 @@ sudo xbps-install -S libcurl sqlite-devel
sudo apt install libcurl4-gnutls-dev sqlite-devel sudo apt install libcurl4-gnutls-dev sqlite-devel
``` ```
## cookies ## Cookies
### Firefox ### Firefox
#### Option 1 (requires sqlite-devel) #### Option 1 (requires sqlite-devel)
Create a file named `firefox_profile` in the build directory and paste in your [firefox profile folder path](https://support.mozilla.org/en-US/kb/profiles-where-firefox-stores-user-data) Create a file named `firefox_profile` in the build directory and paste in your [firefox profile folder path](https://support.mozilla.org/en-US/kb/profiles-where-firefox-stores-user-data)
@ -42,7 +42,7 @@ Create a file called `auth_cookie` and paste the cookie in the file \
Go back to firefox and copy the `_session` cookie into a file named `session_cookie` \ Go back to firefox and copy the `_session` cookie into a file named `session_cookie` \
This needs to be redone everytime the cookie expires (~30 minutes) This needs to be redone everytime the cookie expires (~30 minutes)
### chrome ### chrome
#### Option 1 (requires sqlite-devel and libgcrypt) NOT CURRENTLY FUNCTIONAL #### Option 1 (requires sqlite-devel and libgcrypt)
Create a file named `chrome_profile` in the build directory and paste in your chrome profile folder path (found on [chrome://version](chrome://version)) Create a file named `chrome_profile` in the build directory and paste in your chrome profile folder path (found on [chrome://version](chrome://version))
#### Option 2 #### Option 2
Go to settings > privacy and security > cookies > see all cookies > vhx.tv > __cf_bm \ Go to settings > privacy and security > cookies > see all cookies > vhx.tv > __cf_bm \

View File

@ -399,6 +399,118 @@ namespace dropout_dl {
return config_page; return config_page;
} }
void cookie::get_value_from_db(sqlite3 *db, const std::string &sql_query_base, const std::string& value, bool verbose, int (*callback)(void*,int,char**,char**)) {
std::string sql_mod_base = sql_query_base;
if (sql_mod_base.find("WHERE") == std::string::npos) {
sql_mod_base += " WHERE ";
}
else {
sql_mod_base += " AND ";
}
sql_mod_base += "name='" + this->name + "';";
std::string sql_value_query = "SELECT " + value + ' ' + sql_mod_base;
std::string sql_length_query = "SELECT length(" + value + ") " + sql_mod_base;
std::string tmp;
char *err_code = nullptr;
int rc;
if (verbose) {
std::cout << sql_value_query << '\n' << sql_length_query << std::endl;
}
rc = sqlite3_exec(db, sql_length_query.c_str(), callback, &tmp, &err_code);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(3);
} else if (verbose) {
std::cout << "Got " << this->name << " cookie length\n";
}
this->len = std::stoi(tmp);
rc = sqlite3_exec(db, sql_value_query.c_str(), callback, &tmp, &err_code);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(3);
} else if (verbose) {
std::cout << "Got " << this->name << " cookie\n";
}
this->str = tmp;
}
void cookie::format_from_chrome() {
this->str = this->str.substr(3);
this->len -= 3;
}
void cookie::chrome_decrypt(const std::string &password, int iterations, const std::string &salt, int length) {
this->format_from_chrome();
uint8_t key[32];
char output[this->len + 2];
char iv[16];
for (char& c : iv) {
c = ' ';
}
for (char& c : output) {
c = 0;
}
gcry_kdf_derive(password.c_str(), password.size(), GCRY_KDF_PBKDF2, GCRY_KDF_ARGON2ID, salt.c_str(), salt.size(), iterations, length, key);
gcry_cipher_hd_t handle;
gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(handle, (const void*) &key, length);
gcry_cipher_setiv(handle, (const void*)&iv, 16);
unsigned long err = gcry_cipher_decrypt(handle, output, this->len, this->str.c_str(), this->len);
if (err) {
std::cout << gcry_strerror(err) << std::endl;
exit(2);
}
this->str = output;
this->str = this->str.substr(0, this->len-7);
this->len -= 7;
}
void cookie::url_decode() {
std::string out;
for (int i = 0; i < this->str.size() - 3; i++) {
if (substr_is(this->str, i, "%3D")) {
out += "=";
i += 2;
}
else {
out += this->str[i];
}
}
this->str = out;
this->len = out.size();
}
std::vector<std::string> episode::get_qualities() { std::vector<std::string> episode::get_qualities() {
if (!qualities.empty()) { if (!qualities.empty()) {
return qualities; return qualities;

View File

@ -9,9 +9,104 @@
#include <algorithm> #include <algorithm>
#include <fstream> #include <fstream>
#include <filesystem> #include <filesystem>
#include <sqlite3.h>
#ifdef DROPOUT_DL_GCRYPT
#include <gcrypt.h>
#endif
namespace dropout_dl { namespace dropout_dl {
class cookie {
public:
static int sqlite_write_callback(void* data, int argc, char** argv, char** azColName)
{
if (argc < 1) {
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
return -1;
}
else {
*(std::string*)data = argv[0];
return 0;
}
}
static int sqlite_write_callback_uchar(void* data, int argc, char** argv, char** azColName)
{
if (argc < 1) {
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
return -1;
}
else {
auto* ck = (dropout_dl::cookie*)data;
for (int i = 0; i < ck->len; i++) {
if (argv[0][i] > 32 && argv[0][i] < 126) {
std::cout << (unsigned char) argv[0][i] << ' ';
}
else {
std::cout << std::hex << ((int)argv[0][i] & 0xFF) << ' ';
}
ck->str[i] = (unsigned char)argv[0][i];
}
return 0;
}
}
std::string name;
std::string str;
int len;
explicit cookie(const std::string& name) {
this->name = name;
this->len = 0;
}
cookie(const std::string& name, const std::string& cookie) {
this->name = name;
this->str = cookie;
this->len = cookie.size();
}
cookie(const std::string& cookie, int length) {
this->str = cookie;
this->name = "?";
this->len = length;
}
cookie(const std::string& name, const std::string& cookie, int length) {
this->name = name;
this->str = cookie;
this->len = length;
}
/**
*
* @param db - An sqlite3 database
* @param sql_query_base - A base without the name search e.g. "FROM cookies" this function would then append the text "SELECT <value>" and "WHERE name='<name>'"
* @param value - The name of the value to fill the cookie with
*
*
*/
void get_value_from_db(sqlite3* db, const std::string& sql_query_base, const std::string& value, bool verbose = false, int (*callback)(void*,int,char**,char**) = sqlite_write_callback);
void format_from_chrome();
/**
*
* @param password - Default is "peanuts". This works for linux. The password should be keychain password on MacOS
* @param salt - Salt is "saltysalt" for both MacOS and Linux
* @param length - Length of 16 is standard for both MacOS and Linux
* @param iterations - 1 on linux and 1003 on MacOS
*/
void chrome_decrypt(const std::string& password = "peanuts", int iterations = 1, const std::string& salt = "saltysalt", int length = 16);
void url_decode();
};
bool substr_is(const std::string& string, int start, const std::string& test_str); bool substr_is(const std::string& string, int start, const std::string& test_str);
void replace_all(std::string& str, const std::string& from, const std::string& to); void replace_all(std::string& str, const std::string& from, const std::string& to);
@ -76,12 +171,12 @@ namespace dropout_dl {
void download(const std::string& quality, const std::string& series_directory, std::string filename = ""); void download(const std::string& quality, const std::string& series_directory, std::string filename = "");
episode(const std::string& episode_url, std::vector<std::string> cookies, bool verbose = false) { episode(const std::string& episode_url, std::vector<cookie> cookies, bool verbose = false) {
this->episode_url = episode_url; this->episode_url = episode_url;
this->verbose = verbose; this->verbose = verbose;
episode_data = get_episode_page(episode_url, cookies[0], cookies[1]); episode_data = get_episode_page(episode_url, cookies[0].str, cookies[1].str);
name = get_episode_name(episode_data); name = get_episode_name(episode_data);
@ -124,7 +219,7 @@ namespace dropout_dl {
std::cout << "Got embedded url: " << this->embedded_url << '\n'; std::cout << "Got embedded url: " << this->embedded_url << '\n';
} }
this->embedded_page_data = get_embedded_page(this->embedded_url, cookies[0]); this->embedded_page_data = get_embedded_page(this->embedded_url, cookies[0].str);
if (this->embedded_page_data.find("you are not authorized") != std::string::npos) { if (this->embedded_page_data.find("you are not authorized") != std::string::npos) {
std::cerr << "ERROR: Could not access video. Try refreshing cookies.\n"; std::cerr << "ERROR: Could not access video. Try refreshing cookies.\n";

View File

@ -4,293 +4,9 @@
#ifdef DROPOUT_DL_SQLITE #ifdef DROPOUT_DL_SQLITE
#include <sqlite3.h> #include <sqlite3.h>
#ifdef DROPOUT_DL_GCRYPT
#include <gcrypt.h>
#endif
#endif #endif
static int sqlite_write_callback(void* data, int argc, char** argv, char** azColName) namespace dropout_dl {
{
if (argc < 1) {
std::cerr << "ERROR: sqlite could not find dropout.tv cookie" << std::endl;
return -1;
}
else {
*(std::string*)data = argv[0];
return 0;
}
}
#ifdef DROPOUT_DL_SQLITE
std::vector<std::string> get_cookies_from_firefox(const std::filesystem::path& firefox_profile_path, bool verbose = false) {
std::fstream firefox_profile_file(firefox_profile_path);
std::string firefox_profile;
std::string auth_cookie;
std::string session_cookie;
std::vector<std::string> out;
firefox_profile_file >> firefox_profile;
if (std::filesystem::is_directory(firefox_profile)) {
sqlite3 *db;
if (verbose) {
std::cout << "Getting firefox cookies from firefox sqlite db\n";
}
if (!std::filesystem::is_directory("tmp"))
std::filesystem::create_directories("tmp");
std::filesystem::remove("tmp/firefox_cookies.sqlite");
std::filesystem::copy_file(firefox_profile + "/cookies.sqlite", "tmp/firefox_cookies.sqlite");
int rc = sqlite3_open("tmp/firefox_cookies.sqlite", &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
exit(1);
} else {
if (verbose) {
std::cout << "Firefox database opened successfully\n";
}
}
char *err_code = nullptr;
std::string sql("SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='__cf_bm';");
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &auth_cookie, &err_code);
out.emplace_back(auth_cookie);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(2);
} else if (verbose) {
std::cout << "Got __cf_bm cookie from firefox sqlite db\n";
}
sql = "SELECT value FROM moz_cookies WHERE host LIKE '%dropout.tv%' AND name='_session';";
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &session_cookie, &err_code);
out.emplace_back(session_cookie);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(3);
} else if (verbose) {
std::cout << "Got _session cookie from firefox sqlite db\n";
}
sqlite3_close(db);
}
return out;
}
#ifdef DROPOUT_DL_GCRYPT
std::vector<std::string> get_cookies_from_chrome(const std::filesystem::path& chrome_profile_path, bool verbose = false) {
std::fstream chrome_profile_file(chrome_profile_path);
std::string chrome_profile;
std::string auth_cookie;
int auth_cookie_length;
std::string session_cookie;
int session_cookie_length;
std::vector<std::string> out;
getline(chrome_profile_file, chrome_profile);
if (std::filesystem::is_directory(chrome_profile)) {
sqlite3 *db;
if (verbose) {
std::cout << "Getting chrome cookies from chrome sqlite db\n";
}
int rc = sqlite3_open((chrome_profile + "/Cookies").c_str(), &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
exit(1);
} else {
if (verbose) {
std::cout << "Chrome database opened successfully\n";
}
}
char *err_code = nullptr;
std::string len;
std::string sql = "SELECT length(encrypted_value) FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='__cf_bm';";
sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &len, &err_code);
auth_cookie_length = std::stoi(len);
sql = "SELECT encrypted_value FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='__cf_bm';";
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &auth_cookie, &err_code);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(2);
} else if (verbose) {
std::cout << "Got __cf_bm cookie from chrome sqlite db\n" << auth_cookie << '\n';
}
sql = "SELECT length(encrypted_value) FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='_session';";
sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &len, &err_code);
session_cookie_length = std::stoi(len);
sql = "SELECT encrypted_value FROM cookies WHERE host_key LIKE '%dropout.tv%' AND name='_session';";
rc = sqlite3_exec(db, sql.c_str(), sqlite_write_callback, &session_cookie, &err_code);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL error: %s\n", err_code);
sqlite3_free(err_code);
sqlite3_close(db);
exit(3);
} else if (verbose) {
std::cout << "Got _session cookie from chrome sqlite db\n";
}
sqlite3_close(db);
// system(("echo \"SELECT value FROM moz_cookies WHERE originAttributes LIKE '%dropout.tv%';\" | sqlite3 " + firefox_profile + "/cookies.sqlite > cookie").c_str());
}
// For mac os this is your keychain password
// For linux leave as "peanuts"
std::string password = "peanuts";
std::string salt = "saltysalt";
int length = 16;
int iterations = 1;
uint8_t key[32];
char output[2048];
char iv[16];
for (char& c : iv) {
c = ' ';
}
for (char& c : output) {
c = 0;
}
for (int i = 0; i < auth_cookie_length; i++) {
std::cout << std::hex << (0xFF & (int)auth_cookie[i]) << ' ';
}
std::cout << '\n';
gcry_kdf_derive(password.c_str(), password.size(), GCRY_KDF_PBKDF2, GCRY_KDF_ARGON2ID, salt.c_str(), salt.size(), iterations, length, key);
gcry_cipher_hd_t handle;
gcry_cipher_open(&handle, GCRY_CIPHER_AES, GCRY_CIPHER_MODE_CBC, 0);
gcry_cipher_setkey(handle, (const void*) &key, length);
gcry_cipher_setiv(handle, (const void*)&iv, 16);
unsigned long err = gcry_cipher_decrypt(handle, (unsigned char*)output, 2048, auth_cookie.c_str() + 3, auth_cookie_length - 3);
if (err) {
std::cout << gcry_strerror(err) << std::endl;
exit(2);
}
for (char& c : output) {
if (c == '\017') {
c = 0;
}
}
out.emplace_back(output);
gcry_cipher_setiv(handle, (const void*)&iv, 16);
gcry_cipher_decrypt(handle, (unsigned char*)output, 2048, session_cookie.c_str() + 3, session_cookie_length - 3);
out.emplace_back(output);
return out;
}
#endif
#endif
std::vector<std::string> get_cookies_from_files(const std::filesystem::path& auth_cookie_path, const std::filesystem::path& session_cookie_path, bool verbose = false) {
std::fstream auth_cookie_file("auth_cookie");
std::fstream session_cookie_file("session_cookie");
std::string auth_cookie;
std::string session_cookie;
std::vector<std::string> out;
auth_cookie_file >> auth_cookie;
if (verbose) {
std::cout << "Got __cf_bm cookie from auth_cookie file db\n";
}
out.emplace_back(auth_cookie);
session_cookie_file >> session_cookie;
if (verbose) {
std::cout << "Got _session cookie from auth_cookie file db\n";
}
out.emplace_back(session_cookie);
return out;
}
std::vector<std::string> get_cookies(bool verbose = false) {
#ifdef DROPOUT_DL_SQLITE
std::filesystem::path firefox_profile("firefox_profile");
#ifdef DROPOUT_DL_GCRYPT
std::filesystem::path chrome_profile("chrome_profile");
#endif
#endif
std::filesystem::path auth_cookie("auth_cookie");
std::filesystem::path session_cookie("session_cookie");
#ifdef DROPOUT_DL_SQLITE
if (std::filesystem::exists(firefox_profile)) {
return get_cookies_from_firefox(firefox_profile, verbose);
} else
#ifdef DROPOUT_DL_GCRYPT
if (std::filesystem::exists(chrome_profile)) {
return get_cookies_from_chrome(chrome_profile, verbose);
} else
#endif
#endif
if (std::filesystem::exists(auth_cookie) && std::filesystem::exists(session_cookie)){
return get_cookies_from_files(auth_cookie, session_cookie, verbose);
}
else {
std::cerr << "ERROR: dropout.tv cookies could not be found" << std::endl;
exit(7);
}
}
class options { class options {
public: public:
@ -304,7 +20,7 @@ public:
std::string filename; std::string filename;
std::string output_directory; std::string output_directory;
std::string episode; std::string episode;
std::vector<std::string> cookies; std::vector<cookie> cookies;
static std::vector<std::string> convert_program_args(int argc, char** argv) { static std::vector<std::string> convert_program_args(int argc, char** argv) {
std::vector<std::string> out; std::vector<std::string> out;
@ -370,7 +86,7 @@ public:
"\t--help Display this message\n" "\t--help Display this message\n"
"\t--quality Set the quality of the downloaded video. Quality can be set to 'all' which\n" "\t--quality Set the quality of the downloaded video. Quality can be set to 'all' which\n"
"\t will download all qualities and place them into separate folders\n" "\t will download all qualities and place them into separate folders\n"
"\t--output Set the output filename\n" "\t--output Set the output filename. Only works for single episode downloads\n"
"\t--output-directory Set the directory where files are output\n" "\t--output-directory Set the directory where files are output\n"
"\t--verbose Display debug information while running\n" "\t--verbose Display debug information while running\n"
"\t--force-cookies Interpret the next to arguments as authentication cookie and session cookie\n" "\t--force-cookies Interpret the next to arguments as authentication cookie and session cookie\n"
@ -394,14 +110,191 @@ public:
} }
} }
}; };
}
#ifdef DROPOUT_DL_SQLITE
std::vector<dropout_dl::cookie> get_cookies_from_firefox(const std::filesystem::path& firefox_profile_path, bool verbose = false) {
std::fstream firefox_profile_file(firefox_profile_path);
std::string firefox_profile;
dropout_dl::cookie auth("__cf_bm");
dropout_dl::cookie session("_session");
std::vector<dropout_dl::cookie> out;
firefox_profile_file >> firefox_profile;
if (std::filesystem::is_directory(firefox_profile)) {
sqlite3 *db;
if (verbose) {
std::cout << "Getting firefox cookies from firefox sqlite db\n";
}
if (!std::filesystem::is_directory("tmp"))
std::filesystem::create_directories("tmp");
std::filesystem::remove("tmp/firefox_cookies.sqlite");
std::filesystem::copy_file(firefox_profile + "/cookies.sqlite", "tmp/firefox_cookies.sqlite");
int rc = sqlite3_open("tmp/firefox_cookies.sqlite", &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
exit(1);
} else {
if (verbose) {
std::cout << "Firefox database opened successfully\n";
}
}
std::string len;
auth.get_value_from_db(db, "FROM moz_cookies WHERE host LIKE '%dropout.tv%'", "value");
session.get_value_from_db(db, "FROM moz_cookies WHERE host LIKE '%dropout.tv%'", "value");
sqlite3_close(db);
}
if (verbose) {
std::cout << auth.name << ": " << auth.len << ": " << auth.str << '\n';
std::cout << session.name << ": " << session.len << ": " << session.str << '\n';
}
out.push_back(auth);
out.push_back(session);
return out;
}
#ifdef DROPOUT_DL_GCRYPT
std::vector<dropout_dl::cookie> get_cookies_from_chrome(const std::filesystem::path& chrome_profile_path, bool verbose = false) {
std::fstream chrome_profile_file(chrome_profile_path);
std::string chrome_profile;
dropout_dl::cookie auth("__cf_bm");
dropout_dl::cookie session("_session");
std::vector<dropout_dl::cookie> out;
getline(chrome_profile_file, chrome_profile);
if (std::filesystem::is_directory(chrome_profile)) {
sqlite3 *db;
if (verbose) {
std::cout << "Getting chrome cookies from chrome sqlite db\n";
}
int rc = sqlite3_open((chrome_profile + "/Cookies").c_str(), &db);
if (rc) {
std::cerr << "Can't open database: " << sqlite3_errmsg(db) << '\n';
exit(1);
} else {
if (verbose) {
std::cout << "Chrome database opened successfully\n";
}
}
std::string len;
auth.get_value_from_db(db, "FROM cookies WHERE host_key LIKE '%dropout.tv%'", "encrypted_value");
session.get_value_from_db(db, "FROM cookies WHERE host_key LIKE '%dropout.tv%'", "encrypted_value");
sqlite3_close(db);
}
auth.chrome_decrypt();
session.chrome_decrypt();
session.url_decode();
if (verbose) {
std::cout << auth.name << ": " << auth.len << ": " << auth.str << '\n';
std::cout << session.name << ": " << session.len << ": " << session.str << '\n';
}
out.push_back(auth);
out.push_back(session);
return out;
}
#endif
#endif
std::vector<dropout_dl::cookie> get_cookies_from_files(const std::filesystem::path& auth_cookie_path, const std::filesystem::path& session_cookie_path, bool verbose = false) {
std::fstream auth_cookie_file("auth_cookie");
std::fstream session_cookie_file("session_cookie");
std::string auth_cookie;
std::string session_cookie;
std::vector<dropout_dl::cookie> out;
auth_cookie_file >> auth_cookie;
if (verbose) {
std::cout << "Got __cf_bm cookie from auth_cookie file db\n";
}
out.emplace_back(auth_cookie);
session_cookie_file >> session_cookie;
if (verbose) {
std::cout << "Got _session cookie from auth_cookie file db\n";
}
out.emplace_back(session_cookie);
return out;
}
std::vector<dropout_dl::cookie> get_cookies(bool verbose = false) {
#ifdef DROPOUT_DL_SQLITE
std::filesystem::path firefox_profile("firefox_profile");
#ifdef DROPOUT_DL_GCRYPT
std::filesystem::path chrome_profile("chrome_profile");
#endif
#endif
std::filesystem::path auth_cookie("auth_cookie");
std::filesystem::path session_cookie("session_cookie");
#ifdef DROPOUT_DL_SQLITE
if (std::filesystem::exists(firefox_profile)) {
return get_cookies_from_firefox(firefox_profile, verbose);
} else
#ifdef DROPOUT_DL_GCRYPT
if (std::filesystem::exists(chrome_profile)) {
return get_cookies_from_chrome(chrome_profile, verbose);
} else
#endif
#endif
if (std::filesystem::exists(auth_cookie) && std::filesystem::exists(session_cookie)){
return get_cookies_from_files(auth_cookie, session_cookie, verbose);
}
else {
std::cerr << "ERROR: dropout.tv cookies could not be found" << std::endl;
exit(7);
}
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
options options(argc, argv); dropout_dl::options options(argc, argv);
std::cout << "quality: " << options.quality << std::endl; // std::cout << "quality: " << options.quality << std::endl;
std::cout << "verbose: " << options.verbose << std::endl; // std::cout << "verbose: " << options.verbose << std::endl;
std::cout << "url: \"" << options.url << '"' << std::endl; // std::cout << "url: \"" << options.url << '"' << std::endl;
std::string firefox_profile; std::string firefox_profile;
std::string chrome_profile; std::string chrome_profile;

View File

@ -5,7 +5,7 @@
#include "season.h" #include "season.h"
namespace dropout_dl { namespace dropout_dl {
episode get_episode(const std::string& html_data, int& start_point, const std::vector<std::string>& cookies) { episode get_episode(const std::string& html_data, int& start_point, const std::vector<cookie>& cookies) {
int link_start = 0; int link_start = 0;
for (int i = start_point; i > 0; i--) { for (int i = start_point; i > 0; i--) {
if (substr_is(html_data, i, "<a")) { if (substr_is(html_data, i, "<a")) {
@ -33,7 +33,7 @@ namespace dropout_dl {
exit(8); exit(8);
} }
std::vector<episode> season::get_episodes(const std::string &html_data, const std::vector<std::string>& cookies) { std::vector<episode> season::get_episodes(const std::string &html_data, const std::vector<cookie>& cookies) {
std::vector<episode> out; std::vector<episode> out;
std::string site_video(R"(class="browse-item-link" data-track-event="site_video")"); std::string site_video(R"(class="browse-item-link" data-track-event="site_video")");

View File

@ -18,11 +18,11 @@ namespace dropout_dl {
std::string page_data; std::string page_data;
std::vector<episode> episodes; std::vector<episode> episodes;
static std::vector<episode> get_episodes(const std::string& html_data, const std::vector<std::string>& cookies); static std::vector<episode> get_episodes(const std::string& html_data, const std::vector<cookie>& cookies);
void download(const std::string& quality, const std::string& series_directory); void download(const std::string& quality, const std::string& series_directory);
season(const std::string& url, const std::string& name, const std::vector<std::string>& cookies, const std::string& series_name = "") { season(const std::string& url, const std::string& name, const std::vector<cookie>& cookies, const std::string& series_name = "") {
this->url = url; this->url = url;
this->name = name; this->name = name;
this->series_name = series_name; this->series_name = series_name;

View File

@ -40,7 +40,7 @@ namespace dropout_dl {
return "-1"; return "-1";
} }
std::vector<season> series::get_seasons(const std::string &html_data, const std::vector<std::string>& cookies) { std::vector<season> series::get_seasons(const std::string &html_data, const std::vector<cookie>& cookies) {
std::vector<season> out; std::vector<season> out;
std::string search_class("js-switch-season"); std::string search_class("js-switch-season");
@ -127,7 +127,7 @@ namespace dropout_dl {
} }
season series::get_season(const std::string &url, const std::vector<std::string>& cookies) { season series::get_season(const std::string &url, const std::vector<cookie>& cookies) {
std::string html_data = get_generic_page(url); std::string html_data = get_generic_page(url);
std::string search_class("js-switch-season"); std::string search_class("js-switch-season");

View File

@ -20,13 +20,13 @@ namespace dropout_dl {
static std::string get_series_name(const std::string& html_data); static std::string get_series_name(const std::string& html_data);
static std::vector<season> get_seasons(const std::string& html_data, const std::vector<std::string>& cookies); static std::vector<season> get_seasons(const std::string& html_data, const std::vector<cookie>& cookies);
static season get_season(const std::string& url, const std::vector<std::string>& cookies); static season get_season(const std::string& url, const std::vector<cookie>& cookies);
void download(const std::string& quality, const std::string& base); void download(const std::string& quality, const std::string& base);
explicit series(const std::string& url, const std::vector<std::string>& cookies) { explicit series(const std::string& url, const std::vector<dropout_dl::cookie>& cookies) {
this->url = url; this->url = url;
this->page_data = get_generic_page(url); this->page_data = get_generic_page(url);
this->name = get_series_name(page_data); this->name = get_series_name(page_data);