--[[
DESCRIPTION
This is a demo config file to show, what you can do with lua.
Feature list:
XEP-0004 Forms parsing and filling
XEP-0030 Info/items discovery requests (mcabber already can do replies)
XEP-0047 In-Bound Byte Streams (sending, receiving, saving with specified name, rejecting)
XEP-0077 In-Band Registration (only registration, but with data forms too)
XEP-0146 Remote commands requests
Jobs (actions, fired when some event occurs, now in one file, updated on exit)
Room nicks completion
MPD status polling (can be turned off)
Beep on all messages, even on chatroom ones
Url saving to file (for urlview)
Transported buddies availability indication
Actions on multiple marked buddies
Fallback commands (localized also! :) )
Help for fallback commands (well, I know, that it can be done with mcabber's help system, but it requires access to system files...)
All features have native mcabber interface
REQUIREMENTS
liblua-loudmouth (lm.lua and loudmouth.so)
liblua-socket - mpd
NOTES
Ibb uses own iq handler. This is the laziest way to implement this.
BUILTINS
print (global) - prints to log/status/logwindow
dofile (global) - loads lua file from default mcabber location
main methods:
- run - run literal mcabber command
- beep - beep
- log - print to log w/specified priority
- print_info - print info into specified buffer
- config_file - format full file name from relative to mcabber's config dir
- status - get current user status and message
- roster - get list of roster jids (rooms, buddies and agents)
- current_buddy - get jid of current buddy
- buddy_info - get table with info about jid and its resources
- connection - get lightuserdata for mcabber's lm connection
- timer - run function periodically
- bgread - run command and read it's output in background
- add_feature - add string to feature list (for disco#info)
- del_feature - delete string from feature list
- add_completion - adds word to completions
- del_completion - removes word from completions
- command - adds/removes mcabber command
- option - sets/gets mcabber option
STRUCTURE
To allow your chunk of configuration (eg foo.lua) to play friendly with other, do:
- place it into a separate file, eg foo.lua
- if you need hooks, do
hook_d[hookname].foo = function ( args ) foo ( ) end
- if you register commands, also do
commands_help['foo'] = "arg1 arg2\n\nFoo does bar."
- append to the end of this file
dopath 'foo'
- try to be friendly to module reloads, eg unregister handlers, where appropriate,
reset bindings
- you can omit unregistering of commands and xmpp features - module will unregister
them automatically.
- for now you can use parse_args and rebuild_args_string to deal with argument string,
but this is likely to be replaced with something more perfect.
--]]
-- This is a hack to allow loading of lm.lua and loudmouth.so from ~/.mcabber
-- instead of installing them system-wide
package.path = main.config_file ( '?.lua' ) .. ';' .. package.path
package.cpath = main.config_file ( '?.so' ) .. ';' .. package.cpath
require 'lm'
-- COMMON SUPPORT ROUTINES
function shell_escape ( str )
if str then
return "'" .. str:gsub ( "'", "'\\''" ) .. "'"
else
return "''"
end
end
-- This is for debugging purposes, for real reloading need to quote and bracket keys.
function table_to_string ( tab, pre )
local prefix = pre or ""
local tbls, jk = "", ""
for key, val in pairs ( tab ) do
if type ( val ) == 'table' then
tbls = string.format ( "%s %s%s = %s,\n", tbls, prefix, tostring(key), table_to_string ( val, " " .. prefix ) )
else
jk = string.format ( "%s %s = %q,", jk, tostring(key), tostring(val) )
end
end
if tbls == "" then
return string.format ( "{%s }", jk:sub ( 1, -2 ) )
else
return string.format ( "{%s\n%s%s}", jk, tbls, prefix )
end
end
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
return true
elseif value == 'disable' or value == 'no' or value == 'false' or value == 'off' or value == false then
return false
else
return nil
end
end
-- FIXME: eats spaces
function parse_args ( args )
local ret = {}
local still_opts = true
local optname
local option = false
for word in args:gmatch ( "%S+" ) do
if still_opts and not option and word:sub ( 1, 1 ) == '-' then
option = true
optname = word:sub ( 2 )
elseif option then
ret[optname] = word
option = false
else
still_opts = false
table.insert ( ret, word )
end
end
return ret
end
-- FIXME: get rid of this
function rebuild_args_string ( tab )
local flags = nil
local args = nil
for k, v in pairs (tab) do
if type (k) == 'number' then
if args then
args = args .. ' ' .. v
else
args = v
end
else
if flags then
flags = flags .. ' ' .. '-' .. k .. ' ' .. v
else
flags = '-' .. k .. ' ' .. v
end
end
end
if flags and args then
return flags .. ' ' .. args
elseif flags then
return flags
elseif args then
return args
else
return ''
end
end
-- COMMANDS
-- Help strings should not contain command, only arguments. This is necessary to support soft aliases.
commands_help = {
post = "filename\n\nSends file as a message. Just shorthand.",
s = "status [message]\n\nSets your status, but takes into account mpd (if enabled).",
beep = "[enable|disable|on|off|yes|no|true|false]\n\nEnables or disables beeping on all messages.\nIf state is omitted, prints current state.",
cmd = "shell_command\n\nRuns shell command in background and sends output to current buddy.\nWorks asynchroneously, and may break long output in the middle of line",
exthelp = "[command]\n\nPrints help for a given command, or list of available help topics.",
reload = "\n\nJust a shorthand to reload lua config file. Note, that for now this discards all changes to configuration, open forms, transferred files.",
['join!'] = "\n\nForcibly joins to current buddy. Just saves you typing of full room name (that can be quite long) in a case of a non-bookmarked rooms.",
count = "\n\nPrints number of resources of current buddy. Useful to determine member count of large room.",
toggle = "\n\nToggles away/online status.",
}
main.command ( 'post',
function ( args )
main.run ( 'say_to -f ' .. args .. ' .' )
end, 'filename' )
main.command ( 's',
function ( args )
main.run ( ('status %s %s'):format ( args, mpd_getstatus () ) )
end, 'status' )
main.command ( 'cmd',
function ( args )
local to = main.current_buddy ()
main.run ( ('send_to -q %q $ %s'):format ( to, args ) )
main.bgread ( args,
function ( data )
if data then
main.run ( ('send_to -q %q %s'):format ( to, data ) )
return true
else
return false
end
end )
end, 'filename' )
main.command ( 'exthelp',
function ( args )
if commands_help[args] then
print ( "\n /" .. args .. ' ' .. commands_help[args] )
else
print ( "No help for this command." )
list = "Help available for commands: "
for k in pairs (commands_help) do
list = list .. k .. ', '
end
print ( list:sub ( 1, -3 ) )
print ( "For built-in mcabber commands see /help" )
end
end, 'cmd' )
main.command ( 'reload',
function ( args )
dofile ( main.config_file ( 'mcabberrc.lua' ) )
end )
main.command ( 'join!',
function ( args )
main.run ( 'room join ' .. main.current_buddy () )
end )
main.command ( 'count',
function ( args )
local count = 0
for resource in pairs ( main.buddy_info ( main.current_buddy () ).resources ) do
count = count + 1
end
print ( "Resource count: " .. count )
end )
main.command ( 'toggle',
function ( args )
local stat, mess = main.status ()
if stat == 'o' then
main.run ( 'status away ' .. mess )
else
main.run ( 'status online ' .. mess )
end
end )
-- commands to allow leading smileys
for k, arg in ipairs ( { ')', '/', '(', 'D', '-/', 'S', '1', ']', '[' } ) do
main.command ( arg,
function ( args )
main.run ( 'say :' .. arg .. ' ' .. args )
end )
end
-- HOOKS
hooks_d = {
['hook-message-in'] = { },
['hook-message-out'] = { },
['hook-status-change'] = { },
['hook-my-status-change'] = { },
['hook-post-connect'] = { },
['hook-pre-disconnect'] = { },
['hook-start'] = { },
['hook-quit'] = { },
}
-- hook:
-- - hook-message-in
-- jid
-- groupchat
-- message
-- - hook-message-out
-- jid
-- message
-- - hook-status-change
-- jid
-- resource
-- new_status
-- old_status
-- message
-- - hook-my-status-change
-- new_status
-- message
-- - hook-post-connect
-- - hook-pre-disconnect
-- - hook-start
-- - hook-quit
function hook_handler ( args )
for mod, cb in pairs ( hooks_d[args.hook] ) do
if cb then
cb ( args )
end
end
end
-- SAVING URLS TO FILE
dopath 'urls'
-- TRANSPORTED BUDDIES AVAILABILITY INDICATION
dopath 'transports'
-- BEEPING ON ALL MESSAGES
dopath 'beep'
-- MARKING
dopath 'marking'
-- MPD
dopath 'mpd'
-- FORMS (XEP-0004)
dopath 'xep0004'
-- DISCO (XEP-0030)
dopath 'xep0030'
-- IBB (XEP-0047)
dopath 'xep0047'
-- IN-BAND REGISTRATION (XEP-0077)
dopath 'xep0077'
-- REMOTE CONTROLLING CLIENTS (XEP-0146)
dopath 'xep0146'
-- JOBS
dopath 'jobs'
-- ROOM NICK COMPLETION
dopath 'room_priv'
-- The End -- vim: se ts=4: --