changeset 121:12d8f2d20c77

Irccd: merge all plugin data in Plugin class, #492
author David Demelier <markand@malikania.fr>
date Tue, 03 May 2016 21:28:34 +0200
parents 4cb417fd4e18
children 2aecbd638b1c
files lib/irccd/cmd-plugin-info.cpp lib/irccd/irccd.cpp lib/irccd/js-plugin.cpp lib/irccd/plugin.cpp lib/irccd/plugin.hpp lib/irccd/server-event.cpp
diffstat 6 files changed, 162 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/lib/irccd/cmd-plugin-info.cpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/cmd-plugin-info.cpp	Tue May 03 21:28:34 2016 +0200
@@ -52,10 +52,10 @@
 	auto plugin = irccd.requirePlugin(request.at("plugin").toString());
 	
 	return json::object({
-		{ "author",	plugin->info().author	},
-		{ "license",	plugin->info().license	},
-		{ "summary",	plugin->info().summary	},
-		{ "version",	plugin->info().version	}
+		{ "author",	plugin->author()	},
+		{ "license",	plugin->license()	},
+		{ "summary",	plugin->summary()	},
+		{ "version",	plugin->version()	}
 	});
 #else
 	(void)irccd;
--- a/lib/irccd/irccd.cpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/irccd.cpp	Tue May 03 21:28:34 2016 +0200
@@ -253,10 +253,10 @@
 #if defined(WITH_JS)
 	post(ServerEvent(server->info().name, origin, channel,
 		[=] (Plugin &plugin) -> std::string {
-			return util::parseMessage(message, server->settings().command, plugin.info().name).second == util::MessageType::Command ? "onCommand" : "onMessage";
+			return util::parseMessage(message, server->settings().command, plugin.name()).second == util::MessageType::Command ? "onCommand" : "onMessage";
 		},
 		[=] (Plugin &plugin) {
-			util::MessagePair pack = util::parseMessage(message, server->settings().command, plugin.info().name);
+			util::MessagePair pack = util::parseMessage(message, server->settings().command, plugin.name());
 
 			if (pack.second == util::MessageType::Command)
 				plugin.onCommand(std::move(server), std::move(origin), std::move(channel), std::move(pack.first));
@@ -481,10 +481,10 @@
 #if defined(WITH_JS)
 	post(ServerEvent(server->info().name, origin, /* channel */ "",
 		[=] (Plugin &plugin) -> std::string {
-			return util::parseMessage(message, server->settings().command, plugin.info().name).second == util::MessageType::Command ? "onQueryCommand" : "onQuery";
+			return util::parseMessage(message, server->settings().command, plugin.name()).second == util::MessageType::Command ? "onQueryCommand" : "onQuery";
 		},
 		[=] (Plugin &plugin) {
-			util::MessagePair pack = util::parseMessage(message, server->settings().command, plugin.info().name);
+			util::MessagePair pack = util::parseMessage(message, server->settings().command, plugin.name());
 
 			if (pack.second == util::MessageType::Command)
 				plugin.onQueryCommand(std::move(server), std::move(origin), std::move(pack.first));
@@ -861,9 +861,9 @@
 	/* Initial load now */
 	try {
 		plugin->onLoad();
-		m_plugins.insert({plugin->info().name, plugin});
+		m_plugins.insert({plugin->name(), plugin});
 	} catch (const std::exception &ex) {
-		log::warning(fmt::format("plugin {}: {}", plugin->info().name, ex.what()));
+		log::warning(fmt::format("plugin {}: {}", plugin->name(), ex.what()));
 	}
 }
 
@@ -964,7 +964,7 @@
 		auto plugin = ptr.lock();
 
 		if (plugin) {
-			log::debug() << "timer: finished, removing from plugin `" << plugin->info().name << "'" << std::endl;
+			log::debug() << "timer: finished, removing from plugin `" << plugin->name() << "'" << std::endl;
 			plugin->removeTimer(timer);
 		}
 	});
--- a/lib/irccd/js-plugin.cpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/js-plugin.cpp	Tue May 03 21:28:34 2016 +0200
@@ -67,16 +67,25 @@
  */
 duk::Ret info(duk::ContextPtr ctx)
 {
+	Plugin *plugin = nullptr;
+
 	if (duk::top(ctx) >= 1) {
-		try {
-			duk::push(ctx, duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->requirePlugin(duk::require<std::string>(ctx, 0))->info());
-		} catch (...) {
-			duk::push(ctx, duk::Undefined{});
-		}
+		plugin = duk::getGlobal<duk::RawPointer<Irccd>>(ctx, "\xff""\xff""irccd")->getPlugin(duk::require<std::string>(ctx, 0)).get();
 	} else {
-		duk::push(ctx, duk::getGlobal<duk::RawPointer<Plugin>>(ctx, "\xff""\xff""plugin")->info());
+		plugin = duk::getGlobal<duk::RawPointer<Plugin>>(ctx, "\xff""\xff""plugin");
+	}
+
+	if (!plugin) {
+		return 0;
 	}
 
+	duk::push(ctx, duk::Object{});
+	duk::putProperty(ctx, -1, "name", plugin->name());
+	duk::putProperty(ctx, -1, "author", plugin->author());
+	duk::putProperty(ctx, -1, "license", plugin->license());
+	duk::putProperty(ctx, -1, "summary", plugin->summary());
+	duk::putProperty(ctx, -1, "version", plugin->version());
+
 	return 1;
 }
 
--- a/lib/irccd/plugin.cpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/plugin.cpp	Tue May 03 21:28:34 2016 +0200
@@ -73,13 +73,12 @@
 
 void Plugin::putVars()
 {
-	duk::StackAssert sa{m_context};
+	duk::StackAssert sa(m_context);
 
 	/* Save a reference to this */
 	duk::putGlobal(m_context, "\xff""\xff""plugin", duk::RawPointer<Plugin>{this});
-	duk::putGlobal(m_context, "\xff""\xff""name", m_info.name);
-	duk::putGlobal(m_context, "\xff""\xff""path", m_info.path);
-	duk::putGlobal(m_context, "\xff""\xff""parent", m_info.parent);
+	duk::putGlobal(m_context, "\xff""\xff""name", m_name);
+	duk::putGlobal(m_context, "\xff""\xff""path", m_path);
 }
 
 void Plugin::putPath(const std::string &varname, const std::string &append, path::Path type)
@@ -120,9 +119,9 @@
 	 * dataPath: DATA + plugin/name (e.g ~/.local/share/irccd/plugins/<name>/)
 	 * configPath: CONFIG + plugin/name (e.g ~/.config/irccd/plugin/<name>/)
 	 */
-	putPath("dataPath", "plugin/" + m_info.name, path::PathData);
-	putPath("configPath", "plugin/" + m_info.name, path::PathConfig);
-	putPath("cachePath", "plugin/" + m_info.name, path::PathCache);
+	putPath("dataPath", "plugin/" + m_name, path::PathData);
+	putPath("configPath", "plugin/" + m_name, path::PathConfig);
+	putPath("cachePath", "plugin/" + m_name, path::PathCache);
 }
 
 void Plugin::putConfig(const PluginConfig &config)
@@ -150,12 +149,11 @@
 }
 
 Plugin::Plugin(std::string name, std::string path, const PluginConfig &config)
+	: m_name(std::move(name))
+	, m_path(std::move(path))
 {
 	duk::StackAssert sa(m_context);
 
-	m_info.name = std::move(name);
-	m_info.path = std::move(path);
-
 	/*
 	 * Duktape currently emit useless warnings when a file do
 	 * not exists so we do a homemade access.
@@ -163,11 +161,14 @@
 #if defined(HAVE_STAT)
 	struct stat st;
 
-	if (stat(m_info.path.c_str(), &st) < 0) {
+	if (stat(m_path.c_str(), &st) < 0) {
 		throw std::runtime_error(std::strerror(errno));
 	}
 #endif
 
+#if 0
+	// TODO: not enabled now
+
 	/*
 	 * Store the base path to the plugin, it is required for
 	 * Duktape.modSearch to find external modules and other
@@ -181,6 +182,7 @@
 	} else {
 		m_info.parent = fs::cwd();
 	}
+#endif
 
 	/* Load standard irccd API */
 	loadJsIrccd(m_context);
@@ -199,7 +201,7 @@
 	putPaths();
 
 	/* Try to load the file (does not call onLoad yet) */
-	if (duk::pevalFile(m_context, m_info.path) != 0) {
+	if (duk::pevalFile(m_context, m_path) != 0) {
 		throw duk::error(m_context, -1);
 	}
 
@@ -212,19 +214,19 @@
 	duk::getGlobal<void>(m_context, "info");
 
 	if (duk::type(m_context, -1) == DUK_TYPE_OBJECT) {
-		m_info.author = duk::optionalProperty<std::string>(m_context, -1, "author", "unknown");
-		m_info.license = duk::optionalProperty<std::string>(m_context, -1, "license", "unknown");
-		m_info.summary = duk::optionalProperty<std::string>(m_context, -1, "summary", "unknown");
-		m_info.version = duk::optionalProperty<std::string>(m_context, -1, "version", "unknown");
+		m_author = duk::optionalProperty<std::string>(m_context, -1, "author", m_author);
+		m_license = duk::optionalProperty<std::string>(m_context, -1, "license", m_license);
+		m_summary = duk::optionalProperty<std::string>(m_context, -1, "summary", m_summary);
+		m_version = duk::optionalProperty<std::string>(m_context, -1, "version", m_version);
 	}
 
 	duk::pop(m_context);
 
-	log::debug() << "plugin " << m_info.name << ": " << std::endl;
-	log::debug() << "  author:  " << m_info.author << std::endl;
-	log::debug() << "  license: " << m_info.license << std::endl;
-	log::debug() << "  summary: " << m_info.summary << std::endl;
-	log::debug() << "  version: " << m_info.version << std::endl;
+	log::debug() << "plugin " << m_name << ": " << std::endl;
+	log::debug() << "  author:  " << m_author << std::endl;
+	log::debug() << "  license: " << m_license << std::endl;
+	log::debug() << "  summary: " << m_summary << std::endl;
+	log::debug() << "  version: " << m_version << std::endl;
 }
 
 Plugin::~Plugin()
@@ -234,11 +236,6 @@
 	}
 }
 
-const PluginInfo &Plugin::info() const
-{
-	return m_info;
-}
-
 void Plugin::addTimer(std::shared_ptr<Timer> timer) noexcept
 {
 	std::weak_ptr<Timer> ptr(timer);
@@ -490,20 +487,4 @@
 	call("onWhois", 2);
 }
 
-namespace duk {
-
-void TypeTraits<irccd::PluginInfo>::push(ContextPtr ctx, const PluginInfo &info)
-{
-	duk::StackAssert sa(ctx, 1);
-
-	duk::push(ctx, duk::Object{});
-	duk::putProperty(ctx, -1, "name", info.name);
-	duk::putProperty(ctx, -1, "author", info.author);
-	duk::putProperty(ctx, -1, "license", info.license);
-	duk::putProperty(ctx, -1, "summary", info.summary);
-	duk::putProperty(ctx, -1, "version", info.version);
-}
-
-} // !js
-
 } // !irccd
--- a/lib/irccd/plugin.hpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/plugin.hpp	Tue May 03 21:28:34 2016 +0200
@@ -41,23 +41,6 @@
 class ServerWhois;
 
 /**
- * \class PluginInfo
- * \brief Plugin information
- */
-class PluginInfo {
-public:
-	std::string name;		//!< plugin name (from file on disk)
-	std::string parent;		//!< parent directory
-	std::string path;		//!< full path to the plugin file
-
-	/* Metadata */
-	std::string author{"unknown"};	//!< plugin author
-	std::string license{"unknown"};	//!< plugin license
-	std::string summary{"unknown"};	//!< short plugin description
-	std::string version{"unknown"};	//!< plugin version
-};
-
-/**
  * Configuration map extract from config file.
  */
 using PluginConfig = std::unordered_map<std::string, std::string>;
@@ -99,14 +82,23 @@
 	Signal<std::shared_ptr<Timer>> onTimerEnd;
 
 private:
-	/* JavaScript context */
+	// Plugin information
+	std::string m_name;
+	std::string m_path;
+
+	// Metadata
+	std::string m_author{"unknown"};
+	std::string m_license{"unknown"};
+	std::string m_summary{"unknown"};
+	std::string m_version{"unknown"};
+
+	// JavaScript context
 	duk::Context m_context;
 
-	/* Plugin info and its timers */
-	PluginInfo m_info;
+	// Plugin info and its timers
 	PluginTimers m_timers;
 
-	/* Private helpers */
+	// Private helpers
 	void call(const std::string &name, unsigned nargs = 0);
 	void putVars();
 	void putPath(const std::string &varname, const std::string &append, path::Path type);
@@ -115,7 +107,7 @@
 
 public:
 	/**
-	 * Correct constructor.
+	 * Constructor.
 	 *
 	 * \param name the plugin id
 	 * \param path the fully resolved path to the plugin
@@ -130,9 +122,105 @@
 	~Plugin();
 
 	/**
-	 * Get the plugin information.
+	 * Get the plugin name.
+	 *
+	 * \return the plugin name
+	 */
+	inline const std::string &name() const noexcept
+	{
+		return m_name;
+	}
+
+	/**
+	 * Get the plugin path.
+	 *
+	 * \return the plugin path
+	 * \note some plugins may not exist on the disk
+	 */
+	inline const std::string &path() const noexcept
+	{
+		return m_path;
+	}
+
+	/**
+	 * Get the author.
+	 *
+	 * \return the author
+	 */
+	inline const std::string &author() const noexcept
+	{
+		return m_author;
+	}
+
+	/**
+	 * Set the author.
+	 *
+	 * \param author the author
+	 */
+	inline void setAuthor(std::string author) noexcept
+	{
+		m_author = std::move(author);
+	}
+
+	/**
+	 * Get the license.
+	 *
+	 * \return the license
 	 */
-	const PluginInfo &info() const;
+	inline const std::string &license() const noexcept
+	{
+		return m_license;
+	}
+
+	/**
+	 * Set the license.
+	 *
+	 * \param license the license
+	 */
+	inline void setLicense(std::string license) noexcept
+	{
+		m_license = std::move(license);
+	}
+
+	/**
+	 * Get the summary.
+	 *
+	 * \return the summary
+	 */
+	inline const std::string &summary() const noexcept
+	{
+		return m_summary;
+	}
+
+	/**
+	 * Set the summary.
+	 *
+	 * \param summary the summary
+	 */
+	inline void setSummary(std::string summary) noexcept
+	{
+		m_summary = std::move(summary);
+	}
+
+	/**
+	 * Get the version.
+	 *
+	 * \return the version
+	 */
+	inline const std::string &version() const noexcept
+	{
+		return m_version;
+	}
+
+	/**
+	 * Set the version.
+	 *
+	 * \param version the version
+	 */
+	inline void setVersion(std::string version) noexcept
+	{
+		m_version = std::move(version);
+	}
 
 	/**
 	 * Add a timer to the plugin.
@@ -345,25 +433,6 @@
 	void onWhois(std::shared_ptr<Server> server, ServerWhois info);
 };
 
-namespace duk {
-
-/**
- * \brief Push plugin information.
- */
-template <>
-class TypeTraits<irccd::PluginInfo> {
-public:
-	/**
-	 * Push the plugin information as JavaScript object.
-	 *
-	 * \param ctx the context
-	 * \param info the plugin information
-	 */
-	static void push(ContextPtr ctx, const PluginInfo &info);
-};
-
-} // !duk
-
 } // !irccd
 
 #endif // !IRCCD_PLUGIN_HPP
--- a/lib/irccd/server-event.cpp	Tue May 03 13:51:57 2016 +0200
+++ b/lib/irccd/server-event.cpp	Tue May 03 21:28:34 2016 +0200
@@ -51,7 +51,7 @@
 		try {
 			m_plugin_exec(*pair.second);
 		} catch (const duk::ErrorInfo &info) {
-			log::warning() << "plugin " << pair.second->info().name << ": error: " << info.what() << std::endl;
+			log::warning() << "plugin " << pair.second->name() << ": error: " << info.what() << std::endl;
 
 			if (!info.fileName.empty()) {
 				log::warning() << "    " << info.fileName << ":" << info.lineNumber << std::endl;