src/settings.cpp

changeset 16
730a5638c4ad
parent 14
f0ae064c5b9c
child 25
b8d6b14c1555
--- a/src/settings.cpp	Sat Feb 01 15:42:48 2025 +0100
+++ b/src/settings.cpp	Sat Feb 01 16:01:14 2025 +0100
@@ -26,24 +26,75 @@
 
 #include <format>
 #include <algorithm>
+#include <fstream>
 
 using namespace fm;
 
+static bool check_author(std::string_view author, std::string_view allowed) {
+    // check for exact match
+    if (author == allowed) return true;
+
+    // check mail address matching
+    if (author.contains(std::format("<{}>", allowed))) return true;
+
+    // check local-part from mail address matching
+    if (author.contains(std::format("<{}@", allowed))) return true;
+
+    return false;
+}
+
 [[nodiscard]] bool settings::exclude_author(const std::string &author) const {
     // no allow-list means: always allowed
     if (authors.empty()) return false;
 
     // check all allowed authors
-    return std::ranges::all_of(authors, [&](const auto &allowed) {
-        // check for exact match
-        if (author == allowed) return false;
-
-        // check mail address matching
-        if (author.contains(std::format("<{}>", allowed))) return false;
-
-        // check local-part from mail address matching
-        if (author.contains(std::format("<{}@", allowed))) return false;
-
-        return true;
+    return !std::ranges::any_of(authors, [&](const auto &allowed) {
+        return check_author(author, allowed);
     });
 }
+
+std::string_view trim(const std::string& str) {
+    size_t s = str.find_first_not_of(" \t");
+    size_t l = str.find_last_not_of(" \t") + 1 - s;
+    return std::string_view{str}.substr(s, l);
+}
+
+int settings::parse_authormap(const std::string& path) {
+    std::ifstream file(path);
+
+    if (!file.is_open()) {
+        return -1;
+    }
+
+    std::string line;
+    while (std::getline(file, line)) {
+        line = trim(line);
+
+        // skip empty lines and comments
+        if (line.empty() || line[0] == '#') {
+            continue;
+        }
+
+        // find delimiter
+        size_t delimPos = line.find('=');
+        if (delimPos == std::string::npos) {
+            return -1;
+        }
+
+        auto key = std::string{trim(line.substr(0, delimPos))};
+        auto value = std::string{trim(line.substr(delimPos + 1))};
+        authormap[std::move(key)] = std::move(value);
+    }
+
+    return 0;
+}
+
+std::string settings::map_author(std::string_view author) const {
+    if (authormap.empty()) return std::string{author};
+
+    for (const auto &[old_name, new_name] : authormap) {
+        if (check_author(author, old_name)) return new_name;
+    }
+
+    return std::string{author};
+}

mercurial