summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2013-12-26 15:56:45 (GMT)
committerRemko Tronçon <git@el-tramo.be>2013-12-27 23:06:53 (GMT)
commit5a89265623214164fa7ce36721de05183d53058d (patch)
tree1cb061f1c314668396dd0e16047d995641631d4f /Sluift/boot.lua
parent806efd2603a4083ca433501dcd6e5b8479db0b39 (diff)
downloadswift-5a89265623214164fa7ce36721de05183d53058d.zip
swift-5a89265623214164fa7ce36721de05183d53058d.tar.bz2
Sluift: Refactoring
- Rename boot.lua to core.lua - Support Lua 5.2 - Support version prefixes for sluift module - Add Client:process_events Change-Id: I3fa6d06d1dbdf86f65b9f4203bd2ec5b5526b104
Diffstat (limited to 'Sluift/boot.lua')
-rw-r--r--Sluift/boot.lua454
1 files changed, 0 insertions, 454 deletions
diff --git a/Sluift/boot.lua b/Sluift/boot.lua
deleted file mode 100644
index a28a189..0000000
--- a/Sluift/boot.lua
+++ /dev/null
@@ -1,454 +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, print_functions, indent, accumulator, history)
- local INDENT = ' '
- local accumulator = accumulator or ''
- local history = history or {}
- local indent = indent or ''
- accumulator = accumulator .. '{'
- history[table] = true
- local is_first = true
- for key, value in pairs(table) do
- if print_functions or 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
- if history[value] then
- accumulator = accumulator .. "..."
- else
- accumulator = table_tostring(value, print_functions, indent .. INDENT, accumulator, history)
- end
- else
- accumulator = accumulator .. table_value_tostring(value)
- end
- end
- end
- history[table] = false
- if not is_first then
- accumulator = accumulator .. '\n' .. indent
- end
- accumulator = accumulator .. '}'
- return accumulator
-end
-
-local function tprint(table)
- print(table_tostring(table, true))
-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 (...)
- local options = parse_options({}, ...)
- local f = options.f
- self:async_connect(options)
- self:wait_connected()
- if f then
- local result = { xpcall(function() return f(self) end, debug.traceback) }
- self:disconnect()
- if result[1] then
- table.remove(result, 1)
- return unpack(result)
- else
- error(result[2])
- end
- end
- return true
-end
-
-function Client:events (options)
- local function client_events_iterator(s)
- return s['client']:get_next_event(s['options'])
- end
- return client_events_iterator, {client = self, options = options}
-end
-
-function Client:for_each_event (...)
- local options = parse_options({}, ...)
- if not type(options.f) == 'function' then error('Expected function') end
- for event in self: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 (jid)
- local result = { client = self, 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 (options)
- return self.client:get_disco_items(merge_tables({to = self.jid}, options))
-end
-
-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
---------------------------------------------------------------------------------
-
-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 (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 (...)
- local options = parse_options({}, ...)
- if not type(options.id) == 'string' then error('Expected ID') end
- return self:get_items{items = {{id = options.id}}}
-end
-
-function PubSubNode:create (options)
- options = options or {}
- local configure
- if options['configuration'] then
- configure = { data = pubsub_node_configuration_to_form(options['configuration']) }
- end
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_create', node = self.node, configure = configure }
- }, options))
-end
-
-function PubSubNode:delete (options)
- options = options or {}
- local redirect
- if options['redirect'] then
- redirect = {uri = options['redirect']}
- end
- return self.client:query_pubsub(merge_tables({ type = 'set', to = self.jid, query = {
- _type = 'pubsub_owner_delete', node = self.node, redirect = redirect
- }}, options))
-end
-
-function PubSubNode:set_configuration(options)
- options = options or {}
- local configuration = pubsub_node_configuration_to_form(options['configuration'])
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_owner_configure', node = self.node, data = configuration }
- }, options))
-end
-
-function PubSubNode:set_owner_affiliations(...)
- local options = parse_options({}, ...)
- return self.client:query_pubsub(merge_tables({
- type = 'set', to = self.jid, query = merge_tables({
- _type = 'pubsub_owner_affiliations', node = self.node,
- }, options.affiliations)}, options))
-end
-
-
-function PubSubNode:subscribe(...)
- local options = parse_options(...)
- local jid = options.jid or sluift.jid.to_bare(self.client:jid())
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_subscribe', node = self.node, jid = jid }
- }, options))
-end
-
-function PubSubNode:unsubscribe(options)
- options = options or {}
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_unsubscribe', node = self.node, jid = options['jid'] }
- }, options))
-end
-
-function PubSubNode:get_subscription_options (options)
- return self.client:query_pubsub(merge_tables(
- { type = 'get', to = self.jid, query = {
- _type = 'pubsub_options', node = self.node, jid = options['jid'] }
- }, options))
-end
-
-function PubSubNode:publish(...)
- 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 self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_publish', node = self.node, items = items }
- }, options))
-end
-
-function PubSubNode:retract(...)
- local options = parse_options({}, ...)
- local items = options.items
- if options.id then
- items = {{id = options.id}}
- end
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_retract', node = self.node, items = items, notify = options['notify']
- }}, options))
-end
-
-function PubSubNode:purge(...)
- local options = parse_options({}, ...)
- return self.client:query_pubsub(merge_tables(
- { type = 'set', to = self.jid, query = {
- _type = 'pubsub_owner_purge', node = self.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,
-}