mirror of
https://github.com/Sude-/lgogdownloader.git
synced 2024-11-20 11:49:17 +01:00
Added --status command and made createXML output easier to read
Version check before download now works without local XML data. However it is much slower without the XML data because it calculates MD5 for the files Some changes to config.h - Removed "bHelp" from config because it was not needed - Changed "bNoColor" to "bColor" - Changed "bNoUnicode" to "bUnicode"
This commit is contained in:
parent
a63165d5a5
commit
0d9c27d20a
@ -19,7 +19,6 @@ class Config
|
||||
bool bNoRemoteXML;
|
||||
bool bNoCover;
|
||||
bool bUpdateCheck;
|
||||
bool bHelp;
|
||||
bool bDownload;
|
||||
bool bList;
|
||||
bool bListDetails;
|
||||
@ -29,10 +28,11 @@ class Config
|
||||
bool bNoExtras;
|
||||
bool bNoPatches;
|
||||
bool bNoLanguagePacks;
|
||||
bool bNoUnicode; // don't use Unicode in console output
|
||||
bool bNoColor; // don't use colors
|
||||
bool bUnicode; // use Unicode in console output
|
||||
bool bColor; // use colors
|
||||
bool bVerifyPeer;
|
||||
bool bCheckOrphans;
|
||||
bool bCheckStatus;
|
||||
std::string sGameRegex;
|
||||
std::string sDirectory;
|
||||
std::string sXMLFile;
|
||||
|
@ -49,6 +49,7 @@ class Downloader
|
||||
void repair();
|
||||
void download();
|
||||
void checkOrphans();
|
||||
void checkStatus();
|
||||
CURL* curlhandle;
|
||||
Timer timer;
|
||||
Config config;
|
||||
@ -64,6 +65,8 @@ class Downloader
|
||||
size_t getResumePosition();
|
||||
CURLcode beginDownload();
|
||||
std::string getResponse(const std::string& url);
|
||||
std::string getLocalFileHash(const std::string& filepath);
|
||||
std::string getRemoteFileHash(const std::string& gamename, const std::string& id);
|
||||
|
||||
int HTTP_Login(const std::string& email, const std::string& password);
|
||||
std::vector< std::pair<std::string,std::string> > getGames();
|
||||
|
11
main.cpp
11
main.cpp
@ -76,6 +76,8 @@ int main(int argc, char *argv[])
|
||||
try
|
||||
{
|
||||
bool bInsecure = false;
|
||||
bool bNoColor = false;
|
||||
bool bNoUnicode = false;
|
||||
desc.add_options()
|
||||
("help,h", "Print help message")
|
||||
("login", bpo::value<bool>(&config.bLogin)->zero_tokens()->default_value(false), "Login")
|
||||
@ -98,12 +100,13 @@ int main(int argc, char *argv[])
|
||||
("no-language-packs", bpo::value<bool>(&config.bNoLanguagePacks)->zero_tokens()->default_value(false), "Don't download/list/repair language packs")
|
||||
("no-cover", bpo::value<bool>(&config.bNoCover)->zero_tokens()->default_value(false), "Don't download cover images")
|
||||
("no-remote-xml", bpo::value<bool>(&config.bNoRemoteXML)->zero_tokens()->default_value(false), "Don't use remote XML for repair")
|
||||
("no-unicode", bpo::value<bool>(&config.bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar")
|
||||
("no-color", bpo::value<bool>(&config.bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar")
|
||||
("no-unicode", bpo::value<bool>(&bNoUnicode)->zero_tokens()->default_value(false), "Don't use Unicode in the progress bar")
|
||||
("no-color", bpo::value<bool>(&bNoColor)->zero_tokens()->default_value(false), "Don't use coloring in the progress bar")
|
||||
("verbose", bpo::value<bool>(&config.bVerbose)->zero_tokens()->default_value(false), "Print lots of information")
|
||||
("insecure", bpo::value<bool>(&bInsecure)->zero_tokens()->default_value(false), "Don't verify authenticity of SSL certificates")
|
||||
("timeout", bpo::value<long int>(&config.iTimeout)->default_value(10), "Set timeout for connection\nMaximum time in seconds that connection phase is allowed to take")
|
||||
("check-orphans", bpo::value<bool>(&config.bCheckOrphans)->zero_tokens()->default_value(false), "Check for orphaned files (files found on local filesystem that are not found on GOG servers)")
|
||||
("status", bpo::value<bool>(&config.bCheckStatus)->zero_tokens()->default_value(false), "Show status of files\n\nOutput format:\nstatuscode gamename filename filesize filehash\n\nStatus codes:\nOK - File is OK\nND - File is not downloaded\nMD5 - MD5 mismatch, different version")
|
||||
;
|
||||
|
||||
bpo::store(bpo::parse_command_line(argc, argv, desc), vm);
|
||||
@ -145,6 +148,8 @@ int main(int argc, char *argv[])
|
||||
config.iDownloadRate <<= 10; // Convert download rate from bytes to kilobytes
|
||||
|
||||
config.bVerifyPeer = !bInsecure;
|
||||
config.bColor = !bNoColor;
|
||||
config.bUnicode = !bNoUnicode;
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
@ -203,6 +208,8 @@ int main(int argc, char *argv[])
|
||||
downloader.listGames();
|
||||
else if (config.bCheckOrphans)
|
||||
downloader.checkOrphans();
|
||||
else if (config.bCheckStatus)
|
||||
downloader.checkStatus();
|
||||
else
|
||||
{ // Show help message
|
||||
std::cout << config.sVersionString << std::endl
|
||||
|
@ -69,7 +69,7 @@ int Downloader::init()
|
||||
gogAPI->curlSetOpt(CURLOPT_SSL_VERIFYPEER, config.bVerifyPeer);
|
||||
gogAPI->curlSetOpt(CURLOPT_CONNECTTIMEOUT, config.iTimeout);
|
||||
|
||||
progressbar = new ProgressBar(!config.bNoUnicode, !config.bNoColor);
|
||||
progressbar = new ProgressBar(config.bUnicode, config.bColor);
|
||||
|
||||
bool bInitOK = gogAPI->init();
|
||||
if (config.bLogin || !bInitOK)
|
||||
@ -209,7 +209,7 @@ void Downloader::getGameList()
|
||||
}
|
||||
}
|
||||
|
||||
if (config.bListDetails || config.bDownload || config.bRepair || config.bCheckOrphans)
|
||||
if (config.bListDetails || config.bDownload || config.bRepair || config.bCheckOrphans || config.bCheckStatus)
|
||||
this->getGameDetails();
|
||||
}
|
||||
|
||||
@ -520,6 +520,7 @@ void Downloader::download()
|
||||
{
|
||||
std::cout << "Starting automatic XML creation" << std::endl;
|
||||
Util::createXML(filepath, config.iChunkSize, config.sXMLDirectory);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -552,6 +553,7 @@ void Downloader::download()
|
||||
{
|
||||
std::cout << "Starting automatic XML creation" << std::endl;
|
||||
Util::createXML(filepath, config.iChunkSize, config.sXMLDirectory);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -584,6 +586,7 @@ void Downloader::download()
|
||||
{
|
||||
std::cout << "Starting automatic XML creation" << std::endl;
|
||||
Util::createXML(filepath, config.iChunkSize, config.sXMLDirectory);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -606,30 +609,24 @@ CURLcode Downloader::downloadFile(const std::string& url, const std::string& fil
|
||||
|
||||
// Using local XML data for version check before resuming
|
||||
boost::filesystem::path local_xml_file;
|
||||
if (config.sXMLDirectory.empty())
|
||||
local_xml_file = config.sHome + "/.gogdownloader/xml/" + filenameXML;
|
||||
else
|
||||
local_xml_file = config.sXMLDirectory + "/" + filenameXML;
|
||||
local_xml_file = config.sXMLDirectory + "/" + filenameXML;
|
||||
|
||||
bool bSameVersion = true; // assume same version
|
||||
bool bLocalXMLExists = boost::filesystem::exists(local_xml_file);
|
||||
bool bLocalXMLExists = boost::filesystem::exists(local_xml_file); // This is additional check to see if remote xml should be saved to speed up future version checks
|
||||
std::string localHash = this->getLocalFileHash(filepath);
|
||||
|
||||
if (!xml_data.empty())
|
||||
{
|
||||
// Do version check if local XML file exists
|
||||
if (bLocalXMLExists)
|
||||
// Do version check if local hash exists
|
||||
if (!localHash.empty())
|
||||
{
|
||||
TiXmlDocument remote_xml, local_xml;
|
||||
TiXmlDocument remote_xml;
|
||||
remote_xml.Parse(xml_data.c_str());
|
||||
local_xml.LoadFile(local_xml_file.string());
|
||||
TiXmlNode *fileNodeRemote = remote_xml.FirstChild("file");
|
||||
TiXmlNode *fileNodeLocal = local_xml.FirstChild("file");
|
||||
if (fileNodeRemote && fileNodeLocal)
|
||||
if (fileNodeRemote)
|
||||
{
|
||||
TiXmlElement *fileElemRemote = fileNodeRemote->ToElement();
|
||||
TiXmlElement *fileElemLocal = fileNodeLocal->ToElement();
|
||||
std::string remoteHash = fileElemRemote->Attribute("md5");
|
||||
std::string localHash = fileElemLocal->Attribute("md5");
|
||||
if (remoteHash != localHash)
|
||||
bSameVersion = false;
|
||||
}
|
||||
@ -1518,3 +1515,149 @@ void Downloader::checkOrphans()
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Check status of files
|
||||
void Downloader::checkStatus()
|
||||
{
|
||||
for (unsigned int i = 0; i < games.size(); ++i)
|
||||
{
|
||||
if (!config.bNoInstallers)
|
||||
{
|
||||
for (unsigned int j = 0; j < games[i].installers.size(); ++j)
|
||||
{
|
||||
boost::filesystem::path filepath = Util::makeFilepath(config.sDirectory, games[i].installers[j].path, games[i].gamename);
|
||||
|
||||
std::string remoteHash;
|
||||
std::string localHash;
|
||||
bool bHashOK = true; // assume hash OK
|
||||
size_t filesize;
|
||||
|
||||
localHash = this->getLocalFileHash(filepath.string());
|
||||
remoteHash = this->getRemoteFileHash(games[i].gamename, games[i].installers[j].id);
|
||||
|
||||
if (boost::filesystem::exists(filepath))
|
||||
{
|
||||
filesize = boost::filesystem::file_size(filepath);
|
||||
|
||||
if (remoteHash != localHash)
|
||||
bHashOK = false;
|
||||
|
||||
std::cout << (bHashOK ? "OK " : "MD5 ") << games[i].gamename << " " << filepath.filename().string() << " " << filesize << " " << localHash << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ND " << games[i].gamename << " " << filepath.filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.bNoExtras)
|
||||
{
|
||||
for (unsigned int j = 0; j < games[i].extras.size(); ++j)
|
||||
{
|
||||
boost::filesystem::path filepath = Util::makeFilepath(config.sDirectory, games[i].extras[j].path, games[i].gamename);
|
||||
|
||||
std::string localHash = this->getLocalFileHash(filepath.string());
|
||||
size_t filesize;
|
||||
|
||||
if (boost::filesystem::exists(filepath))
|
||||
{
|
||||
filesize = boost::filesystem::file_size(filepath);
|
||||
std::cout << "OK " << games[i].gamename << " " << filepath.filename().string() << " " << filesize << " " << localHash << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ND " << games[i].gamename << " " << filepath.filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.bNoPatches)
|
||||
{
|
||||
for (unsigned int j = 0; j < games[i].patches.size(); ++j)
|
||||
{
|
||||
boost::filesystem::path filepath = Util::makeFilepath(config.sDirectory, games[i].patches[j].path, games[i].gamename);
|
||||
|
||||
std::string localHash = this->getLocalFileHash(filepath.string());
|
||||
size_t filesize;
|
||||
|
||||
if (boost::filesystem::exists(filepath))
|
||||
{
|
||||
filesize = boost::filesystem::file_size(filepath);
|
||||
std::cout << "OK " << games[i].gamename << " " << filepath.filename().string() << " " << filesize << " " << localHash << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ND " << games[i].gamename << " " << filepath.filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!config.bNoLanguagePacks)
|
||||
{
|
||||
for (unsigned int j = 0; j < games[i].languagepacks.size(); ++j)
|
||||
{
|
||||
boost::filesystem::path filepath = Util::makeFilepath(config.sDirectory, games[i].languagepacks[j].path, games[i].gamename);
|
||||
|
||||
std::string localHash = this->getLocalFileHash(filepath.string());
|
||||
size_t filesize;
|
||||
|
||||
if (boost::filesystem::exists(filepath))
|
||||
{
|
||||
filesize = boost::filesystem::file_size(filepath);
|
||||
std::cout << "OK " << games[i].gamename << " " << filepath.filename().string() << " " << filesize << " " << localHash << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << "ND " << games[i].gamename << " " << filepath.filename().string() << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
std::string Downloader::getLocalFileHash(const std::string& filepath)
|
||||
{
|
||||
std::string localHash;
|
||||
boost::filesystem::path path = filepath;
|
||||
boost::filesystem::path local_xml_file = config.sXMLDirectory + "/" + path.filename().string() + ".xml";
|
||||
if (boost::filesystem::exists(local_xml_file))
|
||||
{
|
||||
TiXmlDocument local_xml;
|
||||
local_xml.LoadFile(local_xml_file.string());
|
||||
TiXmlNode *fileNodeLocal = local_xml.FirstChild("file");
|
||||
if (fileNodeLocal)
|
||||
{
|
||||
TiXmlElement *fileElemLocal = fileNodeLocal->ToElement();
|
||||
localHash = fileElemLocal->Attribute("md5");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (boost::filesystem::exists(path))
|
||||
{
|
||||
localHash = Util::getFileHash(path.string(), RHASH_MD5);
|
||||
}
|
||||
}
|
||||
return localHash;
|
||||
}
|
||||
|
||||
std::string Downloader::getRemoteFileHash(const std::string& gamename, const std::string& id)
|
||||
{
|
||||
std::string remoteHash;
|
||||
std::string xml_data = gogAPI->getXML(gamename, id);
|
||||
if (!xml_data.empty())
|
||||
{
|
||||
TiXmlDocument remote_xml;
|
||||
remote_xml.Parse(xml_data.c_str());
|
||||
TiXmlNode *fileNodeRemote = remote_xml.FirstChild("file");
|
||||
if (fileNodeRemote)
|
||||
{
|
||||
TiXmlElement *fileElemRemote = fileNodeRemote->ToElement();
|
||||
remoteHash = fileElemRemote->Attribute("md5");
|
||||
}
|
||||
}
|
||||
return remoteHash;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user