summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Maudsley <richard.maudsley@isode.com>2014-05-13 14:48:10 (GMT)
committerSwift Review <review@swift.im>2014-05-27 19:53:49 (GMT)
commit058719296f496b14b906fdee3d74d72a78d9f6a2 (patch)
treee15b5e0032b48c924f7f69e20e0b721172a5691d
parente5975a6d4809bf05f8c9df724c926bd26fc4a9df (diff)
downloadswift-contrib-058719296f496b14b906fdee3d74d72a78d9f6a2.zip
swift-contrib-058719296f496b14b906fdee3d74d72a78d9f6a2.tar.bz2
Added Sluift MAM examples. send_mam_query becomes set_mam_query.
Change-Id: I5d81e2476c83a16a8e478656d11d91137b009f3a
-rw-r--r--Sluift/ElementConvertors/MAMQueryConvertor.cpp2
-rw-r--r--Sluift/Examples/MAMRSM.lua23
-rw-r--r--Sluift/Examples/MAMRSMPage.lua36
-rw-r--r--Sluift/Examples/MAMSimple.lua19
-rw-r--r--Sluift/Examples/MAMSupportedFields.lua18
-rw-r--r--Sluift/Examples/MAMUser.lua25
-rw-r--r--Sluift/client.cpp29
-rw-r--r--Sluift/core.lua6
8 files changed, 126 insertions, 32 deletions
diff --git a/Sluift/ElementConvertors/MAMQueryConvertor.cpp b/Sluift/ElementConvertors/MAMQueryConvertor.cpp
index 7d7224e..cf4f787 100644
--- a/Sluift/ElementConvertors/MAMQueryConvertor.cpp
+++ b/Sluift/ElementConvertors/MAMQueryConvertor.cpp
@@ -1,55 +1,55 @@
/*
* Copyright (c) 2014 Kevin Smith and Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#include <boost/numeric/conversion/cast.hpp>
#include <boost/smart_ptr/make_shared.hpp>
#include <lua.hpp>
#include <Sluift/ElementConvertors/MAMQueryConvertor.h>
#include <Sluift/LuaElementConvertors.h>
#include <Swiften/Elements/Form.h>
#include <Swiften/Elements/ResultSet.h>
#pragma clang diagnostic ignored "-Wunused-private-field"
using namespace Swift;
MAMQueryConvertor::MAMQueryConvertor(LuaElementConvertors* convertors) :
- GenericLuaElementConvertor<MAMQuery>("mam_query"),
+ GenericLuaElementConvertor<MAMQuery>("mam"),
convertors(convertors) {
}
MAMQueryConvertor::~MAMQueryConvertor() {
}
boost::shared_ptr<MAMQuery> MAMQueryConvertor::doConvertFromLua(lua_State* L) {
boost::shared_ptr<MAMQuery> result = boost::make_shared<MAMQuery>();
lua_getfield(L, -1, "query_id");
if (lua_isstring(L, -1)) {
result->setQueryID(std::string(lua_tostring(L, -1)));
}
lua_pop(L, 1);
lua_getfield(L, -1, "form");
if (!lua_isnil(L, -1)) {
boost::shared_ptr<Form> form = boost::dynamic_pointer_cast<Form>(convertors->convertFromLuaUntyped(L, -1, "form"));
if (!!form) {
result->setForm(form);
}
}
lua_pop(L, 1);
lua_getfield(L, -1, "result_set");
if (!lua_isnil(L, -1)) {
boost::shared_ptr<ResultSet> resultSet = boost::dynamic_pointer_cast<ResultSet>(convertors->convertFromLuaUntyped(L, -1, "result_set"));
if (!!resultSet) {
result->setResultSet(resultSet);
}
}
lua_pop(L, 1);
return result;
}
void MAMQueryConvertor::doConvertToLua(lua_State* L, boost::shared_ptr<MAMQuery> payload) {
lua_createtable(L, 0, 0);
if (payload->getQueryID()) {
diff --git a/Sluift/Examples/MAMRSM.lua b/Sluift/Examples/MAMRSM.lua
new file mode 100644
index 0000000..c8a1e85
--- /dev/null
+++ b/Sluift/Examples/MAMRSM.lua
@@ -0,0 +1,23 @@
+-- A query using Result Set Management
+-- Usage: ./sluift MAMRSM.lua <jid> <password> <query_dest> <max_results>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+query = {
+ result_set={max_items=arg[4]}
+}
+
+c:set_mam{mam=query, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMRSMPage.lua b/Sluift/Examples/MAMRSMPage.lua
new file mode 100644
index 0000000..cb3307c
--- /dev/null
+++ b/Sluift/Examples/MAMRSMPage.lua
@@ -0,0 +1,36 @@
+-- A page query using Result Set Management
+-- Usage: ./sluift MAMRSMPage.lua <jid> <password> <query_dest> <pages>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:set_options{compress = false, tls = false}
+
+c:connect();
+
+query = {
+ result_set={max_items=5}
+}
+
+done = false
+page = 0
+while not done and page < tonumber(arg[4]) do
+ page = page + 1
+ c:set_mam{mam=query, to=arg[3]}
+ c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then
+ if e.payloads[2].last_id then
+ query.result_set.after = e.payloads[2].last_id
+ else
+ done = true
+ end
+ return true
+ end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+ end)
+end
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMSimple.lua b/Sluift/Examples/MAMSimple.lua
new file mode 100644
index 0000000..13ab1a0
--- /dev/null
+++ b/Sluift/Examples/MAMSimple.lua
@@ -0,0 +1,19 @@
+-- Querying the archive for messages
+-- Usage: ./sluift MAMSimple.lua <jid> <password> <query_dest>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+c:set_mam{mam={}, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMSupportedFields.lua b/Sluift/Examples/MAMSupportedFields.lua
new file mode 100644
index 0000000..0417924
--- /dev/null
+++ b/Sluift/Examples/MAMSupportedFields.lua
@@ -0,0 +1,18 @@
+-- Retrieving form fields
+-- Usage: ./sluift MAMSupportedFields.lua <jid> <password>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+mam_result = c:get_mam{}
+
+for i=1,#mam_result.form.fields do
+ if mam_result.form.fields[i].type ~= "hidden" then
+ print("Server supports: " .. mam_result.form.fields[i].name)
+ end
+end
+
+c:disconnect()
diff --git a/Sluift/Examples/MAMUser.lua b/Sluift/Examples/MAMUser.lua
new file mode 100644
index 0000000..e4a7c28
--- /dev/null
+++ b/Sluift/Examples/MAMUser.lua
@@ -0,0 +1,25 @@
+-- Querying for all messages to/from a particular JID
+-- Usage: ./sluift MAMUser.lua <jid> <password> <query_dest> <query_jid>
+
+sluift.debug = true
+
+c = sluift.new_client(arg[1], arg[2])
+
+c:connect();
+
+fields = {
+ with = arg[4]
+}
+
+query_form = sluift.create_form{fields, form_type="urn:xmpp:mam:0"}
+
+c:set_mam{mam={form=query_form}, to=arg[3]}
+
+c:for_each_message(function(e)
+ if e.payloads[1].tag == 'fin' then return true end
+ if e.payloads[1]._type == 'mam_result' then
+ print(e.payloads[1].payload.stanza.payloads[1].text)
+ end
+end)
+
+c:disconnect()
diff --git a/Sluift/client.cpp b/Sluift/client.cpp
index 8dcd9ae..4b065ab 100644
--- a/Sluift/client.cpp
+++ b/Sluift/client.cpp
@@ -1,37 +1,37 @@
/*
- * Copyright (c) 2013 Remko Tronçon
+ * Copyright (c) 2013-2014 Remko Tronçon
* Licensed under the GNU General Public License.
* See the COPYING file for more information.
*/
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/assign/list_of.hpp>
#include <iostream>
#include <Sluift/SluiftClient.h>
#include <Swiften/JID/JID.h>
#include <Swiften/Elements/SoftwareVersion.h>
#include <Swiften/Elements/Message.h>
#include <Swiften/Elements/Presence.h>
#include <Swiften/Elements/RawXMLPayload.h>
#include <Swiften/Elements/RosterItemPayload.h>
#include <Swiften/Elements/RosterPayload.h>
#include <Swiften/Elements/DiscoInfo.h>
#include <Swiften/Elements/MAMQuery.h>
#include <Swiften/Disco/ClientDiscoManager.h>
#include <Swiften/Queries/GenericRequest.h>
#include <Swiften/Presence/PresenceSender.h>
#include <Swiften/Roster/XMPPRoster.h>
#include <Swiften/Roster/SetRosterRequest.h>
#include <Swiften/Presence/SubscriptionManager.h>
#include <Swiften/Roster/XMPPRosterItem.h>
#include <Swiften/Queries/IQRouter.h>
#include <Swiften/Queries/Requests/GetSoftwareVersionRequest.h>
#include <Sluift/Lua/FunctionRegistration.h>
#include <Swiften/Base/foreach.h>
#include <Swiften/Base/IDGenerator.h>
#include <Sluift/Lua/Check.h>
#include <Sluift/Lua/Value.h>
#include <Sluift/Lua/Exception.h>
#include <Sluift/Lua/LuaUtils.h>
@@ -420,97 +420,70 @@ SLUIFT_LUA_FUNCTION_WITH_HELP(
SluiftClient* client = getClient(L);
Lua::checkType(L, 2, LUA_TTABLE);
lua_getfield(L, 2, "host");
if (!lua_isnil(L, -1)) {
client->getOptions().manualHostname = lua_tostring(L, -1);
}
lua_getfield(L, 2, "port");
if (!lua_isnil(L, -1)) {
client->getOptions().manualPort = boost::numeric_cast<int>(lua_tointeger(L, -1));
}
lua_getfield(L, 2, "ack");
if (!lua_isnil(L, -1)) {
client->getOptions().useAcks = lua_toboolean(L, -1);
}
lua_getfield(L, 2, "compress");
if (!lua_isnil(L, -1)) {
client->getOptions().useStreamCompression = lua_toboolean(L, -1);
}
lua_getfield(L, 2, "tls");
if (!lua_isnil(L, -1)) {
bool useTLS = lua_toboolean(L, -1);
client->getOptions().useTLS = (useTLS ? ClientOptions::UseTLSWhenAvailable : ClientOptions::NeverUseTLS);
}
lua_getfield(L, 2, "bosh_url");
if (!lua_isnil(L, -1)) {
client->getOptions().boshURL = URL::fromString(lua_tostring(L, -1));
}
lua_getfield(L, 2, "allow_plain_without_tls");
if (!lua_isnil(L, -1)) {
client->getOptions().allowPLAINWithoutTLS = lua_toboolean(L, -1);
}
lua_pushvalue(L, 1);
return 0;
}
-SLUIFT_LUA_FUNCTION_WITH_HELP(
- Client, send_mam_query,
-
- "Builds and sends a MAM query.\n",
-
- "self\n"
- "mam_query parameters for the query\n"
- "jid optional jid to set in the 'to' field of the IQ stanza",
-
- "See help('MAMQuery') for details."
-) {
- Lua::checkType(L, 2, LUA_TTABLE);
- boost::shared_ptr<MAMQuery> mamQuery = boost::make_shared<MAMQuery>();
- lua_getfield(L, 2, "mam_query");
- if (lua_istable(L, -1)) {
- mamQuery = boost::dynamic_pointer_cast<MAMQuery>(Sluift::globals.elementConvertor.convertFromLuaUntyped(L, -1, "mam_query"));
- }
- JID jid;
- lua_getfield(L, 2, "jid");
- if (!lua_isnil(L, -1)) {
- jid = JID(lua_tostring(L, -1));
- }
- IQRouter *router = getClient(L)->getClient()->getIQRouter();
- router->sendIQ(IQ::createRequest(IQ::Set, jid, IDGenerator().generateID(), mamQuery));
- return 0;
-}
-
static void pushEvent(lua_State* L, const SluiftClient::Event& event) {
switch (event.type) {
case SluiftClient::Event::MessageType: {
Message::ref message = boost::dynamic_pointer_cast<Message>(event.stanza);
Lua::Table result = boost::assign::map_list_of
("type", boost::make_shared<Lua::Value>(std::string("message")))
("from", boost::make_shared<Lua::Value>(message->getFrom().toString()))
("body", boost::make_shared<Lua::Value>(message->getBody()))
("message_type", boost::make_shared<Lua::Value>(MessageConvertor::convertMessageTypeToString(message->getType())));
Lua::pushValue(L, result);
addPayloadsToTable(L, message->getPayloads());
Lua::registerTableToString(L, -1);
break;
}
case SluiftClient::Event::PresenceType: {
Presence::ref presence = boost::dynamic_pointer_cast<Presence>(event.stanza);
Lua::Table result = boost::assign::map_list_of
("type", boost::make_shared<Lua::Value>(std::string("presence")))
("from", boost::make_shared<Lua::Value>(presence->getFrom().toString()))
("status", boost::make_shared<Lua::Value>(presence->getStatus()))
("presence_type", boost::make_shared<Lua::Value>(PresenceConvertor::convertPresenceTypeToString(presence->getType())));
Lua::pushValue(L, result);
addPayloadsToTable(L, presence->getPayloads());
Lua::registerTableToString(L, -1);
break;
}
case SluiftClient::Event::PubSubEventType: {
Sluift::globals.elementConvertor.convertToLua(L, event.pubsubEvent);
lua_pushstring(L, "pubsub");
lua_setfield(L, -2, "type");
lua_pushstring(L, event.from.toString().c_str());
lua_setfield(L, -2, "from");
lua_rawgeti(L, LUA_REGISTRYINDEX, Sluift::globals.coreLibIndex);
lua_getfield(L, -1, "process_pubsub_event");
diff --git a/Sluift/core.lua b/Sluift/core.lua
index dfac21a..7487de1 100644
--- a/Sluift/core.lua
+++ b/Sluift/core.lua
@@ -1,37 +1,37 @@
--[[
- Copyright (c) 2013 Remko Tronçon
+ Copyright (c) 2013-2014 Remko Tronçon
Licensed under the GNU General Public License.
See the COPYING file for more information.
--]]
local sluift = select(1, ...)
local _G = _G
local pairs, ipairs, print, tostring, type, error, assert, next, rawset, xpcall, unpack, io = pairs, ipairs, print, tostring, type, error, assert, next, rawset, xpcall, unpack, io
local setmetatable, getmetatable = setmetatable, getmetatable
local string = require "string"
local table = require "table"
local debug = require "debug"
_ENV = nil
--------------------------------------------------------------------------------
-- Table utility methods
--------------------------------------------------------------------------------
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
@@ -715,72 +715,72 @@ end
for method, event_type in pairs({messages = 'message', pubsub_events = 'pubsub'}) do
_H = {
"Returns an iterator over all events of type `" .. event_type .. "`.",
parameters = { "self" },
options = remove_help_parameters("type", get_help(Client.for_each_event).options)
}
Client[method] = function (client, ...)
local options = parse_options({}, ...)
options['type'] = event_type
return client:events (options)
end
register_help(Client[method])
end
_H = {
[[
Process all pending events
]],
parameters = { "self" }
}
function Client:process_events ()
for event in self:events{timeout=0} do end
end
register_help(Client.process_events)
--
-- 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'}
+ get = {'software_version', 'disco_items', 'xml', 'dom', 'vcard', 'mam'},
+ set = {'command', 'mam'}
}
for query_action, query_types in pairs(get_set_shortcuts) do
for _, query_type in ipairs(query_types) do
_H = {
"Sends a `" .. query_action .. "` query of type `" .. query_type .. "`.\n" ..
"Apart from the options below, all top level elements of `" .. query_type .. "` can be passed.",
parameters = { "self" },
options = remove_help_parameters({"query", "type"}, extra_help["Client.get"].options),
}
local method = query_action .. '_' .. query_type
Client[method] = 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
register_help(Client[method])
end
end
_H = {
[[ Returns a @{PubSub} object for communicating with the PubSub service at `jid`. ]],
parameters = {
"self",
{"jid", "The JID of the PubSub service"}
}
}
function Client:pubsub (jid)
local result = { client = self, jid = jid }
setmetatable(result, PubSub)
return result
end
register_help(Client.pubsub)
--------------------------------------------------------------------------------