Mercurial > irccd
changeset 161:49095643ae67
Irccd: store commands in a dedicated CommandService, #508
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 24 May 2016 13:56:35 +0200 |
parents | c1acfacc46bd |
children | a24e2de22565 |
files | lib/irccd/CMakeSources.cmake lib/irccd/application.cpp lib/irccd/application.hpp lib/irccd/cmd-help.cpp lib/irccd/irccd.cpp lib/irccd/irccd.hpp lib/irccd/irccdctl.cpp lib/irccd/irccdctl.hpp lib/irccd/service-command.cpp lib/irccd/service-command.hpp lib/irccd/service-server.cpp lib/irccd/service-transport.cpp |
diffstat | 12 files changed, 213 insertions(+), 182 deletions(-) [+] |
line wrap: on
line diff
--- a/lib/irccd/CMakeSources.cmake Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/CMakeSources.cmake Tue May 24 13:56:35 2016 +0200 @@ -1,7 +1,6 @@ set( HEADERS ${CMAKE_CURRENT_LIST_DIR}/alias.hpp - ${CMAKE_CURRENT_LIST_DIR}/application.hpp ${CMAKE_CURRENT_LIST_DIR}/connection.hpp ${CMAKE_CURRENT_LIST_DIR}/cmd-help.hpp ${CMAKE_CURRENT_LIST_DIR}/cmd-plugin-info.hpp @@ -63,6 +62,7 @@ ${CMAKE_CURRENT_LIST_DIR}/server-state-connecting.hpp ${CMAKE_CURRENT_LIST_DIR}/server-state-disconnected.hpp ${CMAKE_CURRENT_LIST_DIR}/service.hpp + ${CMAKE_CURRENT_LIST_DIR}/service-command.hpp ${CMAKE_CURRENT_LIST_DIR}/service-interrupt.hpp ${CMAKE_CURRENT_LIST_DIR}/service-module.hpp ${CMAKE_CURRENT_LIST_DIR}/service-plugin.hpp @@ -81,7 +81,6 @@ set( SOURCES ${CMAKE_CURRENT_LIST_DIR}/alias.cpp - ${CMAKE_CURRENT_LIST_DIR}/application.cpp ${CMAKE_CURRENT_LIST_DIR}/connection.cpp ${CMAKE_CURRENT_LIST_DIR}/config.cpp ${CMAKE_CURRENT_LIST_DIR}/cmd-help.cpp @@ -137,6 +136,7 @@ ${CMAKE_CURRENT_LIST_DIR}/server-state-connected.cpp ${CMAKE_CURRENT_LIST_DIR}/server-state-connecting.cpp ${CMAKE_CURRENT_LIST_DIR}/server-state-disconnected.cpp + ${CMAKE_CURRENT_LIST_DIR}/service-command.cpp ${CMAKE_CURRENT_LIST_DIR}/service-interrupt.cpp ${CMAKE_CURRENT_LIST_DIR}/service-module.cpp ${CMAKE_CURRENT_LIST_DIR}/service-plugin.cpp
--- a/lib/irccd/application.cpp Tue May 24 13:00:35 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,76 +0,0 @@ -/* - * application.cpp -- super base class to create irccd front ends - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "application.hpp" -#include "cmd-help.hpp" -#include "cmd-plugin-info.hpp" -#include "cmd-plugin-list.hpp" -#include "cmd-plugin-load.hpp" -#include "cmd-plugin-reload.hpp" -#include "cmd-plugin-unload.hpp" -#include "cmd-server-cmode.hpp" -#include "cmd-server-cnotice.hpp" -#include "cmd-server-connect.hpp" -#include "cmd-server-disconnect.hpp" -#include "cmd-server-info.hpp" -#include "cmd-server-invite.hpp" -#include "cmd-server-join.hpp" -#include "cmd-server-kick.hpp" -#include "cmd-server-list.hpp" -#include "cmd-server-me.hpp" -#include "cmd-server-message.hpp" -#include "cmd-server-mode.hpp" -#include "cmd-server-nick.hpp" -#include "cmd-server-notice.hpp" -#include "cmd-server-part.hpp" -#include "cmd-server-reconnect.hpp" -#include "cmd-server-topic.hpp" -#include "cmd-watch.hpp" - -namespace irccd { - -Application::Application() -{ - // Register all commands. - addCommand(std::make_unique<command::Help>()); - addCommand(std::make_unique<command::PluginInfo>()); - addCommand(std::make_unique<command::PluginList>()); - addCommand(std::make_unique<command::PluginLoad>()); - addCommand(std::make_unique<command::PluginReload>()); - addCommand(std::make_unique<command::PluginUnload>()); - addCommand(std::make_unique<command::ServerChannelMode>()); - addCommand(std::make_unique<command::ServerChannelNotice>()); - addCommand(std::make_unique<command::ServerConnect>()); - addCommand(std::make_unique<command::ServerDisconnect>()); - addCommand(std::make_unique<command::ServerInfo>()); - addCommand(std::make_unique<command::ServerInvite>()); - addCommand(std::make_unique<command::ServerJoin>()); - addCommand(std::make_unique<command::ServerKick>()); - addCommand(std::make_unique<command::ServerList>()); - addCommand(std::make_unique<command::ServerMe>()); - addCommand(std::make_unique<command::ServerMessage>()); - addCommand(std::make_unique<command::ServerMode>()); - addCommand(std::make_unique<command::ServerNick>()); - addCommand(std::make_unique<command::ServerNotice>()); - addCommand(std::make_unique<command::ServerPart>()); - addCommand(std::make_unique<command::ServerReconnect>()); - addCommand(std::make_unique<command::ServerTopic>()); - addCommand(std::make_unique<command::Watch>()); -} - -} // !irccd
--- a/lib/irccd/application.hpp Tue May 24 13:00:35 2016 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * application.hpp -- super base class to create irccd front ends - * - * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef IRCCD_APPLICATION_HPP -#define IRCCD_APPLICATION_HPP - -/** - * \file application.hpp - * \brief Base class for irccd and irccdctl. - */ - -#include <cassert> -#include <memory> -#include <unordered_map> - -#include "command.hpp" -#include "sysconfig.hpp" - -namespace irccd { - -/** - * Map of commands. - */ -using RemoteCommands = std::unordered_map<std::string, std::unique_ptr<RemoteCommand>>; - -/** - * \brief Base class for creating irccd front ends. - */ -class Application { -protected: - /** - * Map of commands. - */ - RemoteCommands m_commands; - -public: - /** - * Create the application and fill the commands with predefined commands. - */ - IRCCD_EXPORT Application(); - - /** - * Access the remote commands. - * - * \return the commands - */ - inline const RemoteCommands &commands() const noexcept - { - return m_commands; - } - - /** - * Add a new command. - * - * \pre command must not be null - * \pre the command must not exist - * \param command the command - */ - inline void addCommand(std::unique_ptr<RemoteCommand> command) - { - assert(command); - assert(m_commands.count(command->name()) == 0); - - m_commands.emplace(command->name(), std::move(command)); - } -}; - -} // !irccd - -#endif // !_IRCCD_APPLICATION_HPP_
--- a/lib/irccd/cmd-help.cpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/cmd-help.cpp Tue May 24 13:56:35 2016 +0200 @@ -41,12 +41,12 @@ json::Value Help::request(Irccdctl &irccdctl, const RemoteCommandRequest &args) const { - auto it = irccdctl.commands().find(args.arg(0U)); + auto it = irccdctl.commandService().find(args.arg(0U)); - if (it == irccdctl.commands().end()) + if (!it) log::warning() << "there is no command named: " << args.arg(0U) << std::endl; else - log::warning() << it->second->usage() << std::flush; + log::warning() << it->usage() << std::flush; return nullptr; }
--- a/lib/irccd/irccd.cpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/irccd.cpp Tue May 24 13:56:35 2016 +0200 @@ -18,6 +18,7 @@ #include "irccd.hpp" #include "logger.hpp" +#include "service-command.hpp" #include "service-interrupt.hpp" #include "service-module.hpp" #include "service-plugin.hpp" @@ -33,7 +34,8 @@ namespace irccd { Irccd::Irccd() - : m_interruptService(std::make_shared<InterruptService>()) + : m_commandService(std::make_shared<CommandService>()) + , m_interruptService(std::make_shared<InterruptService>()) , m_serverService(std::make_shared<ServerService>(*this)) , m_transportService(std::make_shared<TransportService>(*this)) , m_ruleService(std::make_shared<RuleService>())
--- a/lib/irccd/irccd.hpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/irccd.hpp Tue May 24 13:56:35 2016 +0200 @@ -31,13 +31,12 @@ #include <mutex> #include <vector> -#include "application.hpp" #include "sysconfig.hpp" namespace irccd { +class CommandService; class InterruptService; -class Irccd; class ModuleService; class PluginService; class RuleService; @@ -49,7 +48,7 @@ * \class Irccd * \brief Irccd main instance. */ -class Irccd : public Application { +class Irccd { private: // Main loop stuff. std::atomic<bool> m_running{true}; @@ -57,6 +56,7 @@ std::vector<std::function<void (Irccd &)>> m_events; // Services. + std::shared_ptr<CommandService> m_commandService; std::shared_ptr<InterruptService> m_interruptService; std::shared_ptr<ServerService> m_serverService; std::shared_ptr<TransportService> m_transportService; @@ -89,6 +89,16 @@ } /** + * Access the command service. + * + * \return the service + */ + inline CommandService &commandService() noexcept + { + return *m_commandService; + } + + /** * Access the server service. * * \return the service
--- a/lib/irccd/irccdctl.cpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/irccdctl.cpp Tue May 24 13:56:35 2016 +0200 @@ -25,6 +25,7 @@ #include <format.h> +#include "command.hpp" #include "elapsed-timer.hpp" #include "fs.hpp" #include "ini.hpp" @@ -205,7 +206,7 @@ // This is the alias name. Alias alias(option.key()); - if (m_commands.count(option.key()) > 0) + if (m_commandService.contains(option.key())) throw std::invalid_argument("there is already a command named " + option.key()); // Iterate over the list of commands to execute for this alias. @@ -450,10 +451,10 @@ if (alias != m_aliases.end()) exec(alias->second, args); else { - auto cmd = m_commands.find(name); + auto cmd = m_commandService.find(name); - if (cmd != m_commands.end()) - exec(*cmd->second, args); + if (cmd) + exec(*cmd, args); else throw std::invalid_argument("no alias or command named " + name); }
--- a/lib/irccd/irccdctl.hpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/irccdctl.hpp Tue May 24 13:56:35 2016 +0200 @@ -30,9 +30,9 @@ #include <string> #include "alias.hpp" -#include "application.hpp" #include "connection.hpp" #include "options.hpp" +#include "service-command.hpp" namespace irccd { @@ -47,7 +47,7 @@ /** * \brief Main irccdctl class. */ -class Irccdctl : public Application { +class Irccdctl { private: // Irccd's information. unsigned short m_major{0}; @@ -58,6 +58,9 @@ bool m_javascript{true}; bool m_ssl{true}; + // Commands. + CommandService m_commandService; + std::unique_ptr<Connection> m_connection; std::unordered_map<std::string, Alias> m_aliases; @@ -79,6 +82,16 @@ public: /** + * Get the command service. + * + * \return the command service + */ + inline CommandService &commandService() noexcept + { + return m_commandService; + } + + /** * Execute the given command and wait for its result. * * \param cmd the command
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/irccd/service-command.cpp Tue May 24 13:56:35 2016 +0200 @@ -0,0 +1,93 @@ +/* + * service-command.cpp -- store remote commands + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <algorithm> + +#include "cmd-help.hpp" +#include "cmd-plugin-info.hpp" +#include "cmd-plugin-list.hpp" +#include "cmd-plugin-load.hpp" +#include "cmd-plugin-reload.hpp" +#include "cmd-plugin-unload.hpp" +#include "cmd-server-cmode.hpp" +#include "cmd-server-cnotice.hpp" +#include "cmd-server-connect.hpp" +#include "cmd-server-disconnect.hpp" +#include "cmd-server-info.hpp" +#include "cmd-server-invite.hpp" +#include "cmd-server-join.hpp" +#include "cmd-server-kick.hpp" +#include "cmd-server-list.hpp" +#include "cmd-server-me.hpp" +#include "cmd-server-message.hpp" +#include "cmd-server-mode.hpp" +#include "cmd-server-nick.hpp" +#include "cmd-server-notice.hpp" +#include "cmd-server-part.hpp" +#include "cmd-server-reconnect.hpp" +#include "cmd-server-topic.hpp" +#include "cmd-watch.hpp" +#include "service-command.hpp" + +namespace irccd { + +CommandService::CommandService() + : m_commands{ + std::make_shared<command::Help>(), + std::make_shared<command::PluginInfo>(), + std::make_shared<command::PluginList>(), + std::make_shared<command::PluginLoad>(), + std::make_shared<command::PluginReload>(), + std::make_shared<command::PluginUnload>(), + std::make_shared<command::ServerChannelMode>(), + std::make_shared<command::ServerChannelNotice>(), + std::make_shared<command::ServerConnect>(), + std::make_shared<command::ServerDisconnect>(), + std::make_shared<command::ServerInfo>(), + std::make_shared<command::ServerInvite>(), + std::make_shared<command::ServerJoin>(), + std::make_shared<command::ServerKick>(), + std::make_shared<command::ServerList>(), + std::make_shared<command::ServerMe>(), + std::make_shared<command::ServerMessage>(), + std::make_shared<command::ServerMode>(), + std::make_shared<command::ServerNick>(), + std::make_shared<command::ServerNotice>(), + std::make_shared<command::ServerPart>(), + std::make_shared<command::ServerReconnect>(), + std::make_shared<command::ServerTopic>(), + std::make_shared<command::Watch>(), + } +{ +} + +bool CommandService::contains(const std::string &name) const noexcept +{ + return find(name) != nullptr; +} + +std::shared_ptr<RemoteCommand> CommandService::find(const std::string &name) const noexcept +{ + auto it = std::find_if(m_commands.begin(), m_commands.end(), [&] (const auto &cmd) { + return cmd->name() == name; + }); + + return it == m_commands.end() ? nullptr : *it; +} + +} // !irccd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lib/irccd/service-command.hpp Tue May 24 13:56:35 2016 +0200 @@ -0,0 +1,70 @@ +/* + * service-command.hpp -- store remote commands + * + * Copyright (c) 2013-2016 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef IRCCD_SERVICE_COMMAND_HPP +#define IRCCD_SERVICE_COMMAND_HPP + +/** + * \file service-command.hpp + * \brief Store remote commands. + */ + +#include <memory> +#include <vector> + +#include "sysconfig.hpp" + +namespace irccd { + +class RemoteCommand; + +/** + * \brief Store remote commands. + */ +class CommandService { +private: + std::vector<std::shared_ptr<RemoteCommand>> m_commands; + +public: + /** + * Default constructor. + * + * Populate the commands with predefined ones. + */ + IRCCD_EXPORT CommandService(); + + /** + * Tells if a command exists. + * + * \param name the command name + * \return true if the command exists + */ + IRCCD_EXPORT bool contains(const std::string &name) const noexcept; + + /** + * Find a command by name. + * + * \param name the command name + * \return the command or empty one if not found + */ + IRCCD_EXPORT std::shared_ptr<RemoteCommand> find(const std::string &name) const noexcept; +}; + +} // !irccd + +#endif // !IRCCD_SERVICE_COMMAND_HPP
--- a/lib/irccd/service-server.cpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/service-server.cpp Tue May 24 13:56:35 2016 +0200 @@ -21,6 +21,7 @@ #include <format.h> #include "irccd.hpp" +#include "json.hpp" #include "logger.hpp" #include "plugin.hpp" #include "server.hpp"
--- a/lib/irccd/service-transport.cpp Tue May 24 13:00:35 2016 +0200 +++ b/lib/irccd/service-transport.cpp Tue May 24 13:56:35 2016 +0200 @@ -16,8 +16,11 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include "command.hpp" #include "irccd.hpp" +#include "json.hpp" #include "logger.hpp" +#include "service-command.hpp" #include "service-transport.hpp" #include "transport-client.hpp" #include "transport-server.hpp" @@ -44,9 +47,9 @@ } // 2. Search for a command - auto it = m_irccd.commands().find(name->toString()); + auto cmd = m_irccd.commandService().find(name->toString()); - if (it == m_irccd.commands().end()) { + if (!cmd) { // TODO: send error again log::warning("command does not exists"); return; @@ -56,12 +59,11 @@ json::Value response = json::object({}); try { - response = it->second->exec(m_irccd, object); + response = cmd->exec(m_irccd, object); // Adjust if command has returned something else. - if (!response.isObject()) { + if (!response.isObject()) response = json::object({}); - } response.insert("status", true); } catch (const std::exception &ex) { @@ -70,7 +72,7 @@ } // 4. Store the command name result. - response.insert("response", it->first); + response.insert("response", name->toString()); // 5. Send the result. tc->send(response.toJson(0));