Skip to content

Commit

Permalink
Python bindings now provide enough functionality to implement iksrost…
Browse files Browse the repository at this point in the history
…er.c

git-svn-id: https://iksemel.googlecode.com/svn/trunk@50 6ddeccfd-2234-0410-8ab0-45b763562eda
  • Loading branch information
[email protected] committed Oct 18, 2011
1 parent cb96e23 commit 978b733
Show file tree
Hide file tree
Showing 6 changed files with 83 additions and 16 deletions.
7 changes: 5 additions & 2 deletions ChangeLog
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
2001-10-10 Gurer
2011-10-18 Gurer
* python/: Python bindings and test scripts

2011-10-10 Gurer
* iks.c: iks_string() returns nul terminated strings for cdata nodes

2001-10-07 Gurer
2011-10-07 Gurer
* sax.c: Fix handling of ending ]] sequences in CDATA sections
bug report and patch by oscarvdbosch
* tst-sax.c: Test coverage for fixed bug
Expand Down
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
V1.5 (upcoming release)
* You can now use OpenSSL or GNUTLS as the TLS back-end (compile time option).
* Python bindings. You can use iksemel from Python as an XMPP client library
or as a very fast and memory efficient XML parser.

V1.4 (2009-07-25)
* Some previously rejected valid UTF8 sequences are now accepted.
Expand Down
2 changes: 2 additions & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ versions.

TLS support requires OpenSSL (>0.9.8) or GNUTLS (>2.0.0) library.

Python bindings requires Python (>2.2).


Compiling & Install:
--------------------
Expand Down
1 change: 0 additions & 1 deletion TODO
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

==> 1.5 release, abi/api compatible, will be released in a few months

* integrate python binding from pardus into the main tree
* parser: Ӓ and ꉟ like entities must be unescaped.


Expand Down
56 changes: 51 additions & 5 deletions python/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,34 @@ start_sasl(Stream *self, enum ikssasltype type)
Py_DECREF(o);
}

static void
make_bind(Stream *self)
{
iks *x, *y, *z;
PyObject *o;
char *resource;

o = PyObject_GetAttrString(self->jid, "resource");
if (!o) return;
resource = PyString_AsString(o);
if (!resource) {
PyErr_Clear();
resource = "iksemel";
}

x = iks_new("iq");
iks_insert_attrib(x, "type", "set");
y = iks_insert(x, "bind");
iks_insert_attrib(y, "xmlns", IKS_NS_XMPP_BIND);
z = iks_insert(y, "resource");
iks_insert_cdata(z, resource, 0);

iks_send(self->parser, x);

iks_delete(x);
Py_DECREF(o);
}

static void
on_features(Stream *self, iks *node)
{
Expand All @@ -125,13 +153,9 @@ on_features(Stream *self, iks *node)
if (self->use_sasl) {
if (self->use_tls && !iks_is_secure(self->parser)) return;
if (self->authorized) {
#if 0
if (self->features & IKS_STREAM_BIND) {
x = iks_make_resource_bind(sess->acc);
iks_send(self->parser, x);
iks_delete(x);
make_bind(self);
}
#endif
if (self->features & IKS_STREAM_SESSION) {
x = iks_make_session();
iks_insert_attrib(x, "id", "auth");
Expand All @@ -147,6 +171,26 @@ on_features(Stream *self, iks *node)
}
}

static void
on_success(Stream *self, iks *node)
{
PyObject *o;
char *domain;

o = PyObject_GetAttrString(self->jid, "domain");
if (!o) return;
domain = PyString_AsString(o);
if (!domain) {
Py_DECREF(o);
return;
}

self->authorized = 1;
iks_send_header(self->parser, domain);

Py_DECREF(o);
}

static int
on_stream(Stream *self, int type, iks *node)
{
Expand All @@ -159,6 +203,8 @@ on_stream(Stream *self, int type, iks *node)
case IKS_NODE_NORMAL:
if (strcmp("stream:features", iks_name(node)) == 0) {
on_features(self, node);
} else if (strcmp("success", iks_name(node)) == 0) {
on_success(self, node);
}
#if 0
case IKS_NODE_START:
Expand Down
31 changes: 23 additions & 8 deletions python/test/stream.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,53 @@

import sys
import select
from optparse import OptionParser

import iksemel


class MyStream(iksemel.Stream):
def on_stanza(self, doc):
print doc, type(doc)
if doc.name() == "iq" and doc.get("type") == "result" and doc.get("id") == "auth":
iq = iksemel.Document("iq")
iq.set("type", "get")
iq.set("id", "roster")
query = iq.insert("query")
query.set("xmlns", "jabber:iq:roster")
self.send(iq)
if doc.name() == "iq" and doc.get("type") == "result" and doc.get("id") == "roster":
print "Roster:"
print doc
# FIXME: exit

def on_xml(self, text, is_incoming):
if not self.options.verbose:
return
pre = "SEND"
if is_incoming:
pre = "RECV"
print "%s [%s]" % (pre, text)

def ask_password(self):
pw = self.password
pw = self.options.password
if pw is None:
pw = raw_input("Password? ")
return pw


def get_roster(jid, password):
def get_roster(options, jid):
my = MyStream()
my.password = password
my.options = options
my.connect(jid=iksemel.JID(jid), tls=False)

while 1:
select.select([my], [], [])
my.recv()

if __name__ == "__main__":
pw = None
if len(sys.argv) > 2:
pw = sys.argv[2]
get_roster(sys.argv[1], pw)
parser = OptionParser()
parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Print XML communication")
parser.add_option("-p", "--password", dest="password", action="store", default=None, help="Use given password")
options, args = parser.parse_args()

get_roster(options, args[0])

0 comments on commit 978b733

Please sign in to comment.