diff --git a/src/main.cpp b/src/main.cpp index 1069bc3..16c2524 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,21 +31,27 @@ int main(int argc, const char** argv) { } time_t start = time(nullptr); - Search search; + Search rootsearch; for(int i = 1; i < argc; ++i) { Log::info << "Load File: " << argv[i]; - search.addFile(argv[i]); + rootsearch.addFile(argv[i]); } time_t end = time(nullptr); - Log::info << search.getChatCount() << " Chats with " << search.getMessageCount() << " Messages loaded in " << end-start << "s"; + Log::info << rootsearch.getChatCount() << " Chats with " << rootsearch.getMessageCount() << " Messages loaded in " << end-start << "s"; signal(SIGINT, sig_handler); + Search* search = nullptr; + while(run) { - Log::info << "Enter Search String: "; + if(!search) + search = &rootsearch; + + Log::info << search->getMessageCount() << " Messages. Enter searchterm: "; std::string searchterm; std::getline(std::cin, searchterm); + Log::trace << "searchterm: \"" << searchterm << "\""; if(!run) break; @@ -56,10 +62,12 @@ int main(int argc, const char** argv) { if(!run) break; - std::list results = search.search(searchterm, parsedflags); - Log::info << results.size() << " results"; + time_t start = time(nullptr); + std::list results = search->search(searchterm, parsedflags); + time_t end = time(nullptr); + Log::info << results.size() << " results found in " << end-start << "s"; if(results.size()) { - Log::info << "Print results?"; + Log::info << "Print results ?"; char c; std::cin >> c; @@ -68,12 +76,40 @@ int main(int argc, const char** argv) { if(c == 'y' || c == 'Y') { //print results for(const Message* m : results) { - Log::info << search.getShortChatname(m->chatid) << ": (" << m->messageid << ") " << m->text; + Log::info << search->getShortChatname(m->chatid) << ": (" << m->messageid << ") " << m->text; + } + } + + Log::info << "New Subfilter (y)? Clear Search (c)? Change current Filter (anykey)?"; + std::cin >> c; + + if(!run) break; + + if(c == 'y' || c == 'Y') { + //filter + Search* subsearch = new Search(*search, &results); + + //delete old subsearch (dont delete root) + if(search != &rootsearch) + delete search; + + //set new search + search = subsearch; + } else if(c == 'c' || c == 'C') { + //move to root search + if(search != &rootsearch) { + delete search; + search = &rootsearch; } } } + + std::cin.ignore(std::numeric_limits::max(), '\n'); } + if(search != &rootsearch) + delete search; + Log::stop(); return 0; } diff --git a/src/search.cpp b/src/search.cpp index 7ab1455..9cebf5b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -35,6 +35,19 @@ static bool matchesRegex(const std::string& msg, const std::regex& reg) { } Search::Search() {} +Search::Search(const Search& orig, std::list* list) { + //copy messages + if(list) { + for(const Message* m : *list) { + msgs.push_back(*m); + } + } else { + msgs = orig.msgs; + } + + //copy chatnames + chatnames = orig.chatnames; +} Search::~Search() {} Searchflags Search::fromString(const std::string& str) { @@ -69,6 +82,8 @@ void Search::addFile(const std::string& file) { if(j.contains("messages")) { chatnames.insert({j["id"], j["name"].get()}); loadMessages(j["messages"], j["id"]); + + return; } //multi chat export @@ -89,7 +104,11 @@ void Search::addFile(const std::string& file) { Log::note << "Loaded Chat: " << name << " (" << id << ")"; } + + return; } + + Log::warn << "File " << file << " could not be parsed! Export as json!"; } catch (nlohmann::detail::parse_error& e) { Log::error << "Could not load File: " << e.what(); } @@ -155,11 +174,35 @@ void Search::runsearch(T st, bool (*checker)(const std::string& msg, T text), st } } +static void readText(const json& t, std::string& out) { + if(t.is_null()) return; + if(t.is_string()) + out = t; + if(t.is_array()) { + std::ostringstream buff; + for(const json& entr : t) { + if(entr.is_string()) + buff << (const std::string&) entr; + else if(entr.contains("text")) + buff << (const std::string&) entr["text"]; + } + out = buff.str(); + } +} + 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"]}); + if(m.contains("text")) { + std::string text; + readText(m["text"], text); + msgs.push_back({text, chatid, m["id"]}); + } else { + Log::warn << "text less message: " << m; + } + } catch(const nlohmann::detail::exception& e) { + Log::warn << "Parse error: " << e.id << " " << e.what(); } catch(...) { failed ++; } diff --git a/src/search.h b/src/search.h index a7bbb98..f14008b 100644 --- a/src/search.h +++ b/src/search.h @@ -18,6 +18,8 @@ enum class Searchflags { NONE = 0, IGNORECASE = 1, REGEX = 2, + + //ideen: nach sender filtern, nur nachrichten mit medien, nur nachrichten ohne medien, medien Dateinamen, nach datum filtern }; Searchflags operator|=(Searchflags& lhs, const Searchflags sf); @@ -27,6 +29,8 @@ bool operator&(Searchflags& lhs, const Searchflags sf); class Search { public: Search(); + //copy chatnames from orig, and message list either from orig, or - if set - from list + Search(const Search& orig, std::list* list = nullptr); ~Search(); static Searchflags fromString(const std::string&);