replaced boost json with jsoncpp

This commit is contained in:
tastytea 2018-04-14 13:57:03 +02:00
parent 2a6282a989
commit 6fa86a3c57
Signed by: tastytea
GPG Key ID: 59346E0EA35C67E5
6 changed files with 81 additions and 84 deletions

View File

@ -1,6 +1,6 @@
cmake_minimum_required (VERSION 3.7) cmake_minimum_required (VERSION 3.7)
project (mastorss project (mastorss
VERSION 0.4.2 VERSION 0.4.3
LANGUAGES CXX LANGUAGES CXX
) )
@ -10,6 +10,7 @@ include(FindBoost)
set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
include_directories(${PROJECT_SOURCE_DIR}/src) include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_BINARY_DIR}) include_directories(${PROJECT_BINARY_DIR})
@ -29,7 +30,7 @@ add_definitions(${Boost_DEFINITIONS})
file(GLOB sources src/*.cpp) file(GLOB sources src/*.cpp)
add_executable(mastorss ${sources}) 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(TARGETS mastorss DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES watchwords.json install(FILES watchwords.json

View File

@ -13,9 +13,9 @@ The documentation is far from complete, sorry.
* C++ compiler (tested: gcc 6.4, clang 5.0) * C++ compiler (tested: gcc 6.4, clang 5.0)
* [cmake](https://cmake.org/) (tested: 3.9.6) * [cmake](https://cmake.org/) (tested: 3.9.6)
* [boost](http://www.boost.org/) (tested: 1.63.0) * [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) * [curlpp](http://www.curlpp.org/) (tested: 0.8.1)
* [mastodon-cpp](https://github.com/tastytea/mastodon-cpp) (at least: 0.8.6) * [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 ## Get sourcecode

View File

@ -17,45 +17,48 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <cstdint> #include <cstdint>
#include <boost/property_tree/ptree.hpp> #include <fstream>
#include <boost/property_tree/json_parser.hpp> #include <sstream>
#include <boost/property_tree/xml_parser.hpp> #include <experimental/filesystem>
#include <boost/filesystem.hpp> #include <jsoncpp/json/json.h>
#include <mastodon-cpp/mastodon-cpp.hpp> #include <mastodon-cpp/mastodon-cpp.hpp>
#include "mastorss.hpp" #include "mastorss.hpp"
namespace pt = boost::property_tree;
using std::cout; using std::cout;
using std::cerr; using std::cerr;
using std::cin; using std::cin;
using std::string; using std::string;
namespace fs = std::experimental::filesystem;
std::uint16_t read_config(string &instance, string &access_token, string &feedurl) std::uint16_t read_config(string &instance, string &access_token, string &feedurl)
{ {
bool config_changed = false; bool config_changed = false;
// Read config file, get access token // Read config file, get access token
try { std::ifstream file(filepath + "config-" + profile + ".json");
pt::read_json(filepath + "config-" + profile + ".json", config); if (file.is_open())
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)
{ {
// most likely no config file found std::stringstream json;
cout << "Config file not readable. Building new one.\n"; json << file.rdbuf();
const boost::filesystem::path path(filepath); file.close();
boost::filesystem::create_directory(filepath); 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()) if (instance.empty())
{ {
cout << "Instance: "; cout << "Instance: ";
cin >> instance; cin >> instance;
config.put(profile + ".instance", instance); config[profile + ".instance"] = instance;
config_changed = true; config_changed = true;
} }
if (access_token.empty()) if (access_token.empty())
@ -77,14 +80,14 @@ std::uint16_t read_config(string &instance, string &access_token, string &feedur
cout << "Insert code: "; cout << "Insert code: ";
cin >> code; cin >> code;
masto.register_app2(client_id, ret = masto.register_app2(client_id,
client_secret, client_secret,
"urn:ietf:wg:oauth:2.0:oob", "urn:ietf:wg:oauth:2.0:oob",
code, code,
access_token); access_token);
if (ret == 0) if (ret == 0)
{ {
config.put(profile + ".access_token", access_token); config[profile + ".access_token"] = access_token;
config_changed = true; config_changed = true;
} }
else else
@ -104,13 +107,29 @@ std::uint16_t read_config(string &instance, string &access_token, string &feedur
{ {
cout << "feedurl: "; cout << "feedurl: ";
cin >> feedurl; cin >> feedurl;
config.put(profile + ".feedurl", feedurl); config[profile + ".feedurl"] = feedurl;
config_changed = true; config_changed = true;
} }
if (config_changed) if (config_changed)
{ {
pt::write_json(filepath + "config-" + profile + ".json", config); write_config();
} }
return 0; 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;
}

View File

@ -21,15 +21,11 @@
#include <cstdint> #include <cstdint>
#include <thread> #include <thread>
#include <chrono> #include <chrono>
#include <boost/property_tree/ptree.hpp> #include <jsoncpp/json/json.h>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/filesystem.hpp>
#include <mastodon-cpp/mastodon-cpp.hpp> #include <mastodon-cpp/mastodon-cpp.hpp>
#include "version.hpp" #include "version.hpp"
#include "mastorss.hpp" #include "mastorss.hpp"
namespace pt = boost::property_tree;
using Mastodon::API; using Mastodon::API;
using std::cout; using std::cout;
using std::cerr; using std::cerr;
@ -39,7 +35,7 @@ using std::string;
// Initialize global variables // Initialize global variables
std::uint16_t max_size = 500; std::uint16_t max_size = 500;
const string filepath = string(getenv("HOME")) + "/.config/mastorss/"; const string filepath = string(getenv("HOME")) + "/.config/mastorss/";
pt::ptree config; Json::Value config;
std::string profile; std::string profile;
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -73,14 +69,14 @@ int main(int argc, char *argv[])
} }
entries = parse_website(answer); 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 (last_entry.empty())
{ {
// If no last_entry is stored in the config file, // If no last_entry is stored in the config file,
// make last_entry the second-newest entry. // make last_entry the second-newest entry.
last_entry = entries.at(1); last_entry = entries.at(1);
} }
config.put(profile + ".last_entry", entries.front()); config[profile + ".last_entry"] = entries.front();
bool new_content = false; bool new_content = false;
for (auto rit = entries.rbegin(); rit != entries.rend(); ++rit) 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. // Write the new last_entry only if no error happened.
pt::write_json(filepath + "config-" + profile + ".json", config); write_config();
return 0; return 0;
} }

View File

@ -4,17 +4,17 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/property_tree/ptree.hpp> #include <jsoncpp/json/json.h>
namespace pt = boost::property_tree;
using std::string; using std::string;
extern std::uint16_t max_size; extern std::uint16_t max_size;
extern const string filepath; extern const string filepath;
extern pt::ptree config; extern Json::Value config;
extern std::string profile; extern std::string profile;
std::uint16_t read_config(string &instance, string &access_token, string &feedurl); std::uint16_t read_config(string &instance, string &access_token, string &feedurl);
const bool write_config();
std::vector<string> parse_website(const string &xml); std::vector<string> parse_website(const string &xml);
void unescape_html(const string &str); void unescape_html(const string &str);

View File

@ -22,17 +22,16 @@
#include <sstream> #include <sstream>
#include <locale> #include <locale>
#include <codecvt> #include <codecvt>
#include <fstream>
#include <jsoncpp/json/json.h>
#include <boost/property_tree/ptree.hpp> #include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/json_parser.hpp>
#include <boost/property_tree/xml_parser.hpp> #include <boost/property_tree/xml_parser.hpp>
#include <boost/filesystem.hpp>
#include <mastodon-cpp/mastodon-cpp.hpp> #include <mastodon-cpp/mastodon-cpp.hpp>
#include "mastorss.hpp" #include "mastorss.hpp"
namespace pt = boost::property_tree;
using std::cerr; using std::cerr;
using std::string; using std::string;
namespace pt = boost::property_tree;
// Translate &#0123; to chars, translate some named entities to chars // Translate &#0123; to chars, translate some named entities to chars
void unescape_html(string &str) void unescape_html(string &str)
@ -66,44 +65,33 @@ void unescape_html(string &str)
std::vector<string> parse_website(const string &xml) std::vector<string> parse_website(const string &xml)
{ {
pt::ptree json; Json::Value list;
std::vector<string> watchwords; std::vector<string> 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 << "ERROR: " << filepath << "watchwords.json not found or not readable.\n";
cerr << e.what() << '\n';
return {}; return {};
} }
try
{
// Read profile-specific hashtags or fail silently // Read profile-specific hashtags or fail silently
for (const pt::ptree::value_type &value : json.get_child(profile + ".tags")) for (const Json::Value &value : list[profile + ".tags"])
{ {
watchwords.push_back(value.second.data()); watchwords.push_back(value.asString());
} }
}
catch (const std::exception &e)
{
// Node not found, no problem
}
try
{
// Read global hashtags or fail silently // Read global hashtags or fail silently
for (const pt::ptree::value_type &value : json.get_child("global.tags")) for (const Json::Value &value : list["global.tags"])
{ {
watchwords.push_back(value.second.data()); watchwords.push_back(value.asString());
}
}
catch (const std::exception &e)
{
// Node not found, no problem
} }
pt::ptree rss; pt::ptree rss;
@ -126,9 +114,9 @@ std::vector<string> parse_website(const string &xml)
try try
{ {
// Skip entries beginning with this text // 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 (!skip.empty())
{ {
if (title.compare(0, skip.length(), skip) == 0) if (title.compare(0, skip.length(), skip) == 0)
@ -192,16 +180,9 @@ std::vector<string> parse_website(const string &xml)
// Read regular expressions from the config file and delete all matches. // Read regular expressions from the config file and delete all matches.
void individual_fixes(string &str) 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.asString());
{
std::regex refix(v.second.data());
str = std::regex_replace(str, refix, ""); str = std::regex_replace(str, refix, "");
} }
} }
catch (const std::exception &e)
{
// Node not found, no problem
}
}