initial import with basic functionality

This commit is contained in:
Michael Mandl 2018-03-29 16:15:52 +02:00
commit 7183624f63
5 changed files with 272 additions and 0 deletions

38
CMakeLists.txt Normal file
View file

@ -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}
)

32
include/dokuwiki.h Normal file
View file

@ -0,0 +1,32 @@
#pragma once
#include <string>
#include <memory>
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<impl> pimpl;
};

38
source/dokuwiki.cpp Normal file
View file

@ -0,0 +1,38 @@
#include "dokuwiki.h"
#include "dokuwiki.impl.h"
#include <xmlrpc-c/client.hpp>
#include <iostream>
DokuWiki::DokuWiki(const std::string &url, const std::string &username, const std::string &password)
: pimpl{std::make_unique<impl>(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);
}

133
source/dokuwiki.impl.cpp Normal file
View file

@ -0,0 +1,133 @@
#include "dokuwiki.impl.h"
#include <iostream>
template <>
xmlrpc_c::value DokuWiki::impl::executeCommand(const std::string &command,
const std::list<std::string> &params)
{
xmlrpc_c::client_xml client(&m_clientTransport);
xmlrpc_c::paramList requestParams;
for (const auto &param : 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<std::string> &params)
{
try
{
return xmlrpc_c::value_struct(executeCommand<xmlrpc_c::value>(command, params));
}
catch (girerr::error &e)
{
throw DokuWiki::error(e.what());
}
}
template<>
std::string DokuWiki::impl::executeCommand(const std::string &command,
const std::list<std::string> &params)
{
try
{
return xmlrpc_c::value_string(executeCommand<xmlrpc_c::value>(command, params));
}
catch (girerr::error &e)
{
throw DokuWiki::error(e.what());
}
}
template<>
int DokuWiki::impl::executeCommand(const std::string &command,
const std::list<std::string> &params)
{
try
{
return xmlrpc_c::value_int(executeCommand<xmlrpc_c::value>(command, params));
}
catch (girerr::error &e)
{
throw DokuWiki::error(e.what());
}
}
template<>
bool DokuWiki::impl::executeCommand(const std::string &command,
const std::list<std::string> &params)
{
try
{
return xmlrpc_c::value_boolean(executeCommand<xmlrpc_c::value>(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<bool>("dokuwiki.login", { username, password }) == false)
{
throw DokuWiki::error("login failed");
}
}
std::string DokuWiki::impl::getVersion()
{
return executeCommand<std::string>("dokuwiki.getVersion");
}
std::string DokuWiki::impl::getTime()
{
std::time_t currentTime = executeCommand<int>("dokuwiki.getTime");
return std::asctime(std::localtime(&currentTime));
}
std::string DokuWiki::impl::getPage(const std::string &pageName)
{
return executeCommand<std::string>("wiki.getPage", { pageName });
}
std::string DokuWiki::impl::getWikiTitle()
{
return executeCommand<std::string>("dokuwiki.getTitle");
}
DokuWiki::PageInfo DokuWiki::impl::getPageInfo(const std::string &pageName)
{
auto values = static_cast<std::map<std::string, xmlrpc_c::value>>(executeCommand<xmlrpc_c::value_struct>("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;
}

31
source/dokuwiki.impl.h Normal file
View file

@ -0,0 +1,31 @@
#pragma once
#include "dokuwiki.h"
#include <xmlrpc-c/client.hpp>
#include <string>
#include <list>
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 <typename ReturnType>
ReturnType executeCommand(const std::string &command,
const std::list<std::string> &params = {});
};