diff options
Diffstat (limited to 'Sluift/boot.lua')
-rw-r--r-- | Sluift/boot.lua | 436 |
1 files changed, 0 insertions, 436 deletions
diff --git a/Sluift/boot.lua b/Sluift/boot.lua deleted file mode 100644 index 2505736..0000000 --- a/Sluift/boot.lua +++ /dev/null @@ -1,436 +0,0 @@ ---[[ - Copyright (c) 2013 Remko Tronçon - Licensed under the GNU General Public License. - See the COPYING file for more information. ---]] - -local Client = {} -local PubSub = {} -local PubSubNode = {} - --------------------------------------------------------------------------------- --- Utility methods --------------------------------------------------------------------------------- - -local function merge_tables(...) - local result = {} - for _, table in ipairs({...}) do - for k, v in pairs(table) do - result[k] = v - end - end - return result -end - -local function clone_table(table) - return merge_tables(table) -end - -local function parse_options(unnamed_parameters, arg1, arg2) - local options = {} - if type(arg1) == 'table' then - options = arg1 - f = arg2 - elseif type(arg1) == 'function' then - f = arg1 - end - options.f = f or options.f - return clone_table(options) -end - - -local function table_value_tostring(value) - local result = tostring(value) - if type(value) == 'number' then return result - elseif type(value) == 'boolean' then return result - elseif type(value) == 'string' then return "'" .. result .. "'" - else return '<' .. result .. '>' - end -end - -local function table_tostring(table, indent, accumulator) - local INDENT = ' ' - local accumulator = accumulator or '' - local indent = indent or '' - accumulator = accumulator .. '{' - local is_first = true - for key, value in pairs(table) do - if type(value) ~= 'function' then - if not is_first then - accumulator = accumulator .. ',' - end - is_first = false - accumulator = accumulator .. '\n' .. indent .. INDENT .. '[' .. table_value_tostring(key) .. '] = ' - if type(value) == 'table' then - accumulator = table_tostring(value, indent .. INDENT, accumulator) - else - accumulator = accumulator .. table_value_tostring(value) - end - end - end - if not is_first then - accumulator = accumulator .. '\n' .. indent - end - accumulator = accumulator .. '}' - return accumulator -end - -local function tprint(table) - print(table_tostring(table)) -end - -local function register_table_tostring(table) - if type(table) == 'table' then - local metatable = getmetatable(table) - if not metatable then - metatable = {} - setmetatable(table, metatable) - end - metatable.__tostring = table_tostring - end - return table -end - -local function get_by_type(table, typ) - for _, v in ipairs(table) do - if v['_type'] == typ then - return v - end - end -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 - --------------------------------------------------------------------------------- --- Client --------------------------------------------------------------------------------- - -function Client.connect (client, ...) - local options = parse_options({}, ...) - local f = options.f - client:async_connect(options) - client:wait_connected() - if f then - local result = { xpcall(function() return f(client) end, debug.traceback) } - client:disconnect() - if result[1] then - table.remove(result, 1) - return unpack(result) - else - error(result[2]) - end - end - return true -end - -function Client.events (client, options) - local function client_events_iterator(s) - return s['client']:get_next_event(s['options']) - end - return client_events_iterator, {client = client, options = options} -end - -function Client.for_each_event (client, ...) - local options = parse_options({}, ...) - if not type(options.f) == 'function' then error('Expected function') end - for event in client:events(options) do - local result = options.f(event) - if result then - return result - end - end -end - -for method, event_type in pairs({message = 'message', presence = 'presence', pubsub_event = 'pubsub'}) do - Client['for_each_' .. method] = function (client, ...) - local options = parse_options({}, ...) - options['type'] = event_type - return client:for_each_event (options) - end - - Client['get_next_' .. method] = function (client, ...) - local options = parse_options({}, ...) - options['type'] = event_type - return client:get_next_event(options) - end -end - -for method, event_type in pairs({messages = 'message', pubsub_events = 'pubsub'}) do - Client[method] = function (client, ...) - local options = parse_options({}, ...) - options['type'] = event_type - return client:events (options) - end -end - --- --- Register get_* and set_* convenience methods for some type of queries --- --- Example usages: --- client:get_software_version{to = 'alice@wonderland.lit'} --- client:set_command{to = 'alice@wonderland.lit', command = { type = 'execute', node = 'uptime' }} --- -local get_set_shortcuts = { - get = {'software_version', 'disco_items', 'xml', 'dom', 'vcard'}, - set = {'command'} -} -for query_action, query_types in pairs(get_set_shortcuts) do - for _, query_type in ipairs(query_types) do - Client[query_action .. '_' .. query_type] = function (client, options) - options = options or {} - if type(options) ~= 'table' then error('Invalid options: ' .. options) end - options['query'] = merge_tables({_type = query_type}, options[query_type] or {}) - return client[query_action](client, options) - end - end -end - -function Client.pubsub (client, jid) - local result = { client = client, jid = jid } - setmetatable(result, PubSub) - return result -end - --------------------------------------------------------------------------------- --- PubSub --------------------------------------------------------------------------------- - -PubSub.__index = PubSub - -local function process_pubsub_event (event) - if event._type == 'pubsub_event_items' then - -- Add 'item' shortcut to payload of first item - event.item = event.items and event.items[1] and - event.items[1].data and event.items[1].data[1] - end -end - -function PubSub.list_nodes (service, options) - return service.client:get_disco_items(merge_tables({to = service.jid}, options)) -end - -function PubSub.node (service, node) - local result = { client = service.client, jid = service.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 --------------------------------------------------------------------------------- - -PubSubNode.__index = 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 } -end - -function PubSubNode.list_items (node, options) - return node.client:get_disco_items(merge_tables({to = node.jid, query = { node = node.node }}, options)) -end - -local simple_pubsub_node_queries = { - get_configuration = 'pubsub_owner_configure', - get_subscriptions = 'pubsub_subscriptions', - get_affiliations = 'pubsub_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 (node, ...) - 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 = node.node}, items) - return node.client:query_pubsub(merge_tables({ - type = 'get', to = node.jid, query = items}, options)) -end - -function PubSubNode.get_item (node, ...) - local options = parse_options({}, ...) - if not type(options.id) == 'string' then error('Expected ID') end - return PubSubNode.get_items(node, {items = {{id = options.id}}}) -end - -function PubSubNode.create (node, options) - options = options or {} - local configure - if options['configuration'] then - configure = { data = pubsub_node_configuration_to_form(options['configuration']) } - end - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_create', node = node.node, configure = configure } - }, options)) -end - -function PubSubNode.delete (node, options) - options = options or {} - local redirect - if options['redirect'] then - redirect = {uri = options['redirect']} - end - return node.client:query_pubsub(merge_tables({ type = 'set', to = node.jid, query = { - _type = 'pubsub_owner_delete', node = node.node, redirect = redirect - }}, options)) -end - -function PubSubNode.set_configuration(node, options) - options = options or {} - local configuration = pubsub_node_configuration_to_form(options['configuration']) - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_owner_configure', node = node.node, data = configuration } - }, options)) -end - -function PubSubNode.subscribe(node, ...) - local options = parse_options(...) - local jid = options.jid or sluift.jid.to_bare(node.client:jid()) - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_subscribe', node = node.node, jid = jid } - }, options)) -end - -function PubSubNode.unsubscribe(node, options) - options = options or {} - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_unsubscribe', node = node.node, jid = options['jid'] } - }, options)) -end - -function PubSubNode.get_subscription_options (node, options) - return node.client:query_pubsub(merge_tables( - { type = 'get', to = node.jid, query = { - _type = 'pubsub_options', node = node.node, jid = options['jid'] } - }, options)) -end - -function PubSubNode.publish(node, ...) - local options = parse_options({}, ...) - local items = options.items or {} - if options.item then - if type(options.item) == 'string' or options.item._type then - items = {{id = options.id, data = { options.item } }} - options.id = nil - else - items = { options.item } - end - options.item = nil - end - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_publish', node = node.node, items = items } - }, options)) -end - -function PubSubNode.retract(node, ...) - local options = parse_options({}, ...) - local items = options.items - if options.id then - items = {{id = options.id}} - end - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_retract', node = node.node, items = items, notify = options['notify'] - }}, options)) -end - -function PubSubNode.purge(node, ...) - local options = parse_options({}, ...) - return node.client:query_pubsub(merge_tables( - { type = 'set', to = node.jid, query = { - _type = 'pubsub_owner_purge', node = node.node - }}, options)) -end - --- Iterators over events -for _, method in ipairs({'events', 'get_next_event', 'for_each_event'}) do - PubSubNode[method] = function (node, ...) - local options = parse_options({}, ...) - options['if'] = function (event) - return event.type == 'pubsub' and event.from == node.jid and event.node == node.node - end - return node.client[method](node.client, options) - end -end - --------------------------------------------------------------------------------- --- Service discovery --------------------------------------------------------------------------------- - -local disco = { - features = { - DISCO_INFO = 'http://jabber.org/protocol/disco#info', - COMMANDS = 'http://jabber.org/protocol/commands', - USER_LOCATION = 'http://jabber.org/protocol/geoloc', - USER_TUNE = 'http://jabber.org/protocol/tune', - USER_AVATAR_METADATA = 'urn:xmpp:avatar:metadata', - USER_ACTIVITY = 'http://jabber.org/protocol/activity', - USER_PROFILE = 'urn:xmpp:tmp:profile' - } -} - --------------------------------------------------------------------------------- - -return { - Client = Client, - register_table_tostring = register_table_tostring, - register_get_by_type_index = register_get_by_type_index, - process_pubsub_event = process_pubsub_event, - tprint = tprint, - disco = disco, -} |