summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Sluift/ResponseSink.h5
-rw-r--r--Sluift/sluift.cpp115
2 files changed, 92 insertions, 28 deletions
diff --git a/Sluift/ResponseSink.h b/Sluift/ResponseSink.h
index 042d6e0..700363a 100644
--- a/Sluift/ResponseSink.h
+++ b/Sluift/ResponseSink.h
@@ -35,6 +35,11 @@ namespace Swift {
this->responseReceived = true;
}
+ void operator()(ErrorPayload::ref error) {
+ this->error = error;
+ this->responseReceived = true;
+ }
+
private:
bool responseReceived;
boost::shared_ptr<T> payload;
diff --git a/Sluift/sluift.cpp b/Sluift/sluift.cpp
index 8f32da6..98922cb 100644
--- a/Sluift/sluift.cpp
+++ b/Sluift/sluift.cpp
@@ -14,18 +14,8 @@ extern "C" {
#include <deque>
#include <boost/assign/list_of.hpp>
-#include <Swiften/Client/Client.h>
-#include <Swiften/Client/ClientXMLTracer.h>
-#include <Swiften/JID/JID.h>
-#include <Swiften/EventLoop/SimpleEventLoop.h>
-#include <Swiften/Network/BoostNetworkFactories.h>
-#include <Swiften/Network/TimerFactory.h>
-#include <Swiften/Network/Timer.h>
-#include <Swiften/Elements/SoftwareVersion.h>
-#include <Swiften/Queries/Requests/GetSoftwareVersionRequest.h>
-#include <Swiften/Queries/RawRequest.h>
-#include <Swiften/Roster/XMPPRoster.h>
-#include <Swiften/Base/sleep.h>
+#include <Swiften/Swiften.h>
+
#include "Watchdog.h"
#include "SluiftException.h"
#include "ResponseSink.h"
@@ -120,17 +110,6 @@ class SluiftClient {
client->setSoftwareVersion(name, version, os);
}
- SoftwareVersion::ref getSoftwareVersion(const JID& jid) {
- ResponseSink<SoftwareVersion> sink;
- GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(jid, client->getIQRouter());
- request->onResponse.connect(boost::ref(sink));
- request->send();
- while (!sink.hasResponse()) {
- eventLoop.runUntilEvents();
- }
- return sink.getResponsePayload();
- }
-
Stanza::ref getNextEvent(int timeout) {
if (!pendingEvents.empty()) {
Stanza::ref event = pendingEvents.front();
@@ -152,7 +131,10 @@ class SluiftClient {
}
std::vector<XMPPRosterItem> getRoster() {
- client->requestRoster();
+ if (!rosterReceived) {
+ // If we haven't requested it yet, request it for the first time
+ client->requestRoster();
+ }
while (!rosterReceived) {
eventLoop.runUntilEvents();
}
@@ -287,9 +269,27 @@ static int sluift_client_get_roster(lua_State *L) {
static int sluift_client_get_version(lua_State *L) {
try {
SluiftClient* client = getClient(L);
- JID jid(std::string(luaL_checkstring(L, 2)));
- SoftwareVersion::ref version = client->getSoftwareVersion(jid);
- if (version) {
+
+ ResponseSink<SoftwareVersion> sink;
+ GetSoftwareVersionRequest::ref request = GetSoftwareVersionRequest::create(std::string(luaL_checkstring(L, 2)), client->getClient()->getIQRouter());
+ request->onResponse.connect(boost::ref(sink));
+ request->send();
+ while (!sink.hasResponse()) {
+ eventLoop.runUntilEvents();
+ }
+
+ if (ErrorPayload::ref error = sink.getResponseError()) {
+ lua_pushnil(L);
+ // TODO
+ if (error->getCondition() == ErrorPayload::RemoteServerNotFound) {
+ lua_pushstring(L, "Remote server not found");
+ }
+ else {
+ lua_pushstring(L, "Error");
+ }
+ return 2;
+ }
+ else if (SoftwareVersion::ref version = sink.getResponsePayload()) {
Lua::Table result = boost::assign::map_list_of
("name", boost::make_shared<Lua::Value>(version->getName()))
("version", boost::make_shared<Lua::Value>(version->getVersion()))
@@ -446,13 +446,70 @@ static int sluift_client_get_next_event(lua_State *L) {
}
}
+
+static int sluift_client_add_contact(lua_State* L) {
+ try {
+ eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ JID jid(luaL_checkstring(L, 2));
+
+ client->getRoster();
+ if (!client->getClient()->getRoster()->containsJID(jid)) {
+ RosterItemPayload item;
+ item.setJID(jid);
+ RosterPayload::ref roster = boost::make_shared<RosterPayload>();
+ roster->addItem(item);
+
+ ResponseSink<RosterPayload> sink;
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, client->getClient()->getIQRouter());
+ request->onResponse.connect(boost::ref(sink));
+ request->send();
+ while (!sink.hasResponse()) {
+ eventLoop.runUntilEvents();
+ }
+ if (sink.getResponseError()) {
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ }
+ client->getClient()->getSubscriptionManager()->requestSubscription(jid);
+ lua_pushboolean(L, true);
+ return 1;
+ }
+ catch (const SluiftException& e) {
+ return luaL_error(L, e.getReason().c_str());
+ }
+}
+
+static int sluift_client_remove_contact(lua_State* L) {
+ try {
+ eventLoop.runOnce();
+ SluiftClient* client = getClient(L);
+ JID jid(luaL_checkstring(L, 2));
+
+ RosterPayload::ref roster = boost::make_shared<RosterPayload>();
+ roster->addItem(RosterItemPayload(JID(luaL_checkstring(L, 2)), "", RosterItemPayload::Remove));
+ ResponseSink<RosterPayload> sink;
+ SetRosterRequest::ref request = SetRosterRequest::create(roster, client->getClient()->getIQRouter());
+ request->onResponse.connect(boost::ref(sink));
+ request->send();
+ while (!sink.hasResponse()) {
+ eventLoop.runUntilEvents();
+ }
+ lua_pushboolean(L, !sink.getResponseError());
+ return 1;
+ }
+ catch (const SluiftException& e) {
+ return luaL_error(L, e.getReason().c_str());
+ }
+}
+
static int sluift_client_gc (lua_State *L) {
SluiftClient* client = getClient(L);
delete client;
return 0;
}
-
static const luaL_reg sluift_client_functions[] = {
{"connect", sluift_client_connect},
{"async_connect", sluift_client_async_connect},
@@ -470,6 +527,8 @@ static const luaL_reg sluift_client_functions[] = {
{"set_options", sluift_client_set_options},
{"for_event", sluift_client_for_event},
{"get_next_event", sluift_client_get_next_event},
+ {"add_contact", sluift_client_add_contact},
+ {"remove_contact", sluift_client_remove_contact},
{"__gc", sluift_client_gc},
{NULL, NULL}
};