mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2024-11-20 11:49:17 +01:00
whitespace fix
This commit is contained in:
parent
5ad708e5b6
commit
fab2ab5b94
26
main.cpp
26
main.cpp
@ -33,24 +33,24 @@ int main(int argc, char *argv[])
|
|||||||
config.sConfigFilePath = config.sHome + "/.gogdownloader/config.cfg";
|
config.sConfigFilePath = config.sHome + "/.gogdownloader/config.cfg";
|
||||||
config.sXMLDirectory = config.sHome + "/.gogdownloader/xml";
|
config.sXMLDirectory = config.sHome + "/.gogdownloader/xml";
|
||||||
|
|
||||||
// Create gogdownloader directories
|
// Create gogdownloader directories
|
||||||
boost::filesystem::path path = config.sXMLDirectory;
|
boost::filesystem::path path = config.sXMLDirectory;
|
||||||
if (!boost::filesystem::exists(path))
|
if (!boost::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::create_directories(path))
|
if (!boost::filesystem::create_directories(path))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create directory: " << path << std::endl;
|
std::cout << "Failed to create directory: " << path << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create help text for --platform option
|
// Create help text for --platform option
|
||||||
std::string platform_text = "Select which installers are downloaded\n"
|
std::string platform_text = "Select which installers are downloaded\n"
|
||||||
+ std::to_string(INSTALLER_WINDOWS) + " = Windows\n"
|
+ std::to_string(INSTALLER_WINDOWS) + " = Windows\n"
|
||||||
+ std::to_string(INSTALLER_MAC) + " = Mac\n"
|
+ std::to_string(INSTALLER_MAC) + " = Mac\n"
|
||||||
+ std::to_string(INSTALLER_WINDOWS | INSTALLER_MAC) + " = Both";
|
+ std::to_string(INSTALLER_WINDOWS | INSTALLER_MAC) + " = Both";
|
||||||
// Create help text for --language option
|
// Create help text for --language option
|
||||||
std::string language_text = "Select which language installers are downloaded\n"
|
std::string language_text = "Select which language installers are downloaded\n"
|
||||||
+ std::to_string(LANGUAGE_EN) + " = English\n"
|
+ std::to_string(LANGUAGE_EN) + " = English\n"
|
||||||
+ std::to_string(LANGUAGE_DE) + " = German\n"
|
+ std::to_string(LANGUAGE_DE) + " = German\n"
|
||||||
+ std::to_string(LANGUAGE_FR) + " = French\n"
|
+ std::to_string(LANGUAGE_FR) + " = French\n"
|
||||||
@ -165,7 +165,7 @@ int main(int argc, char *argv[])
|
|||||||
// Make sure that directory has trailing slash
|
// Make sure that directory has trailing slash
|
||||||
if (!config.sDirectory.empty())
|
if (!config.sDirectory.empty())
|
||||||
if (config.sDirectory.at(config.sDirectory.length()-1)!='/')
|
if (config.sDirectory.at(config.sDirectory.length()-1)!='/')
|
||||||
config.sDirectory += "/";
|
config.sDirectory += "/";
|
||||||
|
|
||||||
Downloader downloader(config);
|
Downloader downloader(config);
|
||||||
int result = downloader.init();
|
int result = downloader.init();
|
||||||
|
@ -159,7 +159,7 @@ int API::login(const std::string& email, const std::string& password)
|
|||||||
url = oauth_sign_url2(url.c_str(), NULL, OA_HMAC, NULL, CONSUMER_KEY, CONSUMER_SECRET, token.c_str(), secret.c_str());
|
url = oauth_sign_url2(url.c_str(), NULL, OA_HMAC, NULL, CONSUMER_KEY, CONSUMER_SECRET, token.c_str(), secret.c_str());
|
||||||
std::string token_resp = this->getResponse(url);
|
std::string token_resp = this->getResponse(url);
|
||||||
|
|
||||||
rc = oauth_split_url_parameters(token_resp.c_str(), &rv);
|
rc = oauth_split_url_parameters(token_resp.c_str(), &rv);
|
||||||
qsort(rv, rc, sizeof(char *), oauth_cmpstringp);
|
qsort(rv, rc, sizeof(char *), oauth_cmpstringp);
|
||||||
if (rc == 2 && !strncmp(rv[0], "oauth_token=", OAUTH_TOKEN_LENGTH) && !strncmp(rv[1], "oauth_token_secret=", OAUTH_SECRET_LENGTH)) {
|
if (rc == 2 && !strncmp(rv[0], "oauth_token=", OAUTH_TOKEN_LENGTH) && !strncmp(rv[1], "oauth_token_secret=", OAUTH_SECRET_LENGTH)) {
|
||||||
this->config.oauth_token = rv[0]+OAUTH_TOKEN_LENGTH+1;
|
this->config.oauth_token = rv[0]+OAUTH_TOKEN_LENGTH+1;
|
||||||
|
@ -482,70 +482,70 @@ CURLcode Downloader::downloadFile(std::string url, std::string filepath)
|
|||||||
{
|
{
|
||||||
CURLcode res = CURLE_RECV_ERROR; // assume network error
|
CURLcode res = CURLE_RECV_ERROR; // assume network error
|
||||||
bool bResume = false;
|
bool bResume = false;
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
size_t offset=0;
|
size_t offset=0;
|
||||||
|
|
||||||
// Get directory from filepath
|
// Get directory from filepath
|
||||||
boost::filesystem::path pathname = filepath;
|
boost::filesystem::path pathname = filepath;
|
||||||
std::string directory = pathname.parent_path().string();
|
std::string directory = pathname.parent_path().string();
|
||||||
|
|
||||||
// Check that directory exists and create subdirectories
|
// Check that directory exists and create subdirectories
|
||||||
boost::filesystem::path path = directory;
|
boost::filesystem::path path = directory;
|
||||||
if (boost::filesystem::exists(path))
|
if (boost::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory(path))
|
if (!boost::filesystem::is_directory(path))
|
||||||
{
|
{
|
||||||
std::cout << path << " is not directory" << std::endl;
|
std::cout << path << " is not directory" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::create_directories(path))
|
if (!boost::filesystem::create_directories(path))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create directory: " << path << std::endl;
|
std::cout << "Failed to create directory: " << path << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if ((outfile=fopen(filepath.c_str(), "r"))!=NULL)
|
if ((outfile=fopen(filepath.c_str(), "r"))!=NULL)
|
||||||
{
|
{
|
||||||
// File exists, resume
|
// File exists, resume
|
||||||
if ((outfile = freopen(filepath.c_str(), "r+", outfile))!=NULL )
|
if ((outfile = freopen(filepath.c_str(), "r+", outfile))!=NULL )
|
||||||
{
|
{
|
||||||
bResume = true;
|
bResume = true;
|
||||||
fseek(outfile, 0, SEEK_END);
|
fseek(outfile, 0, SEEK_END);
|
||||||
offset = ftell(outfile);
|
offset = ftell(outfile);
|
||||||
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM, offset);
|
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM, offset);
|
||||||
this->resume_position = offset;
|
this->resume_position = offset;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to reopen " << filepath << std::endl;
|
std::cout << "Failed to reopen " << filepath << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// File doesn't exist, create new file
|
// File doesn't exist, create new file
|
||||||
if ((outfile=fopen(filepath.c_str(), "w"))!=NULL)
|
if ((outfile=fopen(filepath.c_str(), "w"))!=NULL)
|
||||||
{
|
{
|
||||||
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM, offset); // start downloading from the beginning of file
|
curl_easy_setopt(curlhandle, CURLOPT_RESUME_FROM, offset); // start downloading from the beginning of file
|
||||||
this->resume_position = 0;
|
this->resume_position = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create " << filepath << std::endl;
|
std::cout << "Failed to create " << filepath << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
curl_easy_setopt(curlhandle, CURLOPT_URL, url.c_str());
|
curl_easy_setopt(curlhandle, CURLOPT_URL, url.c_str());
|
||||||
curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, outfile);
|
curl_easy_setopt(curlhandle, CURLOPT_WRITEDATA, outfile);
|
||||||
res = this->beginDownload();
|
res = this->beginDownload();
|
||||||
|
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
|
|
||||||
// Download failed and was not a resume attempt so delete the file
|
// Download failed and was not a resume attempt so delete the file
|
||||||
if (res != CURLE_OK && !bResume)
|
if (res != CURLE_OK && !bResume)
|
||||||
@ -556,16 +556,16 @@ CURLcode Downloader::downloadFile(std::string url, std::string filepath)
|
|||||||
std::cout << "Failed to delete " << path << std::endl;
|
std::cout << "Failed to delete " << path << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Repair file
|
// Repair file
|
||||||
int Downloader::repairFile(std::string url, std::string filepath, std::string xml_data, std::string xml_dir)
|
int Downloader::repairFile(std::string url, std::string filepath, std::string xml_data, std::string xml_dir)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
FILE *outfile;
|
FILE *outfile;
|
||||||
size_t offset=0;
|
size_t offset=0;
|
||||||
if (xml_dir.empty())
|
if (xml_dir.empty())
|
||||||
xml_dir = config.sHome + "/.gogdownloader/xml";
|
xml_dir = config.sHome + "/.gogdownloader/xml";
|
||||||
|
|
||||||
size_t from_offset, to_offset;
|
size_t from_offset, to_offset;
|
||||||
@ -584,11 +584,11 @@ int Downloader::repairFile(std::string url, std::string filepath, std::string xm
|
|||||||
boost::filesystem::path pathname = filepath;
|
boost::filesystem::path pathname = filepath;
|
||||||
std::string filename = pathname.filename().string();
|
std::string filename = pathname.filename().string();
|
||||||
|
|
||||||
TiXmlDocument xml;
|
TiXmlDocument xml;
|
||||||
if (!xml_data.empty()) {
|
if (!xml_data.empty()) {
|
||||||
std::cout << "XML: Using remote file" << std::endl;
|
std::cout << "XML: Using remote file" << std::endl;
|
||||||
xml.Parse(xml_data.c_str());
|
xml.Parse(xml_data.c_str());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::string xml_file = xml_dir + "/" + filename + ".xml";
|
std::string xml_file = xml_dir + "/" + filename + ".xml";
|
||||||
@ -596,34 +596,34 @@ int Downloader::repairFile(std::string url, std::string filepath, std::string xm
|
|||||||
xml.LoadFile(xml_file);
|
xml.LoadFile(xml_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
TiXmlNode *fileNode = xml.FirstChild("file");
|
TiXmlNode *fileNode = xml.FirstChild("file");
|
||||||
if (!fileNode)
|
if (!fileNode)
|
||||||
{
|
{
|
||||||
std::cout << "XML: Parsing failed / not valid XML" << std::endl;
|
std::cout << "XML: Parsing failed / not valid XML" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "XML: Valid XML" << std::endl;
|
std::cout << "XML: Valid XML" << std::endl;
|
||||||
TiXmlElement *fileElem = fileNode->ToElement();
|
TiXmlElement *fileElem = fileNode->ToElement();
|
||||||
info.filename = fileElem->Attribute("name");
|
info.filename = fileElem->Attribute("name");
|
||||||
info.hash = fileElem->Attribute("md5");
|
info.hash = fileElem->Attribute("md5");
|
||||||
std::stringstream(fileElem->Attribute("chunks")) >> info.chunks;
|
std::stringstream(fileElem->Attribute("chunks")) >> info.chunks;
|
||||||
std::stringstream(fileElem->Attribute("total_size")) >> info.size;
|
std::stringstream(fileElem->Attribute("total_size")) >> info.size;
|
||||||
|
|
||||||
//Iterate through all chunk nodes
|
//Iterate through all chunk nodes
|
||||||
TiXmlNode *chunkNode = fileNode->FirstChild();
|
TiXmlNode *chunkNode = fileNode->FirstChild();
|
||||||
while (chunkNode)
|
while (chunkNode)
|
||||||
{
|
{
|
||||||
TiXmlElement *chunkElem = chunkNode->ToElement();
|
TiXmlElement *chunkElem = chunkNode->ToElement();
|
||||||
std::stringstream(chunkElem->Attribute("from")) >> from_offset;
|
std::stringstream(chunkElem->Attribute("from")) >> from_offset;
|
||||||
std::stringstream(chunkElem->Attribute("to")) >> to_offset;
|
std::stringstream(chunkElem->Attribute("to")) >> to_offset;
|
||||||
info.chunk_from.push_back(from_offset);
|
info.chunk_from.push_back(from_offset);
|
||||||
info.chunk_to.push_back(to_offset);
|
info.chunk_to.push_back(to_offset);
|
||||||
info.chunk_hash.push_back(chunkElem->GetText());
|
info.chunk_hash.push_back(chunkElem->GetText());
|
||||||
chunkNode = fileNode->IterateChildren(chunkNode);
|
chunkNode = fileNode->IterateChildren(chunkNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "XML: Parsing finished" << std::endl << std::endl
|
std::cout << "XML: Parsing finished" << std::endl << std::endl
|
||||||
<< info.filename << std::endl
|
<< info.filename << std::endl
|
||||||
@ -631,33 +631,33 @@ int Downloader::repairFile(std::string url, std::string filepath, std::string xm
|
|||||||
<< "\tChunks:\t" << info.chunks << std::endl
|
<< "\tChunks:\t" << info.chunks << std::endl
|
||||||
<< "\tSize:\t" << info.size << " bytes" << std::endl << std::endl;
|
<< "\tSize:\t" << info.size << " bytes" << std::endl << std::endl;
|
||||||
|
|
||||||
// Check if file exists
|
// Check if file exists
|
||||||
if ((outfile=fopen(filepath.c_str(), "r"))!=NULL)
|
if ((outfile=fopen(filepath.c_str(), "r"))!=NULL)
|
||||||
{
|
{
|
||||||
// File exists
|
// File exists
|
||||||
if ((outfile = freopen(filepath.c_str(), "r+", outfile))!=NULL )
|
if ((outfile = freopen(filepath.c_str(), "r+", outfile))!=NULL )
|
||||||
{
|
{
|
||||||
fseek(outfile, 0, SEEK_END);
|
fseek(outfile, 0, SEEK_END);
|
||||||
offset = ftell(outfile);
|
offset = ftell(outfile);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "Failed to reopen " << filepath << std::endl;
|
std::cout << "Failed to reopen " << filepath << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::cout << "File doesn't exist " << filepath << std::endl;
|
std::cout << "File doesn't exist " << filepath << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset != info.size)
|
if (offset != info.size)
|
||||||
{
|
{
|
||||||
std::cout << "Filesizes don't match" << std::endl
|
std::cout << "Filesizes don't match" << std::endl
|
||||||
<< "Incomplete download or different version" << std::endl;
|
<< "Incomplete download or different version" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i<info.chunks; i++)
|
for (int i=0; i<info.chunks; i++)
|
||||||
{
|
{
|
||||||
@ -709,7 +709,7 @@ int Downloader::repairFile(std::string url, std::string filepath, std::string xm
|
|||||||
res = 1;
|
res = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(outfile);
|
fclose(outfile);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -718,57 +718,57 @@ int Downloader::repairFile(std::string url, std::string filepath, std::string xm
|
|||||||
int Downloader::downloadCovers(std::string gamename, std::string directory, std::string cover_xml_data)
|
int Downloader::downloadCovers(std::string gamename, std::string directory, std::string cover_xml_data)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
TiXmlDocument xml;
|
TiXmlDocument xml;
|
||||||
|
|
||||||
// Check that directory exists and create subdirectories
|
// Check that directory exists and create subdirectories
|
||||||
boost::filesystem::path path = directory;
|
boost::filesystem::path path = directory;
|
||||||
if (boost::filesystem::exists(path))
|
if (boost::filesystem::exists(path))
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::is_directory(path))
|
if (!boost::filesystem::is_directory(path))
|
||||||
{
|
{
|
||||||
std::cout << path << " is not directory" << std::endl;
|
std::cout << path << " is not directory" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!boost::filesystem::create_directories(path))
|
if (!boost::filesystem::create_directories(path))
|
||||||
{
|
{
|
||||||
std::cout << "Failed to create directory: " << path << std::endl;
|
std::cout << "Failed to create directory: " << path << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xml.Parse(cover_xml_data.c_str());
|
xml.Parse(cover_xml_data.c_str());
|
||||||
TiXmlElement *rootNode = xml.RootElement();
|
TiXmlElement *rootNode = xml.RootElement();
|
||||||
if (!rootNode)
|
if (!rootNode)
|
||||||
{
|
{
|
||||||
std::cout << "Not valid XML" << std::endl;
|
std::cout << "Not valid XML" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
TiXmlNode *gameNode = rootNode->FirstChild();
|
TiXmlNode *gameNode = rootNode->FirstChild();
|
||||||
while (gameNode)
|
while (gameNode)
|
||||||
{
|
{
|
||||||
TiXmlElement *gameElem = gameNode->ToElement();
|
TiXmlElement *gameElem = gameNode->ToElement();
|
||||||
std::string game_name = gameElem->Attribute("name");
|
std::string game_name = gameElem->Attribute("name");
|
||||||
|
|
||||||
if (game_name == gamename)
|
if (game_name == gamename)
|
||||||
{
|
{
|
||||||
boost::match_results<std::string::const_iterator> what;
|
boost::match_results<std::string::const_iterator> what;
|
||||||
TiXmlNode *coverNode = gameNode->FirstChild();
|
TiXmlNode *coverNode = gameNode->FirstChild();
|
||||||
while (coverNode)
|
while (coverNode)
|
||||||
{
|
{
|
||||||
TiXmlElement *coverElem = coverNode->ToElement();
|
TiXmlElement *coverElem = coverNode->ToElement();
|
||||||
std::string cover_url = coverElem->GetText();
|
std::string cover_url = coverElem->GetText();
|
||||||
// Get file extension for the image
|
// Get file extension for the image
|
||||||
boost::regex e1(".*(\\.\\w+)$", boost::regex::perl | boost::regex::icase);
|
boost::regex e1(".*(\\.\\w+)$", boost::regex::perl | boost::regex::icase);
|
||||||
boost::regex_search(cover_url, what, e1);
|
boost::regex_search(cover_url, what, e1);
|
||||||
std::string file_extension = what[1];
|
std::string file_extension = what[1];
|
||||||
std::string cover_name = std::string("cover_") + coverElem->Attribute("id") + file_extension;
|
std::string cover_name = std::string("cover_") + coverElem->Attribute("id") + file_extension;
|
||||||
std::string filepath = directory + "/" + cover_name;
|
std::string filepath = directory + "/" + cover_name;
|
||||||
|
|
||||||
std::cout << "Downloading cover " << filepath << std::endl;
|
std::cout << "Downloading cover " << filepath << std::endl;
|
||||||
CURLcode result = this->downloadFile(cover_url, filepath);
|
CURLcode result = this->downloadFile(cover_url, filepath);
|
||||||
@ -789,15 +789,15 @@ int Downloader::downloadCovers(std::string gamename, std::string directory, std:
|
|||||||
std::cout << "failed to get error code: " << curl_easy_strerror(result) << std::endl;
|
std::cout << "failed to get error code: " << curl_easy_strerror(result) << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
coverNode = gameNode->IterateChildren(coverNode);
|
coverNode = gameNode->IterateChildren(coverNode);
|
||||||
}
|
}
|
||||||
break; // Found cover for game, no need to go through rest of the game nodes
|
break; // Found cover for game, no need to go through rest of the game nodes
|
||||||
}
|
}
|
||||||
gameNode = rootNode->IterateChildren(gameNode);
|
gameNode = rootNode->IterateChildren(gameNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Downloader::beginDownload()
|
CURLcode Downloader::beginDownload()
|
||||||
@ -928,31 +928,31 @@ size_t Downloader::getResumePosition()
|
|||||||
int Downloader::HTTP_Login(const std::string& email, const std::string& password)
|
int Downloader::HTTP_Login(const std::string& email, const std::string& password)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
std::string postdata;
|
std::string postdata;
|
||||||
std::ostringstream memory;
|
std::ostringstream memory;
|
||||||
std::string buk;
|
std::string buk;
|
||||||
|
|
||||||
// Get "buk" for login form
|
// Get "buk" for login form
|
||||||
std::string json = this->getResponse("http://www.gog.com/user/ajax/?a=get");
|
std::string json = this->getResponse("http://www.gog.com/user/ajax/?a=get");
|
||||||
|
|
||||||
Json::Value root;
|
Json::Value root;
|
||||||
Json::Reader *jsonparser = new Json::Reader;
|
Json::Reader *jsonparser = new Json::Reader;
|
||||||
bool parsingSuccessful = jsonparser->parse(json, root);
|
bool parsingSuccessful = jsonparser->parse(json, root);
|
||||||
if (!parsingSuccessful)
|
if (!parsingSuccessful)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << json << std::endl;
|
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << json << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::cout << jsonparser->getFormatedErrorMessages();
|
std::cout << jsonparser->getFormatedErrorMessages();
|
||||||
return res = 0;
|
return res = 0;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << root << std::endl;
|
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << root << std::endl;
|
||||||
#endif
|
#endif
|
||||||
buk = root["buk"].asString();
|
buk = root["buk"].asString();
|
||||||
|
|
||||||
//Create postdata - escape characters in email/password to support special characters
|
//Create postdata - escape characters in email/password to support special characters
|
||||||
postdata = "log_email=" + (std::string)curl_easy_escape(curlhandle, email.c_str(),email.size())
|
postdata = "log_email=" + (std::string)curl_easy_escape(curlhandle, email.c_str(),email.size())
|
||||||
+ "&log_password=" + (std::string)curl_easy_escape(curlhandle, password.c_str(), password.size())
|
+ "&log_password=" + (std::string)curl_easy_escape(curlhandle, password.c_str(), password.size())
|
||||||
+ "&buk=" + (std::string)curl_easy_escape(curlhandle, buk.c_str(), buk.size());
|
+ "&buk=" + (std::string)curl_easy_escape(curlhandle, buk.c_str(), buk.size());
|
||||||
curl_easy_setopt(curlhandle, CURLOPT_URL, "https://secure.gog.com/login");
|
curl_easy_setopt(curlhandle, CURLOPT_URL, "https://secure.gog.com/login");
|
||||||
@ -968,27 +968,27 @@ int Downloader::HTTP_Login(const std::string& email, const std::string& password
|
|||||||
curl_easy_setopt(curlhandle, CURLOPT_MAXREDIRS, -1);
|
curl_easy_setopt(curlhandle, CURLOPT_MAXREDIRS, -1);
|
||||||
json = this->getResponse("http://www.gog.com/user/ajax/?a=get");
|
json = this->getResponse("http://www.gog.com/user/ajax/?a=get");
|
||||||
|
|
||||||
parsingSuccessful = jsonparser->parse(json, root);
|
parsingSuccessful = jsonparser->parse(json, root);
|
||||||
if (!parsingSuccessful)
|
if (!parsingSuccessful)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << json << std::endl;
|
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << json << std::endl;
|
||||||
#endif
|
#endif
|
||||||
std::cout << jsonparser->getFormatedErrorMessages();
|
std::cout << jsonparser->getFormatedErrorMessages();
|
||||||
return res = 0;
|
return res = 0;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << root << std::endl;
|
std::cerr << "DEBUG INFO (Downloader::HTTP_Login)" << std::endl << root << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (root["user"]["email"].asString() == email)
|
if (root["user"]["email"].asString() == email)
|
||||||
res = 1; // Login successful
|
res = 1; // Login successful
|
||||||
else
|
else
|
||||||
res = 0; // Login failed
|
res = 0; // Login failed
|
||||||
|
|
||||||
delete jsonparser;
|
delete jsonparser;
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get list of games from account page
|
// Get list of games from account page
|
||||||
@ -1026,25 +1026,25 @@ std::vector<std::string> Downloader::getGames()
|
|||||||
delete jsonparser;
|
delete jsonparser;
|
||||||
|
|
||||||
// Parse HTML to get game names
|
// Parse HTML to get game names
|
||||||
htmlcxx::HTML::ParserDom parser;
|
htmlcxx::HTML::ParserDom parser;
|
||||||
tree<htmlcxx::HTML::Node> dom = parser.parseTree(html);
|
tree<htmlcxx::HTML::Node> dom = parser.parseTree(html);
|
||||||
tree<htmlcxx::HTML::Node>::iterator it = dom.begin();
|
tree<htmlcxx::HTML::Node>::iterator it = dom.begin();
|
||||||
tree<htmlcxx::HTML::Node>::iterator end = dom.end();
|
tree<htmlcxx::HTML::Node>::iterator end = dom.end();
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
{
|
||||||
if (it->tagName()=="div")
|
if (it->tagName()=="div")
|
||||||
{
|
{
|
||||||
it->parseAttributes();
|
it->parseAttributes();
|
||||||
std::string classname = it->attribute("class").second;
|
std::string classname = it->attribute("class").second;
|
||||||
if (classname=="shelf_game")
|
if (classname=="shelf_game")
|
||||||
{
|
{
|
||||||
// Game name is contained in data-gameindex attribute
|
// Game name is contained in data-gameindex attribute
|
||||||
std::string game = it->attribute("data-gameindex").second;
|
std::string game = it->attribute("data-gameindex").second;
|
||||||
if (!game.empty())
|
if (!game.empty())
|
||||||
games.push_back(game);
|
games.push_back(game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
@ -1056,25 +1056,25 @@ std::vector<std::string> Downloader::getFreeGames()
|
|||||||
std::string html = this->getResponse("https://secure.gog.com/catalogue/ajax?a=getGames&tab=all_genres&genre=all_genres&price=0&order=alph&publisher=&releaseDate=&availability=&gameMode=&rating=&search=&sort=vote&system=&language=&mixPage=1");
|
std::string html = this->getResponse("https://secure.gog.com/catalogue/ajax?a=getGames&tab=all_genres&genre=all_genres&price=0&order=alph&publisher=&releaseDate=&availability=&gameMode=&rating=&search=&sort=vote&system=&language=&mixPage=1");
|
||||||
|
|
||||||
// Parse HTML to get game names
|
// Parse HTML to get game names
|
||||||
htmlcxx::HTML::ParserDom parser;
|
htmlcxx::HTML::ParserDom parser;
|
||||||
tree<htmlcxx::HTML::Node> dom = parser.parseTree(html);
|
tree<htmlcxx::HTML::Node> dom = parser.parseTree(html);
|
||||||
tree<htmlcxx::HTML::Node>::iterator it = dom.begin();
|
tree<htmlcxx::HTML::Node>::iterator it = dom.begin();
|
||||||
tree<htmlcxx::HTML::Node>::iterator end = dom.end();
|
tree<htmlcxx::HTML::Node>::iterator end = dom.end();
|
||||||
for (; it != end; ++it)
|
for (; it != end; ++it)
|
||||||
{
|
{
|
||||||
if (it->tagName()=="a")
|
if (it->tagName()=="a")
|
||||||
{
|
{
|
||||||
it->parseAttributes();
|
it->parseAttributes();
|
||||||
std::string classname = it->attribute("class").second;
|
std::string classname = it->attribute("class").second;
|
||||||
if (classname=="game-title-link")
|
if (classname=="game-title-link")
|
||||||
{
|
{
|
||||||
std::string game = it->attribute("href").second;
|
std::string game = it->attribute("href").second;
|
||||||
game.assign(game.begin()+game.find_last_of("/")+1,game.end());
|
game.assign(game.begin()+game.find_last_of("/")+1,game.end());
|
||||||
if (!game.empty())
|
if (!game.empty())
|
||||||
games.push_back(game);
|
games.push_back(game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return games;
|
return games;
|
||||||
}
|
}
|
||||||
|
198
src/util.cpp
198
src/util.cpp
@ -47,134 +47,134 @@ std::string Util::makeFilepath(const std::string& directory, const std::string&
|
|||||||
|
|
||||||
std::string Util::getFileHash(const std::string& filename, unsigned hash_id)
|
std::string Util::getFileHash(const std::string& filename, unsigned hash_id)
|
||||||
{
|
{
|
||||||
unsigned char digest[rhash_get_digest_size(hash_id)];
|
unsigned char digest[rhash_get_digest_size(hash_id)];
|
||||||
char result[rhash_get_hash_length(hash_id)];
|
char result[rhash_get_hash_length(hash_id)];
|
||||||
|
|
||||||
rhash_library_init();
|
rhash_library_init();
|
||||||
int i = rhash_file(hash_id, filename.c_str(), digest);
|
int i = rhash_file(hash_id, filename.c_str(), digest);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
std::cout << "LibRHash error: " << strerror(errno) << std::endl;
|
std::cout << "LibRHash error: " << strerror(errno) << std::endl;
|
||||||
else
|
else
|
||||||
rhash_print_bytes(result, digest, rhash_get_digest_size(hash_id), RHPR_HEX);
|
rhash_print_bytes(result, digest, rhash_get_digest_size(hash_id), RHPR_HEX);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Util::getChunkHash(unsigned char *chunk, size_t chunk_size, unsigned hash_id)
|
std::string Util::getChunkHash(unsigned char *chunk, size_t chunk_size, unsigned hash_id)
|
||||||
{
|
{
|
||||||
unsigned char digest[rhash_get_digest_size(hash_id)];
|
unsigned char digest[rhash_get_digest_size(hash_id)];
|
||||||
char result[rhash_get_hash_length(hash_id)];
|
char result[rhash_get_hash_length(hash_id)];
|
||||||
|
|
||||||
rhash_library_init();
|
rhash_library_init();
|
||||||
int i = rhash_msg(hash_id, chunk, chunk_size, digest);
|
int i = rhash_msg(hash_id, chunk, chunk_size, digest);
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
std::cout << "LibRHash error: " << strerror(errno) << std::endl;
|
std::cout << "LibRHash error: " << strerror(errno) << std::endl;
|
||||||
else
|
else
|
||||||
rhash_print_bytes(result, digest, rhash_get_digest_size(hash_id), RHPR_HEX);
|
rhash_print_bytes(result, digest, rhash_get_digest_size(hash_id), RHPR_HEX);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create GOG XML
|
// Create GOG XML
|
||||||
int Util::createXML(std::string filepath, size_t chunk_size, std::string xml_dir)
|
int Util::createXML(std::string filepath, size_t chunk_size, std::string xml_dir)
|
||||||
{
|
{
|
||||||
int res = 0;
|
int res = 0;
|
||||||
FILE *infile;
|
FILE *infile;
|
||||||
FILE *xmlfile;
|
FILE *xmlfile;
|
||||||
size_t filesize, size;
|
size_t filesize, size;
|
||||||
int chunks, i;
|
int chunks, i;
|
||||||
std::string home = (std::string)getenv("HOME");
|
std::string home = (std::string)getenv("HOME");
|
||||||
if (xml_dir.empty())
|
if (xml_dir.empty())
|
||||||
xml_dir = home + "/.gogdownloader/xml";
|
xml_dir = home + "/.gogdownloader/xml";
|
||||||
|
|
||||||
// Make sure directory exists
|
// Make sure directory exists
|
||||||
boost::filesystem::path path = xml_dir;
|
boost::filesystem::path path = xml_dir;
|
||||||
if (!boost::filesystem::exists(path)) {
|
if (!boost::filesystem::exists(path)) {
|
||||||
if (!boost::filesystem::create_directories(path)) {
|
if (!boost::filesystem::create_directories(path)) {
|
||||||
std::cout << "Failed to create directory: " << path << std::endl;
|
std::cout << "Failed to create directory: " << path << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((infile=fopen(filepath.c_str(), "r"))!=NULL) {
|
if ((infile=fopen(filepath.c_str(), "r"))!=NULL) {
|
||||||
//File exists
|
//File exists
|
||||||
fseek(infile, 0, SEEK_END);
|
fseek(infile, 0, SEEK_END);
|
||||||
filesize = ftell(infile);
|
filesize = ftell(infile);
|
||||||
rewind(infile);
|
rewind(infile);
|
||||||
} else {
|
} else {
|
||||||
std::cout << filepath << " doesn't exist" << std::endl;
|
std::cout << filepath << " doesn't exist" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get filename
|
// Get filename
|
||||||
boost::filesystem::path pathname = filepath;
|
boost::filesystem::path pathname = filepath;
|
||||||
std::string filename = pathname.filename().string();
|
std::string filename = pathname.filename().string();
|
||||||
std::string filenameXML = xml_dir + "/" + filename + ".xml";
|
std::string filenameXML = xml_dir + "/" + filename + ".xml";
|
||||||
|
|
||||||
std::cout << filename << std::endl;
|
std::cout << filename << std::endl;
|
||||||
//Determine number of chunks
|
//Determine number of chunks
|
||||||
int remaining = filesize % chunk_size;
|
int remaining = filesize % chunk_size;
|
||||||
chunks = (remaining == 0) ? filesize/chunk_size : (filesize/chunk_size)+1;
|
chunks = (remaining == 0) ? filesize/chunk_size : (filesize/chunk_size)+1;
|
||||||
std::cout << "Filesize: " << filesize << " bytes" << std::endl
|
std::cout << "Filesize: " << filesize << " bytes" << std::endl
|
||||||
<< "Chunks: " << chunks << std::endl
|
<< "Chunks: " << chunks << std::endl
|
||||||
<< "Chunk size: " << (chunk_size >> 20) << " MB" << std::endl
|
<< "Chunk size: " << (chunk_size >> 20) << " MB" << std::endl
|
||||||
<< "MD5: " << std::flush;
|
<< "MD5: " << std::flush;
|
||||||
std::string file_md5 = Util::getFileHash(filepath.c_str(), RHASH_MD5);
|
std::string file_md5 = Util::getFileHash(filepath.c_str(), RHASH_MD5);
|
||||||
std::cout << file_md5 << std::endl;
|
std::cout << file_md5 << std::endl;
|
||||||
|
|
||||||
TiXmlDocument xml;
|
TiXmlDocument xml;
|
||||||
TiXmlElement *fileElem = new TiXmlElement("file");
|
TiXmlElement *fileElem = new TiXmlElement("file");
|
||||||
fileElem->SetAttribute("name", filename);
|
fileElem->SetAttribute("name", filename);
|
||||||
fileElem->SetAttribute("md5", file_md5);
|
fileElem->SetAttribute("md5", file_md5);
|
||||||
fileElem->SetAttribute("chunks", chunks);
|
fileElem->SetAttribute("chunks", chunks);
|
||||||
fileElem->SetAttribute("total_size", filesize);
|
fileElem->SetAttribute("total_size", filesize);
|
||||||
|
|
||||||
std::cout << "Getting MD5 for chunks" << std::endl;
|
std::cout << "Getting MD5 for chunks" << std::endl;
|
||||||
for (i = 0; i < chunks; i++) {
|
for (i = 0; i < chunks; i++) {
|
||||||
size_t range_begin = i*chunk_size;
|
size_t range_begin = i*chunk_size;
|
||||||
fseek(infile, range_begin, SEEK_SET);
|
fseek(infile, range_begin, SEEK_SET);
|
||||||
if ((i == chunks-1) && (remaining != 0))
|
if ((i == chunks-1) && (remaining != 0))
|
||||||
chunk_size = remaining;
|
chunk_size = remaining;
|
||||||
size_t range_end = range_begin + chunk_size - 1;
|
size_t range_end = range_begin + chunk_size - 1;
|
||||||
unsigned char *chunk = (unsigned char *) malloc(chunk_size * sizeof(unsigned char *));
|
unsigned char *chunk = (unsigned char *) malloc(chunk_size * sizeof(unsigned char *));
|
||||||
if (chunk == NULL)
|
if (chunk == NULL)
|
||||||
{
|
{
|
||||||
std::cout << "Memory error" << std::endl;
|
std::cout << "Memory error" << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
size = fread(chunk, 1, chunk_size, infile);
|
size = fread(chunk, 1, chunk_size, infile);
|
||||||
if (size != chunk_size)
|
if (size != chunk_size)
|
||||||
{
|
{
|
||||||
std::cout << "Read error" << std::endl;
|
std::cout << "Read error" << std::endl;
|
||||||
free(chunk);
|
free(chunk);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
std::string hash = Util::getChunkHash(chunk, chunk_size, RHASH_MD5);
|
std::string hash = Util::getChunkHash(chunk, chunk_size, RHASH_MD5);
|
||||||
free(chunk);
|
free(chunk);
|
||||||
|
|
||||||
TiXmlElement *chunkElem = new TiXmlElement("chunk");
|
TiXmlElement *chunkElem = new TiXmlElement("chunk");
|
||||||
chunkElem->SetAttribute("id", i);
|
chunkElem->SetAttribute("id", i);
|
||||||
chunkElem->SetAttribute("from", range_begin);
|
chunkElem->SetAttribute("from", range_begin);
|
||||||
chunkElem->SetAttribute("to", range_end);
|
chunkElem->SetAttribute("to", range_end);
|
||||||
chunkElem->SetAttribute("method", "md5");
|
chunkElem->SetAttribute("method", "md5");
|
||||||
TiXmlText *text = new TiXmlText(hash);
|
TiXmlText *text = new TiXmlText(hash);
|
||||||
chunkElem->LinkEndChild(text);
|
chunkElem->LinkEndChild(text);
|
||||||
fileElem->LinkEndChild(chunkElem);
|
fileElem->LinkEndChild(chunkElem);
|
||||||
|
|
||||||
std::cout << "Chunks hashed " << (i+1) << " / " << chunks << "\r" << std::flush;
|
std::cout << "Chunks hashed " << (i+1) << " / " << chunks << "\r" << std::flush;
|
||||||
}
|
}
|
||||||
fclose(infile);
|
fclose(infile);
|
||||||
xml.LinkEndChild(fileElem);
|
xml.LinkEndChild(fileElem);
|
||||||
|
|
||||||
std::cout << std::endl << "Writing XML: " << filenameXML << std::endl;
|
std::cout << std::endl << "Writing XML: " << filenameXML << std::endl;
|
||||||
if ((xmlfile=fopen(filenameXML.c_str(), "w"))!=NULL) {
|
if ((xmlfile=fopen(filenameXML.c_str(), "w"))!=NULL) {
|
||||||
xml.Print(xmlfile);
|
xml.Print(xmlfile);
|
||||||
fclose(xmlfile);
|
fclose(xmlfile);
|
||||||
res = 1;
|
res = 1;
|
||||||
} else {
|
} else {
|
||||||
std::cout << "Can't create " << filenameXML << std::endl;
|
std::cout << "Can't create " << filenameXML << std::endl;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user