From 7183624f639ac82c79f20e63184ca24855fe59b1 Mon Sep 17 00:00:00 2001 From: Michael Mandl Date: Thu, 29 Mar 2018 16:15:52 +0200 Subject: [PATCH] initial import with basic functionality --- CMakeLists.txt | 38 +++++++++++ include/dokuwiki.h | 32 ++++++++++ source/dokuwiki.cpp | 38 +++++++++++ source/dokuwiki.impl.cpp | 133 +++++++++++++++++++++++++++++++++++++++ source/dokuwiki.impl.h | 31 +++++++++ 5 files changed, 272 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 include/dokuwiki.h create mode 100644 source/dokuwiki.cpp create mode 100644 source/dokuwiki.impl.cpp create mode 100644 source/dokuwiki.impl.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..79f6f6b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,38 @@ +cmake_minimum_required(VERSION 3.5) + +find_package(XMLRPC REQUIRED c++2 client) + +project(DokuWiki LANGUAGES CXX) + +set(dokuwiki_headers + include/dokuwiki.h + source/dokuwiki.impl.h +) + +set(dokuwiki_sources + source/dokuwiki.impl.cpp + source/dokuwiki.cpp +) + +add_library(${PROJECT_NAME} + ${dokuwiki_headers} + ${dokuwiki_sources} +) + +target_include_directories(${PROJECT_NAME} + PUBLIC + include + PRIVATE + ${XMLRPC_INCLUDE_DIRS} +) + +target_compile_features(${PROJECT_NAME} + PUBLIC + cxx_std_17 +) + +target_link_libraries(${PROJECT_NAME} + PRIVATE + ${XMLRPC_LIBRARIES} +) + diff --git a/include/dokuwiki.h b/include/dokuwiki.h new file mode 100644 index 0000000..500708c --- /dev/null +++ b/include/dokuwiki.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include + +class DokuWiki +{ + public: + using error = std::runtime_error; + + struct PageInfo + { + std::string name; + std::string author; + std::string timestamp; + }; + + public: + DokuWiki(const std::string &url, const std::string &username, const std::string &password); + ~DokuWiki(); + + std::string getVersion(); + std::string getTime(); + std::string getPage(const std::string &pageName); + std::string getWikiTitle(); + PageInfo getPageInfo(const std::string &pageName); + + private: + class impl; + std::unique_ptr pimpl; +}; + diff --git a/source/dokuwiki.cpp b/source/dokuwiki.cpp new file mode 100644 index 0000000..f688ea6 --- /dev/null +++ b/source/dokuwiki.cpp @@ -0,0 +1,38 @@ +#include "dokuwiki.h" +#include "dokuwiki.impl.h" + +#include + +#include + +DokuWiki::DokuWiki(const std::string &url, const std::string &username, const std::string &password) + : pimpl{std::make_unique(url, username, password)} +{ +} + +DokuWiki::~DokuWiki() = default; + +std::string DokuWiki::getVersion() +{ + return pimpl->getVersion(); +} + +std::string DokuWiki::getTime() +{ + return pimpl->getTime(); +} + +std::string DokuWiki::getPage(const std::string &pageName) +{ + return pimpl->getPage(pageName); +} + +std::string DokuWiki::getWikiTitle() +{ + return pimpl->getWikiTitle(); +} + +DokuWiki::PageInfo DokuWiki::getPageInfo(const std::string &pageName) +{ + return pimpl->getPageInfo(pageName); +} diff --git a/source/dokuwiki.impl.cpp b/source/dokuwiki.impl.cpp new file mode 100644 index 0000000..5f74746 --- /dev/null +++ b/source/dokuwiki.impl.cpp @@ -0,0 +1,133 @@ +#include "dokuwiki.impl.h" + +#include + +template <> +xmlrpc_c::value DokuWiki::impl::executeCommand(const std::string &command, + const std::list ¶ms) +{ + xmlrpc_c::client_xml client(&m_clientTransport); + + xmlrpc_c::paramList requestParams; + for (const auto ¶m : params) + { + requestParams.add(xmlrpc_c::value_string(param)); + } + + xmlrpc_c::rpcPtr rpc(command, requestParams); + + xmlrpc_c::carriageParm_curl0 carriageParm(m_url); + + rpc->call(&client, &carriageParm); + + return rpc->getResult(); +} + +template<> +xmlrpc_c::value_struct DokuWiki::impl::executeCommand(const std::string &command, + const std::list ¶ms) +{ + try + { + return xmlrpc_c::value_struct(executeCommand(command, params)); + } + catch (girerr::error &e) + { + throw DokuWiki::error(e.what()); + } +} + +template<> +std::string DokuWiki::impl::executeCommand(const std::string &command, + const std::list ¶ms) +{ + try + { + return xmlrpc_c::value_string(executeCommand(command, params)); + } + catch (girerr::error &e) + { + throw DokuWiki::error(e.what()); + } +} + +template<> +int DokuWiki::impl::executeCommand(const std::string &command, + const std::list ¶ms) +{ + try + { + return xmlrpc_c::value_int(executeCommand(command, params)); + } + catch (girerr::error &e) + { + throw DokuWiki::error(e.what()); + } +} + +template<> +bool DokuWiki::impl::executeCommand(const std::string &command, + const std::list ¶ms) +{ + try + { + return xmlrpc_c::value_boolean(executeCommand(command, params)); + } + catch (girerr::error &e) + { + throw DokuWiki::error(e.what()); + } +} + +DokuWiki::impl::impl(const std::string &url, const std::string &username, const std::string &password) + : m_url(url) +{ + login(username, password); +} + +void DokuWiki::impl::login(const std::string &username, const std::string &password) +{ + if (executeCommand("dokuwiki.login", { username, password }) == false) + { + throw DokuWiki::error("login failed"); + } +} + +std::string DokuWiki::impl::getVersion() +{ + return executeCommand("dokuwiki.getVersion"); +} + +std::string DokuWiki::impl::getTime() +{ + std::time_t currentTime = executeCommand("dokuwiki.getTime"); + + return std::asctime(std::localtime(¤tTime)); +} + +std::string DokuWiki::impl::getPage(const std::string &pageName) +{ + return executeCommand("wiki.getPage", { pageName }); +} + +std::string DokuWiki::impl::getWikiTitle() +{ + return executeCommand("dokuwiki.getTitle"); +} + +DokuWiki::PageInfo DokuWiki::impl::getPageInfo(const std::string &pageName) +{ + auto values = static_cast>(executeCommand("wiki.getPageInfo", { pageName })); + + std::time_t modificationTime = xmlrpc_c::value_int(values["version"]); + + DokuWiki::PageInfo pageInfo = + { + xmlrpc_c::value_string(values["name"]), + xmlrpc_c::value_string(values["author"]), + std::asctime(std::localtime(&modificationTime)) + }; + + return pageInfo; +} + diff --git a/source/dokuwiki.impl.h b/source/dokuwiki.impl.h new file mode 100644 index 0000000..c8f39a1 --- /dev/null +++ b/source/dokuwiki.impl.h @@ -0,0 +1,31 @@ +#pragma once + +#include "dokuwiki.h" + +#include + +#include +#include + +class DokuWiki::impl +{ + private: + std::string m_url; + xmlrpc_c::clientXmlTransport_curl m_clientTransport; + + public: + impl(const std::string &url, const std::string &username, const std::string &password); + + void login(const std::string &username, const std::string &password); + std::string getVersion(); + std::string getTime(); + std::string getPage(const std::string &pageName); + std::string getWikiTitle(); + + DokuWiki::PageInfo getPageInfo(const std::string &pageName); + + template + ReturnType executeCommand(const std::string &command, + const std::list ¶ms = {}); +}; +