Some code restructuring

- Move some code from Downloader::init() to constructor
- Add function API::isLoggedIn()
- Add function Downloader::isLoggedIn()
- Don't call Downloader::getGameList() from Downloader::init(). Call it from other functions if/when needed

Also fix some login issues
This commit is contained in:
Sude 2016-12-17 21:01:44 +02:00
parent f93c8ee753
commit dea82b7991
5 changed files with 148 additions and 53 deletions

View File

@ -55,6 +55,7 @@ class API
API(const std::string& token,const std::string& secret);
int init();
bool isLoggedIn();
int login(const std::string& email, const std::string& password);
int getAPIConfig();
std::string getResponse(const std::string& url);

View File

@ -63,6 +63,7 @@ class Downloader
public:
Downloader(Config &conf);
virtual ~Downloader();
bool isLoggedIn();
int init();
int login();
int listGames();

View File

@ -8,6 +8,7 @@
#include "config.h"
#include "util.h"
#include "globalconstants.h"
#include "ssl_thread_setup.h"
#include <fstream>
#include <boost/filesystem.hpp>
@ -475,17 +476,43 @@ int main(int argc, char *argv[])
std::cerr << std::endl;
}
Downloader downloader(config);
int initResult = downloader.init();
// Init curl globally
ssl_thread_setup();
curl_global_init(CURL_GLOBAL_ALL);
int iLoginResult = 0;
if (config.bLoginAPI || config.bLoginHTTP || initResult == 1)
if (config.bLoginAPI)
{
if (!config.bLoginAPI && !config.bLoginHTTP)
downloader.config.bLoginAPI = true;
iLoginResult = downloader.login();
if (iLoginResult == 0)
return 1;
config.sToken = "";
config.sSecret = "";
}
Downloader downloader(config);
int iLoginTries = 0;
bool bLoginOK = false;
// Login because --login, --login-api or --login-website was used
if (config.bLoginAPI || config.bLoginHTTP)
bLoginOK = downloader.login();
bool bIsLoggedin = downloader.isLoggedIn();
// Login because we are not logged in
while (iLoginTries++ < config.iRetries && !bIsLoggedin)
{
bLoginOK = downloader.login();
if (bLoginOK)
{
bIsLoggedin = downloader.isLoggedIn();
}
}
// Login failed, cleanup
if (!bLoginOK && !bIsLoggedin)
{
curl_global_cleanup();
ssl_thread_cleanup();
return 1;
}
// Make sure that config file and cookie file are only readable/writable by owner
@ -495,9 +522,9 @@ int main(int argc, char *argv[])
Util::setFilePermissions(config.sCookiePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
}
if (config.bSaveConfig || iLoginResult == 1)
if (config.bSaveConfig || bLoginOK)
{
if (iLoginResult == 1)
if (bLoginOK)
{
set_vm_value(vm, "token", downloader.config.sToken);
set_vm_value(vm, "secret", downloader.config.sSecret);
@ -553,11 +580,17 @@ int main(int argc, char *argv[])
if (!config.bRespectUmask)
Util::setFilePermissions(config.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
if (config.bSaveConfig)
{
curl_global_cleanup();
ssl_thread_cleanup();
return 0;
}
}
else
{
std::cerr << "Failed to create config: " << config.sConfigFilePath << std::endl;
curl_global_cleanup();
ssl_thread_cleanup();
return 1;
}
}
@ -574,15 +607,28 @@ int main(int argc, char *argv[])
ofs.close();
if (!config.bRespectUmask)
Util::setFilePermissions(config.sConfigFilePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
curl_global_cleanup();
ssl_thread_cleanup();
return 0;
}
else
{
std::cerr << "Failed to create config: " << config.sConfigFilePath << std::endl;
curl_global_cleanup();
ssl_thread_cleanup();
return 1;
}
}
bool bInitOK = downloader.init();
if (!bInitOK)
{
curl_global_cleanup();
ssl_thread_cleanup();
return 1;
}
int res = 0;
if (config.bShowWishlist)
@ -622,5 +668,8 @@ int main(int argc, char *argv[])
if (!config.sOrphanRegex.empty() && config.bDownload)
downloader.checkOrphans();
curl_global_cleanup();
ssl_thread_cleanup();
return res;
}

View File

@ -41,11 +41,32 @@ API::API(const std::string& token, const std::string& secret)
this->config.oauth_secret = secret;
}
/* Initialize the API
returns 0 if failed
returns 1 if successful
*/
int API::init()
{
int res = 0;
this->getAPIConfig();
if (!this->getError())
res = 1;
else
this->clearError();
return res;
}
/* Login check
returns false if not logged in
returns true if logged in
*/
bool API::isLoggedIn()
{
int res = 0;
// Check if we already have token and secret
if (!this->config.oauth_token.empty() && !this->config.oauth_secret.empty())
{
@ -56,7 +77,6 @@ int API::init()
return res;
}
int API::getAPIConfig()
{
std::string url = "https://api.gog.com/downloader2/status/stable/"; // Stable API

View File

@ -7,7 +7,6 @@
#include "downloader.h"
#include "util.h"
#include "globalconstants.h"
#include "ssl_thread_setup.h"
#include "downloadinfo.h"
#include "message.h"
@ -28,6 +27,8 @@
#include <htmlcxx/html/Uri.h>
#include <termios.h>
#include <algorithm>
#include <thread>
#include <mutex>
namespace bptime = boost::posix_time;
@ -41,41 +42,15 @@ std::mutex mtx_create_directories; // Mutex for creating directories in Download
Downloader::Downloader(Config &conf)
{
ssl_thread_setup();
this->config = conf;
if (config.bLoginHTTP && boost::filesystem::exists(config.sCookiePath))
if (!boost::filesystem::remove(config.sCookiePath))
std::cerr << "Failed to delete " << config.sCookiePath << std::endl;
}
Downloader::~Downloader()
{
if (config.bReport)
if (this->report_ofs)
this->report_ofs.close();
delete progressbar;
delete gogAPI;
delete gogWebsite;
curl_easy_cleanup(curlhandle);
curl_global_cleanup();
ssl_thread_cleanup();
// Make sure that cookie file is only readable/writable by owner
if (!config.bRespectUmask)
Util::setFilePermissions(config.sCookiePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
}
/* Initialize the downloader
returns 0 if successful
returns 1 if failed
*/
int Downloader::init()
{
this->resume_position = 0;
this->retries = 0;
// Initialize curl and set curl options
curl_global_init(CURL_GLOBAL_ALL);
curlhandle = curl_easy_init();
curl_easy_setopt(curlhandle, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(curlhandle, CURLOPT_USERAGENT, config.sVersionString.c_str());
@ -100,7 +75,6 @@ int Downloader::init()
// Create new GOG website handle
gogWebsite = new Website(config);
bool bWebsiteIsLoggedIn = gogWebsite->IsLoggedIn();
// Create new API handle and set curl options for the API
gogAPI = new API(config.sToken, config.sSecret);
@ -110,12 +84,55 @@ int Downloader::init()
if (!config.sCACertPath.empty())
gogAPI->curlSetOpt(CURLOPT_CAINFO, config.sCACertPath.c_str());
gogAPI->init();
progressbar = new ProgressBar(config.bUnicode, config.bColor);
}
bool bInitOK = gogAPI->init(); // Initialize the API
if (!bInitOK || !bWebsiteIsLoggedIn || config.bLoginHTTP || config.bLoginAPI)
return 1;
Downloader::~Downloader()
{
if (config.bReport)
if (this->report_ofs)
this->report_ofs.close();
delete progressbar;
delete gogAPI;
delete gogWebsite;
curl_easy_cleanup(curlhandle);
// Make sure that cookie file is only readable/writable by owner
if (!config.bRespectUmask)
Util::setFilePermissions(config.sCookiePath, boost::filesystem::owner_read | boost::filesystem::owner_write);
}
/* Login check
returns false if not logged in
returns true if logged in
*/
bool Downloader::isLoggedIn()
{
bool bIsLoggedIn = false;
config.bLoginAPI = false;
config.bLoginHTTP = false;
bool bWebsiteIsLoggedIn = gogWebsite->IsLoggedIn();
if (!bWebsiteIsLoggedIn)
config.bLoginHTTP = true;
bool bIsLoggedInAPI = gogAPI->isLoggedIn();
if (!bIsLoggedInAPI)
config.bLoginAPI = true;
if (bIsLoggedInAPI && bWebsiteIsLoggedIn)
bIsLoggedIn = true;
return bIsLoggedIn;
}
/* Initialize the downloader
returns 0 if failed
returns 1 if successful
*/
int Downloader::init()
{
if (!config.sGameHasDLCList.empty())
{
if (config.gamehasdlc.empty())
@ -127,25 +144,18 @@ int Downloader::init()
}
gogWebsite->setConfig(config); // Update config for website handle
if (config.bCover && config.bDownload && !config.bUpdateCheck)
coverXML = this->getResponse(config.sCoverList);
// updateCheck() calls getGameList() if needed
// getGameList() is not needed when using cache unless we want to list games from account
if ( !config.bUpdateCheck && (!config.bUseCache || (config.bUseCache && config.bList)) && config.sFileIdString.empty() && !config.bShowWishlist )
this->getGameList();
if (config.bReport && (config.bDownload || config.bRepair))
{
this->report_ofs.open(config.sReportFilePath);
if (!this->report_ofs)
{
config.bReport = false;
std::cerr << "Failed to create " << config.sReportFilePath << std::endl;
return 1;
return 0;
}
}
return 0;
return 1;
}
/* Login
@ -183,6 +193,11 @@ int Downloader::login()
// Login to website
if (config.bLoginHTTP)
{
// Delete old cookies
if (boost::filesystem::exists(config.sCookiePath))
if (!boost::filesystem::remove(config.sCookiePath))
std::cerr << "Failed to delete " << config.sCookiePath << std::endl;
if (!gogWebsite->Login(email, password))
{
std::cerr << "HTTP: Login failed" << std::endl;
@ -308,6 +323,9 @@ int Downloader::getGameDetails()
}
}
if (gameItems.empty())
this->getGameList();
if (!gameItems.empty())
{
for (unsigned int i = 0; i < gameItems.size(); ++i)
@ -578,6 +596,9 @@ int Downloader::listGames()
}
else
{ // List game names
if (gameItems.empty())
this->getGameList();
for (unsigned int i = 0; i < gameItems.size(); ++i)
{
std::cout << gameItems[i].name << std::endl;
@ -878,6 +899,9 @@ void Downloader::download()
if (this->games.empty())
this->getGameDetails();
if (config.bCover && !config.bUpdateCheck)
coverXML = this->getResponse(config.sCoverList);
for (unsigned int i = 0; i < games.size(); ++i)
{
if (config.bSaveSerials && !games[i].serials.empty())