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