2013-03-15 21:46:16 +01:00
/* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law . You can redistribute it
* and / or modify it under the terms of the Do What The Fuck You Want
* To Public License , Version 2 , as published by Sam Hocevar . See
2013-03-24 22:56:57 +01:00
* http : //www.wtfpl.net/ for more details. */
2013-03-15 21:46:16 +01:00
# include "downloader.h"
# include "config.h"
# include "util.h"
2013-03-23 19:12:49 +01:00
# include "globalconstants.h"
2013-03-15 21:46:16 +01:00
# include <fstream>
# include <boost/filesystem.hpp>
# include <boost/program_options.hpp>
# if __GNUC__
# if __x86_64__ || __ppc64__ || __LP64__
# define ENVIRONMENT64
# else
# define ENVIRONMENT32
# endif
# endif
2013-11-29 14:47:08 +01:00
# define VERSION_NUMBER "2.10"
2013-03-19 18:29:58 +01:00
# ifndef VERSION_STRING
# define VERSION_STRING "LGOGDownloader " VERSION_NUMBER
# endif
2013-03-15 21:46:16 +01:00
namespace bpo = boost : : program_options ;
int main ( int argc , char * argv [ ] )
{
Config config ;
2013-03-19 18:29:58 +01:00
config . sVersionString = VERSION_STRING ;
2013-12-11 10:27:53 +01:00
char * xdgconfig = getenv ( " XDG_CONFIG_HOME " ) ;
char * xdgcache = getenv ( " XDG_CACHE_HOME " ) ;
std : : string home = ( std : : string ) getenv ( " HOME " ) ;
2013-03-15 21:46:16 +01:00
2013-12-11 10:27:53 +01:00
if ( xdgconfig )
{
config . sConfigDirectory = ( std : : string ) xdgconfig + " /lgogdownloader " ;
config . sCookiePath = config . sConfigDirectory + " /cookies.txt " ;
config . sConfigFilePath = config . sConfigDirectory + " /config.cfg " ;
}
else
{
config . sConfigDirectory = home + " /.config/lgogdownloader " ;
config . sCookiePath = config . sConfigDirectory + " /cookies.txt " ;
config . sConfigFilePath = config . sConfigDirectory + " /config.cfg " ;
}
if ( xdgcache )
config . sXMLDirectory = ( std : : string ) xdgcache + " /lgogdownloader/xml " ;
else
config . sXMLDirectory = home + " /.cache/lgogdownloader/xml " ;
// Create lgogdownloader directories
2013-03-16 22:35:57 +01:00
boost : : filesystem : : path path = config . sXMLDirectory ;
if ( ! boost : : filesystem : : exists ( path ) )
{
if ( ! boost : : filesystem : : create_directories ( path ) )
2013-12-11 10:27:53 +01:00
{
std : : cout < < " Failed to create directory: " < < path < < std : : endl ;
return 1 ;
}
}
path = config . sConfigDirectory ;
if ( ! boost : : filesystem : : exists ( path ) )
{
if ( ! boost : : filesystem : : create_directories ( path ) )
2013-03-16 22:35:57 +01:00
{
std : : cout < < " Failed to create directory: " < < path < < std : : endl ;
return 1 ;
}
}
2013-03-15 21:46:16 +01:00
// Create help text for --platform option
2013-03-23 19:12:49 +01:00
std : : string platform_text = " Select which installers are downloaded \n " ;
unsigned int platform_sum = 0 ;
2013-04-25 09:48:10 +02:00
for ( unsigned int i = 0 ; i < GlobalConstants : : PLATFORMS . size ( ) ; + + i )
2013-03-23 19:12:49 +01:00
{
2013-04-25 09:48:10 +02:00
platform_text + = std : : to_string ( GlobalConstants : : PLATFORMS [ i ] . platformId ) + " = " + GlobalConstants : : PLATFORMS [ i ] . platformString + " \n " ;
2013-03-23 19:12:49 +01:00
platform_sum + = GlobalConstants : : LANGUAGES [ i ] . languageId ;
}
platform_text + = std : : to_string ( platform_sum ) + " = All " ;
2013-03-15 21:46:16 +01:00
// Create help text for --language option
2013-03-23 19:12:49 +01:00
std : : string language_text = " Select which language installers are downloaded \n " ;
unsigned int language_sum = 0 ;
for ( unsigned int i = 0 ; i < GlobalConstants : : LANGUAGES . size ( ) ; + + i )
{
language_text + = std : : to_string ( GlobalConstants : : LANGUAGES [ i ] . languageId ) + " = " + GlobalConstants : : LANGUAGES [ i ] . languageString + " \n " ;
language_sum + = GlobalConstants : : LANGUAGES [ i ] . languageId ;
}
language_text + = " Add the values to download multiple languages \n All = " + std : : to_string ( language_sum ) + " \n "
+ " French + Polish = " + std : : to_string ( GlobalConstants : : LANGUAGE_FR ) + " + " + std : : to_string ( GlobalConstants : : LANGUAGE_PL ) + " = " + std : : to_string ( GlobalConstants : : LANGUAGE_FR | GlobalConstants : : LANGUAGE_PL ) ;
2013-03-15 21:46:16 +01:00
bpo : : variables_map vm ;
bpo : : options_description desc ( " Options " ) ;
bpo : : options_description config_file_options ( " Configuration " ) ;
try
{
2013-08-02 14:54:37 +02:00
bool bInsecure = false ;
2013-11-14 14:40:59 +01:00
bool bNoColor = false ;
bool bNoUnicode = false ;
2013-11-18 12:19:02 +01:00
bool bNoDuplicateHandler = false ;
2013-11-19 11:47:10 +01:00
bool bNoCover = false ;
bool bNoInstallers = false ;
bool bNoExtras = false ;
bool bNoPatches = false ;
bool bNoLanguagePacks = false ;
bool bNoRemoteXML = false ;
2013-03-15 21:46:16 +01:00
desc . add_options ( )
( " help,h " , " Print help message " )
( " login " , bpo : : value < bool > ( & config . bLogin ) - > zero_tokens ( ) - > default_value ( false ) , " Login " )
( " list " , bpo : : value < bool > ( & config . bList ) - > zero_tokens ( ) - > default_value ( false ) , " List games " )
( " list-details " , bpo : : value < bool > ( & config . bListDetails ) - > zero_tokens ( ) - > default_value ( false ) , " List games with detailed info " )
( " download " , bpo : : value < bool > ( & config . bDownload ) - > zero_tokens ( ) - > default_value ( false ) , " Download " )
2013-04-11 12:49:24 +02:00
( " repair " , bpo : : value < bool > ( & config . bRepair ) - > zero_tokens ( ) - > default_value ( false ) , " Repair downloaded files \n Use --repair --download to redownload files when filesizes don't match (possibly different version). Redownload will delete the old file " )
2013-03-15 21:46:16 +01:00
( " game " , bpo : : value < std : : string > ( & config . sGameRegex ) - > default_value ( " " ) , " Set regular expression filter \n for download/list/repair (Perl syntax) \n Aliases: \" all \" , \" free \" " )
( " directory " , bpo : : value < std : : string > ( & config . sDirectory ) - > default_value ( " " ) , " Set download directory " )
2013-06-28 14:49:00 +02:00
( " limit-rate " , bpo : : value < curl_off_t > ( & config . iDownloadRate ) - > default_value ( 0 ) , " Limit download rate to value in kB \n 0 = unlimited " )
2013-03-15 21:46:16 +01:00
( " create-xml " , bpo : : value < std : : string > ( & config . sXMLFile ) - > default_value ( " " ) , " Create GOG XML for file \n \" automatic \" to enable automatic XML creation " )
( " xml-directory " , bpo : : value < std : : string > ( & config . sXMLDirectory ) , " Set directory for GOG XML files " )
( " chunk-size " , bpo : : value < size_t > ( & config . iChunkSize ) - > default_value ( 10 ) , " Chunk size (in MB) when creating XML " )
( " update-check " , bpo : : value < bool > ( & config . bUpdateCheck ) - > zero_tokens ( ) - > default_value ( false ) , " Check for update notifications " )
2013-04-25 09:48:10 +02:00
( " platform " , bpo : : value < unsigned int > ( & config . iInstallerType ) - > default_value ( GlobalConstants : : PLATFORM_WINDOWS ) , platform_text . c_str ( ) )
2013-03-23 19:12:49 +01:00
( " language " , bpo : : value < unsigned int > ( & config . iInstallerLanguage ) - > default_value ( GlobalConstants : : LANGUAGE_EN ) , language_text . c_str ( ) )
2013-11-19 11:47:10 +01:00
( " no-installers " , bpo : : value < bool > ( & bNoInstallers ) - > zero_tokens ( ) - > default_value ( false ) , " Don't download/list/repair installers " )
( " no-extras " , bpo : : value < bool > ( & bNoExtras ) - > zero_tokens ( ) - > default_value ( false ) , " Don't download/list/repair extras " )
( " no-patches " , bpo : : value < bool > ( & bNoPatches ) - > zero_tokens ( ) - > default_value ( false ) , " Don't download/list/repair patches " )
( " no-language-packs " , bpo : : value < bool > ( & bNoLanguagePacks ) - > zero_tokens ( ) - > default_value ( false ) , " Don't download/list/repair language packs " )
( " no-cover " , bpo : : value < bool > ( & bNoCover ) - > zero_tokens ( ) - > default_value ( false ) , " Don't download cover images " )
( " no-remote-xml " , bpo : : value < bool > ( & bNoRemoteXML ) - > zero_tokens ( ) - > default_value ( false ) , " Don't use remote XML for repair " )
2013-11-14 14:40:59 +01:00
( " 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 " )
2013-11-18 12:19:02 +01:00
( " no-duplicate-handling " , bpo : : value < bool > ( & bNoDuplicateHandler ) - > zero_tokens ( ) - > default_value ( false ) , " Don't use duplicate handler for installers \n Duplicate installers from different languages are handled separately " )
2013-03-15 21:46:16 +01:00
( " verbose " , bpo : : value < bool > ( & config . bVerbose ) - > zero_tokens ( ) - > default_value ( false ) , " Print lots of information " )
2013-08-02 14:54:37 +02:00
( " insecure " , bpo : : value < bool > ( & bInsecure ) - > zero_tokens ( ) - > default_value ( false ) , " Don't verify authenticity of SSL certificates " )
2013-06-10 14:15:08 +02:00
( " timeout " , bpo : : value < long int > ( & config . iTimeout ) - > default_value ( 10 ) , " Set timeout for connection \n Maximum time in seconds that connection phase is allowed to take " )
2013-10-14 21:31:12 +02:00
( " 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) " )
2013-11-14 14:40:59 +01:00
( " status " , bpo : : value < bool > ( & config . bCheckStatus ) - > zero_tokens ( ) - > default_value ( false ) , " Show status of files \n \n Output format: \n statuscode gamename filename filesize filehash \n \n Status codes: \n OK - File is OK \n ND - File is not downloaded \n MD5 - MD5 mismatch, different version " )
2013-03-15 21:46:16 +01:00
;
bpo : : store ( bpo : : parse_command_line ( argc , argv , desc ) , vm ) ;
bpo : : notify ( vm ) ;
// Read token and secret from config file
config_file_options . add_options ( )
( " token " , bpo : : value < std : : string > ( & config . sToken ) - > default_value ( " " ) , " oauth token " )
( " secret " , bpo : : value < std : : string > ( & config . sSecret ) - > default_value ( " " ) , " oauth secret " )
;
if ( boost : : filesystem : : exists ( config . sConfigFilePath ) )
{
std : : ifstream ifs ( config . sConfigFilePath . c_str ( ) ) ;
if ( ! ifs )
{
std : : cout < < " Could not open config file: " < < config . sConfigFilePath < < std : : endl ;
return 1 ;
}
else
{
bpo : : store ( bpo : : parse_config_file ( ifs , config_file_options ) , vm ) ;
bpo : : notify ( vm ) ;
ifs . close ( ) ;
}
}
if ( vm . count ( " help " ) )
{
std : : cout < < config . sVersionString < < std : : endl
< < desc < < std : : endl ;
return 0 ;
}
if ( vm . count ( " chunk-size " ) )
config . iChunkSize < < = 20 ; // Convert chunk size from bytes to megabytes
if ( vm . count ( " limit-rate " ) )
config . iDownloadRate < < = 10 ; // Convert download rate from bytes to kilobytes
2013-04-25 11:05:17 +02:00
2013-08-02 14:54:37 +02:00
config . bVerifyPeer = ! bInsecure ;
2013-11-14 14:40:59 +01:00
config . bColor = ! bNoColor ;
config . bUnicode = ! bNoUnicode ;
2013-11-18 12:19:02 +01:00
config . bDuplicateHandler = ! bNoDuplicateHandler ;
2013-11-19 11:47:10 +01:00
config . bCover = ! bNoCover ;
config . bInstallers = ! bNoInstallers ;
config . bExtras = ! bNoExtras ;
config . bPatches = ! bNoPatches ;
config . bLanguagePacks = ! bNoLanguagePacks ;
config . bRemoteXML = ! bNoRemoteXML ;
2013-03-15 21:46:16 +01:00
}
catch ( std : : exception & e )
{
std : : cerr < < " Error: " < < e . what ( ) < < std : : endl ;
return 1 ;
}
catch ( . . . )
{
std : : cerr < < " Exception of unknown type! " < < std : : endl ;
return 1 ;
}
2013-04-25 11:12:37 +02:00
if ( config . iInstallerType < GlobalConstants : : PLATFORMS [ 0 ] . platformId | | config . iInstallerType > platform_sum )
2013-03-15 21:46:16 +01:00
{
std : : cout < < " Invalid value for --platform " < < std : : endl ;
return 1 ;
}
2013-04-25 11:12:37 +02:00
if ( config . iInstallerLanguage < GlobalConstants : : LANGUAGES [ 0 ] . languageId | | config . iInstallerLanguage > language_sum )
2013-03-23 19:12:49 +01:00
{
std : : cout < < " Invalid value for --language " < < std : : endl ;
return 1 ;
}
2013-03-15 21:46:16 +01:00
if ( ! config . sXMLDirectory . empty ( ) )
{
// Make sure that xml directory doesn't have trailing slash
if ( config . sXMLDirectory . at ( config . sXMLDirectory . length ( ) - 1 ) = = ' / ' )
config . sXMLDirectory . assign ( config . sXMLDirectory . begin ( ) , config . sXMLDirectory . end ( ) - 1 ) ;
}
// Create GOG XML for a file
if ( ! config . sXMLFile . empty ( ) & & ( config . sXMLFile ! = " automatic " ) )
{
Util : : createXML ( config . sXMLFile , config . iChunkSize , config . sXMLDirectory ) ;
return 0 ;
}
// Make sure that directory has trailing slash
if ( ! config . sDirectory . empty ( ) )
if ( config . sDirectory . at ( config . sDirectory . length ( ) - 1 ) ! = ' / ' )
2013-03-16 22:35:57 +01:00
config . sDirectory + = " / " ;
2013-03-15 21:46:16 +01:00
Downloader downloader ( config ) ;
int result = downloader . init ( ) ;
if ( config . bLogin )
return result ;
2013-03-16 02:22:45 +01:00
else if ( config . bUpdateCheck ) // Update check has priority over download and list
downloader . updateCheck ( ) ;
2013-03-15 21:46:16 +01:00
else if ( config . bRepair ) // Repair file
downloader . repair ( ) ;
2013-04-05 20:19:03 +02:00
else if ( config . bDownload ) // Download games
downloader . download ( ) ;
2013-03-15 21:46:16 +01:00
else if ( config . bListDetails | | config . bList ) // Detailed list of games/extras
downloader . listGames ( ) ;
2013-10-14 21:31:12 +02:00
else if ( config . bCheckOrphans )
downloader . checkOrphans ( ) ;
2013-11-14 14:40:59 +01:00
else if ( config . bCheckStatus )
downloader . checkStatus ( ) ;
2013-03-15 21:46:16 +01:00
else
{ // Show help message
std : : cout < < config . sVersionString < < std : : endl
< < desc < < std : : endl ;
}
return 0 ;
}