Ported to mastodon-cpp 0.105.0.
the build was successful Подробиці

This commit is contained in:
tastytea 2019-04-20 01:47:23 +02:00
джерело a4988d72f2
коміт 64f78e0300
Підписано: tastytea
Ідентифікатор GPG ключа: CFC39497F1B26E07
10 змінених файлів з 117 додано та 137 видалено

@ -2,7 +2,7 @@ pipeline:
download:
image: plugins/download
pull: true
source: https://schlomp.space/attachments/5ab8f994-669a-47f8-8ac7-ed5902ad0339
source: https://schlomp.space/attachments/e1c1e64b-1192-4037-aad4-95238ad648b0
destination: mastodon-cpp.deb
gcc6:

@ -1,8 +1,8 @@
cmake_minimum_required (VERSION 3.7)
project (expandurl-mastodon
VERSION 0.9.14
LANGUAGES CXX
)
VERSION 0.9.14
LANGUAGES CXX
)
include(GNUInstallDirs)
find_package(CURL REQUIRED)
@ -15,14 +15,10 @@ set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
# uint_fast16_t can be bigger than 16 bit, but that doesn't matter because
# everything but the last 16 bit is padded with zeroes.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format")
endif()
set(CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG} -Wall -Wextra -Wpedantic -ftrapv \
-fsanitize=undefined -g -Og -fno-omit-frame-pointer")
include_directories(${PROJECT_SOURCE_DIR}/src)
include_directories(${PROJECT_BINARY_DIR})
include_directories(${CURL_INCLUDE_DIRS})
@ -37,26 +33,26 @@ link_directories(${LIBXDG_BASEDIR_LIBRARY_DIRS})
# Write version in header
configure_file (
"${PROJECT_SOURCE_DIR}/src/version.hpp.in"
"${PROJECT_BINARY_DIR}/version.hpp"
)
"${PROJECT_SOURCE_DIR}/src/version.hpp.in"
"${PROJECT_BINARY_DIR}/version.hpp"
)
file(GLOB sources src/*.cpp)
add_executable(expandurl-mastodon ${sources})
target_link_libraries(expandurl-mastodon
${CURLPP_LIBRARIES} ${JSONCPP_LIBRARIES}
${LIBXDG_BASEDIR_LIBRARIES} mastodon-cpp pthread stdc++fs)
${CURLPP_LIBRARIES} ${JSONCPP_LIBRARIES} ${LIBXDG_BASEDIR_LIBRARIES}
mastodon-cpp pthread stdc++fs)
install(TARGETS expandurl-mastodon DESTINATION ${CMAKE_INSTALL_BINDIR})
set(WITH_MAN "YES" CACHE STRING "WITH_MAN defaults to \"YES\"")
if (WITH_MAN)
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
DEPENDS "${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.1.adoc"
COMMAND ${CMAKE_SOURCE_DIR}/build_manpage.sh
ARGS ${PROJECT_VERSION})
add_custom_target(run ALL
DEPENDS "${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1"
WORKING_DIRECTORY "${PROJECT_BINARY_DIR}"
DEPENDS "${CMAKE_SOURCE_DIR}/${CMAKE_PROJECT_NAME}.1.adoc"
COMMAND ${CMAKE_SOURCE_DIR}/build_manpage.sh
ARGS ${PROJECT_VERSION})
add_custom_target(run ALL
DEPENDS "${PROJECT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1")
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}.1
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1)
endif()

@ -65,7 +65,7 @@ Have a look at the [manpage](https://schlomp.space/tastytea/expandurl-mastodon/s
# Copyright
```PLAIN
Copyright © 2018 tastytea <tastytea@tastytea.de>.
Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>.
License GPLv3: GNU GPL version 3 <https://www.gnu.org/licenses/gpl-3.0.html>.
This program comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to redistribute it under certain conditions.

@ -4,8 +4,9 @@ name="expandurl-mastodon"
if [ -n "${1}" ]; then
dir="$(dirname ${0})"
version="${1}"
cp -vf "${dir}/${name}.1.adoc" .
sed -Ei "s/(Revision: +)[0-9]+\.[0-9]\.[0-9]/\1${1}/" "${name}.1.adoc"
sed -Ei "s/(Revision: +)[0-9]+\.[0-9]\.[0-9]/\1${version}/" "${name}.1.adoc"
a2x --doctype manpage --format manpage --no-xmllint "${name}.1.adoc"
else
echo "usage: ${0} VERSION" >&2

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -42,7 +42,7 @@ ConfigJSON::ConfigJSON(const string &filename, const string &subdir)
_filepath += '/' + filename;
}
const bool ConfigJSON::read()
bool ConfigJSON::read()
{
std::ifstream file(_filepath);
if (file.is_open())
@ -60,7 +60,7 @@ const bool ConfigJSON::read()
}
}
const bool ConfigJSON::write()
bool ConfigJSON::write()
{
std::ofstream file(_filepath);
if (file.is_open())

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -43,14 +43,14 @@ public:
*
* @return `true` on success
*/
const bool read();
bool read();
/*!
* @brief Write the file
*
* @return `true` on success
*/
const bool write();
bool write();
/*!
* @brief Returns a reference to the config as Json::Value

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -27,15 +27,15 @@
#include <jsoncpp/json/json.h>
#include "configjson.hpp"
using namespace Mastodon;
using std::string;
using Mastodon::API;
using Mastodon::Easy;
extern ConfigJSON configfile;
void signal_handler(int signum);
/*!
* @brief Extract URLs from HTML
*
@ -54,7 +54,7 @@ const string expand(const string &url);
/*!
* @brief Filters out tracking stuff
*
*
* Currently removes all arguments beginning with `utm_`
*
* @param url URL to filter
@ -70,7 +70,7 @@ const string strip(const string &url);
* inserted.
*
*/
const void init_replacements();
void init_replacements();
class Listener
@ -82,24 +82,24 @@ public:
/*!
* @brief Starts listening on Mastodon
*/
const void start();
void start();
/*!
* @brief Stops listening on Mastodon
*/
const void stop();
void stop();
const std::vector<Easy::Notification> get_new_messages();
const std::vector<Easy::Notification> catchup();
Easy::Status get_status(const string &id);
const bool send_reply(const Easy::Status &to_status, const string &message);
bool send_reply(const Easy::Status &to_status, const string &message);
const string get_parent_id(const Easy::Notification &notif);
const bool stillrunning() const;
bool stillrunning() const;
private:
string _instance;
string _access_token;
std::unique_ptr<Easy> _masto;
std::unique_ptr<Easy::API> _masto;
string _stream;
std::unique_ptr<API::http> _ptr;
std::thread _thread;
@ -109,10 +109,10 @@ private:
string _proxy_password;
Json::Value &_config;
const void read_config();
const bool write_config();
const bool register_app();
const void set_proxy(Easy &masto);
void read_config();
bool write_config();
bool register_app();
void set_proxy(Easy::API &masto);
};
#endif // EXPANDURL_MASTODON_HPP

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -18,14 +18,16 @@
#include <chrono>
#include <csignal>
#include <regex>
#include <numeric>
#include <syslog.h>
#include <unistd.h> // getuid()
#include <curlpp/cURLpp.hpp>
#include "configjson.hpp"
#include "expandurl-mastodon.hpp"
using namespace Mastodon;
using std::string;
using Mastodon::Easy;
bool running = true;
ConfigJSON configfile("expandurl-mastodon.json");
@ -50,7 +52,7 @@ void signal_handler(int signum)
}
}
int main(int argc, char *argv[])
int main()
{
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
@ -99,11 +101,11 @@ int main(int argc, char *argv[])
status = listener.get_status(id);
if (status.valid())
{
string message = "";
for (const string &url : get_urls(status.content()))
{
message += url + " \n";
}
const std::vector<string> vec = get_urls(status.content());
const string message =
std::accumulate(vec.begin(), vec.end(), string(),
[](const string &s1, const string s2)
{ return s1 + s2 + " \n"; });
if (!message.empty())
{
if (!listener.send_reply(notif.status(), message))

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -26,6 +26,7 @@
using std::cout;
using std::string;
using std::uint8_t;
Listener::Listener()
: _instance("")
@ -59,7 +60,7 @@ Listener::Listener()
}
}
_masto = std::make_unique<Easy>(_instance, _access_token);
_masto = std::make_unique<Easy::API>(_instance, _access_token);
_masto->set_useragent(static_cast<const string>("expandurl-mastodon/") +
global::version);
set_proxy(*_masto);
@ -69,7 +70,7 @@ Listener::~Listener()
{
}
const void Listener::read_config()
void Listener::read_config()
{
_instance = _config["account"].asString();
_instance = _instance.substr(_instance.find('@') + 1);
@ -79,44 +80,19 @@ const void Listener::read_config()
_proxy_password = _config["proxy"]["password"].asString();
}
const void Listener::start()
void Listener::start()
{
constexpr uint_fast8_t delay_after_error = 120;
static std::uint_fast16_t ret;
_thread = std::thread([=]
{
ret = 0;
_running = true;
Easy masto(_instance, _access_token);
masto.set_useragent(static_cast<const string>("expandurl-mastodon/") +
global::version);
set_proxy(masto);
ret = masto.get_stream(Mastodon::API::v1::streaming_user, _stream, _ptr);
syslog(LOG_DEBUG, "Connection lost.");
if (ret != 0 && ret != 14) // 14 means canceled by user
{
syslog(LOG_ERR, "Connection terminated: Error %u", ret);
syslog(LOG_INFO, "Waiting for %u seconds", delay_after_error);
std::this_thread::sleep_for(std::chrono::seconds(delay_after_error));
}
_running = false;
});
while (!_ptr)
{
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
Easy::API masto(_instance, _access_token);
_running = true;
if (ret == 0)
{
syslog(LOG_NOTICE, "Connected to %s", _instance.c_str());
}
else if (ret != 14)
{ // If the stream thread sleeps, the main thread should sleep too
std::this_thread::sleep_for(std::chrono::seconds(delay_after_error));
}
masto.set_useragent(string("expandurl-mastodon/") + global::version);
set_proxy(masto);
masto.get_stream(Mastodon::API::v1::streaming_user, _ptr, _stream);
syslog(LOG_NOTICE, "Connecting to %s ...", _instance.c_str());
}
const void Listener::stop()
void Listener::stop()
{
if (!configfile.write())
{
@ -150,14 +126,25 @@ const std::vector<Easy::Notification> Listener::get_new_messages()
{
for (const Easy::stream_event &event : Easy::parse_stream(_stream))
{
if (event.first == Easy::event_type::Notification)
if (event.type == Easy::event_type::Notification)
{
Easy::Notification notif(event.second);
Easy::Notification notif(event.data);
if (notif.type() == Easy::notification_type::Mention)
{
v.push_back(notif);
}
}
else if (event.type == Easy::event_type::Error)
{
constexpr uint8_t delay_after_error = 120;
syslog(LOG_DEBUG, "Connection lost.");
const Json::Value err;
syslog(LOG_ERR, "Connection terminated: Error %u",
err["error_code"].asUInt());
syslog(LOG_INFO, "Waiting for %u seconds", delay_after_error);
std::this_thread::sleep_for(std::chrono::seconds(delay_after_error));
_running = false;
}
}
_stream.clear();
lastping = system_clock::now();
@ -183,26 +170,25 @@ const std::vector<Easy::Notification> Listener::catchup()
if (last_id != "")
{
syslog(LOG_DEBUG, "Catching up...");
API::parametermap parameter =
parameters parameter =
{
{ "since_id", { last_id } },
{ "exclude_types", { "follow", "favourite", "reblog" } }
};
string answer;
std::uint_fast16_t ret;
return_call ret;;
ret = _masto->get(API::v1::notifications, parameter, answer);
ret = _masto->get(API::v1::notifications, parameter);
if (ret == 0)
if (ret)
{
for (const string str : Easy::json_array_to_vector(answer))
for (const string str : Easy::json_array_to_vector(ret.answer))
{
v.push_back(Easy::Notification(str));
}
}
else
{
syslog(LOG_ERR, "Could not catch up: Error %u", ret);
syslog(LOG_ERR, "Could not catch up: Error %u", ret.error_code);
}
}
@ -211,26 +197,24 @@ const std::vector<Easy::Notification> Listener::catchup()
Mastodon::Easy::Status Listener::get_status(const string &id)
{
std::uint_fast16_t ret;
string answer;
return_call ret;
ret = _masto->get(API::v1::statuses_id, {{ "id", { id }}},
answer);
if (ret == 0)
ret = _masto->get(API::v1::statuses_id, {{ "id", { id }}});
if (ret)
{
return Easy::Status(answer);
return Easy::Status(ret.answer);
}
else
{
syslog(LOG_ERR, "Error %u in %s.", ret, __FUNCTION__);
syslog(LOG_ERR, "Error %u in %s.", ret.error_code, __FUNCTION__);
return Easy::Status();
}
}
const bool Listener::send_reply(const Easy::Status &to_status,
const string &message)
bool Listener::send_reply(const Easy::Status &to_status,
const string &message)
{
std::uint_fast16_t ret = 0;
Easy::return_entity<Easy::Status> ret;
Easy::Status new_status;
if (to_status.visibility() == Easy::visibility_type::Public)
@ -246,52 +230,49 @@ const bool Listener::send_reply(const Easy::Status &to_status,
new_status.sensitive(to_status.sensitive());
new_status.spoiler_text(to_status.spoiler_text());
_masto->send_toot(new_status, ret);
ret = _masto->send_post(new_status);
if (ret == 0)
if (ret)
{
syslog(LOG_DEBUG, "Sent reply");
return true;
}
else
{
syslog(LOG_ERR, "Error %u in %s.", ret, __FUNCTION__);
syslog(LOG_ERR, "Error %u in %s.", ret.error_code, __FUNCTION__);
return false;
}
}
const string Listener::get_parent_id(const Easy::Notification &notif)
{
string answer;
std::uint_fast16_t ret;
return_call ret;
// Retry up to 2 times
for (std::uint_fast8_t retries = 1; retries <= 2; ++retries)
{
// Fetch full status
ret = _masto->get(API::v1::search, {{ "q", { notif.status().url() }}},
answer);
if (ret > 0)
ret = _masto->get(API::v1::search, {{ "q", { notif.status().url() }}});
if (!ret)
{
syslog(LOG_ERR, "Error %u: Could not fetch status (in %s).",
ret, __FUNCTION__);
ret.error_code, __FUNCTION__);
return 0;
}
ret = _masto->get(API::v1::statuses_id,
{{ "id", { notif.status().id() }}},
answer);
{{ "id", { notif.status().id() }}});
if (ret > 0)
if (!ret)
{
syslog(LOG_ERR, "Error %u: Could not get status (in %s).",
ret, __FUNCTION__);
ret.error_code, __FUNCTION__);
return 0;
}
else
{
_config["last_id"] = notif.id();
const Easy::Status s(answer);
const Easy::Status s(ret.answer);
// If parent is found, return ID; else retry
if (!s.in_reply_to_id().empty())
@ -309,23 +290,23 @@ const string Listener::get_parent_id(const Easy::Notification &notif)
return 0;
}
const bool Listener::stillrunning() const
bool Listener::stillrunning() const
{
return _running;
}
const bool Listener::register_app()
bool Listener::register_app()
{
cout << "Account (username@instance): ";
std::cin >> _instance;
_config["account"] = _instance;
_instance = _instance.substr(_instance.find('@') + 1);
_masto = std::make_unique<Easy>(_instance, "");
_masto = std::make_unique<Easy::API>(_instance, "");
_masto->set_useragent(static_cast<const string>("expandurl-mastodon/") +
global::version);
std::uint_fast16_t ret;
return_call ret;
string client_id, client_secret, url;
ret = _masto->register_app1("expandurl-mastodon",
"urn:ietf:wg:oauth:2.0:oob",
@ -334,7 +315,7 @@ const bool Listener::register_app()
client_id,
client_secret,
url);
if (ret == 0)
if (ret)
{
string code;
cout << "Visit " << url << " to authorize this application.\n";
@ -345,25 +326,25 @@ const bool Listener::register_app()
"urn:ietf:wg:oauth:2.0:oob",
code,
_access_token);
if (ret == 0)
if (ret)
{
_config["access_token"] = _access_token;
return true;
}
else
{
syslog(LOG_ERR, "register_app2(): %u", ret);
syslog(LOG_ERR, "register_app2(): %u", ret.error_code);
}
}
else
{
syslog(LOG_ERR, "register_app1(): %u", ret);
syslog(LOG_ERR, "register_app1(): %u", ret.error_code);
}
return false;
}
const void Listener::set_proxy(Mastodon::Easy &masto)
void Listener::set_proxy(Easy::API &masto)
{
if (!_proxy.empty())
{

@ -1,5 +1,5 @@
/* This file is part of expandurl-mastodon.
* Copyright © 2018 tastytea <tastytea@tastytea.de>
* Copyright © 2018, 2019 tastytea <tastytea@tastytea.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -41,7 +41,7 @@ const std::vector<string> get_urls(const string &html)
// Add URL to vector if it is not a mention.#
if (match[2].str().find("mention") == std::string::npos)
{
string url = Easy::unescape_html(match[1].str());
string url = unescape_html(match[1].str());
v.push_back(strip(expand(url)));
}
buffer = match.suffix().str();
@ -106,7 +106,7 @@ const string strip(const string &url)
return newurl;
}
const void init_replacements()
void init_replacements()
{
using replace_pair = std::pair<const std::string, const std::string>;
Json::Value &config = configfile.get_json();