multiuserchat.py 6.3 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
"""
Implementation of the XEP-0045: Multi-User Chat.
Add some facilities that are not available on the XEP_0045
louiz’'s avatar
louiz’ committed
10
slix plugin
11
"""
12

13
from xml.etree import cElementTree as ET
14

mathieui's avatar
mathieui committed
15
from poezio.common import safeJID
16
from slixmpp import JID
mathieui's avatar
mathieui committed
17
from slixmpp.exceptions import IqError, IqTimeout
18 19 20
import logging
log = logging.getLogger(__name__)

21
NS_MUC_ADMIN = 'http://jabber.org/protocol/muc#admin'
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
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)
mathieui's avatar
mathieui committed
44

45 46
    def callback(iq):
        if not iq or iq['type'] == 'error':
mathieui's avatar
mathieui committed
47
            xmpp.core.information('Unable to destroy room %s' % room, 'Info')
48
        else:
49
            xmpp.core.information('Room %s destroyed' % room, 'Info')
mathieui's avatar
mathieui committed
50

51
    iq.send(callback=callback)
52
    return True
53

mathieui's avatar
mathieui committed
54

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

mathieui's avatar
mathieui committed
62

63 64 65 66
def send_groupchat_message(xmpp, jid, line):
    """
    Send a message to the groupchat
    """
67
    jid = safeJID(jid)
68
    xmpp.send_message(mto=jid, mbody=line, mtype='groupchat')
69

mathieui's avatar
mathieui committed
70

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

mathieui's avatar
mathieui committed
83

84 85 86 87
def change_subject(xmpp, jid, subject):
    """
    Change the room subject
    """
88
    jid = safeJID(jid)
89
    msg = xmpp.make_message(jid)
90 91 92
    msg['type'] = 'groupchat'
    msg['subject'] = subject
    msg.send()
93

mathieui's avatar
mathieui committed
94

louiz’'s avatar
louiz’ committed
95
def change_nick(core, jid, nick, status=None, show=None):
96 97 98
    """
    Change our own nick in a room
    """
louiz’'s avatar
louiz’ committed
99
    xmpp = core.xmpp
mathieui's avatar
mathieui committed
100 101
    presence = xmpp.make_presence(
        pshow=show, pstatus=status, pto=safeJID('%s/%s' % (jid, nick)))
louiz’'s avatar
louiz’ committed
102 103
    core.events.trigger('changing_nick', presence)
    presence.send()
104

mathieui's avatar
mathieui committed
105 106 107 108 109 110 111 112

def join_groupchat(core,
                   jid,
                   nick,
                   passwd='',
                   status=None,
                   show=None,
                   seconds=None):
113
    xmpp = core.xmpp
mathieui's avatar
mathieui committed
114 115
    stanza = xmpp.make_presence(
        pto='%s/%s' % (jid, nick), pstatus=status, pshow=show)
116 117 118 119 120
    x = ET.Element('{http://jabber.org/protocol/muc}x')
    if passwd:
        passelement = ET.Element('password')
        passelement.text = passwd
        x.append(passelement)
121
    if seconds is not None:
122
        history = ET.Element('{http://jabber.org/protocol/muc}history')
123 124
        history.attrib['seconds'] = str(seconds)
        x.append(history)
125 126 127 128 129
    stanza.append(x)
    core.events.trigger('joining_muc', stanza)
    to = stanza["to"]
    stanza.send()
    xmpp.plugin['xep_0045'].rooms[jid] = {}
130
    xmpp.plugin['xep_0045'].our_nicks[jid] = to.resource
131

mathieui's avatar
mathieui committed
132

133 134 135 136
def leave_groupchat(xmpp, jid, own_nick, msg):
    """
    Leave the groupchat
    """
137
    jid = safeJID(jid)
138
    try:
139
        xmpp.plugin['xep_0045'].leave_muc(jid, own_nick, msg)
140
    except KeyError:
mathieui's avatar
mathieui committed
141 142 143 144 145
        log.debug(
            "muc.leave_groupchat: could not leave the room %s",
            jid,
            exc_info=True)

146

147
def set_user_role(xmpp, jid, nick, reason, role, callback=None):
148
    """
149
    (try to) Set the role of a MUC user
150
    (role = 'none': eject user)
151
    """
152
    jid = safeJID(jid)
153
    iq = xmpp.make_iq_set()
154
    query = ET.Element('{%s}query' % NS_MUC_ADMIN)
mathieui's avatar
mathieui committed
155
    item = ET.Element('{%s}item' % NS_MUC_ADMIN, {'nick': nick, 'role': role})
156
    if reason:
157
        reason_el = ET.Element('{%s}reason' % NS_MUC_ADMIN)
158 159 160 161 162
        reason_el.text = reason
        item.append(reason_el)
    query.append(item)
    iq.append(query)
    iq['to'] = jid
163
    if callback:
164
        return iq.send(callback=callback)
louiz’'s avatar
louiz’ committed
165
    try:
166
        return iq.send()
mathieui's avatar
mathieui committed
167
    except (IqError, IqTimeout) as e:
louiz’'s avatar
louiz’ committed
168
        return e.iq
mathieui's avatar
mathieui committed
169

mathieui's avatar
mathieui committed
170 171 172 173 174 175 176 177

def set_user_affiliation(xmpp,
                         muc_jid,
                         affiliation,
                         nick=None,
                         jid=None,
                         reason=None,
                         callback=None):
mathieui's avatar
mathieui committed
178 179 180
    """
    (try to) Set the affiliation of a MUC user
    """
181
    muc_jid = safeJID(muc_jid)
182 183
    query = ET.Element('{http://jabber.org/protocol/muc#admin}query')
    if nick:
mathieui's avatar
mathieui committed
184 185 186 187
        item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {
            'affiliation': affiliation,
            'nick': nick
        })
188
    else:
mathieui's avatar
mathieui committed
189 190 191 192
        item = ET.Element('{http://jabber.org/protocol/muc#admin}item', {
            'affiliation': affiliation,
            'jid': str(jid)
        })
mathieui's avatar
mathieui committed
193 194

    if reason:
mathieui's avatar
mathieui committed
195 196
        reason_item = ET.Element(
            '{http://jabber.org/protocol/muc#admin}reason')
mathieui's avatar
mathieui committed
197 198 199
        reason_item.text = reason
        item.append(reason_item)

200
    query.append(item)
201
    iq = xmpp.make_iq_set(query)
202 203
    iq['to'] = muc_jid
    if callback:
204
        return iq.send(callback=callback)
mathieui's avatar
mathieui committed
205
    try:
mathieui's avatar
mathieui committed
206
        return xmpp.plugin['xep_0045'].set_affiliation(
mathieui's avatar
mathieui committed
207 208
            str(muc_jid),
            str(jid) if jid else None, nick, affiliation)
209
    except:
210
        log.debug('Error setting the affiliation: %s', exc_info=True)
211
        return False
212

mathieui's avatar
mathieui committed
213

214 215 216 217
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)
218
    iq = xmpp.make_iq_set(query)
219
    iq['to'] = room
220
    iq.send()
221

mathieui's avatar
mathieui committed
222

223 224 225
def configure_room(xmpp, room, form):
    if form is None:
        return
226
    iq = xmpp.make_iq_set()
227 228
    iq['to'] = room
    query = ET.Element('{http://jabber.org/protocol/muc#owner}query')
229
    form['type'] = 'submit'
230
    query.append(form.xml)
231
    iq.append(query)
232
    iq.send()