diff --git a/.gitignore b/.gitignore index 40fa305..57797e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ /build/ /doc/ /update_gh-pages.sh +/src/examples/example99* diff --git a/CMakeLists.txt b/CMakeLists.txt index f1a61fb..cb25364 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required (VERSION 3.7) project (mastodon-cpp - VERSION 0.6.6 + VERSION 0.7.0 LANGUAGES CXX ) @@ -9,6 +9,7 @@ include(GNUInstallDirs) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall") +set(CXX_EXTENSIONS OFF) set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -26,13 +27,25 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") endif() # Library -file(GLOB sources src/*.cpp src/*.hpp src/api/*.cpp) +if(WITHOUT_EASY) + file(GLOB sources src/*.cpp src/api/*.cpp) +else() + file(GLOB sources src/*.cpp src/api/*.cpp src/easy/*.cpp) +endif() add_library(mastodon-cpp SHARED ${sources}) set_target_properties(mastodon-cpp PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${mastodon-cpp_VERSION_MAJOR} ) -target_link_libraries(mastodon-cpp curlpp) +if(WITHOUT_EASY) + target_link_libraries(mastodon-cpp curlpp) + install(FILES src/mastodon-cpp.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mastodon-cpp) +else() + target_link_libraries(mastodon-cpp curlpp jsoncpp) + install(FILES src/mastodon-cpp.hpp src/easy/easy.hpp + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/mastodon-cpp) +endif() install(TARGETS mastodon-cpp LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${PROJECT_SOURCE_DIR}/src/mastodon-cpp.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) @@ -54,7 +67,7 @@ if(WITH_EXAMPLES) foreach(src ${sources_examples}) get_filename_component(bin ${src} NAME_WE) add_executable(${bin} ${src}) - target_link_libraries(${bin} -lpthread -ljsoncpp mastodon-cpp) + target_link_libraries(${bin} pthread jsoncpp mastodon-cpp) endforeach() endif() diff --git a/src/easy/account.cpp b/src/easy/account.cpp new file mode 100644 index 0000000..bdfc479 --- /dev/null +++ b/src/easy/account.cpp @@ -0,0 +1,252 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2018 tastytea + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include // get_time +#include +#include +#include "easy.hpp" +#include "macros.hpp" + +using namespace Mastodon; +using Account = Easy::Account; +using std::string; + +Account::Account(const string &json) +: _valid(false) +{ + std::stringstream ss(json); + ss >> _tree; + + if (_tree.isNull()) + { + std::cerr << "ERROR: Could not build Account from JSON string\n"; + ttdebug << "String was: " << json << '\n'; + } + else + { + _valid = true; + } +} + +const bool Account::valid() const +{ + return _valid; +} + +const string Account::acct() const +{ + if (_tree["acct"].isString()) + { + return _tree["acct"].asString(); + } + + ttdebug << "Could not get account data: acct\n"; + return ""; +} + +const string Account::avatar() const +{ + if (_tree["avatar"].isString()) + { + return _tree["avatar"].asString(); + } + + ttdebug << "Could not get account data: avatar\n"; + return ""; +} + +const string Account::avatar_static() const +{ + if (_tree["avatar_static"].isString()) + { + return _tree["avatar_static"].asString(); + } + + ttdebug << "Could not get account data: avatar_static\n"; + return ""; +} + +const std::chrono::system_clock::time_point Account::created_at() const +{ + if (_tree["created_at"].isString()) + { + std::stringstream sstime(_tree["created_at"].asString()); + struct std::tm tm = {0}; + sstime >> std::get_time(&tm, "%Y-%m-%dT%T"); + std::time_t time = timegm(&tm); + return std::chrono::system_clock::from_time_t(time); + } + + ttdebug << "Could not get account data: created_at\n"; + // Return clocks epoch + return std::chrono::system_clock::time_point(); +} + +const string Account::display_name() const +{ + if (_tree["display_name"].isString()) + { + return _tree["display_name"].asString(); + } + + ttdebug << "Could not get account data: display_name\n"; + return ""; +} + +const std::uint64_t Account::followers_count() const +{ + if (_tree["followers_count"].isUInt64()) + { + return _tree["followers_count"].asUInt64(); + } + + ttdebug << "Could not get account data: followers_count\n"; + return 0; +} + +const std::uint64_t Account::following_count() const +{ + if (_tree["following_count"].isUInt64()) + { + return _tree["following_count"].asUInt64(); + } + + ttdebug << "Could not get account data: following_count\n"; + return 0; +} + +const string Account::header() const +{ + if (_tree["header"].isString()) + { + return _tree["header"].asString(); + } + + ttdebug << "Could not get account data: header\n"; + return ""; +} + +const string Account::header_static() const +{ + if (_tree["header_static"].isString()) + { + return _tree["header_static"].asString(); + } + + ttdebug << "Could not get account data: header_static\n"; + return ""; +} + +const std::uint64_t Account::id() const +{ + if (_tree["id"].isUInt64()) + { + return _tree["id"].asUInt64(); + } + + ttdebug << "Could not get account data: id\n"; + return 0; +} + +const bool Account::locked() const +{ + if (_tree["locked"].isBool()) + { + return _tree["locked"].asBool(); + } + + ttdebug << "Could not get account data: locked\n"; + return false; +} + +const string Account::note() const +{ + if (_tree["note"].isString()) + { + return _tree["note"].asString(); + } + + ttdebug << "Could not get account data: note\n"; + return ""; +} + +const string Account::note_plain() const +{ + if (_tree["source"]["note"].isString()) + { + return _tree["source"]["note"].asString(); + } + + ttdebug << "Could not get account data: note_plain\n"; + return ""; +} + +const Easy::visibility Account::privacy() const +{ + if (_tree["source"]["privacy"].isString()) + { + const string strprivacy = _tree["source"]["privacy"].asString(); + if (strprivacy.compare("public")) + return visibility::Public; + else if (strprivacy.compare("unlisted")) + return visibility::Unlisted; + else if (strprivacy.compare("private")) + return visibility::Private; + else if (strprivacy.compare("direct")) + return visibility::Direct; + } + + ttdebug << "Could not get account data: privacy\n"; + return visibility::Undefined; +} + +const bool Account::sensitive() const +{ + if (_tree["source"]["sensitive"].isBool()) + { + return _tree["source"]["sensitive"].asBool(); + } + + ttdebug << "Could not get account data: sensitive\n"; + return false; +} + +const std::uint64_t Account::statuses_count() const +{ + if (_tree["statuses_count"].isUInt64()) + { + return _tree["statuses_count"].asUInt64(); + } + + ttdebug << "Could not get account data: statuses_count\n"; + return 0; +} + +const string Account::username() const +{ + if (_tree["username"].isString()) + { + return _tree["username"].asString(); + } + + ttdebug << "Could not get account data: username\n"; + return ""; +} diff --git a/src/easy/easy.cpp b/src/easy/easy.cpp new file mode 100644 index 0000000..1ee446c --- /dev/null +++ b/src/easy/easy.cpp @@ -0,0 +1,27 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2018 tastytea + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include "easy.hpp" + +using namespace Mastodon; +using std::string; + +Easy::Easy(const string &instance, const string &access_token) +: API(instance, access_token) +{ + // +} diff --git a/src/easy/easy.hpp b/src/easy/easy.hpp new file mode 100644 index 0000000..8dc4308 --- /dev/null +++ b/src/easy/easy.hpp @@ -0,0 +1,181 @@ +/* This file is part of mastodon-cpp. + * Copyright © 2018 tastytea + * + * 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 + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef MASTODON_EASY_CPP_HPP +#define MASTODON_EASY_CPP_HPP + +#include +#include +#include +#include +#include "mastodon-cpp.hpp" + +using std::string; +using std::uint16_t; + +namespace Mastodon +{ +/*! + * @brief Child of Mastodon::API with abstract methods. + */ +class Easy : public API +{ +public: + /*! + * @brief Describes visibility of toots. + * + * The names begin with a capital letter because some of them + * are reserved keywords when written in all-lowercase. + */ + enum class visibility + { + Direct, + Private, + Unlisted, + Public, + Undefined + }; + + /*! + * @brief Constructs a new Easy object. + * + * To register your application, leave access_token blank and call + * register_app1() and register_app2(). + * + * @param instance The hostname of your instance + * @param access_token The access token + */ + explicit Easy(const string &instance, const string &access_token); + + /*! + * @brief Class to hold accounts. + */ + class Account + { + public: + /*! + * @brief Constructs an account object from a JSON string. + * + * @param json JSON string + */ + Account(const string &json); + + /*! + * @brief Returns true if the account holds valid data + */ + const bool valid() const; + + /*! + * @brief Returns username + * + * `username` for users on the same instance, `user@hostname` + * for users on other instances. + */ + const string acct() const; + + /*! + * @brief Returns URL of avatar + */ + const string avatar() const; + + /*! + * @brief Returns URL of static avatar + */ + const string avatar_static() const; + + /*! + * @brief Returns time of creation + */ + const std::chrono::system_clock::time_point created_at() const; + + /*! + * @brief Returns display name + */ + const string display_name() const; + + /*! + * @brief Returns number of followers + */ + const std::uint64_t followers_count() const; + + /*! + * @brief Returns number of people this account follows + */ + const std::uint64_t following_count() const; + + /*! + * @brief Returns URL of header image + */ + const string header() const; + + /*! + * @brief Returns URL of static header image + */ + const string header_static() const; + + /*! + * @brief Returns account-ID + */ + const std::uint64_t id() const; + + /*! + * @brief Returns true if the account is locked + */ + const bool locked() const; + + /*! + * @brief Returns note + */ + const string note() const; + + /*! + * @brief Returns plaintext version of note + */ + const string note_plain() const; + + /*! + * @brief Returns default privacy of new toots + */ + const visibility privacy() const; + + /*! + * @brief Returns if media is amrked as sensitive by default + */ + const bool sensitive() const; + + /*! + * @brief Returns number of statuses + */ + const std::uint64_t statuses_count() const; + + /*! + * @brief Returns URL of the profile + */ + const string url() const; + + /*! + * @brief Returns username (without @hostname) + */ + const string username() const; + + private: + Json::Value _tree; + bool _valid; + }; +}; +} + +#endif // MASTODON_EASY_CPP_HPP diff --git a/src/macros.hpp b/src/macros.hpp index 50cb294..29ef058 100644 --- a/src/macros.hpp +++ b/src/macros.hpp @@ -17,6 +17,7 @@ #ifndef MACROS_HPP #define MACROS_HPP +#include #ifdef DEBUG #define ttdebug std::cerr << "[" << __FILE__ << ":" << __LINE__ << "] DEBUG: " @@ -24,5 +25,4 @@ #define ttdebug false && std::cerr #endif - #endif // MACROS_HPP