summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Sluift/core.lua33
-rw-r--r--Sluift/sluift.cpp2
2 files changed, 25 insertions, 10 deletions
diff --git a/Sluift/core.lua b/Sluift/core.lua
index 48b8a97..ecd3c5e 100644
--- a/Sluift/core.lua
+++ b/Sluift/core.lua
@@ -410,70 +410,91 @@ local function get_by_type(table, typ)
end
local function register_get_by_type_index(table)
if type(table) == 'table' then
local metatable = getmetatable(table)
if not metatable then
metatable = {}
setmetatable(table, metatable)
end
metatable.__index = get_by_type
end
return table
end
local function call(options)
local f = options[1]
local result = { xpcall(f, debug.traceback) }
if options.finally then
options.finally()
end
if result[1] then
table.remove(result, 1)
return unpack(result)
else
error(result[2])
end
end
local function read_file(file)
local f = io.open(file, 'rb')
local result = f:read('*all')
f:close()
return result
end
+_H = {
+ [[ Generate a form table, suitable for PubSubConfiguration and MAMQuery ]],
+ parameters = { {"fields", "The fields that will be converted into a form table"},
+ {"form_type", "If specified, add a form_type field with this value"},
+ {"type", "Form type, e.g. 'submit'"} }
+}
+local function create_form(fields, ...)
+ local options = parse_options({}, ...)
+ local result = { fields = {} }
+ for var, value in pairs(fields) do
+ result.fields[#result.fields+1] = { name = var, value = value }
+ end
+ if options.form_type then
+ result.fields[#result.fields+1] = { name = 'form_type', value = form_type }
+ end
+ if options.type then
+ result['type'] = type
+ end
+ return result
+end
+
--------------------------------------------------------------------------------
-- Metatables
--------------------------------------------------------------------------------
_H = {
[[ Client interface ]]
}
local Client = {
_with_prompt = function(client) return client:jid() end
}
Client.__index = Client
register_class_table_help(Client, "Client")
_H = {
[[ Interface to communicate with a PubSub service ]]
}
local PubSub = {}
PubSub.__index = PubSub
register_class_table_help(PubSub, "PubSub")
_H = {
[[ Interface to communicate with a PubSub node on a service ]]
}
local PubSubNode = {}
PubSubNode.__index = PubSubNode
register_class_table_help(PubSubNode, "PubSubNode")
--------------------------------------------------------------------------------
-- with
--------------------------------------------------------------------------------
local original_G
@@ -777,78 +798,71 @@ function PubSub:node (node)
local result = { client = self.client, jid = self.jid, node = node }
setmetatable(result, PubSubNode)
return result
end
local simple_pubsub_queries = {
get_default_configuration = 'pubsub_owner_default',
get_subscriptions = 'pubsub_subscriptions',
get_affiliations = 'pubsub_affiliations',
get_default_subscription_options = 'pubsub_default',
}
for method, query_type in pairs(simple_pubsub_queries) do
PubSub[method] = function (service, options)
options = options or {}
return service.client:query_pubsub(merge_tables(
{ type = 'get', to = service.jid, query = { _type = query_type } },
options))
end
end
for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do
PubSub[method] = function (node, ...)
local options = parse_options({}, ...)
options['if'] = function (event)
return event.type == 'pubsub' and event.from == node.jid and event.node == node
end
return node.client[method](node.client, options)
end
end
--------------------------------------------------------------------------------
-- PubSubNode
--------------------------------------------------------------------------------
local function pubsub_node_configuration_to_form(configuration)
- if not configuration then
- return
- end
- local fields = { {name = 'form_type', value = 'http://jabber.org/protocol/pubsub#node_config'} }
- for var, value in pairs(configuration) do
- fields[#fields+1] = { name = var, value = value }
- end
- return { type = "submit", fields = fields }
+ return create_form{configuration, form_type="http://jabber.org/protocol/pubsub#node_config", type="submit"}
end
function PubSubNode:list_items (options)
return self.client:get_disco_items(merge_tables({to = self.jid, disco_items = { node = self.node }}, options))
end
local simple_pubsub_node_queries = {
get_configuration = 'pubsub_owner_configure',
get_subscriptions = 'pubsub_subscriptions',
get_affiliations = 'pubsub_affiliations',
get_owner_subscriptions = 'pubsub_owner_subscriptions',
get_owner_affiliations = 'pubsub_owner_affiliations',
get_default_subscription_options = 'pubsub_default',
}
for method, query_type in pairs(simple_pubsub_node_queries) do
PubSubNode[method] = function (node, options)
return node.client:query_pubsub(merge_tables({
type = 'get', to = node.jid, query = {
_type = query_type, node = node.node
}}, options))
end
end
function PubSubNode:get_items (...)
local options = parse_options({}, ...)
local items = options.items or {}
if options.maximum_items then
items = merge_tables({maximum_items = options.maximum_items}, items)
end
items = merge_tables({_type = 'pubsub_items', node = self.node}, items)
return self.client:query_pubsub(merge_tables({
type = 'get', to = self.jid, query = items}, options))
end
function PubSubNode:get_item (...)
@@ -986,37 +1000,38 @@ local disco = {
USER_AVATAR_METADATA = 'urn:xmpp:avatar:metadata',
USER_ACTIVITY = 'http://jabber.org/protocol/activity',
USER_PROFILE = 'urn:xmpp:tmp:profile'
}
}
--------------------------------------------------------------------------------
_H = nil
extra_help['sluift'] = {
[[
This module provides methods for XMPP communication.
The main entry point of this module is the `new_client` method, which creates a
new client for communicating with an XMPP server.
]],
classes = help_classes
}
return {
Client = Client,
register_help = register_help,
register_class_help = register_class_help,
register_table_tostring = register_table_tostring,
register_table_equals = register_table_equals,
register_get_by_type_index = register_get_by_type_index,
process_pubsub_event = process_pubsub_event,
tprint = tprint,
read_file = read_file,
disco = disco,
get_help = get_help,
help = help,
extra_help = extra_help,
copy = copy,
- with = with
+ with = with,
+ create_form = create_form
}
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index a04ceeb..b55649b 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -359,65 +359,65 @@ SLUIFT_API int luaopen_sluift(lua_State* L) {
luaL_register(L, lua_tostring(L, 1), sluift_functions);
lua_pushinteger(L, -1);
lua_setfield(L, -2, "timeout");
lua_pushboolean(L, 0);
lua_setfield(L, -2, "debug");
lua_pushvalue(L, -1);
Sluift::globals.moduleLibIndex = luaL_ref(L, LUA_REGISTRYINDEX);
// Load core lib code
if (luaL_loadbuffer(L, core_lua, core_lua_size, "core.lua") != 0) {
lua_error(L);
}
lua_pushvalue(L, -2);
lua_call(L, 1, 1);
Sluift::globals.coreLibIndex = luaL_ref(L, LUA_REGISTRYINDEX);
// Register functions
Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, "Sluift");
Lua::FunctionRegistry::getInstance().createFunctionTable(L, "JID");
lua_setfield(L, -2, "jid");
Lua::FunctionRegistry::getInstance().createFunctionTable(L, "Base64");
lua_setfield(L, -2, "base64");
Lua::FunctionRegistry::getInstance().createFunctionTable(L, "IDN");
lua_setfield(L, -2, "idn");
Lua::FunctionRegistry::getInstance().createFunctionTable(L, "Crypto");
lua_setfield(L, -2, "crypto");
#ifdef HAVE_ITUNES
Lua::FunctionRegistry::getInstance().createFunctionTable(L, "iTunes");
lua_setfield(L, -2, "itunes");
#endif
// Register convenience functions
lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
std::vector<std::string> coreLibExports = boost::assign::list_of
- ("tprint")("disco")("help")("get_help")("copy")("with")("read_file");
+ ("tprint")("disco")("help")("get_help")("copy")("with")("read_file")("create_form");
foreach (const std::string& coreLibExport, coreLibExports) {
lua_getfield(L, -1, coreLibExport.c_str());
lua_setfield(L, -3, coreLibExport.c_str());
}
lua_pop(L, 1);
// Load client metatable
lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
std::vector<std::string> tables = boost::assign::list_of("Client");
foreach(const std::string& table, tables) {
lua_getfield(L, -1, table.c_str());
Lua::FunctionRegistry::getInstance().addFunctionsToTable(L, table);
lua_pop(L, 1);
}
lua_pop(L, 1);
// Register documentation for all elements
foreach (boost::shared_ptr<LuaElementConvertor> convertor, Sluift::globals.elementConvertor.getConvertors()) {
boost::optional<LuaElementConvertor::Documentation> documentation = convertor->getDocumentation();
if (documentation) {
Lua::registerClassHelp(L, documentation->className, documentation->description);
}
}
// Register global documentation
Lua::registerExtraHelp(L, -1, "sluift");
return 1;
}