Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
gajim
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
l-n-s
gajim
Commits
fa49d305
Commit
fa49d305
authored
21 years ago
by
Yann Leboulanger
Browse files
Options
Downloads
Patches
Plain Diff
Jabberpy V0.5
parent
cf2c7b50
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
common/jabber.py
+67
-66
67 additions, 66 deletions
common/jabber.py
common/xmlstream.py
+41
-40
41 additions, 40 deletions
common/xmlstream.py
with
108 additions
and
106 deletions
common/jabber.py
+
67
−
66
View file @
fa49d305
## jabber.py
## jabber.py
##
## Copyright (C) 2001 Matthew Allum
##
...
...
@@ -86,7 +86,7 @@ DBG_NODE_UNKNOWN = 'jb-node-unknown' ; debug.debug_flags.append( DBG_NODE_UNK
#
# JANA core namespaces
# JANA core namespaces
# from http://www.jabber.org/jana/namespaces.php as of 2003-01-12
# "myname" means that namespace didnt have a name in the jabberd headers
#
...
...
@@ -107,7 +107,7 @@ NS_COMP_ACCEPT = "jabber:component:accept" # myname
NS_COMP_CONNECT
=
"
jabber:component:connect
"
# myname
#
# JANA JEP namespaces, ordered by JEP
# from http://www.jabber.org/jana/namespaces.php as of 2003-01-12
...
...
@@ -140,10 +140,10 @@ NS_P_COMMANDS = _NS_PROTOCOL + "/commands" # JEP-0050
"""
2002-01-11 jaclu
Defined in jabberd/lib/lib.h, but not JANA aproved and not used in jabber.py
so commented out, should/could propably be removed...
NS_ADMIN =
"
jabber:iq:admin
"
NS_AUTH_OK =
"
jabber:iq:auth:0k
"
NS_CONFERENCE =
"
jabber:iq:conference
"
...
...
@@ -189,13 +189,13 @@ def ustr(what):
return
r
xmlstream
.
ustr
=
ustr
class
NodeProcessed
(
Exception
):
pass
# currently only for Connection._expectedIqHandler
class
NodeProcessed
(
Exception
):
pass
# currently only for Connection._expectedIqHandler
class
Connection
(
xmlstream
.
Client
):
"""
Forms the base for both Client and Component Classes
"""
def
__init__
(
self
,
host
,
port
,
namespace
,
debug
=
False
,
log
=
False
,
connection
=
xmlstream
.
TCP
,
hostIP
=
None
,
proxy
=
None
):
debug
=
[]
,
log
=
False
,
connection
=
xmlstream
.
TCP
,
hostIP
=
None
,
proxy
=
None
):
xmlstream
.
Client
.
__init__
(
self
,
host
,
port
,
namespace
,
debug
=
debug
,
log
=
log
,
connection
=
connection
,
...
...
@@ -207,11 +207,11 @@ class Connection(xmlstream.Client):
self
.
registerProtocol
(
'
presence
'
,
Presence
)
self
.
registerHandler
(
'
iq
'
,
self
.
_expectedIqHandler
,
system
=
True
)
self
.
_expected
=
{}
self
.
_id
=
0
;
self
.
lastErr
=
''
self
.
lastErrCode
=
0
...
...
@@ -230,13 +230,13 @@ class Connection(xmlstream.Client):
print
"
WARNING! setIqHandler(...) method is obsolette, use registerHandler(
'
iq
'
,...) instead.
"
return
self
.
registerHandler
(
'
iq
'
,
func
,
type
,
ns
)
def
header
(
self
):
def
header
(
self
):
self
.
DEBUG
(
"
stream: sending initial header
"
,
DBG_INIT
)
str
=
u
"
<?xml version=
'
1.0
'
encoding=
'
UTF-8
'
?>
\
<stream:stream to=
'
%s
'
xmlns=
'
%s
'"
%
(
self
.
_host
,
self
.
_namespace
)
if
self
.
_outgoingID
:
str
=
str
+
"
id=
'
%s
'
"
%
self
.
_outgoingID
if
self
.
_outgoingID
:
str
=
str
+
"
id=
'
%s
'
"
%
self
.
_outgoingID
str
=
str
+
"
xmlns:stream=
'
http://etherx.jabber.org/streams
'
>
"
self
.
send
(
str
)
self
.
process
(
timeout
)
...
...
@@ -276,7 +276,7 @@ class Connection(xmlstream.Client):
if
not
self
.
handlers
[
name
].
has_key
(
ns
):
ns
=
''
if
not
self
.
handlers
[
name
].
has_key
(
typ
):
typ
=
''
if
not
self
.
handlers
[
name
].
has_key
(
typns
):
typns
=
''
if
typ
==
typns
:
typns
=
''
if
typ
==
typns
:
typns
=
''
chain
=
[]
for
key
in
[
'
default
'
,
typ
,
ns
,
typns
]:
# we will use all handlers: from very common to very particular
...
...
@@ -307,10 +307,10 @@ class Connection(xmlstream.Client):
def
registerHandler
(
self
,
name
,
handler
,
type
=
''
,
ns
=
''
,
chained
=
False
,
makefirst
=
False
,
system
=
False
):
"""
Sets the callback func for processing incoming stanzas.
Multiple callback functions can be set which are called in
succession. Callback can optionally raise an NodeProcessed error to
stop stanza from further processing. A type and namespace attributes can
succession. Callback can optionally raise an NodeProcessed error to
stop stanza from further processing. A type and namespace attributes can
also be optionally passed so the callback is only called when a stanza of
this type is received. Namespace attribute MUST be omitted if you
this type is received. Namespace attribute MUST be omitted if you
registering an Iq processing handler.
If
'
chainOutput
'
is set to False (the default), the given function
...
...
@@ -359,7 +359,7 @@ class Connection(xmlstream.Client):
self.lastErr and self.lastErrCode is set to the received error. If
the operation times out (which only happens if a timeout value is
given), waitForResponse will return None and self.lastErr will be
set to
"
Timeout
"
.
set to
"
Timeout
"
.
Changed default from timeout=0 to timeout=300 to avoid hangs in
scripts and such.
If you _really_ want no timeout, just set it to 0
"""
...
...
@@ -372,7 +372,7 @@ class Connection(xmlstream.Client):
self
.
DEBUG
(
"
waiting with timeout:%s for %s
"
%
(
timeout
,
ustr
(
ID
)),
DBG_NODE_IQ
)
else
:
self
.
DEBUG
(
"
waiting for %s
"
%
ustr
(
ID
),
DBG_NODE_IQ
)
while
(
not
self
.
_expected
[
ID
])
and
not
has_timed_out
:
if
not
self
.
process
(
0.2
):
return
None
if
timeout
and
(
time
.
time
()
>
abort_time
):
...
...
@@ -405,17 +405,17 @@ class Connection(xmlstream.Client):
"""
Returns a unique ID
"""
self
.
_id
=
self
.
_id
+
1
return
ustr
(
self
.
_id
)
#############################################################################
class
Client
(
Connection
):
"""
Class for managing a client connection to a jabber server.
"""
def
__init__
(
self
,
host
,
port
=
5222
,
debug
=
False
,
log
=
False
,
def
__init__
(
self
,
host
,
port
=
5222
,
debug
=
[]
,
log
=
False
,
connection
=
xmlstream
.
TCP
,
hostIP
=
None
,
proxy
=
None
):
Connection
.
__init__
(
self
,
host
,
port
,
NS_CLIENT
,
debug
,
log
,
connection
=
connection
,
hostIP
=
hostIP
,
proxy
=
proxy
)
self
.
registerHandler
(
'
iq
'
,
self
.
_IqRosterManage
,
'
result
'
,
NS_ROSTER
,
system
=
True
)
self
.
registerHandler
(
'
iq
'
,
self
.
_IqRosterManage
,
'
set
'
,
NS_ROSTER
,
system
=
True
)
self
.
registerHandler
(
'
iq
'
,
self
.
_IqRegisterResult
,
'
result
'
,
NS_REGISTER
,
system
=
True
)
...
...
@@ -478,7 +478,7 @@ class Client(Connection):
"
NS_REGISTER and type==result
"
self
.
_reg_info
=
{}
for
item
in
iq_obj
.
getQueryNode
().
getChildren
():
self
.
_reg_info
[
item
.
getName
()]
=
item
.
getData
()
self
.
_reg_info
[
item
.
getName
()]
=
item
.
getData
()
def
_IqAgentsResult
(
self
,
conn
,
iq_obj
):
"
NS_AGENTS and type==result
"
...
...
@@ -515,13 +515,13 @@ class Client(Connection):
auth_set_iq
=
Iq
(
type
=
'
set
'
)
auth_set_iq
.
setID
(
'
auth-set
'
)
q
=
auth_set_iq
.
setQuery
(
NS_AUTH
)
q
.
insertTag
(
'
username
'
).
insertData
(
username
)
q
.
insertTag
(
'
resource
'
).
insertData
(
resource
)
if
auth_ret_query
.
getTag
(
'
token
'
):
token
=
auth_ret_query
.
getTag
(
'
token
'
).
getData
()
seq
=
auth_ret_query
.
getTag
(
'
sequence
'
).
getData
()
self
.
DEBUG
(
"
zero-k authentication supported
"
,(
DBG_INIT
,
DBG_NODE_IQ
))
...
...
@@ -538,7 +538,7 @@ class Client(Connection):
else
:
self
.
DEBUG
(
"
plain text authentication supported
"
,(
DBG_INIT
,
DBG_NODE_IQ
))
q
.
insertTag
(
'
password
'
).
insertData
(
passwd
)
iq_result
=
self
.
SendAndWaitForResponse
(
auth_set_iq
)
if
iq_result
==
None
:
...
...
@@ -592,7 +592,6 @@ class Client(Connection):
if
groups
!=
None
:
for
group
in
groups
:
item
.
insertTag
(
'
group
'
).
insertData
(
group
)
# self.send(iq)
dummy
=
self
.
SendAndWaitForResponse
(
iq
)
# Do we need to wait??
...
...
@@ -620,7 +619,7 @@ class Client(Connection):
# self.DEBUG("Requesting reg info from %s%s:" % (agent, self._host), DBG_NODE_IQ)
self
.
DEBUG
(
"
Requesting reg info from %s:
"
%
agent
,
DBG_NODE_IQ
)
self
.
DEBUG
(
ustr
(
reg_iq
),
DBG_NODE_IQ
)
return
self
.
SendAndWaitForResponse
(
reg_iq
)
return
self
.
SendAndWaitForResponse
(
reg_iq
)
def
getRegInfo
(
self
):
...
...
@@ -656,14 +655,16 @@ class Client(Connection):
Note that you must be authorised before attempting to deregister.
"""
if
agent
:
agent
=
agent
+
'
.
'
self
.
send
(
Presence
(
to
=
agent
+
self
.
_host
,
type
=
'
unsubscribed
'
))
# This is enough f.e. for icqv7t or jit
# agent = agent + '.'
# self.send(Presence(to=agent+self._host,type='unsubscribed')) # This is enough f.e. for icqv7t or jit
self
.
send
(
Presence
(
to
=
agent
,
type
=
'
unsubscribed
'
))
# This is enough f.e. for icqv7t or jit
if
agent
is
None
:
agent
=
''
q
=
self
.
requestRegInfo
()
kids
=
q
.
getQueryPayload
()
keyTag
=
kids
.
getTag
(
"
key
"
)
iq
=
Iq
(
to
=
agent
+
self
.
_host
,
type
=
"
set
"
)
# iq = Iq(to=agent+self._host, type="set")
iq
=
Iq
(
to
=
agent
,
type
=
"
set
"
)
iq
.
setQuery
(
NS_REGISTER
)
iq
.
setQueryNode
(
""
)
q
=
iq
.
getQueryNode
()
...
...
@@ -766,7 +767,7 @@ class Protocol(xmlstream.Node):
try
:
return
JID
(
self
.
getAttr
(
'
to
'
))
except
:
return
None
def
getFrom
(
self
):
"""
Returns the
'
from
'
attribute as a JID object.
"""
try
:
return
JID
(
self
.
getAttr
(
'
from
'
))
...
...
@@ -808,7 +809,7 @@ class Protocol(xmlstream.Node):
def
getX
(
self
,
index
=
0
):
"""
Returns the x namespace, optionally passed an index if there are
multiple tags.
"""
try
:
return
self
.
getXNodes
(
'
x
'
)[
index
].
namespace
try
:
return
self
.
getXNodes
()[
index
].
namespace
except
:
return
None
...
...
@@ -829,10 +830,10 @@ class Protocol(xmlstream.Node):
if
type
(
payload
)
==
type
(
''
)
or
type
(
payload
)
==
type
(
u
''
):
payload
=
xmlstream
.
NodeBuilder
(
payload
).
getDom
()
x
.
kids
=
[]
# should be a method for this realy
x
.
kids
=
[]
# should be a method for this realy
x
.
insertNode
(
payload
)
def
getXPayload
(
self
,
val
=
None
):
"""
Returns the x tags
'
payload as a list of Node instances.
"""
nodes
=
[]
...
...
@@ -849,7 +850,7 @@ class Protocol(xmlstream.Node):
nodes
.
append
(
xnode
.
kids
[
0
])
return
nodes
def
getXNode
(
self
,
val
=
None
):
"""
Returns the x Node instance. If there are multiple tags
the first Node is returned. For multiple X nodes use getXNodes
...
...
@@ -904,7 +905,7 @@ class Message(Protocol):
except
:
return
None
def
getSubject
(
self
):
def
getSubject
(
self
):
"""
Returns the message
'
s subject.
"""
try
:
return
self
.
getTag
(
'
subject
'
).
getData
()
except
:
return
None
...
...
@@ -928,7 +929,7 @@ class Message(Protocol):
else
:
body
=
self
.
insertTag
(
'
body
'
).
putData
(
val
)
def
setSubject
(
self
,
val
):
"""
Sets the message subject text.
"""
subj
=
self
.
getTag
(
'
subject
'
)
...
...
@@ -959,7 +960,7 @@ class Message(Protocol):
automatically set.
"""
m
=
Message
(
to
=
self
.
getFrom
(),
body
=
reply_txt
)
if
not
self
.
getType
()
==
None
:
m
.
setType
(
self
.
getType
())
m
.
setType
(
self
.
getType
())
t
=
self
.
getThread
()
if
t
:
m
.
setThread
(
t
)
return
m
...
...
@@ -993,7 +994,7 @@ class Presence(Protocol):
"""
Returns the presence priority
"""
try
:
return
self
.
getTag
(
'
priority
'
).
getData
()
except
:
return
None
def
setShow
(
self
,
val
):
"""
Sets the presence show
"""
show
=
self
.
getTag
(
'
show
'
)
...
...
@@ -1014,7 +1015,7 @@ class Presence(Protocol):
#############################################################################
class
Iq
(
Protocol
):
class
Iq
(
Protocol
):
"""
Class for creating and managing jabber <iq> protocol
elements
"""
def
__init__
(
self
,
to
=
None
,
type
=
None
,
query
=
None
,
attrs
=
None
,
frm
=
None
,
payload
=
[],
node
=
None
):
...
...
@@ -1069,12 +1070,12 @@ class Iq(Protocol):
if
not
add
:
q
.
kids
=
[]
q
.
insertNode
(
payload
)
def
getQueryPayload
(
self
):
"""
Returns the query
'
s payload as a Node list
"""
q
=
self
.
getQueryNode
()
if
q
:
return
q
.
kids
def
getQueryNode
(
self
):
"""
Returns any textual data contained by the query tag
"""
try
:
return
self
.
getTag
(
'
query
'
)
...
...
@@ -1141,7 +1142,7 @@ class Roster:
def
getStatus
(
self
,
jid
):
## extended
"""
Returns the
'
status
'
value for a Roster item with the given jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
status
'
]
return
None
...
...
@@ -1149,7 +1150,7 @@ class Roster:
def
getShow
(
self
,
jid
):
## extended
"""
Returns the
'
show
'
value for a Roster item with the given jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
show
'
]
return
None
...
...
@@ -1158,16 +1159,16 @@ class Roster:
def
getOnline
(
self
,
jid
):
## extended
"""
Returns the
'
online
'
status for a Roster item with the given jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
online
'
]
return
None
def
getSub
(
self
,
jid
):
"""
Returns the
'
subscription
'
status for a Roster item with the given
jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
sub
'
]
return
None
...
...
@@ -1175,7 +1176,7 @@ class Roster:
def
getName
(
self
,
jid
):
"""
Returns the
'
name
'
for a Roster item with the given jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
name
'
]
return
None
...
...
@@ -1192,7 +1193,7 @@ class Roster:
def
getAsk
(
self
,
jid
):
"""
Returns the
'
ask
'
status for a Roster item with the given jid.
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
return
self
.
_data
[
jid
][
'
ask
'
]
return
None
...
...
@@ -1258,12 +1259,12 @@ class Roster:
def
_setOnline
(
self
,
jid
,
val
):
"""
Used internally - private
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
self
.
_data
[
jid
][
'
online
'
]
=
val
if
self
.
_listener
!=
None
:
self
.
_listener
(
"
update
"
,
jid
,
{
'
online
'
:
val
})
else
:
## fall back
else
:
## fall back
jid_basic
=
JID
(
jid
).
getStripped
()
if
self
.
_data
.
has_key
(
jid_basic
):
self
.
_data
[
jid_basic
][
'
online
'
]
=
val
...
...
@@ -1273,12 +1274,12 @@ class Roster:
def
_setShow
(
self
,
jid
,
val
):
"""
Used internally - private
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
self
.
_data
[
jid
][
'
show
'
]
=
val
self
.
_data
[
jid
][
'
show
'
]
=
val
if
self
.
_listener
!=
None
:
self
.
_listener
(
"
update
"
,
jid
,
{
'
show
'
:
val
})
else
:
## fall back
else
:
## fall back
jid_basic
=
JID
(
jid
).
getStripped
()
if
self
.
_data
.
has_key
(
jid_basic
):
self
.
_data
[
jid_basic
][
'
show
'
]
=
val
...
...
@@ -1288,12 +1289,12 @@ class Roster:
def
_setStatus
(
self
,
jid
,
val
):
"""
Used internally - private
"""
jid
=
ustr
(
jid
)
jid
=
ustr
(
jid
)
if
self
.
_data
.
has_key
(
jid
):
self
.
_data
[
jid
][
'
status
'
]
=
val
if
self
.
_listener
!=
None
:
self
.
_listener
(
"
update
"
,
jid
,
{
'
status
'
:
val
})
else
:
## fall back
else
:
## fall back
jid_basic
=
JID
(
jid
).
getStripped
()
if
self
.
_data
.
has_key
(
jid_basic
):
self
.
_data
[
jid_basic
][
'
status
'
]
=
val
...
...
@@ -1320,12 +1321,12 @@ class JID:
bits
=
jid
.
split
(
'
@
'
,
1
)
self
.
node
=
bits
[
0
]
jid
=
bits
[
1
]
if
jid
.
find
(
'
/
'
)
==
-
1
:
self
.
domain
=
jid
self
.
resource
=
''
else
:
self
.
domain
,
self
.
resource
=
jid
.
split
(
'
/
'
,
1
)
self
.
domain
,
self
.
resource
=
jid
.
split
(
'
/
'
,
1
)
else
:
self
.
node
=
node
self
.
domain
=
domain
...
...
@@ -1342,7 +1343,7 @@ class JID:
def
getBasic
(
self
):
"""
Returns a jid string with no resource
"""
return
self
.
node
+
'
@
'
+
self
.
domain
return
self
.
node
+
'
@
'
+
self
.
domain
def
getNode
(
self
):
"""
Returns JID Node as string
"""
...
...
@@ -1375,7 +1376,7 @@ class JID:
def
getStripped
(
self
):
"""
Returns a JID string with no resource
"""
"""
Returns a JID string with no resource
"""
if
self
.
node
:
return
self
.
node
+
'
@
'
+
self
.
domain
else
:
return
self
.
domain
...
...
@@ -1395,7 +1396,7 @@ class JID:
class
Component
(
Connection
):
"""
docs to come soon...
"""
def
__init__
(
self
,
host
,
port
,
connection
=
xmlstream
.
TCP
,
debug
=
False
,
log
=
False
,
ns
=
NS_COMP_ACCEPT
,
hostIP
=
None
,
proxy
=
None
):
debug
=
[]
,
log
=
False
,
ns
=
NS_COMP_ACCEPT
,
hostIP
=
None
,
proxy
=
None
):
Connection
.
__init__
(
self
,
host
,
port
,
namespace
=
ns
,
debug
=
debug
,
log
=
log
,
connection
=
connection
,
hostIP
=
hostIP
,
proxy
=
proxy
)
self
.
_auth_OK
=
False
...
...
@@ -1404,7 +1405,7 @@ class Component(Connection):
def
auth
(
self
,
secret
):
"""
will disconnect on failure
"""
self
.
send
(
u
"
<handshake id=
'
1
'
>%s</handshake>
"
self
.
send
(
u
"
<handshake id=
'
1
'
>%s</handshake>
"
%
sha
.
new
(
self
.
getIncomingID
()
+
secret
).
hexdigest
()
)
while
not
self
.
_auth_OK
:
...
...
@@ -1434,7 +1435,7 @@ class Log(Protocol):
## eg: <log type='warn' from='component'>Hello Log File</log>
def
__init__
(
self
,
attrs
=
None
,
type
=
None
,
frm
=
None
,
to
=
None
,
payload
=
[],
node
=
None
):
Protocol
.
__init__
(
self
,
'
log
'
,
attrs
=
attrs
,
type
=
type
,
frm
=
frm
,
to
=
to
,
payload
=
payload
,
node
=
node
)
def
setBody
(
self
,
val
):
"
Sets the log message text.
"
self
.
getTag
(
'
log
'
).
putData
(
val
)
...
...
This diff is collapsed.
Click to expand it.
common/xmlstream.py
+
41
−
40
View file @
fa49d305
## xmlstream.py
## xmlstream.py
##
## Copyright (C) 2001 Matthew Allum
##
...
...
@@ -28,7 +28,7 @@ case.
"""
# $Id
: xmlstream.py,v 1.42 2004/01/08 15:47:40 snakeru Exp
$
# $Id$
import
time
,
sys
,
re
,
socket
from
select
import
select
...
...
@@ -37,7 +37,7 @@ import xml.parsers.expat
import
debug
_debug
=
debug
VERSION
=
"
0.5
-rc1
"
VERSION
=
"
0.5
"
False
=
0
True
=
1
...
...
@@ -78,7 +78,7 @@ class error:
self
.
value
=
str
(
value
)
def
__str__
(
self
):
return
self
.
value
class
Node
:
"""
A simple XML DOM like class
"""
def
__init__
(
self
,
tag
=
None
,
parent
=
None
,
attrs
=
{},
payload
=
[],
node
=
None
):
...
...
@@ -93,7 +93,7 @@ class Node:
if
parent
:
self
.
parent
=
parent
# if self.parent and not self.namespace: self.namespace=self.parent.namespace
# Doesn't checked if this neccessary
# if self.parent and not self.namespace: self.namespace=self.parent.namespace
# Doesn't checked if this neccessary
for
attr
in
attrs
.
keys
():
self
.
attrs
[
attr
]
=
attrs
[
attr
]
...
...
@@ -101,7 +101,7 @@ class Node:
for
i
in
payload
:
if
type
(
i
)
==
type
(
self
):
self
.
insertNode
(
i
)
else
:
self
.
insertXML
(
i
)
# self.insertNode(Node(node=i))
# Alternative way. Needs perfomance testing.
# self.insertNode(Node(node=i))
# Alternative way. Needs perfomance testing.
def
setParent
(
self
,
node
):
"
Set the nodes parent node.
"
...
...
@@ -127,29 +127,29 @@ class Node:
"
Get a value for the nodes named attribute.
"
try
:
return
self
.
attrs
[
key
]
except
:
return
None
def
putData
(
self
,
data
):
"
Set the nodes textual data
"
"
Set the nodes textual data
"
self
.
data
.
append
(
data
)
def
insertData
(
self
,
data
):
"
Set the nodes textual data
"
"
Set the nodes textual data
"
self
.
data
.
append
(
data
)
def
getData
(
self
):
"
Return the nodes textual data
"
"
Return the nodes textual data
"
return
''
.
join
(
self
.
data
)
def
getDataAsParts
(
self
):
"
Return the node data as an array
"
"
Return the node data as an array
"
return
self
.
data
def
getNamespace
(
self
):
"
Returns the nodes namespace.
"
"
Returns the nodes namespace.
"
return
self
.
namespace
def
setNamespace
(
self
,
namespace
):
"
Set the nodes namespace.
"
"
Set the nodes namespace.
"
self
.
namespace
=
namespace
def
insertTag
(
self
,
name
=
None
,
attrs
=
{},
payload
=
[],
node
=
None
):
...
...
@@ -178,7 +178,7 @@ class Node:
def
_xmlnode2str
(
self
,
parent
=
None
):
"""
Returns an xml ( string ) representation of the node
and it children
"""
s
=
"
<
"
+
self
.
name
s
=
"
<
"
+
self
.
name
if
self
.
namespace
:
if
parent
and
parent
.
namespace
!=
self
.
namespace
:
s
=
s
+
"
xmlns =
'
%s
'
"
%
self
.
namespace
...
...
@@ -186,7 +186,7 @@ class Node:
val
=
ustr
(
self
.
attrs
[
key
])
s
=
s
+
"
%s=
'
%s
'"
%
(
key
,
XMLescape
(
val
)
)
s
=
s
+
"
>
"
cnt
=
0
cnt
=
0
if
self
.
kids
!=
None
:
for
a
in
self
.
kids
:
if
(
len
(
self
.
data
)
-
1
)
>=
cnt
:
s
=
s
+
XMLescape
(
self
.
data
[
cnt
])
...
...
@@ -199,12 +199,13 @@ class Node:
s
=
s
+
"
</
"
+
self
.
name
+
"
>
"
return
s
def
getTag
(
self
,
name
):
def
getTag
(
self
,
name
,
index
=
None
):
"""
Returns a child node with tag name. Returns None
if not found.
"""
for
node
in
self
.
kids
:
if
node
.
getName
()
==
name
:
return
node
if
not
index
:
return
node
if
index
is
not
None
:
index
-=
1
return
None
def
getTags
(
self
,
name
):
...
...
@@ -214,7 +215,7 @@ class Node:
if
node
.
getName
()
==
name
:
nodes
.
append
(
node
)
return
nodes
def
getChildren
(
self
):
"""
Returns a nodes children
"""
return
self
.
kids
...
...
@@ -242,7 +243,7 @@ class NodeBuilder:
self
.
__depth
=
0
self
.
_dispatch_depth
=
1
if
data
:
self
.
_parser
.
Parse
(
data
,
1
)
def
unknown_starttag
(
self
,
tag
,
attrs
):
...
...
@@ -293,8 +294,8 @@ class NodeBuilder:
class
Stream
(
NodeBuilder
):
"""
Extention of NodeBuilder class. Handles stream of XML stanzas.
Calls dispatch method for every child of root node
"""
Extention of NodeBuilder class. Handles stream of XML stanzas.
Calls dispatch method for every child of root node
(stream:stream for jabber stream).
attributes _read, _write and _reader must be set by external entity
"""
...
...
@@ -371,7 +372,7 @@ class Stream(NodeBuilder):
except
:
self
.
DEBUG
(
"
xmlstream write threw error
"
,
DBG_CONN_ERROR
)
self
.
disconnected
(
self
)
def
process
(
self
,
timeout
=
0
):
"""
Receives incoming data (if any) and processes it.
Waits for data no more than timeout seconds.
"""
...
...
@@ -379,7 +380,7 @@ class Stream(NodeBuilder):
data
=
self
.
read
()
self
.
_parser
.
Parse
(
data
)
return
len
(
data
)
return
'
0
'
# Zero means that nothing received but link is alive.
return
'
0
'
# Zero means that nothing received but link is alive.
def
disconnect
(
self
):
"""
Close the stream and socket
"""
...
...
@@ -387,7 +388,7 @@ class Stream(NodeBuilder):
while
self
.
process
():
pass
self
.
_sock
.
close
()
self
.
_sock
=
None
def
disconnected
(
self
,
conn
):
"""
Called when a Network Error or disconnection occurs.
"""
try
:
self
.
disconnectHandler
(
conn
)
...
...
@@ -399,7 +400,7 @@ class Stream(NodeBuilder):
raise
error
(
"
Standart disconnectionHandler called. Replace it with appropriate for your client.
"
)
def
log
(
self
,
data
,
inout
=
''
):
"""
Logs data to the specified filehandle. Data is time stamped
"""
Logs data to the specified filehandle. Data is time stamped
and prefixed with inout
"""
if
self
.
_logFH
is
not
None
:
if
self
.
_timestampLog
:
...
...
@@ -431,7 +432,7 @@ class Client(Stream):
Stream
.
__init__
(
self
,
namespace
,
debug
,
log
,
id
)
self
.
_host
=
host
self
.
_port
=
port
self
.
_port
=
port
self
.
_sock
=
sock
self
.
_connection
=
connection
if
hostIP
:
self
.
_hostIP
=
hostIP
...
...
@@ -528,33 +529,33 @@ class Client(Stream):
self
.
DEBUG
(
'
unknown connection type
'
,
DBG_CONN_ERROR
)
raise
IOError
(
'
unknown connection type
'
)
class
Server
:
class
Server
:
def
now
(
self
):
return
time
.
ctime
(
time
.
time
())
def
__init__
(
self
,
maxclients
=
10
):
self
.
host
=
''
self
.
host
=
''
self
.
port
=
5222
self
.
streams
=
[]
# make main sockets for accepting new client requests
self
.
mainsocks
,
self
.
readsocks
,
self
.
writesocks
=
[],
[],
[]
self
.
portsock
=
socket
(
AF_INET
,
SOCK_STREAM
)
self
.
portsock
.
bind
((
self
.
host
,
self
.
port
))
self
.
portsock
.
listen
(
maxclients
)
self
.
portsock
.
bind
((
self
.
host
,
self
.
port
))
self
.
portsock
.
listen
(
maxclients
)
self
.
mainsocks
.
append
(
self
.
portsock
)
# add to main list to identify
self
.
readsocks
.
append
(
self
.
portsock
)
# add to select inputs list
self
.
readsocks
.
append
(
self
.
portsock
)
# add to select inputs list
# event loop: listen and multiplex until server process killed
def
serve
(
self
):
print
'
select-server loop starting
'
while
1
:
print
"
LOOPING
"
readables
,
writeables
,
exceptions
=
select
(
self
.
readsocks
,
...
...
@@ -562,7 +563,7 @@ class Server:
for
sockobj
in
readables
:
if
sockobj
in
self
.
mainsocks
:
# for ready input sockets
newsock
,
address
=
sockobj
.
accept
()
# accept not block
print
'
Connect:
'
,
address
,
id
(
newsock
)
print
'
Connect:
'
,
address
,
id
(
newsock
)
self
.
readsocks
.
append
(
newsock
)
self
.
_makeNewStream
(
newsock
)
# add to select list, wait
...
...
@@ -571,9 +572,9 @@ class Server:
data
=
sockobj
.
recv
(
1024
)
# recv should not block
print
'
\t
got
'
,
data
,
'
on
'
,
id
(
sockobj
)
if
not
data
:
# if closed by the clients
if
not
data
:
# if closed by the clients
sockobj
.
close
()
# close here and remv from
self
.
readsocks
.
remove
(
sockobj
)
self
.
readsocks
.
remove
(
sockobj
)
else
:
# this may block: should really select for writes too
sockobj
.
send
(
'
Echo=>%s
'
%
data
)
...
...
@@ -592,7 +593,7 @@ class Server:
for
s
in
self
.
streams
:
socks
.
append
(
s
.
getSocket
())
return
socks
def
_getStreamFromSocket
(
self
,
sock
):
for
s
in
self
.
streams
:
if
s
.
getSocket
()
==
sock
:
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment