Logging of the messages, customizable replies, assigning groups
This commit is contained in:
parent
f03f392cee
commit
7f57cd3bf6
21 changed files with 288 additions and 62 deletions
|
@ -85,7 +85,7 @@ Config::Module Config::getModuleConfig(const std::string& name) const {
|
|||
YAML::Node prm = conf["permissions"];
|
||||
if (prm.IsMap()) {
|
||||
for (const auto& node : prm) {
|
||||
Module::List& list = result.permissions.emplace(node.first.as<std::string>(), Module::List()).first->second;
|
||||
Shared::Strings& list = result.permissions.emplace(node.first.as<std::string>(), Shared::Strings()).first->second;
|
||||
YAML::Node lst = node.second;
|
||||
if (lst.IsSequence())
|
||||
for (const YAML::Node& member : lst)
|
||||
|
@ -93,6 +93,25 @@ Config::Module Config::getModuleConfig(const std::string& name) const {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Shared::Responses Config::getResponses() const {
|
||||
Shared::Responses responses;
|
||||
|
||||
YAML::Node replies = root["replies"];
|
||||
if (!replies || !replies.IsMap())
|
||||
return responses;
|
||||
|
||||
for (const std::pair<Shared::Result, std::string_view>& entry : Shared::results) {
|
||||
YAML::Node options = replies[entry.second];
|
||||
if (!options.IsSequence())
|
||||
continue;
|
||||
|
||||
Shared::Strings& out = responses.emplace(entry.first, Shared::Strings()).first->second;
|
||||
for (const YAML::Node& option : options)
|
||||
out.emplace_back(option.as<std::string>());
|
||||
}
|
||||
|
||||
return responses;
|
||||
}
|
||||
|
|
|
@ -10,17 +10,16 @@
|
|||
|
||||
#include "yaml-cpp/yaml.h"
|
||||
|
||||
#include "shared/definitions.h"
|
||||
#include "shared/result.h"
|
||||
#include "logger.h"
|
||||
|
||||
class Config {
|
||||
public:
|
||||
struct Module {
|
||||
typedef std::vector<std::string> List;
|
||||
typedef std::map<std::string, List> Permissions;
|
||||
|
||||
bool enabled;
|
||||
std::string alias;
|
||||
Permissions permissions;
|
||||
Shared::Permissions permissions;
|
||||
};
|
||||
|
||||
public:
|
||||
|
@ -36,6 +35,7 @@ public:
|
|||
Logger::Level getLogLevel() const;
|
||||
gloox::TLSPolicy getTLSPolicy() const;
|
||||
Module getModuleConfig(const std::string& name) const;
|
||||
Shared::Responses getResponses() const;
|
||||
|
||||
private:
|
||||
YAML::Node root;
|
||||
|
|
|
@ -3,8 +3,51 @@
|
|||
|
||||
#include "core.h"
|
||||
|
||||
#include "connection/connection.h"
|
||||
|
||||
Core::Core(const std::string& configPath):
|
||||
config(configPath),
|
||||
router(),
|
||||
logger(config.getLogLevel())
|
||||
logger(config.getLogLevel()),
|
||||
router(logger),
|
||||
initialized(false)
|
||||
{}
|
||||
|
||||
void Core::send(const std::string& jid, const std::string& body) {
|
||||
std::shared_ptr<Connection> cn = connection.lock();
|
||||
if (!cn) {
|
||||
logger.log(Logger::warning, "Couldn't send a message to " + jid + ", connection is not available", {"Core"});
|
||||
return;
|
||||
}
|
||||
|
||||
cn->send(jid, body);
|
||||
}
|
||||
|
||||
void Core::initialize(const std::shared_ptr<Connection>& cn) {
|
||||
connection = cn;
|
||||
router.setConnection(cn);
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
initializeActors();
|
||||
initializeResponses();
|
||||
|
||||
initialized = true;
|
||||
}
|
||||
|
||||
void Core::setGroup(const std::string& jid, const std::string& group) {
|
||||
router.registerActor(jid, group);
|
||||
// todo save config
|
||||
}
|
||||
|
||||
void Core::initializeActors() {
|
||||
for (const std::pair<const std::string, std::string>& pair : config.getActors()) {
|
||||
logger.log(Logger::info, "registering actor " + pair.first + " as " + pair.second, {"Core"});
|
||||
router.registerActor(pair.first, pair.second);
|
||||
}
|
||||
}
|
||||
|
||||
void Core::initializeResponses() {
|
||||
for (const std::pair<Shared::Result, Shared::Strings>& pair : config.getResponses())
|
||||
router.setResponses(pair.first, pair.second);
|
||||
}
|
||||
|
|
|
@ -4,17 +4,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
|
||||
#include "config.h"
|
||||
#include "router.h"
|
||||
#include "logger.h"
|
||||
|
||||
class Connection;
|
||||
|
||||
class Core {
|
||||
public:
|
||||
Core(const std::string& configPath);
|
||||
|
||||
void send(const std::string& jid, const std::string& body);
|
||||
void initialize(const std::shared_ptr<Connection>& connection);
|
||||
void setGroup(const std::string& jid, const std::string& group);
|
||||
|
||||
public:
|
||||
Config config;
|
||||
Router router;
|
||||
Logger logger;
|
||||
Router router;
|
||||
|
||||
private:
|
||||
void initializeActors();
|
||||
void initializeResponses();
|
||||
|
||||
private:
|
||||
bool initialized;
|
||||
std::weak_ptr<Connection> connection;
|
||||
|
||||
};
|
||||
|
|
|
@ -129,7 +129,7 @@ void Logger::handleLog(gloox::LogLevel level, gloox::LogArea area, const std::st
|
|||
std::cout << clear << '\t' << message << clear << std::endl;
|
||||
}
|
||||
|
||||
void Logger::log(Level lvl, const std::string& message, const std::vector<std::string>& domain) {
|
||||
void Logger::log(Level lvl, const std::string& message, const std::vector<std::string>& domain) const {
|
||||
if (lvl < level)
|
||||
return;
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ public:
|
|||
|
||||
void handleLog(gloox::LogLevel level, gloox::LogArea area, const std::string& message) override;
|
||||
|
||||
void log(Level level, const std::string& message, const std::vector<std::string>& domain = {});
|
||||
void log(Level level, const std::string& message, const std::vector<std::string>& domain = {}) const;
|
||||
|
||||
static gloox::LogLevel convert(Level level);
|
||||
static Level convert(gloox::LogLevel level);
|
||||
|
|
|
@ -4,10 +4,19 @@
|
|||
#include "router.h"
|
||||
|
||||
#include "module/module.h"
|
||||
#include "connection/connection.h"
|
||||
|
||||
Router::Router():
|
||||
Router::Router(const Logger& logger):
|
||||
logger(logger),
|
||||
modules(),
|
||||
actors(),
|
||||
defaultGroup("Stranger")
|
||||
defaultGroup("Stranger"),
|
||||
responses({
|
||||
{Shared::forbidden, { "Forbidden" }},
|
||||
{Shared::error, { "Command error" }},
|
||||
{Shared::unhandled, { "No such command" }},
|
||||
}),
|
||||
generator(std::random_device{}())
|
||||
{}
|
||||
|
||||
void Router::registerModule(const std::string& key, const std::shared_ptr<Module::Module>& module) {
|
||||
|
@ -34,15 +43,29 @@ void Router::routeMessage(const std::string& sender, const std::string& body) {
|
|||
|
||||
std::vector<std::string> args = Module::Module::split(body);
|
||||
Modules::iterator mItr = modules.find(args[0]);
|
||||
if (mItr == modules.end())
|
||||
return;
|
||||
if (mItr == modules.end()) {
|
||||
logger.log(Logger::debug, "could not find module \"" + args[0] + "\" to handle message from " + sender, {"Router"});
|
||||
return onMessageResult(Shared::unhandled, sender);
|
||||
}
|
||||
|
||||
std::shared_ptr<Module::Module> module = mItr->second.lock();
|
||||
if (!module)
|
||||
return;
|
||||
if (!module) {
|
||||
logger.log(Logger::error, "could not lock module \"" + mItr->first + "\" to handle message from " + sender, {"Router"});
|
||||
return onMessageResult(Shared::error, sender);
|
||||
}
|
||||
|
||||
args.erase(args.begin());
|
||||
module->message(aItr->second, args);
|
||||
Shared::Result result;
|
||||
try {
|
||||
result = module->message(aItr->second, args);
|
||||
if (result == Shared::success)
|
||||
logger.log(Logger::debug, "module \"" + mItr->first + "\" successfully handled message from " + sender, {"Router"});
|
||||
} catch (...) {
|
||||
logger.log(Logger::error, "module \"" + mItr->first + "\" thew an unhandled exception handling message from " + sender, {"Router"});
|
||||
result = Shared::error;
|
||||
}
|
||||
|
||||
onMessageResult(result, sender);
|
||||
}
|
||||
|
||||
std::map<std::string, std::string> Router::getActors() const {
|
||||
|
@ -54,4 +77,35 @@ std::map<std::string, std::string> Router::getActors() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void Router::setConnection(const std::shared_ptr<Connection>& cn) {
|
||||
connection = cn;
|
||||
}
|
||||
|
||||
void Router::setResponses(Shared::Result result, const Shared::Strings& options) {
|
||||
responses[result] = options;
|
||||
}
|
||||
|
||||
std::string Router::getGroup(const std::string& key) const {
|
||||
Actors::const_iterator itr = actors.find(key);
|
||||
if (itr == actors.end())
|
||||
return defaultGroup;
|
||||
|
||||
return itr->second->getGroup();
|
||||
}
|
||||
|
||||
void Router::onMessageResult(Shared::Result result, const std::string& sender) {
|
||||
Responses::const_iterator rItr = responses.find(result);
|
||||
if (rItr == responses.end() || rItr->second.empty())
|
||||
return;
|
||||
|
||||
std::shared_ptr<Connection> cn = connection.lock();
|
||||
if (!cn) {
|
||||
logger.log(Logger::warning, "Couldn't send a message to " + sender + ", connection is not available", {"Router"});
|
||||
return;
|
||||
}
|
||||
|
||||
const List& options = rItr->second;
|
||||
std::uniform_int_distribution<std::size_t> dist(0, options.size() - 1);
|
||||
cn->send(sender, options[dist(generator)]);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,16 +7,21 @@
|
|||
#include <map>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <random>
|
||||
|
||||
#include "shared/result.h"
|
||||
#include "actor.h"
|
||||
#include "logger.h"
|
||||
|
||||
namespace Module {
|
||||
class Module;
|
||||
};
|
||||
|
||||
class Connection;
|
||||
|
||||
class Router {
|
||||
public:
|
||||
Router();
|
||||
Router(const Logger& logger);
|
||||
|
||||
void registerModule(const std::string& key, const std::shared_ptr<Module::Module>& module);
|
||||
void registerActor(const std::string& key, const std::string& group);
|
||||
|
@ -24,11 +29,24 @@ public:
|
|||
|
||||
std::map<std::string, std::string> getActors() const;
|
||||
|
||||
void setConnection(const std::shared_ptr<Connection>& connection);
|
||||
void setResponses(Shared::Result result, const Shared::Strings& options);
|
||||
std::string getGroup(const std::string& key) const;
|
||||
|
||||
private:
|
||||
void onMessageResult(Shared::Result result, const std::string& sender);
|
||||
|
||||
private:
|
||||
typedef std::map<std::string, std::weak_ptr<Module::Module>> Modules;
|
||||
typedef std::map<std::string, std::shared_ptr<Actor>> Actors;
|
||||
typedef std::vector<std::string> List;
|
||||
typedef std::map<Shared::Result, List> Responses;
|
||||
|
||||
std::weak_ptr<Connection> connection;
|
||||
const Logger& logger;
|
||||
Modules modules;
|
||||
Actors actors;
|
||||
std::string defaultGroup;
|
||||
Responses responses;
|
||||
std::mt19937 generator;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue