#include "search.h" #include #include #include #include #include using json = nlohmann::json; Searchflags operator|=(Searchflags& lhs, const Searchflags sf) { lhs = (Searchflags) ((uint32_t) lhs | (uint32_t) sf); return lhs; } bool operator&(Searchflags& lhs, const Searchflags sf) { return (bool) ((uint32_t) lhs & (uint32_t) sf); } Search::Search() {} Search::~Search() {} Searchflags Search::fromString(const std::string& str) { Searchflags f = Searchflags::NONE; for(char c : str) { switch(c) { case 'R': case 'r': f |= Searchflags::REGEX; break; case 'i': case 'I': f |= Searchflags::IGNORECASE; break; default: break; } } return f; } void Search::addFile(const std::string& file) { //laden den datei try { std::ifstream fstream(file); json j; fstream >> j; if(j.contains("messages")) { chatnames.insert({j["id"], j["name"].get()}); loadMessages(j["messages"], j["id"]); } } catch (nlohmann::detail::parse_error& e) { Log::error << "Could not load File: " << e.what(); } } std::list Search::search(std::string text, Searchflags flags) const { std::list out; if(flags & Searchflags::REGEX) { searchRegex(text, flags & Searchflags::IGNORECASE, out); return out; } if(flags & Searchflags::IGNORECASE) { //turn search to lower mrbesen::util::toLower(text); runsearch(text, &Search::matchesIC, out); } else { runsearch(text, &Search::matches, out); } return out; } const std::string& Search::getChatname(uint64_t id) const { static const std::string UNKOWNCHAT = ""; auto it = chatnames.find(id); if(it == chatnames.end()) return UNKOWNCHAT; return it->second; } std::string Search::getShortChatname(uint64_t id) const { std::string chatname = getChatname(id); if(chatname.size() > 14) { return chatname.substr(0, 14); } return chatname; } void Search::searchRegex(const std::string& text, bool ignoreCase, std::list& out) const { //build regex pattern std::regex pattern(text, (ignoreCase ? std::regex::icase : (std::regex::flag_type) 0)); } void Search::runsearch(const std::string& st, bool (Search::*checker)(const std::string& msg, const std::string& text) const, std::list& out) const { for(const Message& m : msgs) { if((this->*checker)(m.text, st)) { out.push_back(&m); } } } bool Search::matches(const std::string& msg, const std::string& text) const { //simpler contains check return (msg.find(text) != std::string::npos); } bool Search::matchesIC(const std::string& msg, const std::string& text) const { //turn compare string to lower std::string lower; mrbesen::util::toLower(msg, lower); return (lower.find(text) != std::string::npos); } void Search::loadMessages(const json& j, uint64_t chatid) { uint32_t failed = 0; for(const json& m : j) { try { msgs.push_back({m["text"], chatid, m["id"]}); } catch(...) { failed ++; } } if(failed == 0) { Log::info << "Messages Loaded"; } else { Log::warn << failed << " Messages failed to load"; } }