summaryrefslogtreecommitdiff
path: root/src/xmpppy-0.5.0rc1/doc
diff options
context:
space:
mode:
Diffstat (limited to 'src/xmpppy-0.5.0rc1/doc')
-rw-r--r--src/xmpppy-0.5.0rc1/doc/advanced.html116
-rw-r--r--src/xmpppy-0.5.0rc1/doc/basic.html111
-rwxr-xr-xsrc/xmpppy-0.5.0rc1/doc/examples/README.py71
-rwxr-xr-xsrc/xmpppy-0.5.0rc1/doc/examples/bot.py94
-rw-r--r--src/xmpppy-0.5.0rc1/doc/examples/commandsbot.py289
-rwxr-xr-xsrc/xmpppy-0.5.0rc1/doc/examples/logger.py75
-rwxr-xr-xsrc/xmpppy-0.5.0rc1/doc/examples/xsend.py44
-rw-r--r--src/xmpppy-0.5.0rc1/doc/examples/xtalk.py83
-rw-r--r--src/xmpppy-0.5.0rc1/doc/index.html166
-rw-r--r--src/xmpppy-0.5.0rc1/doc/xmpppy.css70
-rw-r--r--src/xmpppy-0.5.0rc1/doc/xmpppy_title.pngbin0 -> 1213 bytes
11 files changed, 1119 insertions, 0 deletions
diff --git a/src/xmpppy-0.5.0rc1/doc/advanced.html b/src/xmpppy-0.5.0rc1/doc/advanced.html
new file mode 100644
index 00000000..4766eff0
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/advanced.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!-- $Id: advanced.html,v 1.2 2004/12/26 08:12:41 snakeru Exp $ -->
+<html xml:lang="ru-RU" lang="ru-RU" xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta content="text/html; charset=koi8-r" http-equiv="content-type" />
+ <title>Xmpppy usage - advanced.</title>
+ </head>
+<!--
+Historical notes
+Intro
+simplexml
+Dispatcher
+-->
+ <body>
+ <h1>Introduction</h1>
+ <p>To write a programs using XMPP technology you must understand the basic
+ principles of it. Xmpppy uses it's own implementation of XML handling
+ procedures - so you should get used to it. Though it is simple enough I hope.</p>
+ <dl>
+ <dn>Node class</dn>
+ <dt>
+ <dl>
+ <dn>prototype</dn>
+ <dt>Node.__init__(name='', attrs={}, payload=[], parent=None, node=None)</dt>
+ <dn>Note that 'name' argument really consists of namespace and node name, space separated. Example:</dn>
+ <dt>node=Node('jabber:client message', attrs={'to':'target@jid.com'},payload=[Node('body',payload=['Hello target!'])])<br />
+ or<br />
+ node=Node('jabber:client message')<br />
+ node['to']='target@jid.com'<br />
+ node.NT.body='Hello target!'
+ </dt>
+ </dl>
+ NT stands for 'New Tag' and explicitly adds new child to the current node.
+ Also the T can be used. That means "find Tag" but if tag exists it acts just like NT otherwise.
+ </dt>
+
+ <dn>Protocol class</dn>
+ <dt>
+ Uses similar syntax. We will use 'node' attribute now:
+ <dl>
+ <dn>prototype</dn>
+ <dt>Protocol.__init__(name=None, to=None, typ=None, frm=None, attrs={}, payload=[], timestamp=None, xmlns='jabber:client', node=None)</dt>
+ <dn>example</dn>
+ <dt>p=Protocol(node=node)<br />
+ or<br />
+ proto=Protocol('message',to='target@jid.com',payload=[Node('body',payload=['Hello target!'])])<br />
+ or<br />
+ proto=Protocol('message',to='target@jid.com')<br />
+ proto.NT.body='Hello target!'
+ </dt>
+ </dl>
+ </dt>
+
+ <dn>Message class</dn>
+ <dt>
+ Similar syntax:
+ <dl>
+ <dn>prototype</dn>
+ <dt>Message.__init__(to=None, body=None, typ=None, subject=None, attrs={}, frm=None, payload=[], timestamp=None, xmlns='jabber:client', node=None)</dt>
+ <dn>example</dn>
+ <dt>m=Message(node=proto)<br />
+ or<br />
+ m=Message('target@jid.com','Hello target!')<br />
+ </dt>
+ </dl>
+ </dt>
+
+ <dn>Iq class</dn>
+ <dt>
+ Similar syntax:
+ <dl>
+ <dn>prototype</dn>
+ <dt>Iq.__init__(typ=None, queryNS=None, attrs={}, to=None, frm=None, payload=[], xmlns='jabber:client', node=None)</dt>
+ <dn>example</dn>
+ <dt>iq=Iq('set',NS_AUTH,payload=[Node('username',payload=['user']),Node('password',payload=['secret'])])<br />
+ or<br />
+ iq=Iq('set',NS_AUTH)<br />
+ iq.T.query.NT.username='user'<br />
+ iq.T.query.NT.password='secret'<br />
+ or<br />
+ iq=Iq('set',NS_AUTH)<br />
+ iq.T.query.T.username='user'<br />
+ iq.T.query.T.password='secret'<br />
+ As I already noted - 'T' acts just like 'NT' if tag doesn't exists.
+ </dt>
+ </dl>
+ </dt>
+
+ <dn>Presence class</dn>
+ <dt>
+ Similar syntax:
+ <dl>
+ <dn>prototype</dn>
+ <dt>Presence.__init__(to=None, typ=None, priority=None, show=None, status=None, attrs={}, frm=None, timestamp=None, payload=[], xmlns='jabber:client', node=None)</dt>
+ <dn>example</dn>
+ <dt>pres=Presence(priority=5, show='xa',status="I'm away from my computer")<br />
+ or<br />
+ pres=Presence()<br />
+ pres.setPriority(5)
+ pres.setShow('xa')
+ pres.setStatus("I'm away from my computer")
+ pres.setTimestamp()
+ or<br />
+ pres=Presence()<br />
+ pres.T.priority=5
+ pres.T.show='xa'
+ pres.T.status="I'm away from my computer"
+ pres.setTimestamp()
+ </dt>
+ </dl>
+ </dt>
+
+ </dl>
+ </body>
+</html>
diff --git a/src/xmpppy-0.5.0rc1/doc/basic.html b/src/xmpppy-0.5.0rc1/doc/basic.html
new file mode 100644
index 00000000..86259d90
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/basic.html
@@ -0,0 +1,111 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xml:lang="ru-RU" lang="ru-RU" xmlns="http://www.w3.org/1999/xhtml">
+<!-- $Id: basic.html,v 1.5 2004/12/26 08:12:42 snakeru Exp $ -->
+ <head>
+ <meta content="text/html; charset=koi8-r" http-equiv="content-type" />
+ <title>Xmpppy usage - basics.</title>
+ </head>
+ <body>
+<!--
+basic
+Объясняется принципы простейшего скриптования. Фактически уровень README.py.
+advanced
+Вольное изложение предмета
+expert
+описание API каждого модуля
+-->
+<h1>Preface.</h1>
+<p>English is not my native language. If you see any bugs in this text, please, let me know.</p>
+<h1>Basic</h1>
+<h2>Introduction.</h2>
+<p>This documents topic is for people who want to quickly try xmpppy for a simple task, like
+writing a command-line script for sending a single message.</p>
+<h2>Writing a simple script</h2>
+<p>This example demonstrates a simple script that sends message to one
+recipient.
+Example:</p>
+<pre>
+xsend test@jabber.org Hello there!
+</pre>
+<p>You don't have a similar tool in your toolkit? Using the xmpppy
+library it can be created easily.
+<br />What? Already have one? Hmm. Maybe you want to simplify things a bit, or just curious how
+to do it one more way? Anyway - let's start now!
+<br />
+First - we declare ourself as a python script and importing needed modules:</p>
+<pre>
+#!/usr/bin/python
+import sys,os,xmpp
+</pre>
+<p>After it we have to check if we have enough arguments on the command-line:</p>
+<pre>
+if len(sys.argv) &lt; 2:
+ print "Syntax: xsend JID text"
+ sys.exit(0)
+</pre>
+<p>After it we must decode arguments. Omitting all checks to simplify our script:</p>
+<pre>
+tojid=sys.argv[1]
+text=' '.join(sys.argv[2:])
+</pre>
+<p>One more non-jabber step: We have to to get our Jabber ID and login
+details. Presuming that all info
+stored in ~/.xsend file:</p>
+<pre>
+jidparams={}
+if os.access(os.environ['HOME']+'/.xsend',os.R_OK):
+ for ln in open(os.environ['HOME']+'/.xsend').readlines():
+ key,val=ln.strip().split('=',1)
+ jidparams[key.lower()]=val
+for mandatory in ['jid','password']:
+ if mandatory not in jidparams.keys():
+ open(os.environ['HOME']+'/.xsend','w').write('#JID=romeo@montague.net\n#PASSWORD=juliet\n')
+ print 'Please ensure the ~/.xsend file has valid JID for sending messages.'
+ sys.exit(0)
+</pre>
+<p>Phew! The most complex (non-jabber ;) ) part is finished. From now on we have to:</p>
+<ul>
+ <li>connect to jabber server</li>
+ <li>authenticate ourselves</li>
+ <li>submit a message</li>
+</ul>
+<p>Let's start:
+<br />
+0. To connect we must have a client instance. Calculating our server name and
+creating Client class instance for it:</p>
+<pre>
+jid=xmpp.protocol.JID(jidparams['jid'])
+cl=xmpp.Client(jid.getDomain(),debug=[])
+</pre>
+<p>1. Connect and authenticate with credentials from the config file.</p>
+<pre>
+cl.connect()
+cl.auth(jid.getNode(),jidparams['password'])
+</pre>
+<p>2. We can go online now (by sending the inital presence) but will not do that, as it is not nessessary for sending a message.
+So we send a message now!</p>
+<pre>
+#cl.sendInitialPresence()
+cl.send(xmpp.protocol.Message(tojid,text))
+</pre>
+<p>We're done! The session must now be closed but since we have not registered
+disconnect handler we will just leave it to python and TCP/IP layer.
+All jabber servers that I know handle <span style="font-style: italic;">such</span>
+disconnects correctly.
+<br />
+You can download this script <a href="examples/xsend.py">here</a>.</p>
+<h3>What now?</h3>
+<p>If you were impressed of how the things were done with xmpppy, you may be interested in
+more thorough examination of xmpppy library. The &quot;advanced&quot; and &quot;expert&quot;
+parts of this document are here to help you.
+<br />
+&quot;<a href="advanced.html">Advanced</a>&quot; (isn't writed yet) part is much like another tutorial and
+describing common principles of XMPP usage via xmpppy prism. It describes ideas that are the foundation of XML handling with the
+simplexml library, the essence of dispatcher's work and how messages are processed, and
+some guidelines to write more complex programs and uses of the library.
+<br />
+&quot;<a href="apidocs/">Expert</a>&quot; part is full library API description documentation.
+This is epydoc generated output - all info is taken from the xmpppy code so you can re-generate it at any time.
+</p>
+</body>
+</html>
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/README.py b/src/xmpppy-0.5.0rc1/doc/examples/README.py
new file mode 100755
index 00000000..ae01dc62
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/README.py
@@ -0,0 +1,71 @@
+#!/usr/bin/python
+# -*- coding: koi8-r -*-
+from xmpp import *
+
+def presenceHandler(conn,presence_node):
+ """ Handler for playing a sound when particular contact became online """
+ targetJID='node@domain.org'
+ if presence_node.getFrom().bareMatch(targetJID):
+ # play a sound
+ pass
+def iqHandler(conn,iq_node):
+ """ Handler for processing some "get" query from custom namespace"""
+ reply=iq_node.buildReply('result')
+ # ... put some content into reply node
+ conn.send(reply)
+ raise NodeProcessed # This stanza is fully processed
+def messageHandler(conn,mess_node): pass
+
+if 1:
+ """
+ Example 1:
+ Connecting to specified IP address.
+ Connecting to port 5223 - TLS is pre-started.
+ Using direct connect.
+ """
+ # Born a client
+ cl=Client('ejabberd.somedomain.org')
+ # ...connect it to SSL port directly
+ if not cl.connect(server=('1.2.3.4',5223)):
+ raise IOError('Can not connect to server.')
+else:
+ """
+ Example 2:
+ Connecting to server via proxy.
+ Assuming that servername resolves to jabber server IP.
+ TLS will be started automatically if available.
+ """
+ # Born a client
+ cl=Client('jabberd2.somedomain.org')
+ # ...connect via proxy
+ if not cl.connect(proxy={'host':'someproxy.somedomain.org','port':'8080','user':'proxyuser','password':'proxyuserpassword'}):
+ raise IOError('Can not connect to server.')
+# ...authorize client
+if not cl.auth('jabberuser','jabberuserpassword','optional resource name'):
+ raise IOError('Can not auth with server.')
+# ...register some handlers (if you will register them before auth they will be thrown away)
+cl.RegisterHandler('presence',presenceHandler)
+cl.RegisterHandler('iq',iqHandler)
+cl.RegisterHandler('message',messageHandler)
+# ...become available
+cl.sendInitPresence()
+# ...work some time
+cl.Process(1)
+# ...if connection is brocken - restore it
+if not cl.isConnected(): cl.reconnectAndReauth()
+# ...send an ASCII message
+cl.send(Message('test@jabber.org','Test message'))
+# ...send a national message
+cl.send(Message('test@jabber.org',unicode('Проверка связи','koi8-r')))
+# ...send another national message
+simplexml.ENCODING='koi8-r'
+cl.send(Message('test@jabber.org','Проверка связи 2'))
+# ...work some more time - collect replies
+cl.Process(1)
+# ...and then disconnect.
+cl.disconnect()
+
+"""
+If you have used jabberpy before you will find xmpppy very similar.
+See the docs for more info about library features.
+"""
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/bot.py b/src/xmpppy-0.5.0rc1/doc/examples/bot.py
new file mode 100755
index 00000000..42636300
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/bot.py
@@ -0,0 +1,94 @@
+#!/usr/bin/python
+# -*- coding: koi8-r -*-
+# $Id: bot.py,v 1.2 2006/10/06 12:30:42 normanr Exp $
+import sys
+import xmpp
+
+commands={}
+i18n={'ru':{},'en':{}}
+########################### user handlers start ##################################
+i18n['en']['HELP']="This is example jabber bot.\nAvailable commands: %s"
+def helpHandler(user,command,args,mess):
+ lst=commands.keys()
+ lst.sort()
+ return "HELP",', '.join(lst)
+
+i18n['en']['EMPTY']="%s"
+i18n['en']['HOOK1']='Responce 1: %s'
+def hook1Handler(user,command,args,mess):
+ return "HOOK1",'You requested: %s'%args
+
+i18n['en']['HOOK2']='Responce 2: %s'
+def hook2Handler(user,command,args,mess):
+ return "HOOK2","hook2 called with %s"%(`(user,command,args,mess)`)
+
+i18n['en']['HOOK3']='Responce 3: static string'
+def hook3Handler(user,command,args,mess):
+ return "HOOK3"*int(args)
+########################### user handlers stop ###################################
+############################ bot logic start #####################################
+i18n['en']["UNKNOWN COMMAND"]='Unknown command "%s". Try "help"'
+i18n['en']["UNKNOWN USER"]="I do not know you. Register first."
+
+def messageCB(conn,mess):
+ text=mess.getBody()
+ user=mess.getFrom()
+ user.lang='en' # dup
+ if text.find(' ')+1: command,args=text.split(' ',1)
+ else: command,args=text,''
+ cmd=command.lower()
+
+ if commands.has_key(cmd): reply=commands[cmd](user,command,args,mess)
+ else: reply=("UNKNOWN COMMAND",cmd)
+
+ if type(reply)==type(()):
+ key,args=reply
+ if i18n[user.lang].has_key(key): pat=i18n[user.lang][key]
+ elif i18n['en'].has_key(key): pat=i18n['en'][key]
+ else: pat="%s"
+ if type(pat)==type(''): reply=pat%args
+ else: reply=pat(**args)
+ else:
+ try: reply=i18n[user.lang][reply]
+ except KeyError:
+ try: reply=i18n['en'][reply]
+ except KeyError: pass
+ if reply: conn.send(xmpp.Message(mess.getFrom(),reply))
+
+for i in globals().keys():
+ if i[-7:]=='Handler' and i[:-7].lower()==i[:-7]: commands[i[:-7]]=globals()[i]
+
+############################# bot logic stop #####################################
+
+def StepOn(conn):
+ try:
+ conn.Process(1)
+ except KeyboardInterrupt: return 0
+ return 1
+
+def GoOn(conn):
+ while StepOn(conn): pass
+
+if len(sys.argv)<3:
+ print "Usage: bot.py username@server.net password"
+else:
+ jid=xmpp.JID(sys.argv[1])
+ user,server,password=jid.getNode(),jid.getDomain(),sys.argv[2]
+
+ conn=xmpp.Client(server)#,debug=[])
+ conres=conn.connect()
+ if not conres:
+ print "Unable to connect to server %s!"%server
+ sys.exit(1)
+ if conres<>'tls':
+ print "Warning: unable to estabilish secure connection - TLS failed!"
+ authres=conn.auth(user,password)
+ if not authres:
+ print "Unable to authorize on %s - check login/password."%server
+ sys.exit(1)
+ if authres<>'sasl':
+ print "Warning: unable to perform SASL auth os %s. Old authentication method used!"%server
+ conn.RegisterHandler('message',messageCB)
+ conn.sendInitPresence()
+ print "Bot started."
+ GoOn(conn)
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/commandsbot.py b/src/xmpppy-0.5.0rc1/doc/examples/commandsbot.py
new file mode 100644
index 00000000..f32c13c6
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/commandsbot.py
@@ -0,0 +1,289 @@
+#!/usr/bin/python
+""" The example of using xmpppy's Ad-Hoc Commands (JEP-0050) implementation.
+"""
+import xmpp
+from xmpp.protocol import *
+
+options = {
+ 'JID': 'circles@example.com',
+ 'Password': '********',
+}
+
+class TestCommand(xmpp.commands.Command_Handler_Prototype):
+ """ Example class. You should read source if you wish to understate how it works. This one
+ actually does some calculations."""
+ name = 'testcommand'
+ description = 'Circle calculations'
+ def __init__(self, jid=''):
+ """ Initialize some internals. Set the first request handler to self.calcTypeForm.
+ """
+ xmpp.commands.Command_Handler_Prototype.__init__(self,jid)
+ self.initial = {
+ 'execute': self.initialForm
+ }
+
+ def initialForm(self, conn, request):
+ """ Assign a session id and send the first form. """
+ sessionid = self.getSessionID()
+ self.sessions[sessionid] = {
+ 'jid':request.getFrom(),
+ 'data':{'type':None}
+ }
+
+ # simulate that the client sent sessionid, so calcTypeForm will be able
+ # to continue
+ request.getTag(name="command").setAttr('sessionid', sessionid)
+
+ return self.calcTypeForm(conn, request)
+
+ def calcTypeForm(self, conn, request):
+ """ Send first form to the requesting user. """
+ # get the session data
+ sessionid = request.getTagAttr('command','sessionid')
+ session = self.sessions[sessionid]
+
+ # What to do when a user sends us a response? Note, that we should always
+ # include 'execute', as it is a default action when requester does not send
+ # exact action to do (should be set to the same as 'next' or 'complete' fields)
+ session['actions'] = {
+ 'cancel': self.cancel,
+ 'next': self.calcTypeFormAccept,
+ 'execute': self.calcTypeFormAccept,
+ }
+
+ # The form to send
+ calctypefield = xmpp.DataField(
+ name='calctype',
+ desc='Calculation Type',
+ value=session['data']['type'],
+ options=[
+ ['Calculate the diameter of a circle','circlediameter'],
+ ['Calculate the area of a circle','circlearea']
+ ],
+ typ='list-single',
+ required=1)
+
+ # We set label attribute... seems that the xmpppy.DataField cannot do that
+ calctypefield.setAttr('label', 'Calculation Type')
+
+ form = xmpp.DataForm(
+ title='Select type of operation',
+ data=[
+ 'Use the combobox to select the type of calculation you would like'\
+ 'to do, then click Next.',
+ calctypefield])
+
+ # Build a reply with the form
+ reply = request.buildReply('result')
+ replypayload = [
+ xmpp.Node('actions',
+ attrs={'execute':'next'},
+ payload=[xmpp.Node('next')]),
+ form]
+ reply.addChild(
+ name='command',
+ namespace=NS_COMMANDS,
+ attrs={
+ 'node':request.getTagAttr('command','node'),
+ 'sessionid':sessionid,
+ 'status':'executing'},
+ payload=replypayload)
+ self._owner.send(reply) # Question: self._owner or conn?
+ raise xmpp.NodeProcessed
+
+ def calcTypeFormAccept(self, conn, request):
+ """ Load the calcType form filled in by requester, then reply with
+ the second form. """
+ # get the session data
+ sessionid = request.getTagAttr('command','sessionid')
+ session = self.sessions[sessionid]
+
+ # load the form
+ node = request.getTag(name='command').getTag(name='x',namespace=NS_DATA)
+ form = xmpp.DataForm(node=node)
+
+ # retrieve the data
+ session['data']['type'] = form.getField('calctype').getValue()
+
+ # send second form
+ return self.calcDataForm(conn, request)
+
+ def calcDataForm(self, conn, request, notavalue=None):
+ """ Send a form asking for diameter. """
+ # get the session data
+ sessionid = request.getTagAttr('command','sessionid')
+ session = self.sessions[sessionid]
+
+ # set the actions taken on requester's response
+ session['actions'] = {
+ 'cancel': self.cancel,
+ 'prev': self.calcTypeForm,
+ 'next': self.calcDataFormAccept,
+ 'execute': self.calcDataFormAccept
+ }
+
+ # create a form
+ radiusfield = xmpp.DataField(desc='Radius',name='radius',typ='text-single')
+ radiusfield.setAttr('label', 'Radius')
+
+ form = xmpp.DataForm(
+ title = 'Enter the radius',
+ data=[
+ 'Enter the radius of the circle (numbers only)',
+ radiusfield])
+
+ # build a reply stanza
+ reply = request.buildReply('result')
+ replypayload = [
+ xmpp.Node('actions',
+ attrs={'execute':'complete'},
+ payload=[xmpp.Node('complete'),xmpp.Node('prev')]),
+ form]
+
+ if notavalue:
+ replypayload.append(xmpp.Node('note',
+ attrs={'type': 'warn'},
+ payload=['You have to enter valid number.']))
+
+ reply.addChild(
+ name='command',
+ namespace=NS_COMMANDS,
+ attrs={
+ 'node':request.getTagAttr('command','node'),
+ 'sessionid':request.getTagAttr('command','sessionid'),
+ 'status':'executing'},
+ payload=replypayload)
+
+ self._owner.send(reply)
+ raise xmpp.NodeProcessed
+
+ def calcDataFormAccept(self, conn, request):
+ """ Load the calcType form filled in by requester, then reply with the result. """
+ # get the session data
+ sessionid = request.getTagAttr('command','sessionid')
+ session = self.sessions[sessionid]
+
+ # load the form
+ node = request.getTag(name='command').getTag(name='x',namespace=NS_DATA)
+ form = xmpp.DataForm(node=node)
+
+ # retrieve the data; if the entered value is not a number, return to second stage
+ try:
+ value = float(form.getField('radius').getValue())
+ except:
+ self.calcDataForm(conn, request, notavalue=True)
+
+ # calculate the answer
+ from math import pi
+ if session['data']['type'] == 'circlearea':
+ result = (value**2) * pi
+ else:
+ result = 2 * value * pi
+
+ # build the result form
+ form = xmpp.DataForm(
+ typ='result',
+ data=[xmpp.DataField(desc='result', name='result', value=result)])
+
+ # build the reply stanza
+ reply = request.buildReply('result')
+ reply.addChild(
+ name='command',
+ namespace=NS_COMMANDS,
+ attrs={
+ 'node':request.getTagAttr('command','node'),
+ 'sessionid':sessionid,
+ 'status':'completed'},
+ payload=[form])
+
+ self._owner.send(reply)
+
+ # erase the data about session
+ del self.sessions[sessionid]
+
+ raise xmpp.NodeProcessed
+
+ def cancel(self, conn, request):
+ """ Requester canceled the session, send a short reply. """
+ # get the session id
+ sessionid = request.getTagAttr('command','sessionid')
+
+ # send the reply
+ reply = request.buildReply('result')
+ reply.addChild(
+ name='command',
+ namespace=NS_COMMANDS,
+ attrs={
+ 'node':request.getTagAttr('command','node'),
+ 'sessionid':sessionid,
+ 'status':'cancelled'})
+ self._owner.send(reply)
+
+ # erase the data about session
+ del self.sessions[sessionid]
+
+ raise xmpp.NodeProcessed
+
+class ConnectionError: pass
+class AuthorizationError: pass
+class NotImplemented: pass
+
+class Bot:
+ """ The main bot class. """
+
+ def __init__(self, JID, Password):
+ """ Create a new bot. Connect to the server and log in. """
+
+ # connect...
+ jid = xmpp.JID(JID)
+ self.connection = xmpp.Client(jid.getDomain(), debug=['always', 'browser', 'testcommand'])
+
+ result = self.connection.connect()
+
+ if result is None:
+ raise ConnectionError
+
+ # authorize
+ result = self.connection.auth(jid.getNode(), Password)
+
+ if result is None:
+ raise AuthorizationError
+
+ # plugins
+ # disco - needed by commands
+
+ # warning: case of "plugin" method names are important!
+ # to attach a command to Commands class, use .plugin()
+ # to attach anything to Client class, use .PlugIn()
+ self.disco = xmpp.browser.Browser()
+ self.disco.PlugIn(self.connection)
+ self.disco.setDiscoHandler({
+ 'info': {
+ 'ids': [{
+ 'category': 'client',
+ 'type': 'pc',
+ 'name': 'Bot'
+ }],
+ 'features': [NS_DISCO_INFO],
+ }
+ })
+
+ self.commands = xmpp.commands.Commands(self.disco)
+ self.commands.PlugIn(self.connection)
+
+ self.command_test = TestCommand()
+ self.command_test.plugin(self.commands)
+
+ # presence
+ self.connection.sendInitPresence(requestRoster=0)
+
+ def loop(self):
+ """ Do nothing except handling new xmpp stanzas. """
+ try:
+ while self.connection.Process(1):
+ pass
+ except KeyboardInterrupt:
+ pass
+
+bot = Bot(**options)
+bot.loop()
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/logger.py b/src/xmpppy-0.5.0rc1/doc/examples/logger.py
new file mode 100755
index 00000000..b99686c1
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/logger.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python
+# -*- coding: koi8-r -*-
+from xmpp import *
+import time,os
+
+#BOT=(botjid,password)
+BOT=('test@penza-gsm.ru','test')
+#CONF=(confjid,password)
+CONF=('talks@conference.jabber.ru','')
+LOGDIR='./'
+PROXY={}
+#PROXY={'host':'192.168.0.1','port':3128,'username':'luchs','password':'secret'}
+#######################################
+
+def LOG(stanza,nick,text):
+ ts=stanza.getTimestamp()
+ if not ts:
+ ts=stanza.setTimestamp()
+ ts=stanza.getTimestamp()
+ tp=time.mktime(time.strptime(ts,'%Y%m%dT%H:%M:%S %Z'))+3600*3
+ if time.localtime()[-1]: tp+=3600
+ tp=time.localtime(tp)
+ fold=stanza.getFrom().getStripped().replace('@','%')+'_'+time.strftime("%Y.%m",tp)
+ day=time.strftime("%d",tp)
+ tm=time.strftime("%H:%M:%S",tp)
+ try: os.mkdir(LOGDIR+fold)
+ except: pass
+ fName='%s%s/%s.%s.html'%(LOGDIR,fold,fold,day)
+ try: open(fName)
+ except:
+ open(fName,'w').write("""<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xml:lang="ru-RU" lang="ru-RU" xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <meta content="text/html; charset=utf-8" http-equiv="content-type" />
+ <title>%s logs for %s.%s.</title>
+ </head>
+ <body>
+<table border="1"><tr><th>time</th><th>who</th><th>text</th></tr>
+"""%(CONF[0],fold,day))
+ text='<pre>%s</pre>'%text
+ open(fName,'a').write((u"<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n"%(tm,nick,text)).encode('utf-8'))
+ print (u"<tr><td>%s</td><td>%s</td><td>%s</td></tr>\n"%(tm,nick,text)).encode('koi8-r','replace')
+# print time.localtime(tp),nick,text
+
+def messageCB(sess,mess):
+ nick=mess.getFrom().getResource()
+ text=mess.getBody()
+ LOG(mess,nick,text)
+
+roster=[]
+def presenceCB(sess,pres):
+ nick=pres.getFrom().getResource()
+ text=''
+ if pres.getType()=='unavailable':
+ if nick in roster:
+ text=nick+unicode(' покинул конференцию','koi8-r')
+ roster.remove(nick)
+ else:
+ if nick not in roster:
+ text=nick+unicode(' пришёл в конференцию','koi8-r')
+ roster.append(nick)
+ if text: LOG(pres,nick,text)
+
+if 1:
+ cl=Client(JID(BOT[0]).getDomain(),debug=[])
+ cl.connect(proxy=PROXY)
+ cl.RegisterHandler('message',messageCB)
+ cl.RegisterHandler('presence',presenceCB)
+ cl.auth(JID(BOT[0]).getNode(),BOT[1])
+ p=Presence(to='%s/logger'%CONF[0])
+ p.setTag('x',namespace=NS_MUC).setTagData('password',CONF[1])
+ p.getTag('x').addChild('history',{'maxchars':'0','maxstanzas':'0'})
+ cl.send(p)
+ while 1:
+ cl.Process(1)
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/xsend.py b/src/xmpppy-0.5.0rc1/doc/examples/xsend.py
new file mode 100755
index 00000000..59b202a9
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/xsend.py
@@ -0,0 +1,44 @@
+#!/usr/bin/python
+# $Id: xsend.py,v 1.8 2006/10/06 12:30:42 normanr Exp $
+import sys,os,xmpp,time
+
+if len(sys.argv) < 2:
+ print "Syntax: xsend JID text"
+ sys.exit(0)
+
+tojid=sys.argv[1]
+text=' '.join(sys.argv[2:])
+
+jidparams={}
+if os.access(os.environ['HOME']+'/.xsend',os.R_OK):
+ for ln in open(os.environ['HOME']+'/.xsend').readlines():
+ if not ln[0] in ('#',';'):
+ key,val=ln.strip().split('=',1)
+ jidparams[key.lower()]=val
+for mandatory in ['jid','password']:
+ if mandatory not in jidparams.keys():
+ open(os.environ['HOME']+'/.xsend','w').write('#Uncomment fields before use and type in correct credentials.\n#JID=romeo@montague.net/resource (/resource is optional)\n#PASSWORD=juliet\n')
+ print 'Please point ~/.xsend config file to valid JID for sending messages.'
+ sys.exit(0)
+
+jid=xmpp.protocol.JID(jidparams['jid'])
+cl=xmpp.Client(jid.getDomain(),debug=[])
+
+con=cl.connect()
+if not con:
+ print 'could not connect!'
+ sys.exit()
+print 'connected with',con
+auth=cl.auth(jid.getNode(),jidparams['password'],resource=jid.getResource())
+if not auth:
+ print 'could not authenticate!'
+ sys.exit()
+print 'authenticated using',auth
+
+#cl.SendInitPresence(requestRoster=0) # you may need to uncomment this for old server
+id=cl.send(xmpp.protocol.Message(tojid,text))
+print 'sent message with id',id
+
+time.sleep(1) # some older servers will not send the message if you disconnect immediately after sending
+
+#cl.disconnect()
diff --git a/src/xmpppy-0.5.0rc1/doc/examples/xtalk.py b/src/xmpppy-0.5.0rc1/doc/examples/xtalk.py
new file mode 100644
index 00000000..8832875f
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/examples/xtalk.py
@@ -0,0 +1,83 @@
+#!/usr/bin/python
+# $Id: xtalk.py,v 1.4 2008/08/09 17:00:18 normanr Exp $
+import sys,os,xmpp,time,select
+
+class Bot:
+
+ def __init__(self,jabber,remotejid):
+ self.jabber = jabber
+ self.remotejid = remotejid
+
+ def register_handlers(self):
+ self.jabber.RegisterHandler('message',self.xmpp_message)
+
+ def xmpp_message(self, con, event):
+ type = event.getType()
+ fromjid = event.getFrom().getStripped()
+ body = event.getBody()
+ if type in ['message', 'chat', None] and fromjid == self.remotejid and body:
+ sys.stdout.write(body + '\n')
+
+ def stdio_message(self, message):
+ m = xmpp.protocol.Message(to=self.remotejid,body=message,typ='chat')
+ self.jabber.send(m)
+
+ def xmpp_connect(self):
+ con=self.jabber.connect()
+ if not con:
+ sys.stderr.write('could not connect!\n')
+ return False
+ sys.stderr.write('connected with %s\n'%con)
+ auth=self.jabber.auth(jid.getNode(),jidparams['password'],resource=jid.getResource())
+ if not auth:
+ sys.stderr.write('could not authenticate!\n')
+ return False
+ sys.stderr.write('authenticated using %s\n'%auth)
+ self.register_handlers()
+ return con
+
+if __name__ == '__main__':
+
+ if len(sys.argv) < 2:
+ print "Syntax: xtalk JID"
+ sys.exit(0)
+
+ tojid=sys.argv[1]
+
+ jidparams={}
+ if os.access(os.environ['HOME']+'/.xtalk',os.R_OK):
+ for ln in open(os.environ['HOME']+'/.xtalk').readlines():
+ if not ln[0] in ('#',';'):
+ key,val=ln.strip().split('=',1)
+ jidparams[key.lower()]=val
+ for mandatory in ['jid','password']:
+ if mandatory not in jidparams.keys():
+ open(os.environ['HOME']+'/.xtalk','w').write('#Uncomment fields before use and type in correct credentials.\n#JID=romeo@montague.net/resource (/resource is optional)\n#PASSWORD=juliet\n')
+ print 'Please point ~/.xtalk config file to valid JID for sending messages.'
+ sys.exit(0)
+
+ jid=xmpp.protocol.JID(jidparams['jid'])
+ cl=xmpp.Client(jid.getDomain())#,debug=[])
+
+ bot=Bot(cl,tojid)
+
+ if not bot.xmpp_connect():
+ sys.stderr.write("Could not connect to server, or password mismatch!\n")
+ sys.exit(1)
+
+ #cl.SendInitPresence(requestRoster=0) # you may need to uncomment this for old server
+
+ socketlist = {cl.Connection._sock:'xmpp',sys.stdin:'stdio'}
+ online = 1
+
+ while online:
+ (i , o, e) = select.select(socketlist.keys(),[],[],1)
+ for each in i:
+ if socketlist[each] == 'xmpp':
+ cl.Process(1)
+ elif socketlist[each] == 'stdio':
+ msg = sys.stdin.readline().rstrip('\r\n')
+ bot.stdio_message(msg)
+ else:
+ raise Exception("Unknown socket type: %s" % repr(socketlist[each]))
+ #cl.disconnect()
diff --git a/src/xmpppy-0.5.0rc1/doc/index.html b/src/xmpppy-0.5.0rc1/doc/index.html
new file mode 100644
index 00000000..583c72a0
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/index.html
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC
+ "-//W3C//DTD XHTML 1.0 Transitional//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head>
+ <title>xmpppy: the jabber python project</title>
+ <link rel="stylesheet" type="text/css" href="xmpppy.css" />
+ </head>
+ <body>
+ <table class="head">
+ <tbody>
+ <tr>
+ <td class="head">
+ <img src="xmpppy_title.png" alt="xmpppy" title="the xmpppy project" height="69" width="300" />
+ </td>
+ <td class="sflogo">
+ <a href="http://sourceforge.net/">
+ <img src="http://sourceforge.net/sflogo.php?group_id=97081&amp;type=4" alt="SourceForge Logo" title="SourceForge Logo" border="0" height="37" hspace="30" width="125" />
+ </a>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <table class="content">
+ <tbody>
+ <tr>
+ <td class="leftside">
+ <h3>about</h3>
+ <p><a href="http://xmpppy.sourceforge.net/">xmpppy</a> is a
+ <a href="http://www.python.org">Python</a> library
+ that is targeted to provide easy scripting with <a href="http://www.jabber.org">Jabber</a>.
+ Similar projects are <a href="http://twistedmatrix.com/projects/words/">Twisted Words</a>
+ and <a href="http://jabberpy.sourceforge.net/">jabber.py.</a></p>
+ <p>This library was not designed from scratch. It inherits some code from
+ jabberpy and have very similar API in many places. Though it is separate
+ project since it have almost completely different architecture and primarily
+ aims to work with jabberd2 - the new Open Source Jabber Server.</p>
+ <p>xmpppy is distributed under the terms of
+ <a href="http://www.gnu.org/licenses/gpl.txt">GNU General Public License</a>
+ and can be freely redistributed without any charge.</p>
+ <h3>documentation</h3>
+ <p>Documentation is now in the process of heavy development and not yet
+ finished but most critical docs exist - please feel free to ask any questions if
+ you will find the docs incomplete (see support section below).</p>
+ <div>
+ <ul>
+ <li><a href="basic.html">Basic documentation</a> - a simple script.</li>
+ <li><a href="advanced.html">Advanced documentation</a> - architecture of library and guidelines.</li>
+ <li><a href="apidocs/index.html">Expert documentation</a> - API docs.</li>
+ </ul>
+ </div>
+ <h3>examples</h3>
+ <p>For these who prefer reading samples of code than digging through [incomplete] docs -
+ here they are. Simple (but working) examples of xmpppy usage.</p>
+ <div>
+ <ul>
+ <li><a href="examples/README.py">README.py</a><br />
+ Self-explanatory library usage example</li>
+ <li><a href="examples/xsend.py">xsend.py</a><br />
+ Command-line utility for sending jabber messages</li>
+ <li><a href="examples/xtalk.py">xtalk.py</a><br />
+ Command-line utility for chatting with a single user</li>
+ <li><a href="examples/bot.py">bot.py</a><br />
+ Xmpppy bot framework, handles messages</li>
+ <li><a href="examples/commandsbot.py">commandsbot.py</a><br />
+ Xmpppy bot framework, handles ad hoc commands</li>
+ <li><a href="examples/logger.py">logger.py</a><br />
+ Simple conference logger bot</li>
+ </ul>
+ </div>
+ <p>You can also look to at the <a href="http://xmpppy.sourceforge.net/irc/">IRC transport</a>,
+ <a href="http://xmpppy.sourceforge.net/mail/">Mail transport</a>,
+ <a href="http://xmpppy.sourceforge.net/yahoo/">Yahoo transport</a> or
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=130713">xmppd</a>
+ project code if you wish to see the serious library usage.</p>
+ <h3>download</h3>
+ <div>You can look for released versions on
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081">downloads page</a>
+ or alternatively you can grab the latest version directly from CVS tree
+ by typing the following commands:
+ <blockquote>
+ cvs -d:pserver:anonymous@xmpppy.cvs.sourceforge.net:/cvsroot/xmpppy login
+ </blockquote>
+ (hit "enter" when you will be prompted for password)
+ <blockquote>
+ cvs -z3 -d:pserver:anonymous@xmpppy.cvs.sourceforge.net:/cvsroot/xmpppy co xmpppy
+ </blockquote>
+ </div>
+ <p>You can also browse xmpppy (and several xmpppy-based
+ projects) CVS online <a href="http://xmpppy.cvs.sourceforge.net/xmpppy/xmpppy/">here</a>.</p>
+ <p>If you have an RSS feed reader, there is
+ an RSS feed of CVS commits <a href="http://xmpppy.sourceforge.net/cvs-xmpppy.xml">here</a>.</p>
+ <h3>support</h3>
+ <p>If you have any questions about using xmpppy you can join
+ <a href="http://lists.sourceforge.net/lists/listinfo/xmpppy-devel">xmpppy-devel maillist</a>.
+ Here you can always find the best support, as you can find the developers here.</p>
+ <h3>donations</h3>
+ <p>If you are willing to help you can consult
+ <a href="http://software.newsforge.com/article.pl?sid=05/01/06/1557225">this article</a>
+ for how to do it. Thanks!</p>
+ <p>If you want to donate some money to encourage me to continue work on
+ library (it helps, really!) you can do it via e-gold system (account 1552795) or via
+ bank transfer (contact me via jabber or email to get the details).</p>
+ <a name="author"></a>
+ <h3>author</h3>
+ <p>Alexey Nezhdanov<br />
+ Russian, born 18 Nov 1976.<br />
+ My timezone is GMT+3<br />
+ e-mail &amp; Jabber: snake at penza-gsm.ru<br />
+ ICQ: 19515046</p>
+ <div>I'm seeking for a job over Internet. It may be jabber-related work or
+ any other.<br />
+ Possible directions of work:
+ <ul>
+ <li>Python projects (preferred)</li>
+ <li>C++ projects</li>
+ <li>Remote systems administering</li>
+ </ul>
+ My skills:
+ <ul>
+ <li>16 years of programming. Basic -> Pascal -> C++ -> Python</li>
+ <li>9 years of system administrator work. DOS -> Win 3.1 -> Win95 -> Win98 -> linux2.2 -> linux2.4 -> linux2.6</li>
+ <li>Automation tasks</li>
+ <li>Automated instant messenging (state change/failures reporting)</li>
+ <li>Some research work:
+ <ul>
+ <li>wavelet audio analysis</li>
+ <li>speech recognising</li>
+ <li>realtime texture [de]compression (for 3D systems).</li>
+ </ul>
+ </li>
+ </ul>
+ </div>
+ </td>
+ <td class="rightside">
+ <h3>downloads</h3>
+ <p>
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=103821">xmpppy</a><br />
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=130713">xmppd.py</a><br />
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=118831">xmpppy-irc</a><br />
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=182511">xmpppy-yahoo</a><br />
+ <a href="http://sourceforge.net/project/showfiles.php?group_id=97081&amp;package_id=168390">pyGAIM-t</a>
+ </p>
+ <p><a href="http://sourceforge.net/project/showfiles.php?group_id=97081">List all files</a></p>
+ <h3>sourceforge</h3>
+ <p>
+ <a href="http://sourceforge.net/projects/xmpppy/">Project Summary</a><br />
+ <a href="http://sourceforge.net/tracker/?atid=616918&amp;group_id=97081">Feature Requests</a><br />
+ <a href="http://sourceforge.net/tracker/?atid=616915&amp;group_id=97081">Bugs</a><br />
+ <a href="http://sourceforge.net/tracker/?atid=616917&amp;group_id=97081">Patches</a><br />
+ </p>
+ <h3>exits</h3>
+ <p>
+ <a href="http://www.jabber.org/">jabber.org</a><br />
+ <a href="http://xmpppy.sourceforge.net/irc/">IRC transport</a><br />
+ <a href="http://xmpppy.sourceforge.net/mail/">Mail transport</a><br />
+ <a href="http://xmpppy.sourceforge.net/yahoo/">Yahoo transport</a><br />
+ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ <p>the <a href="http://sourceforge.net/projects/xmpppy/">xmpppy project</a></p>
+ </body>
+</html>
diff --git a/src/xmpppy-0.5.0rc1/doc/xmpppy.css b/src/xmpppy-0.5.0rc1/doc/xmpppy.css
new file mode 100644
index 00000000..eeed2b2f
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/xmpppy.css
@@ -0,0 +1,70 @@
+/* xmpppy.css - The stylesheet of the xmpppy homepage
+ *
+ * Parts are taken of ickle stylesheet
+ *
+ * Copyleft 2005 by Marek Kubica
+ *
+ * Version 0.0.20050507
+ *
+ */
+
+/* set a background color, a light grey*/
+body {
+ background-color: #F2F2F2;
+}
+
+/* fonts - no serif */
+a, p, ul, td, div {
+ font-family: sans-serif;
+}
+
+/* hyperlinks: blue, not decorated, just bold */
+a {
+ text-decoration: none;
+ color: #00488F;
+ font-weight: bold;
+}
+
+/* the head table, blue like the sf.net logo */
+table.head {
+ width: 100%;
+ background-color: #00488F;
+ text-align: right;
+ border-collapse: collapse;
+}
+
+td.head {
+ padding: 0px;
+}
+
+table.content {
+ padding: 5px;
+ border-spacing: 30px;
+}
+
+td.sflogo {
+ width: 99%;
+}
+
+/* the conentent of the left side fills 80% of the screen */
+td.leftside {
+ width: 80%;
+}
+
+/* the links on the right side fill the remaining 20%
+ * and are displayed on top
+ */
+td.rightside {
+ width: 20%;
+ vertical-align: top;
+}
+
+/* not simple bullets, but squares */
+ul {
+ list-style-type: square;
+}
+
+/* blockquotes in italic */
+blockquote {
+ font-style: italic;
+}
diff --git a/src/xmpppy-0.5.0rc1/doc/xmpppy_title.png b/src/xmpppy-0.5.0rc1/doc/xmpppy_title.png
new file mode 100644
index 00000000..6ffdfb4e
--- /dev/null
+++ b/src/xmpppy-0.5.0rc1/doc/xmpppy_title.png
Binary files differ