Use new list_files, parse dates to check if sessions are old (#4660)

This commit is contained in:
Christian Kaiser 2024-09-19 15:50:02 -03:00 committed by GitHub
parent 31c80a5e0c
commit 5860269358
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 89 additions and 64 deletions

View File

@ -143,30 +143,28 @@ void DataRecovery::searchForSessions()
// Existent sessions // Existent sessions
RECO_TRACE("RECO: Listing sessions from '%s'\n", m_sessionsDir.c_str()); RECO_TRACE("RECO: Listing sessions from '%s'\n", m_sessionsDir.c_str());
for (auto& itemname : base::list_files(m_sessionsDir)) { for (const auto& itemname : base::list_files(m_sessionsDir, base::ItemType::Directories)) {
std::string itempath = base::join_path(m_sessionsDir, itemname); const auto& itempath = base::join_path(m_sessionsDir, itemname);
if (base::is_directory(itempath)) { RECO_TRACE("RECO: Session '%s' ", itempath.c_str());
RECO_TRACE("RECO: Session '%s'\n", itempath.c_str());
SessionPtr session(new Session(&m_config, itempath)); SessionPtr session(new Session(&m_config, itempath));
if (!session->isRunning()) { if (!session->isRunning()) {
if ((session->isEmpty()) || if ((session->isEmpty()) ||
(!session->isCrashedSession() && session->isOldSession())) { (!session->isCrashedSession() && session->isOldSession())) {
RECO_TRACE("RECO: - to be deleted (%s)\n", RECO_TRACE("to be deleted (%s)\n",
session->isEmpty() ? "is empty": session->isEmpty() ? "is empty":
(session->isOldSession() ? "is old": (session->isOldSession() ? "is old":
"unknown reason")); "unknown reason"));
session->removeFromDisk(); session->removeFromDisk();
} }
else { else {
RECO_TRACE("RECO: - to be loaded\n"); RECO_TRACE("to be loaded\n");
sessions.push_back(session); sessions.push_back(session);
} }
} }
else else
RECO_TRACE("is running\n"); RECO_TRACE("is running\n");
} }
}
// Sort sessions from the most recent one to the oldest one // Sort sessions from the most recent one to the oldest one
std::sort(sessions.begin(), sessions.end(), std::sort(sessions.begin(), sessions.end(),

View File

@ -77,7 +77,7 @@ public:
, m_docVersions(nullptr) , m_docVersions(nullptr)
, m_loadInfo(nullptr) , m_loadInfo(nullptr)
, m_taskToken(t) { , m_taskToken(t) {
for (const auto& fn : base::list_files(dir)) { for (const auto& fn : base::list_files(dir, base::ItemType::Files)) {
auto i = fn.find('-'); auto i = fn.find('-');
if (i == std::string::npos) if (i == std::string::npos)
continue; // Has no ID continue; // Has no ID

View File

@ -30,6 +30,7 @@
#include "base/thread.h" #include "base/thread.h"
#include "base/time.h" #include "base/time.h"
#include "doc/cancel_io.h" #include "doc/cancel_io.h"
#include "ui/app_state.h"
#include "fmt/format.h" #include "fmt/format.h"
#include "ver/info.h" #include "ver/info.h"
@ -114,13 +115,14 @@ std::string Session::version()
const Session::Backups& Session::backups() const Session::Backups& Session::backups()
{ {
if (m_backups.empty()) { if (m_backups.empty()) {
for (auto& item : base::list_files(m_path)) { for (const auto& item : base::list_files(m_path, base::ItemType::Directories)) {
if (ui::is_app_state_closing())
continue;
std::string docDir = base::join_path(m_path, item); std::string docDir = base::join_path(m_path, item);
if (base::is_directory(docDir)) {
m_backups.push_back(std::make_shared<Backup>(docDir)); m_backups.push_back(std::make_shared<Backup>(docDir));
} }
} }
}
return m_backups; return m_backups;
} }
@ -147,18 +149,40 @@ bool Session::isOldSession()
return true; return true;
int lifespanDays = m_config->keepEditedSpriteDataFor; int lifespanDays = m_config->keepEditedSpriteDataFor;
base::Time sessionTime = base::get_modification_time(verfile); base::Time sessionTime;
// Get the session time from the name if possible, to avoid re-scanning when transferring files
std::vector<std::string> parts;
base::split_string(base::get_file_title(m_path), parts, "-");
if (parts.size() == 3 && parts[0].size() == 8) {
try {
sessionTime = base::Time(filenamePartToInt(parts[0].substr(0, 4)),
filenamePartToInt(parts[0].substr(4, 2)),
filenamePartToInt(parts[0].substr(6, 2)),
0,
0,
0);
}
catch (const std::exception& ex) {
LOG(ERROR,
"Failed to parse a date from '%s', error: %s",
parts[0].c_str(),
ex.what());
}
}
if (!sessionTime.valid()) {
// Get modification time as a fallback
sessionTime = base::get_modification_time(verfile);
}
return (sessionTime.addDays(lifespanDays) < base::current_time()); return (sessionTime.addDays(lifespanDays) < base::current_time());
} }
bool Session::isEmpty() bool Session::isEmpty()
{ {
for (auto& item : base::list_files(m_path)) { return base::list_files(m_path, base::ItemType::Directories).empty();
if (base::is_directory(base::join_path(m_path, item)))
return false;
}
return true;
} }
void Session::create(base::pid pid) void Session::create(base::pid pid)
@ -385,13 +409,14 @@ void Session::deleteDirectory(const std::string& dir)
if (dir.empty()) if (dir.empty())
return; return;
for (auto& item : base::list_files(dir)) { for (const auto& item : base::list_files(dir, base::ItemType::Files)) {
if (ui::is_app_state_closing())
return;
std::string objfn = base::join_path(dir, item); std::string objfn = base::join_path(dir, item);
if (base::is_file(objfn)) {
RECO_TRACE("RECO: Deleting file '%s'\n", objfn.c_str()); RECO_TRACE("RECO: Deleting file '%s'\n", objfn.c_str());
base::delete_file(objfn); base::delete_file(objfn);
} }
}
base::remove_directory(dir); base::remove_directory(dir);
} }
@ -411,5 +436,20 @@ void Session::fixFilename(Doc* doc)
base::get_file_title(fn) + "-Recovered" + ext)); base::get_file_title(fn) + "-Recovered" + ext));
} }
int Session::filenamePartToInt(const std::string& part) const
{
if (part.empty())
throw base::Exception("Invalid part");
int result = std::strtol(part.c_str(), NULL, 10);
if (errno == ERANGE)
throw base::Exception("Number out of range");
if (result < 0)
throw base::Exception("Negative value");
return result;
}
} // namespace crash } // namespace crash
} // namespace app } // namespace app

View File

@ -78,6 +78,7 @@ namespace crash {
void markDocumentAsCorrectlyClosed(Doc* doc); void markDocumentAsCorrectlyClosed(Doc* doc);
void deleteDirectory(const std::string& dir); void deleteDirectory(const std::string& dir);
void fixFilename(Doc* doc); void fixFilename(Doc* doc);
int filenamePartToInt(const std::string& part) const;
base::pid m_pid; base::pid m_pid;
std::string m_path; std::string m_path;

View File

@ -816,11 +816,8 @@ Extensions::Extensions()
if (!base::is_directory(extensionsDir)) if (!base::is_directory(extensionsDir))
continue; continue;
for (auto& fn : base::list_files(extensionsDir)) { for (const auto& fn : base::list_files(extensionsDir, base::ItemType::Directories)) {
const auto dir = base::join_path(extensionsDir, fn); const auto dir = base::join_path(extensionsDir, fn);
if (!base::is_directory(dir))
continue;
const bool isBuiltinExtension = const bool isBuiltinExtension =
(m_userExtensionsPath != base::get_file_path(dir)); (m_userExtensionsPath != base::get_file_path(dir));

View File

@ -36,9 +36,8 @@ void get_font_dirs(base::paths& fontDirs)
fontDirs.push_back(fontDir); fontDirs.push_back(fontDir);
for (const auto& file : base::list_files(fontDir)) { for (const auto& file : base::list_files(fontDir, base::ItemType::Directories)) {
std::string fullpath = base::join_path(fontDir, file); std::string fullpath = base::join_path(fontDir, file);
if (base::is_directory(fullpath))
q.push(fullpath); // Add subdirectory in the queue q.push(fullpath); // Add subdirectory in the queue
} }
} }

View File

@ -64,11 +64,7 @@ std::set<LangInfo> Strings::availableLanguages() const
if (!base::is_directory(stringsPath)) if (!base::is_directory(stringsPath))
continue; continue;
for (const auto& fn : base::list_files(stringsPath)) { for (const auto& fn : base::list_files(stringsPath, base::ItemType::Files, "*.ini")) {
// Ignore README/LICENSE files.
if (base::get_file_extension(fn) != "ini")
continue;
const std::string langId = base::get_file_title(fn); const std::string langId = base::get_file_title(fn);
std::string path = base::join_path(stringsPath, fn); std::string path = base::join_path(stringsPath, fn);
std::string displayName = langId; std::string displayName = langId;

View File

@ -45,7 +45,7 @@ void PalettesLoaderDelegate::getResourcesPaths(std::map<std::string, std::string
if (base::is_directory(rf.filename())) { if (base::is_directory(rf.filename())) {
path = rf.filename(); path = rf.filename();
path = base::fix_path_separators(path); path = base::fix_path_separators(path);
for (const auto& fn : base::list_files(path)) { for (const auto& fn : base::list_files(path, base::ItemType::Files)) {
// Ignore the default palette that is inside the palettes/ dir // Ignore the default palette that is inside the palettes/ dir
// in the user home dir. // in the user home dir.
if (fn == "default.ase" || if (fn == "default.ase" ||
@ -53,7 +53,6 @@ void PalettesLoaderDelegate::getResourcesPaths(std::map<std::string, std::string
continue; continue;
std::string fullFn = base::join_path(path, fn); std::string fullFn = base::join_path(path, fn);
if (base::is_file(fullFn))
idAndPath[base::get_file_title(fn)] = fullFn; idAndPath[base::get_file_title(fn)] = fullFn;
} }
} }

View File

@ -110,7 +110,7 @@ int AppFS_listFiles(lua_State* L)
lua_newtable(L); lua_newtable(L);
if (path) { if (path) {
int i = 0; int i = 0;
for (auto fn : base::list_files(path)) { for (const auto& fn : base::list_files(path)) {
lua_pushstring(L, fn.c_str()); lua_pushstring(L, fn.c_str());
lua_seti(L, -2, ++i); lua_seti(L, -2, ++i);
} }

View File

@ -109,18 +109,15 @@ bool Sentry::areThereCrashesToReport()
// At least one .dmp file in the completed/ directory means that // At least one .dmp file in the completed/ directory means that
// there was at least one crash in the past (this is for macOS). // there was at least one crash in the past (this is for macOS).
for (auto f : base::list_files(base::join_path(m_dbdir, "completed"))) { if (!base::join_path(m_dbdir, "completed"), base::ItemType::Files, "*.dmp").empty())
if (base::get_file_extension(f) == "dmp")
return true; return true;
}
// In case that "last_crash" doesn't exist we can check for some // In case that "last_crash" doesn't exist we can check for some
// .dmp file in the reports/ directory (it looks like the completed/ // .dmp file in the reports/ directory (it looks like the completed/
// directory is not generated on Windows). // directory is not generated on Windows).
for (auto f : base::list_files(base::join_path(m_dbdir, "reports"))) { if (!base::list_files(base::join_path(m_dbdir, "reports"), base::ItemType::Files, "*.dmp").empty())
if (base::get_file_extension(f) == "dmp")
return true; return true;
}
return false; return false;
} }

View File

@ -159,10 +159,8 @@ FontPopup::FontPopup()
// directories (fontDirs) // directories (fontDirs)
base::paths files; base::paths files;
for (const auto& fontDir : fontDirs) { for (const auto& fontDir : fontDirs) {
for (const auto& file : base::list_files(fontDir)) { for (const auto& file : base::list_files(fontDir, base::ItemType::Files)) {
std::string fullpath = base::join_path(fontDir, file); files.push_back(base::join_path(fontDir, file));
if (base::is_file(fullpath))
files.push_back(fullpath);
} }
} }