From 6fa86a3c577ccf2a6167c0fc1cdd0a08afc18084 Mon Sep 17 00:00:00 2001 From: tastytea Date: Sat, 14 Apr 2018 13:57:03 +0200 Subject: [PATCH] replaced boost json with jsoncpp --- CMakeLists.txt | 5 ++-- README.md | 2 +- src/config.cpp | 73 ++++++++++++++++++++++++++++++------------------ src/mastorss.cpp | 14 ++++------ src/mastorss.hpp | 6 ++-- src/parse.cpp | 65 +++++++++++++++--------------------------- 6 files changed, 81 insertions(+), 84 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb664c6..f1e3c11 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project (mastorss - VERSION 0.4.2 + VERSION 0.4.3 LANGUAGES CXX ) @@ -10,6 +10,7 @@ include(FindBoost) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_BINARY_DIR}) @@ -29,7 +30,7 @@ add_definitions(${Boost_DEFINITIONS}) file(GLOB sources src/*.cpp) add_executable(mastorss ${sources}) -target_link_libraries(mastorss mastodon-cpp ${Boost_LIBRARIES} ssl crypto ${CURL_LIBRARIES} curlpp) +target_link_libraries(mastorss mastodon-cpp ${Boost_LIBRARIES} stdc++fs curl curlpp jsoncpp) install(TARGETS mastorss DESTINATION ${CMAKE_INSTALL_BINDIR}) install(FILES watchwords.json diff --git a/README.md b/README.md index 6d8e5b6..b8cf8db 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ The documentation is far from complete, sorry. * C++ compiler (tested: gcc 6.4, clang 5.0) * [cmake](https://cmake.org/) (tested: 3.9.6) * [boost](http://www.boost.org/) (tested: 1.63.0) - * [libcurl](https://curl.haxx.se/) (tested: 7.58.0) * [curlpp](http://www.curlpp.org/) (tested: 0.8.1) * [mastodon-cpp](https://github.com/tastytea/mastodon-cpp) (at least: 0.8.6) + * [jsoncpp](https://github.com/open-source-parsers/jsoncpp) (tested: 1.8.4) ## Get sourcecode diff --git a/src/config.cpp b/src/config.cpp index 2e28609..928f812 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -17,45 +17,48 @@ #include #include #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include "mastorss.hpp" -namespace pt = boost::property_tree; - using std::cout; using std::cerr; using std::cin; using std::string; +namespace fs = std::experimental::filesystem; std::uint16_t read_config(string &instance, string &access_token, string &feedurl) { bool config_changed = false; // Read config file, get access token - try { - pt::read_json(filepath + "config-" + profile + ".json", config); - instance = config.get(profile + ".instance", ""); - access_token = config.get(profile + ".access_token", ""); - feedurl = config.get(profile + ".feedurl", ""); - max_size = config.get(profile + ".max_size", max_size); - } - catch (std::exception &e) + std::ifstream file(filepath + "config-" + profile + ".json"); + if (file.is_open()) { - // most likely no config file found - cout << "Config file not readable. Building new one.\n"; - const boost::filesystem::path path(filepath); - boost::filesystem::create_directory(filepath); + std::stringstream json; + json << file.rdbuf(); + file.close(); + json >> config; + + instance = config[profile + ".instance"].asString(); + access_token = config[profile + ".access_token"].asString(); + feedurl = config[profile + ".feedurl"].asString(); + max_size = config.get(profile + ".max_size", max_size).asUInt(); + } + else + { + cout << "Config file not found. Building new one.\n"; + fs::create_directory(filepath); } if (instance.empty()) { cout << "Instance: "; cin >> instance; - config.put(profile + ".instance", instance); + config[profile + ".instance"] = instance; config_changed = true; } if (access_token.empty()) @@ -77,14 +80,14 @@ std::uint16_t read_config(string &instance, string &access_token, string &feedur cout << "Insert code: "; cin >> code; - masto.register_app2(client_id, - client_secret, - "urn:ietf:wg:oauth:2.0:oob", - code, - access_token); + ret = masto.register_app2(client_id, + client_secret, + "urn:ietf:wg:oauth:2.0:oob", + code, + access_token); if (ret == 0) { - config.put(profile + ".access_token", access_token); + config[profile + ".access_token"] = access_token; config_changed = true; } else @@ -104,13 +107,29 @@ std::uint16_t read_config(string &instance, string &access_token, string &feedur { cout << "feedurl: "; cin >> feedurl; - config.put(profile + ".feedurl", feedurl); + config[profile + ".feedurl"] = feedurl; config_changed = true; } if (config_changed) { - pt::write_json(filepath + "config-" + profile + ".json", config); + write_config(); } return 0; } + + +const bool write_config() +{ + std::ofstream outfile(filepath + "config-" + profile + ".json"); + if (outfile.is_open()) + { + outfile.write(config.toStyledString().c_str(), + config.toStyledString().length()); + outfile.close(); + + return true; + } + + return false; +} diff --git a/src/mastorss.cpp b/src/mastorss.cpp index ee79fd5..90c2d20 100644 --- a/src/mastorss.cpp +++ b/src/mastorss.cpp @@ -21,15 +21,11 @@ #include #include #include -#include -#include -#include -#include +#include #include #include "version.hpp" #include "mastorss.hpp" -namespace pt = boost::property_tree; using Mastodon::API; using std::cout; using std::cerr; @@ -39,7 +35,7 @@ using std::string; // Initialize global variables std::uint16_t max_size = 500; const string filepath = string(getenv("HOME")) + "/.config/mastorss/"; -pt::ptree config; +Json::Value config; std::string profile; int main(int argc, char *argv[]) @@ -73,14 +69,14 @@ int main(int argc, char *argv[]) } entries = parse_website(answer); - string last_entry = config.get(profile + ".last_entry", ""); + string last_entry = config[profile + ".last_entry"].asString(); if (last_entry.empty()) { // If no last_entry is stored in the config file, // make last_entry the second-newest entry. last_entry = entries.at(1); } - config.put(profile + ".last_entry", entries.front()); + config[profile + ".last_entry"] = entries.front(); bool new_content = false; for (auto rit = entries.rbegin(); rit != entries.rend(); ++rit) @@ -118,7 +114,7 @@ int main(int argc, char *argv[]) } // Write the new last_entry only if no error happened. - pt::write_json(filepath + "config-" + profile + ".json", config); + write_config(); return 0; } diff --git a/src/mastorss.hpp b/src/mastorss.hpp index 349860d..fab9cf7 100644 --- a/src/mastorss.hpp +++ b/src/mastorss.hpp @@ -4,17 +4,17 @@ #include #include #include -#include +#include -namespace pt = boost::property_tree; using std::string; extern std::uint16_t max_size; extern const string filepath; -extern pt::ptree config; +extern Json::Value config; extern std::string profile; std::uint16_t read_config(string &instance, string &access_token, string &feedurl); +const bool write_config(); std::vector parse_website(const string &xml); void unescape_html(const string &str); diff --git a/src/parse.cpp b/src/parse.cpp index 63febde..7f2ccf9 100644 --- a/src/parse.cpp +++ b/src/parse.cpp @@ -22,17 +22,16 @@ #include #include #include +#include +#include #include -#include #include -#include #include #include "mastorss.hpp" -namespace pt = boost::property_tree; - using std::cerr; using std::string; +namespace pt = boost::property_tree; // Translate { to chars, translate some named entities to chars void unescape_html(string &str) @@ -66,44 +65,33 @@ void unescape_html(string &str) std::vector parse_website(const string &xml) { - pt::ptree json; + Json::Value list; std::vector watchwords; - try + std::ifstream file(filepath + "watchwords.json"); + if (file.is_open()) { - pt::read_json(filepath + "watchwords.json", json); + std::stringstream json; + json << file.rdbuf(); + file.close(); + json >> list; } - catch (std::exception &e) + else { - // most likely file not found cerr << "ERROR: " << filepath << "watchwords.json not found or not readable.\n"; - cerr << e.what() << '\n'; return {}; } - try + // Read profile-specific hashtags or fail silently + for (const Json::Value &value : list[profile + ".tags"]) { - // Read profile-specific hashtags or fail silently - for (const pt::ptree::value_type &value : json.get_child(profile + ".tags")) - { - watchwords.push_back(value.second.data()); - } + watchwords.push_back(value.asString()); } - catch (const std::exception &e) + + // Read global hashtags or fail silently + for (const Json::Value &value : list["global.tags"]) { - // Node not found, no problem - } - try - { - // Read global hashtags or fail silently - for (const pt::ptree::value_type &value : json.get_child("global.tags")) - { - watchwords.push_back(value.second.data()); - } - } - catch (const std::exception &e) - { - // Node not found, no problem + watchwords.push_back(value.asString()); } pt::ptree rss; @@ -126,9 +114,9 @@ std::vector parse_website(const string &xml) try { // Skip entries beginning with this text - for (const pt::ptree::value_type &v : config.get_child(profile + ".skip")) + for (const Json::Value &v : config[profile + ".skip"]) { - const string skip = v.second.data(); + const string skip = v.asString(); if (!skip.empty()) { if (title.compare(0, skip.length(), skip) == 0) @@ -192,16 +180,9 @@ std::vector parse_website(const string &xml) // Read regular expressions from the config file and delete all matches. void individual_fixes(string &str) { - try + for (const Json::Value &v : config[profile + ".fixes"]) { - for (const pt::ptree::value_type &v : config.get_child(profile + ".fixes")) - { - std::regex refix(v.second.data()); - str = std::regex_replace(str, refix, ""); - } - } - catch (const std::exception &e) - { - // Node not found, no problem + std::regex refix(v.asString()); + str = std::regex_replace(str, refix, ""); } }