whitespace fix

This commit is contained in:
Sude 2013-03-16 23:35:57 +02:00
parent 5ad708e5b6
commit fab2ab5b94
4 changed files with 334 additions and 334 deletions

View File

@ -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();

View File

@ -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;

View File

@ -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;
} }

View File

@ -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;
} }