replaced boost json with jsoncpp
This commit is contained in:
parent
2a6282a989
commit
6fa86a3c57
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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 { to chars, translate some named entities to chars
|
// Translate { 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
|
||||||
|
for (const Json::Value &value : list[profile + ".tags"])
|
||||||
{
|
{
|
||||||
// Read profile-specific hashtags or fail silently
|
watchwords.push_back(value.asString());
|
||||||
for (const pt::ptree::value_type &value : json.get_child(profile + ".tags"))
|
|
||||||
{
|
|
||||||
watchwords.push_back(value.second.data());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch (const std::exception &e)
|
|
||||||
|
// Read global hashtags or fail silently
|
||||||
|
for (const Json::Value &value : list["global.tags"])
|
||||||
{
|
{
|
||||||
// Node not found, no problem
|
watchwords.push_back(value.asString());
|
||||||
}
|
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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());
|
||||||
{
|
str = std::regex_replace(str, refix, "");
|
||||||
std::regex refix(v.second.data());
|
|
||||||
str = std::regex_replace(str, refix, "");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception &e)
|
|
||||||
{
|
|
||||||
// Node not found, no problem
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user