Improvements to orphan detection:

- blacklist applies to installed files only; use ignorelist for orphans
  - blacklisted but present items are orphans, as they should be
  - use exact matching for file paths: files in wrong location are orphans
This commit is contained in:
Thomas J. Moore 2016-02-20 14:59:52 -06:00
parent d9697ea988
commit 9520f3f3b7
4 changed files with 54 additions and 71 deletions

View File

@ -60,6 +60,7 @@ class Config
std::string sCookiePath; std::string sCookiePath;
std::string sConfigFilePath; std::string sConfigFilePath;
std::string sBlacklistFilePath; std::string sBlacklistFilePath;
std::string sIgnorelistFilePath;
std::string sOrphanRegex; std::string sOrphanRegex;
std::string sCoverList; std::string sCoverList;
std::string sReportFilePath; std::string sReportFilePath;
@ -87,6 +88,7 @@ class Config
curl_off_t iDownloadRate; curl_off_t iDownloadRate;
long int iTimeout; long int iTimeout;
Blacklist blacklist; Blacklist blacklist;
Blacklist ignorelist;
}; };
#endif // CONFIG_H__ #endif // CONFIG_H__

View File

@ -54,6 +54,7 @@ int main(int argc, char *argv[])
config.sCookiePath = config.sConfigDirectory + "/cookies.txt"; config.sCookiePath = config.sConfigDirectory + "/cookies.txt";
config.sConfigFilePath = config.sConfigDirectory + "/config.cfg"; config.sConfigFilePath = config.sConfigDirectory + "/config.cfg";
config.sBlacklistFilePath = config.sConfigDirectory + "/blacklist.txt"; config.sBlacklistFilePath = config.sConfigDirectory + "/blacklist.txt";
config.sIgnorelistFilePath = config.sConfigDirectory + "/ignorelist.txt";
std::string priority_help_text = "Set priority by separating values with \",\"\nCombine values by separating with \"+\""; std::string priority_help_text = "Set priority by separating values with \",\"\nCombine values by separating with \"+\"";
// Create help text for --platform option // Create help text for --platform option
@ -272,6 +273,27 @@ int main(int argc, char *argv[])
} }
} }
if (boost::filesystem::exists(config.sIgnorelistFilePath))
{
std::ifstream ifs(config.sIgnorelistFilePath.c_str());
if (!ifs)
{
std::cerr << "Could not open ignorelist file: " << config.sIgnorelistFilePath << std::endl;
return 1;
}
else
{
std::string line;
std::vector<std::string> lines;
while (!ifs.eof())
{
std::getline(ifs, line);
lines.push_back(std::move(line));
}
config.ignorelist.initialize(lines);
}
}
if (vm.count("chunk-size")) if (vm.count("chunk-size"))
config.iChunkSize <<= 20; // Convert chunk size from bytes to megabytes config.iChunkSize <<= 20; // Convert chunk size from bytes to megabytes

View File

@ -62,7 +62,15 @@ If \fB$XDG_CACHE_HOME\fP is not set, it will use \fI$HOME/.cache/lgogdownloader/
.TP .TP
\fI$XDG_CONFIG_HOME/lgogdownloader/blacklist.txt\fP \fI$XDG_CONFIG_HOME/lgogdownloader/blacklist.txt\fP
Allows user to specify individual files that should not be downloaded or mentioned as orphans. Allows user to specify individual files that should not be downloaded.
.br
It doesn't have to exist, but if it does exist, it must be readable to lgogdownloader.
.TP
\fI$XDG_CONFIG_HOME/lgogdownloader/ignorelist.txt\fP
Allows user to specify individual files that should not be mentioned
as orphans. The file has the same format and interpretation as a
blacklist.
.br .br
It doesn't have to exist, but if it does exist, it must be readable to lgogdownloader. It doesn't have to exist, but if it does exist, it must be readable to lgogdownloader.

View File

@ -2467,6 +2467,17 @@ std::string Downloader::getSerialsFromJSON(const Json::Value& json)
return serials.str(); return serials.str();
} }
// Linear search. Good thing computers are fast and lists are small.
static int isPresent(std::vector<gameFile>& list, const boost::filesystem::path& path, Blacklist& blacklist)
{
if(blacklist.isBlacklisted(path.native()))
return false;
for (unsigned int k = 0; k < list.size(); ++k)
if (list[k].getFilepath() == path.native())
return true;
return false;
}
void Downloader::checkOrphans() void Downloader::checkOrphans()
{ {
// Always check everything when checking for orphaned files // Always check everything when checking for orphaned files
@ -2529,7 +2540,7 @@ void Downloader::checkOrphans()
if (boost::filesystem::is_regular_file(dir_iter->status())) if (boost::filesystem::is_regular_file(dir_iter->status()))
{ {
std::string filepath = dir_iter->path().string(); std::string filepath = dir_iter->path().string();
if (config.blacklist.isBlacklisted(filepath.substr(pathlen))) { if (config.ignorelist.isBlacklisted(filepath.substr(pathlen))) {
if (config.bVerbose) if (config.bVerbose)
std::cerr << "skipped ignorelisted file " << filepath << std::endl; std::cerr << "skipped ignorelisted file " << filepath << std::endl;
} else { } else {
@ -2556,80 +2567,20 @@ void Downloader::checkOrphans()
{ {
for (unsigned int j = 0; j < filepath_vector.size(); ++j) for (unsigned int j = 0; j < filepath_vector.size(); ++j)
{ {
bool bFoundFile = false; // Assume that the file is orphaned bool bFoundFile = isPresent(games[i].installers, filepath_vector[j], config.blacklist)
|| isPresent(games[i].extras, filepath_vector[j], config.blacklist)
|| isPresent(games[i].patches, filepath_vector[j], config.blacklist)
|| isPresent(games[i].languagepacks, filepath_vector[j], config.blacklist);
// Check installers
for (unsigned int k = 0; k < games[i].installers.size(); ++k)
{
if (games[i].installers[k].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
if (!bFoundFile)
{ // Check extras
for (unsigned int k = 0; k < games[i].extras.size(); ++k)
{
if (games[i].extras[k].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
}
if (!bFoundFile)
{ // Check patches
for (unsigned int k = 0; k < games[i].patches.size(); ++k)
{
if (games[i].patches[k].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
}
if (!bFoundFile)
{ // Check language packs
for (unsigned int k = 0; k < games[i].languagepacks.size(); ++k)
{
if (games[i].languagepacks[k].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
}
if (!bFoundFile) if (!bFoundFile)
{ // Check dlcs { // Check dlcs
for (unsigned int k = 0; k < games[i].dlcs.size(); ++k) for (unsigned int k = 0; k < games[i].dlcs.size(); ++k)
{ {
for (unsigned int index = 0; index < games[i].dlcs[k].installers.size(); ++index) bFoundFile = isPresent(games[i].dlcs[k].installers, filepath_vector[j], config.blacklist)
{ || isPresent(games[i].dlcs[k].extras, filepath_vector[j], config.blacklist)
if (games[i].dlcs[k].installers[index].path.find(filepath_vector[j].filename().string()) != std::string::npos) || isPresent(games[i].dlcs[k].patches, filepath_vector[j], config.blacklist);
{ if(bFoundFile)
bFoundFile = true; break;
break;
}
}
if (bFoundFile) break;
for (unsigned int index = 0; index < games[i].dlcs[k].patches.size(); ++index)
{
if (games[i].dlcs[k].patches[index].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
for (unsigned int index = 0; index < games[i].dlcs[k].extras.size(); ++index)
{
if (games[i].dlcs[k].extras[index].path.find(filepath_vector[j].filename().string()) != std::string::npos)
{
bFoundFile = true;
break;
}
}
if (bFoundFile) break;
} }
} }
if (!bFoundFile) if (!bFoundFile)