multiuserchat.py 5.86 KB
Newer Older
louiz’'s avatar
louiz’ committed
1
2
3
4
5
# Copyright 2010-2011 Florent Le Coz <louiz@louiz.org>
#
# This file is part of Poezio.
#
# Poezio is free software: you can redistribute it and/or modify
6
# it under the terms of the zlib license. See the COPYING file.
7

8
9
10
"""
Implementation of the XEP-0045: Multi-User Chat.
Add some facilities that are not available on the XEP_0045
louiz’'s avatar
louiz’ committed
11
slix plugin
12
"""
13

14
from xml.etree import cElementTree as ET
15

mathieui's avatar
mathieui committed
16
from poezio.common import safeJID
17
18
19
import logging
log = logging.getLogger(__name__)

20
NS_MUC_ADMIN = 'http://jabber.org/protocol/muc#admin'
mathieui's avatar
mathieui committed
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
NS_MUC_OWNER = 'http://jabber.org/protocol/muc#owner'


def destroy_room(xmpp, room, reason='', altroom=''):
    """
    destroy a room
    """
    room = safeJID(room)
    if not room:
        return False
    iq = xmpp.make_iq_set()
    iq['to'] = room
    query = ET.Element('{%s}query' % NS_MUC_OWNER)
    destroy = ET.Element('{%s}destroy' % NS_MUC_OWNER)
    if altroom:
        destroy.attrib['jid'] = altroom
    if reason:
        xreason = ET.Element('{%s}reason' % NS_MUC_OWNER)
        xreason.text = reason
        destroy.append(xreason)
    query.append(destroy)
    iq.append(query)
    def callback(iq):
        if not iq or iq['type'] == 'error':
45
46
            xmpp.core.information('Unable to destroy room %s' % room,
                                  'Info')
mathieui's avatar
mathieui committed
47
        else:
48
            xmpp.core.information('Room %s destroyed' % room, 'Info')
49
    iq.send(callback=callback)
mathieui's avatar
mathieui committed
50
    return True
51

52
def send_private_message(xmpp, jid, line):
53
    """
54
    Send a private message
55
    """
56
    jid = safeJID(jid)
57
    xmpp.send_message(mto=jid, mbody=line, mtype='chat')
58

59
60
61
62
def send_groupchat_message(xmpp, jid, line):
    """
    Send a message to the groupchat
    """
63
    jid = safeJID(jid)
64
    xmpp.send_message(mto=jid, mbody=line, mtype='groupchat')
65

66
67
68
69
def change_show(xmpp, jid, own_nick, show, status):
    """
    Change our 'Show'
    """
70
    jid = safeJID(jid)
71
    pres = xmpp.make_presence(pto='%s/%s' % (jid, own_nick))
72
    if show: # if show is None, don't put a <show /> tag. It means "available"
73
74
75
76
77
78
79
80
81
        pres['type'] = show
    if status:
        pres['status'] = status
    pres.send()

def change_subject(xmpp, jid, subject):
    """
    Change the room subject
    """
82
    jid = safeJID(jid)
83
    msg = xmpp.make_message(jid)
84
85
86
    msg['type'] = 'groupchat'
    msg['subject'] = subject
    msg.send()
87

louiz’'s avatar
louiz’ committed
88
def change_nick(core, jid, nick, status=None, show=None):
89
90
91
    """
    Change our own nick in a room
    """
louiz’'s avatar
louiz’ committed
92
93
94
95
    xmpp = core.xmpp
    presence = xmpp.make_presence(pshow=show, pstatus=status, pto=safeJID('%s/%s' % (jid, nick)))
    core.events.trigger('changing_nick', presence)
    presence.send()
96

97
def join_groupchat(core, jid, nick, passwd='', status=None, show=None, seconds=None):
98
    xmpp = core.xmpp
99
    stanza = xmpp.make_presence(pto='%s/%s' % (jid, nick), pstatus=status, pshow=show)
100
101
102
103
104
    x = ET.Element('{http://jabber.org/protocol/muc}x')
    if passwd:
        passelement = ET.Element('password')
        passelement.text = passwd
        x.append(passelement)
105
    if seconds is not None:
106
        history = ET.Element('{http://jabber.org/protocol/muc}history')
107
108
        history.attrib['seconds'] = str(seconds)
        x.append(history)
109
110
111
112
113
    stanza.append(x)
    core.events.trigger('joining_muc', stanza)
    to = stanza["to"]
    stanza.send()
    xmpp.plugin['xep_0045'].rooms[jid] = {}
114
    xmpp.plugin['xep_0045'].our_nicks[jid] = to.resource
115

116
117
118
119
def leave_groupchat(xmpp, jid, own_nick, msg):
    """
    Leave the groupchat
    """
120
    jid = safeJID(jid)
121
    try:
122
        xmpp.plugin['xep_0045'].leave_muc(jid, own_nick, msg)
123
    except KeyError:
mathieui's avatar
mathieui committed
124
125
        log.debug("muc.leave_groupchat: could not leave the room %s",
                jid, exc_info=True)
126

127
def set_user_role(xmpp, jid, nick, reason, role, callback=None):
128
    """
129
    (try to) Set the role of a MUC user
130
    (role = 'none': eject user)
131
    """
132
    jid = safeJID(jid)
133
    iq = xmpp.make_iq_set()
134
    query = ET.Element('{%s}query' % NS_MUC_ADMIN)
135
    item = ET.Element('{%s}item' % NS_MUC_ADMIN, {'nick':nick, 'role':role})
136
    if reason:
137
        reason_el = ET.Element('{%s}reason' % NS_MUC_ADMIN)
138
139
140
141
142
        reason_el.text = reason
        item.append(reason_el)
    query.append(item)
    iq.append(query)
    iq['to'] = jid
143
    if callback:
144
        return iq.send(callback=callback)
louiz’'s avatar
louiz’ committed
145
    try:
146
        return iq.send()
louiz’'s avatar
louiz’ committed
147
148
    except Exception as e:
        return e.iq
mathieui's avatar
mathieui committed
149

150
def set_user_affiliation(xmpp, muc_jid, affiliation, nick=None, jid=None, reason=None, callback=None):
mathieui's avatar
mathieui committed
151
152
153
    """
    (try to) Set the affiliation of a MUC user
    """
154
    muc_jid = safeJID(muc_jid)
155
156
157
158
159
    query = ET.Element('{http://jabber.org/protocol/muc#admin}query')
    if nick:
        item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation':affiliation, 'nick':nick})
    else:
        item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {'affiliation':affiliation, 'jid':str(jid)})
mathieui's avatar
mathieui committed
160
161
162
163
164
165

    if reason:
        reason_item = ET.Element('{http://jabber.org/protocol/muc#admin}reason')
        reason_item.text = reason
        item.append(reason_item)

166
    query.append(item)
167
    iq = xmpp.make_iq_set(query)
168
169
    iq['to'] = muc_jid
    if callback:
170
        return iq.send(callback=callback)
mathieui's avatar
mathieui committed
171
    try:
172
        return xmpp.plugin['xep_0045'].set_affiliation(str(muc_jid), str(jid) if jid else None, nick, affiliation)
173
    except:
mathieui's avatar
mathieui committed
174
175
        import traceback
        log.debug('Error setting the affiliation: %s', traceback.format_exc())
176
        return False
177
178
179
180
181

def cancel_config(xmpp, room):
    query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
    x = ET.Element('{jabber:x:data}x', type='cancel')
    query.append(x)
182
    iq = xmpp.make_iq_set(query)
183
    iq['to'] = room
184
    iq.send()
185
186
187
188

def configure_room(xmpp, room, form):
    if form is None:
        return
189
    iq = xmpp.make_iq_set()
190
191
    iq['to'] = room
    query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
192
    form['type'] = 'submit'
193
    query.append(form.xml)
194
    iq.append(query)
195
    iq.send()
196