diff options
Diffstat (limited to 'src/rttt.hpp')
-rw-r--r-- | src/rttt.hpp | 317 |
1 files changed, 154 insertions, 163 deletions
diff --git a/src/rttt.hpp b/src/rttt.hpp index d1efc93..62afd27 100644 --- a/src/rttt.hpp +++ b/src/rttt.hpp @@ -18,147 +18,133 @@ namespace rttt { - // TODO: move to thing::type - enum class SiteType : int { - Unknown, - HN, - Reddit, - RSS, - Twitter, - }; - - // Consider moving this to view.hpp - enum class list_mode : int { - story, - comment, - feed, - }; - - // TODO: should work with constexpr, but might need newer g++/clang++ - inline std::vector<std::string> split(std::string_view strv, - std::string_view delims = " ", - size_t no_pieces = 0) { - std::vector<std::string> output; - size_t first = 0; - - while (first < strv.size()) { - const auto second = strv.find_first_of(delims, first); - - if (first != second) - output.emplace_back(strv.substr(first, second - first)); - - if (second == std::string_view::npos) { - break; - } else if (no_pieces > 0 && output.size() >= no_pieces - 1) { - output.emplace_back(strv.substr(second + 1, strv.size())); - break; - } - - first = second + 1; +// Consider moving this to view.hpp +enum class list_mode : int { + story, + comment, + feed, +}; + +// TODO: should work with constexpr, but might need newer g++/clang++ +inline std::vector<std::string> split(std::string_view strv, + std::string_view delims = " ", + size_t no_pieces = 0) { + std::vector<std::string> output; + size_t first = 0; + + while (first < strv.size()) { + const auto second = strv.find_first_of(delims, first); + + if (first != second) + output.emplace_back(strv.substr(first, second - first)); + + if (second == std::string_view::npos) { + break; + } else if (no_pieces > 0 && output.size() >= no_pieces - 1) { + output.emplace_back(strv.substr(second + 1, strv.size())); + break; } - return output; + first = second + 1; } - inline void replaceAll(std::string & s, const std::string &search, - const std::string &replace) { - for (size_t pos = 0;; pos += replace.length()) { - pos = s.find(search, pos); - if (pos == std::string::npos) - break; - s.erase(pos, search.length()); - s.insert(pos, replace); - } + return output; +} + +inline void replaceAll(std::string &s, const std::string &search, + const std::string &replace) { + for (size_t pos = 0;; pos += replace.length()) { + pos = s.find(search, pos); + if (pos == std::string::npos) + break; + s.erase(pos, search.length()); + s.insert(pos, replace); } - - inline std::string parse_html(std::string str) { - replaceAll(str, "<p>", "\n"); - - std::string res; - bool inTag = false; - for (auto &ch : str) { - if (ch == '<') { - inTag = true; - } else if (ch == '>') { - inTag = false; - } else { - if (inTag == false) { - res += ch; - } +} + +inline std::string parse_html(std::string str) { + replaceAll(str, "<p>", "\n"); + + std::string res; + bool inTag = false; + for (auto &ch : str) { + if (ch == '<') { + inTag = true; + } else if (ch == '>') { + inTag = false; + } else { + if (inTag == false) { + res += ch; } } - - replaceAll(res, "/", "/"); - replaceAll(res, "'", "'"); - replaceAll(res, ">", ">"); - replaceAll(res, "–", "-"); - replaceAll(res, "“", "\""); - replaceAll(res, "”", "\""); - replaceAll(res, "‘", "'"); - replaceAll(res, "’", "'"); - replaceAll(res, "„", "'"); - replaceAll(res, """, "\""); - replaceAll(res, "&", "&"); - replaceAll(res, "—", "-"); - - return res; } - inline std::tm parse_time(std::string time_string) { - std::tm time = {}; - std::regex e("(\\d{4})-(\\d+)-(\\d+)T(\\d+):(\\d+)"); - std::smatch sm; - std::regex_search(time_string, sm, e); - if (sm.size() > 1) { - time.tm_year = std::stoi(sm[1]) - 1900; - time.tm_mon = std::stoi(sm[2]) - 1; - time.tm_mday = std::stoi(sm[3]); - time.tm_hour = std::stoi(sm[4]); - time.tm_min = std::stoi(sm[5]); - } - return time; + replaceAll(res, "/", "/"); + replaceAll(res, "'", "'"); + replaceAll(res, ">", ">"); + replaceAll(res, "–", "-"); + replaceAll(res, "“", "\""); + replaceAll(res, "”", "\""); + replaceAll(res, "‘", "'"); + replaceAll(res, "’", "'"); + replaceAll(res, "„", "'"); + replaceAll(res, """, "\""); + replaceAll(res, "&", "&"); + replaceAll(res, "—", "-"); + + return res; +} + +inline std::tm parse_time(std::string time_string) { + std::tm time = {}; + std::regex e("(\\d{4})-(\\d+)-(\\d+)T(\\d+):(\\d+)"); + std::smatch sm; + std::regex_search(time_string, sm, e); + if (sm.size() > 1) { + time.tm_year = std::stoi(sm[1]) - 1900; + time.tm_mon = std::stoi(sm[2]) - 1; + time.tm_mday = std::stoi(sm[3]); + time.tm_hour = std::stoi(sm[4]); + time.tm_min = std::stoi(sm[5]); } - - // TODO: Move to text.hpp and rename - inline std::vector<std::string> extractURL(std::string text) { - std::vector<std::string> v; - - // Currently we assume an url always ends with alphanum, / or _ - // ([^/_[:alnum:]]) If this turns out to be false then we could also try to - // filter out trailing punctuation marks etc specifically ([);:.!?] - // std::regex e("(https?://[A-z0-9$–_.+!*‘(),./?=]+?)[),;:.!?]*(\\s|$)"); - // "(https?://[[:alnum:]$-_.+!*‘(),./?=;&#]+?)[^/_[:alnum:]]*(\\s|$)"); - std::regex e("(https?://[[:alnum:]$-_+!*‘,/?=;&#]+?)(\\]\\(|[^/" - "_[:alnum:]]*(\\s|$))"); - std::smatch sm; - while (std::regex_search(text, sm, e)) { - if (sm.size() > 1) - v.push_back(sm[1]); - text = sm.suffix().str(); - } - - return v; + return time; +} + +// TODO: Move to text.hpp and rename +inline std::vector<std::string> extractURL(std::string text) { + std::vector<std::string> v; + + // Currently we assume an url always ends with alphanum, / or _ + // ([^/_[:alnum:]]) If this turns out to be false then we could also try to + // filter out trailing punctuation marks etc specifically ([);:.!?] + // std::regex e("(https?://[A-z0-9$–_.+!*‘(),./?=]+?)[),;:.!?]*(\\s|$)"); + // "(https?://[[:alnum:]$-_.+!*‘(),./?=;&#]+?)[^/_[:alnum:]]*(\\s|$)"); + std::regex e("(https?://[[:alnum:]$-_+!*‘,/?=;&#]+?)(\\]\\(|[^/" + "_[:alnum:]]*(\\s|$))"); + std::smatch sm; + while (std::regex_search(text, sm, e)) { + if (sm.size() > 1) + v.push_back(sm[1]); + text = sm.suffix().str(); } - struct Path { - SiteType type = SiteType::Unknown; - std::string name; - std::string basename; - list_mode mode = list_mode::story; - std::string id; - std::vector<std::string> parts; - }; - - inline Path parse_path(std::string_view path_name) { - Path path; - path.parts = split(path_name, "/"); - auto &v = path.parts; - if (v[0] == "hn") { - path.type = SiteType::HN; - } else if (v[0] == "r") { - path.type = SiteType::Reddit; - } else if (v[0] == "rss") { - path.type = SiteType::RSS; + return v; +} + +struct Path { + std::string name; + std::string basename; + list_mode mode = list_mode::story; + std::string id; + std::vector<std::string> parts; +}; + +inline Path parse_path(std::string_view path_name) { + Path path; + path.parts = split(path_name, "/"); + auto &v = path.parts; + if (v.size() == 1) { + if (v[0] == "rss") { path.basename = "/rss"; if (v.size() == 2 && v[1] != "front") { path.mode = list_mode::feed; @@ -169,43 +155,48 @@ namespace rttt { path.mode = list_mode::story; } return path; - } - if (v.size() == 4) { - if (v[2] == "comments") { - path.mode = list_mode::comment; - } else { - logger::log_ifnot(false); - } - path.name = "/" + v[0] + "/" + v[1] + "/" + v[2] + "/" + v[3]; - path.id = v[3]; - } - path.basename = "/" + v[0] + "/" + v[1]; - if (path.name.empty()) + } else { + path.basename = fmt::format("/{}", v[0]); path.name = path.basename; - return path; + return path; + } } - - inline std::string timeSince(uint64_t t) { - auto delta = current_time() - t; - if (delta < 60) - return std::to_string(delta) + " seconds"; - if (delta < 3600) - return std::to_string(delta / 60) + " minutes"; - if (delta < 24 * 3600) - return std::to_string(delta / 3600) + " hours"; - return std::to_string(delta / 24 / 3600) + " days"; + if (v.size() == 4) { + if (v[2] == "comments") { + path.mode = list_mode::comment; + } else { + logger::log_ifnot(false); + } + path.name = "/" + v[0] + "/" + v[1] + "/" + v[2] + "/" + v[3]; + path.id = v[3]; } - - inline int openInBrowser(std::string uri) { - auto config = rttt::config::load(); - auto base_cmd = config["open_command"].get<std::string>(); + path.basename = "/" + v[0] + "/" + v[1]; + if (path.name.empty()) + path.name = path.basename; + return path; +} + +inline std::string timeSince(uint64_t t) { + auto delta = current_time() - t; + if (delta < 60) + return std::to_string(delta) + " seconds"; + if (delta < 3600) + return std::to_string(delta / 60) + " minutes"; + if (delta < 24 * 3600) + return std::to_string(delta / 3600) + " hours"; + return std::to_string(delta / 24 / 3600) + " days"; +} + +inline int openInBrowser(std::string uri) { + auto config = rttt::config::load(); + auto base_cmd = config["open_command"].get<std::string>(); #ifdef __APPLE__ - if (base_command == "xdg-open") - base_cmd = "open"; + if (base_command == "xdg-open") + base_cmd = "open"; #endif - // std::string cmd = "run-mailcap " + uri + " > /dev/null 2>&1"; - std::string cmd = base_cmd + " \"" + uri + "\" > /dev/null 2>&1 &"; - logger::push("EXECUTING: {}", cmd); - return system(cmd.c_str()); - } + // std::string cmd = "run-mailcap " + uri + " > /dev/null 2>&1"; + std::string cmd = base_cmd + " \"" + uri + "\" > /dev/null 2>&1 &"; + logger::push("EXECUTING: {}", cmd); + return system(cmd.c_str()); +} } // namespace rttt |