multiuserchat.py 5.43 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 11 12
"""
Implementation of the XEP-0045: Multi-User Chat.
Add some facilities that are not available on the XEP_0045
sleek plugin
"""
13

mathieui's avatar
mathieui committed
14
from gettext import gettext as _
15
from xml.etree import cElementTree as ET
16

17
from common import safeJID
18 19 20
import logging
log = logging.getLogger(__name__)

21
NS_MUC_ADMIN = 'http://jabber.org/protocol/muc#admin'
mathieui's avatar
mathieui committed
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
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':
            xmpp.core.information(_('Unable to destroy room %s') % room,
                                  _('Info'))
        else:
            xmpp.core.information(_('Room %s destroyed') % room, _('Info'))
    iq.send(block=False, callback=callback)
    return True
52

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

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

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

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

louiz’'s avatar
louiz’ committed
89
def change_nick(core, jid, nick, status=None, show=None):
90 91 92
    """
    Change our own nick in a room
    """
louiz’'s avatar
louiz’ committed
93 94 95 96
    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()
97

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

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

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

151
def set_user_affiliation(xmpp, muc_jid, affiliation, nick=None, jid=None, reason=None, callback=None):
mathieui's avatar
mathieui committed
152 153 154
    """
    (try to) Set the affiliation of a MUC user
    """
155
    muc_jid = safeJID(muc_jid)
156 157 158 159 160
    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
161 162 163 164 165 166

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

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