Hooks unification
* hook naming scheme unification
* one handler for all
* handler name from option
* multiple transports
* dopath returns error message
--- a/CMakeLists.txt Mon Feb 23 23:23:42 2009 +0200
+++ b/CMakeLists.txt Tue Feb 24 09:14:00 2009 +0200
@@ -6,7 +6,6 @@
option(DEBUG "Enable debugging output" ON)
option(LLM_LOG_HANDLER "Enable registration of log messages handler for lua-loudmouth library's messages" ON)
set(MCABBER_INCLUDE_DIR "/home/isbear/src/mcabber/hglm/mcabber/src" CACHE FILEPATH "Path to mcabber headers")
-set(LUA_HOOK_NAME "hook_handler" CACHE STRING "Lua function name to be called on hook invocation")
## Define targets
add_library(mcabber-lua MODULE main.c util.c)
--- a/TODO Mon Feb 23 23:23:42 2009 +0200
+++ b/TODO Tue Feb 24 09:14:00 2009 +0200
@@ -5,4 +5,5 @@
non-setting settings?
set package searching paths?
do uninitialization of commands and features with objects?
+debug module reloading issue
--- a/config.h.in Mon Feb 23 23:23:42 2009 +0200
+++ b/config.h.in Tue Feb 24 09:14:00 2009 +0200
@@ -8,9 +8,6 @@
// define this to enable lua-loudmouth log messages handler
#cmakedefine LLM_LOG_HANDLER
-// define this to a lua function name that will handle hooks
-#define LUA_HOOK_NAME ( "${LUA_HOOK_NAME}" )
-
// hack for mcabber headers
#define MODULES_ENABLE
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/lua.rc Tue Feb 24 09:14:00 2009 +0200
@@ -0,0 +1,5 @@
+
+# lua function name to be called on hooks invocation
+set lua_hook_function = hook_handler
+load mcabber-lua
+
--- a/examples/mcabberrc.lua Mon Feb 23 23:23:42 2009 +0200
+++ b/examples/mcabberrc.lua Tue Feb 24 09:14:00 2009 +0200
@@ -69,9 +69,9 @@
-- OPTIONS, COMMON SUPPORT ROUTINES
-url_file = main.config_file ( 'urls.log' )
-transport_jid = 'icq.jabber.kiev.ua' -- TODO: allow multiple transports
-beep_enable = false
+url_file = main.config_file ( 'urls.log' )
+transport_jids = { 'icq.jabber.kiev.ua', 'mrim.unixzone.org.ua' }
+beep_enable = false
-- XXX: to C?
char2status = {
@@ -135,7 +135,18 @@
end
end
--- COMMANDS
+function online ( jid )
+ local info = main.buddy_info ( jid )
+ if not info then
+ return false
+ end
+ for resource, params in pairs ( info.resources ) do
+ if params.status ~= '_' then
+ return true
+ end
+ end
+ return false
+end
function yesno ( value )
if value == 'enable' or value == 'yes' or value == 'true' or value == 'on' or value == true then
@@ -168,6 +179,8 @@
return ret
end
+-- COMMANDS
+
-- Help strings should not contain command, only arguments. This is necessary to support soft aliases.
commands_help = {
file = "filename\n\nSends file as a message. Just shorthand.",
@@ -289,7 +302,6 @@
delayed_jobs = {}
--- FIXME: do only if it exists
dopath 'jobs.lua'
function save_jobs ()
@@ -353,55 +365,31 @@
ibb_handler_registered = false
--- Soft hooks, implemented through mcabber options
-function hook_post_connect ()
- main.run ( 'group fold テフノ' )
- main.run ( 'group fold にゃ' )
- main.run ( 'group fold にゃ - Друзі' )
-
- main.run ( 'color muc * on' )
-
- main.run ( ("color roster * *@%s red"):format ( transport_jid ) )
- main.run ( ("color roster dn_? *@%s red"):format ( transport_jid ) )
-
- if mpd_enabled then
- mpd_callback ()
- end
-
- -- FIXME
- if not ibb_handler_registered then
- lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
- main.add_feature ( 'http://jabber.org/protocol/ibb' )
- ibb_handler_registered = true
- end
-end
-
-function hook_pre_disconnect ()
- main.run ( ("color roster * *@%s white"):format ( transport_jid ) )
- main.run ( ("color roster dn_? *@%s brightblack"):format ( transport_jid ) )
-end
-
-- Hard hooks, implemented in C
--- hook
--- - message_in
+-- hook:
+-- - hook-message-in
-- jid
-- groupchat
-- message
--- - message_out
+-- - hook-message-out
-- jid
-- message
--- - status_change
+-- - hook-status-change
-- jid
-- resource
-- new_status
-- old_status
-- message
--- - my_status_change
+-- - hook-my-status-change
-- new_status
-- message
+-- - hook-post-connect
+-- - hook-pre-disconnect
+-- - hook-start
+-- - hook-quit
function hook_handler ( args )
- if args.hook == 'message_in' then
+ if args.hook == 'hook-message-in' then
-- beep on ALL messages, no matter, is it chat or something else.
if beep_enable then
@@ -419,7 +407,7 @@
end
end
- elseif args.hook == 'status_change' then
+ elseif args.hook == 'hook-status-change' then
-- delayed actions
if delayed_jobs[args.jid] and delayed_jobs[args.jid][args.new_status] then
@@ -428,29 +416,55 @@
end
-- transported buddies availability indication
- if args.jid == transport_jid then
- if args.new_status == '_' then
- main.run ( ("color roster * *@%s red"):format ( transport_jid ) )
- main.run ( ("color roster dn_? *@%s red"):format ( transport_jid ) )
+ for k, jid in pairs ( transport_jids ) do
+ if args.jid == jid then
+ if args.new_status == '_' then
+ main.run ( ("color roster * *@%s red"):format ( jid ) )
+ main.run ( ("color roster dn_? *@%s red"):format ( jid ) )
+ else
+ main.run ( ("color roster * *@%s white"):format ( jid ) )
+ main.run ( ("color roster dn_? *@%s brightblack"):format ( jid ) )
+ end
+ end
+ end
+
+ elseif args.hook == 'hook-post-connect' then
+
+ if mpd_enabled then
+ mpd_callback ()
+ end
+
+ -- FIXME
+ if not ibb_handler_registered then
+ lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq', 'normal' )
+ main.add_feature ( 'http://jabber.org/protocol/ibb' )
+ ibb_handler_registered = true
+ end
+
+ elseif args.hook == 'hook-start' then
+
+ -- XXX: for some reason, after module reloading, this is not working properly.
+ for k, jid in pairs ( transport_jids ) do
+ if not online ( jid ) then
+ main.run ( ("color roster * *@%s red"):format ( jid ) )
+ main.run ( ("color roster dn_? *@%s red"):format ( jid ) )
else
- main.run ( ("color roster * *@%s white"):format ( transport_jid ) )
- main.run ( ("color roster dn_? *@%s brightblack"):format ( transport_jid ) )
+ main.run ( ("color roster * *@%s white"):format ( jid ) )
+ main.run ( ("color roster dn_? *@%s brightblack"):format ( jid ) )
end
end
+ elseif args.hook == 'hook-quit' then
+
+ save_jobs ()
+
+ -- FIXME
+ if ibb_handler_registered then
+ lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
+ end
+
end
end
--- (hook_start)
-
-function hook_quit ()
- save_jobs ()
-
- -- FIXME
- if ibb_handler_registered then
- lm.connection.bless( main.connection () ):handler ( ibb_incoming_iq_handler, 'iq' )
- end
-end
-
-- The End -- vim: se ts=4: --
--- a/main.c Mon Feb 23 23:23:42 2009 +0200
+++ b/main.c Tue Feb 24 09:14:00 2009 +0200
@@ -46,11 +46,13 @@
/// dopath
/// Loads lua file from default location.
/// A: string (filename, without ".lua")
+/// R: string (error message, optional)
static int lua_global_dopath (lua_State *L)
{
const char *name = luaL_checkstring (L, 1);
size_t size = lua_objlen (L, 1);
char *path;
+ int ret = 0;
if (!strncmp (name + size - 4, ".lua", 4))
path = mcabber_config_filename (name);
else {
@@ -59,13 +61,16 @@
g_free (fname);
}
- if (luaL_loadfile (L, path))
+ if (ret = luaL_loadfile (L, path))
scr_LogPrint (LPRINT_LOGNORM, "lua: Unable to compile file %s: %s", path, lua_tostring (L, -1));
- else if (lua_pcall (lua, 0, LUA_MULTRET, 0))
+ else if (ret = lua_pcall (lua, 0, LUA_MULTRET, 0))
scr_LogPrint(LPRINT_LOGNORM, "lua: Runtime error in file %s: %s", path, lua_tostring (L, -1));
+ g_free (path);
- g_free (path);
- return 0;
+ if (ret)
+ return 1;
+ else
+ return 0;
}
/// main.config_file
@@ -533,14 +538,13 @@
}
#endif
-#ifndef LUA_HOOK_NAME
-#define LUA_HOOK_NAME ( "hook_handler" )
-#endif
-
static void lua_hook (hk_arg_t *args, lua_State *L)
{
hk_arg_t *arg = args;
- lua_getglobal (lua, LUA_HOOK_NAME);
+ const char *hook = settings_opt_get ("lua_hook_function");
+ if (!hook)
+ return;
+ lua_getglobal (lua, hook);
if (!lua_isfunction (lua, -1)) {
lua_pop (lua, 1);
return;
@@ -553,7 +557,7 @@
arg++;
}
if (lua_pcall (lua, 1, 0, 0)) {
- scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_handler: %s", lua_tostring (lua, -1));
+ scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook handler: %s", lua_tostring (lua, -1));
lua_pop (lua, 1);
}
}
@@ -626,13 +630,14 @@
hk_add_handler ((hk_handler_t) lua_hook, lua);
- lua_getglobal (lua, "hook_start");
- if (!lua_isfunction (lua, -1))
- lua_pop (lua, 1);
- else if (lua_pcall (lua, 0, 0, 0)) {
- scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_start: %s", lua_tostring (lua, -1));
- lua_pop (lua, 1);
+ {
+ hk_arg_t args[] = {
+ { "hook", "hook-start" },
+ { NULL, NULL },
+ };
+ lua_hook (args, lua);
}
+
return NULL;
}
@@ -655,13 +660,11 @@
void g_module_unload (GModule *module)
{
if (lua) {
- lua_getglobal (lua, "hook_quit");
- if (!lua_isfunction (lua, -1))
- lua_pop (lua, 1);
- else if (lua_pcall (lua, 0, 0, 0)) {
- scr_LogPrint (LPRINT_NORMAL, "lua: Error in hook_quit: %s", lua_tostring (lua, -1));
- lua_pop (lua, 1);
- }
+ hk_arg_t args[] = {
+ { "hook", "hook-quit" },
+ { NULL, NULL },
+ };
+ lua_hook (args, lua);
hk_del_handler ((hk_handler_t) lua_hook, lua);