#1 - quicr module
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#include "FileAddressList.hpp"
|
||||
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <cstdlib>
|
||||
#include <algorithm>
|
||||
|
||||
namespace tw::app {
|
||||
|
||||
namespace {
|
||||
|
||||
std::string get_config_dir() {
|
||||
// Try XDG_CONFIG_HOME first
|
||||
const char* xdg_config_home = std::getenv("XDG_CONFIG_HOME");
|
||||
if(xdg_config_home && xdg_config_home[0] != '\0') {
|
||||
return std::string(xdg_config_home) + "/towards";
|
||||
}
|
||||
|
||||
// Fall back to $HOME/.config/towards
|
||||
const char* home = std::getenv("HOME");
|
||||
if(home && home[0] != '\0') {
|
||||
return std::string(home) + "/.config/towards";
|
||||
}
|
||||
|
||||
// Both unset
|
||||
return "";
|
||||
}
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
FileAddressList::FileAddressList(const std::string& file_name) {
|
||||
std::string config_dir = get_config_dir();
|
||||
|
||||
if(config_dir.empty()) {
|
||||
spdlog::debug("XDG_CONFIG_HOME and HOME not set; address lists will not be persisted");
|
||||
m_can_save = false;
|
||||
return;
|
||||
}
|
||||
|
||||
m_path = config_dir + "/" + file_name;
|
||||
m_can_save = true;
|
||||
}
|
||||
|
||||
void FileAddressList::load() {
|
||||
if(m_path.empty()) {
|
||||
return; // No config path available
|
||||
}
|
||||
|
||||
std::ifstream file(m_path);
|
||||
if(!file.is_open()) {
|
||||
// File doesn't exist or can't be read; this is not an error
|
||||
return;
|
||||
}
|
||||
|
||||
m_entries.clear();
|
||||
std::string line;
|
||||
while(std::getline(file, line)) {
|
||||
// Trim whitespace from the line
|
||||
size_t start = line.find_first_not_of(" \t\r\n");
|
||||
size_t end = line.find_last_not_of(" \t\r\n");
|
||||
|
||||
if(start != std::string::npos) {
|
||||
line = line.substr(start, end - start + 1);
|
||||
if(!line.empty()) {
|
||||
m_entries.push_back(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FileAddressList::save() const {
|
||||
if(!m_can_save || m_path.empty()) {
|
||||
return; // Cannot save without config path
|
||||
}
|
||||
|
||||
// Create the directory if needed
|
||||
std::filesystem::path config_path(m_path);
|
||||
std::filesystem::path config_dir = config_path.parent_path();
|
||||
|
||||
try {
|
||||
std::filesystem::create_directories(config_dir);
|
||||
} catch(const std::filesystem::filesystem_error&) {
|
||||
// If we can't create the directory, silently fail to save
|
||||
return;
|
||||
}
|
||||
|
||||
// Write entries to file
|
||||
std::ofstream file(m_path);
|
||||
if(!file.is_open()) {
|
||||
return; // Can't open file for writing; silently fail
|
||||
}
|
||||
|
||||
for(const auto& entry : m_entries) {
|
||||
file << entry << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void FileAddressList::remove(const std::string& entry) {
|
||||
auto it = std::find(m_entries.begin(), m_entries.end(), entry);
|
||||
if(it != m_entries.end()) {
|
||||
m_entries.erase(it);
|
||||
}
|
||||
}
|
||||
|
||||
const std::vector<std::string>& FileAddressList::entries() const {
|
||||
return m_entries;
|
||||
}
|
||||
|
||||
} // namespace tw::app
|
||||
Reference in New Issue
Block a user