regex search, complete dump search
This commit is contained in:
parent
719e9c1776
commit
bc1a0c3850
|
@ -3,6 +3,8 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <signal.h> //signal handler
|
#include <signal.h> //signal handler
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
#include "search.h"
|
#include "search.h"
|
||||||
|
|
||||||
|
@ -11,6 +13,7 @@ static bool run = true;
|
||||||
void sig_handler(int sig_num) {
|
void sig_handler(int sig_num) {
|
||||||
Log::info << "signalHandler triggered";
|
Log::info << "signalHandler triggered";
|
||||||
run = false;
|
run = false;
|
||||||
|
::close(STDIN_FILENO); //interrupt input
|
||||||
(void) sig_num;
|
(void) sig_num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,18 +30,22 @@ int main(int argc, const char** argv) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t start = time(nullptr);
|
||||||
Search search;
|
Search search;
|
||||||
for(int i = 1; i < argc; ++i) {
|
for(int i = 1; i < argc; ++i) {
|
||||||
Log::info << "Load File: " << argv[i];
|
Log::info << "Load File: " << argv[i];
|
||||||
search.addFile(argv[i]);
|
search.addFile(argv[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
time_t end = time(nullptr);
|
||||||
|
Log::info << search.getChatCount() << " Chats with " << search.getMessageCount() << " Messages loaded in " << end-start << "s";
|
||||||
|
|
||||||
signal(SIGINT, sig_handler);
|
signal(SIGINT, sig_handler);
|
||||||
|
|
||||||
while(run) {
|
while(run) {
|
||||||
Log::info << "Enter Search String: ";
|
Log::info << "Enter Search String: ";
|
||||||
std::string searchterm;
|
std::string searchterm;
|
||||||
std::cin >> searchterm;
|
std::getline(std::cin, searchterm);
|
||||||
|
|
||||||
if(!run) break;
|
if(!run) break;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,23 @@ bool operator&(Searchflags& lhs, const Searchflags sf) {
|
||||||
return (bool) ((uint32_t) lhs & (uint32_t) sf);
|
return (bool) ((uint32_t) lhs & (uint32_t) sf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool matches(const std::string& msg, const std::string& text) {
|
||||||
|
//simpler contains check
|
||||||
|
return (msg.find(text) != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool matchesIC(const std::string& msg, const std::string& text) {
|
||||||
|
//turn compare string to lower
|
||||||
|
std::string lower;
|
||||||
|
mrbesen::util::toLower(msg, lower);
|
||||||
|
return (lower.find(text) != std::string::npos);
|
||||||
|
}
|
||||||
|
|
||||||
|
// matches reges is inline, so i need a wrapper
|
||||||
|
static bool matchesRegex(const std::string& msg, const std::regex& reg) {
|
||||||
|
return std::regex_search(msg, reg);
|
||||||
|
}
|
||||||
|
|
||||||
Search::Search() {}
|
Search::Search() {}
|
||||||
Search::~Search() {}
|
Search::~Search() {}
|
||||||
|
|
||||||
|
@ -48,10 +65,31 @@ void Search::addFile(const std::string& file) {
|
||||||
json j;
|
json j;
|
||||||
fstream >> j;
|
fstream >> j;
|
||||||
|
|
||||||
|
//single chat export
|
||||||
if(j.contains("messages")) {
|
if(j.contains("messages")) {
|
||||||
chatnames.insert({j["id"], j["name"].get<std::string>()});
|
chatnames.insert({j["id"], j["name"].get<std::string>()});
|
||||||
loadMessages(j["messages"], j["id"]);
|
loadMessages(j["messages"], j["id"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//multi chat export
|
||||||
|
if(j.contains("chats")) {
|
||||||
|
const json& chatlist = j["chats"]["list"];
|
||||||
|
if(chatlist.is_null()) {
|
||||||
|
Log::error << "File does not contain a chatlist";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const json& chat : chatlist) {
|
||||||
|
uint64_t id = chat["id"];
|
||||||
|
std::string name = "";
|
||||||
|
if(chat.contains("name") && !chat["name"].is_null())
|
||||||
|
name = chat.value("name", "");
|
||||||
|
chatnames.insert({id, name});
|
||||||
|
loadMessages(chat["messages"], id);
|
||||||
|
|
||||||
|
Log::note << "Loaded Chat: " << name << " (" << id << ")";
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (nlohmann::detail::parse_error& e) {
|
} catch (nlohmann::detail::parse_error& e) {
|
||||||
Log::error << "Could not load File: " << e.what();
|
Log::error << "Could not load File: " << e.what();
|
||||||
}
|
}
|
||||||
|
@ -69,9 +107,9 @@ std::list<const Message*> Search::search(std::string text, Searchflags flags) co
|
||||||
//turn search to lower
|
//turn search to lower
|
||||||
mrbesen::util::toLower(text);
|
mrbesen::util::toLower(text);
|
||||||
|
|
||||||
runsearch(text, &Search::matchesIC, out);
|
runsearch<const std::string&>(text, matchesIC, out);
|
||||||
} else {
|
} else {
|
||||||
runsearch(text, &Search::matches, out);
|
runsearch<const std::string&>(text, matches, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
@ -81,6 +119,7 @@ const std::string& Search::getChatname(uint64_t id) const {
|
||||||
static const std::string UNKOWNCHAT = "<unknownchat>";
|
static const std::string UNKOWNCHAT = "<unknownchat>";
|
||||||
auto it = chatnames.find(id);
|
auto it = chatnames.find(id);
|
||||||
if(it == chatnames.end()) return UNKOWNCHAT;
|
if(it == chatnames.end()) return UNKOWNCHAT;
|
||||||
|
if(it->second.empty()) return UNKOWNCHAT;
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,31 +131,30 @@ std::string Search::getShortChatname(uint64_t id) const {
|
||||||
return chatname;
|
return chatname;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Search::searchRegex(const std::string& text, bool ignoreCase, std::list<const Message*>& out) const {
|
uint32_t Search::getChatCount() const {
|
||||||
//build regex pattern
|
return chatnames.size();
|
||||||
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<const Message*>& out) const {
|
uint64_t Search::getMessageCount() const {
|
||||||
|
return msgs.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Search::searchRegex(const std::string& text, bool ignoreCase, std::list<const Message*>& out) const {
|
||||||
|
//build regex pattern
|
||||||
|
const std::regex pattern(text, (ignoreCase ? std::regex::icase : (std::regex::flag_type) 0));
|
||||||
|
|
||||||
|
runsearch<const std::regex&>(pattern, matchesRegex, out);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void Search::runsearch(T st, bool (*checker)(const std::string& msg, T text), std::list<const Message*>& out) const {
|
||||||
for(const Message& m : msgs) {
|
for(const Message& m : msgs) {
|
||||||
if((this->*checker)(m.text, st)) {
|
if(checker(m.text, st)) {
|
||||||
out.push_back(&m);
|
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) {
|
void Search::loadMessages(const json& j, uint64_t chatid) {
|
||||||
uint32_t failed = 0;
|
uint32_t failed = 0;
|
||||||
for(const json& m : j) {
|
for(const json& m : j) {
|
||||||
|
@ -127,9 +165,7 @@ void Search::loadMessages(const json& j, uint64_t chatid) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(failed == 0) {
|
if(failed != 0) {
|
||||||
Log::info << "Messages Loaded";
|
|
||||||
} else {
|
|
||||||
Log::warn << failed << " Messages failed to load";
|
Log::warn << failed << " Messages failed to load";
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -36,13 +36,14 @@ public:
|
||||||
std::list<const Message*> search(std::string text, Searchflags flags = Searchflags::NONE) const;
|
std::list<const Message*> search(std::string text, Searchflags flags = Searchflags::NONE) const;
|
||||||
const std::string& getChatname(uint64_t id) const;
|
const std::string& getChatname(uint64_t id) const;
|
||||||
std::string getShortChatname(uint64_t id) const;
|
std::string getShortChatname(uint64_t id) const;
|
||||||
|
|
||||||
|
uint32_t getChatCount() const;
|
||||||
|
uint64_t getMessageCount() const;
|
||||||
private:
|
private:
|
||||||
void searchRegex(const std::string& text, bool ignoreCase, std::list<const Message*>& out) const;
|
void searchRegex(const std::string& text, bool ignoreCase, std::list<const Message*>& out) const;
|
||||||
|
|
||||||
void runsearch(const std::string& st, bool (Search::*checker)(const std::string& msg, const std::string& text) const, std::list<const Message*>& out) const;
|
template<typename T>
|
||||||
|
void runsearch(T st, bool (*checker)(const std::string& msg, T text), std::list<const Message*>& out) const;
|
||||||
bool matches(const std::string& msg, const std::string& text) const;
|
|
||||||
bool matchesIC(const std::string& msg, const std::string& text) const;
|
|
||||||
|
|
||||||
void loadMessages(const json& j, uint64_t chatid);
|
void loadMessages(const json& j, uint64_t chatid);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue