plugin XEP-0045, text_commands: add some commands:
- handle generic failure in text_commands
- fix command /leave and a logging message
- add commands /kick /ban /affiliate
This commit is contained in:
parent
25382c9db6
commit
56ec86b8e5
2 changed files with 174 additions and 2 deletions
|
|
@ -131,13 +131,19 @@ class TextCommands(object):
|
|||
log.debug("text commands took over")
|
||||
raise failure.Failure(exceptions.CancelError())
|
||||
|
||||
def genericErrback(failure):
|
||||
self.feedBack("Command failed with condition '%s'" % failure.value.condition, mess_data, profile)
|
||||
return False
|
||||
|
||||
try:
|
||||
mess_data["unparsed"] = msg[1 + len(command):] # part not yet parsed of the message
|
||||
d = defer.maybeDeferred(self._commands[command], mess_data, profile)
|
||||
d.addCallbacks(lambda ret: ret, genericErrback) # XXX: dummy callback is needed
|
||||
d.addCallback(retHandling)
|
||||
|
||||
except KeyError:
|
||||
self.feedBack(_("Unknown command /%s. ") % command + self.HELP_SUGGESTION, mess_data, profile)
|
||||
self.debug("text commands took over")
|
||||
log.debug("text commands took over")
|
||||
raise failure.Failure(exceptions.CancelError())
|
||||
|
||||
return d or mess_data # if a command is detected, we should have a deferred, else we send the message normally
|
||||
|
|
|
|||
|
|
@ -45,13 +45,17 @@ PLUGIN_INFO = {
|
|||
"description": _("""Implementation of Multi-User Chat""")
|
||||
}
|
||||
|
||||
AFFILIATIONS = ('owner', 'admin', 'member', 'none', 'outcast')
|
||||
|
||||
|
||||
class UnknownRoom(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class NotReadyYet(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class XEP_0045(object):
|
||||
# TODO: this plugin is messy, need a big cleanup/refactoring
|
||||
|
||||
|
|
@ -125,6 +129,10 @@ class XEP_0045(object):
|
|||
nick += '_'
|
||||
return self.clients[profile].join(room_jid, nick, history_options, password).addCallbacks(self.__room_joined, self.__err_joining_room, callbackKeywords={'profile': profile}, errbackArgs=[room_jid, nick, history_options, password, profile])
|
||||
mess = D_("Error while joining the room %s" % room_jid.userhost())
|
||||
try:
|
||||
mess += " with condition '%s'" % failure.value.condition
|
||||
except AttributeError:
|
||||
pass
|
||||
log.error(mess)
|
||||
self.host.bridge.newAlert(mess, D_("Group chat error"), "ERROR", profile)
|
||||
raise failure
|
||||
|
|
@ -375,6 +383,57 @@ class XEP_0045(object):
|
|||
self.clients[profile] = SatMUCClient(self)
|
||||
return self.clients[profile]
|
||||
|
||||
def kick(self, nick, room_jid, options={}, profile_key=C.PROF_KEY_NONE):
|
||||
"""
|
||||
Kick a participant from the room
|
||||
@param nick (str): nick of the user to kick
|
||||
@param room_jid_s (JID): jid of the room
|
||||
@param options (dict): attribute with extra info (reason, password) as in #XEP-0045
|
||||
@param profile_key (str): %(doc_profile_key)s
|
||||
"""
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not self.__check_profile(profile):
|
||||
raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
|
||||
if room_jid.userhost() not in self.clients[profile].joined_rooms:
|
||||
raise UnknownRoom("This room has not been joined")
|
||||
return self.clients[profile].kick(room_jid, nick, reason=options.get('reason', None))
|
||||
|
||||
def ban(self, entity_jid, room_jid, options={}, profile_key=C.PROF_KEY_NONE):
|
||||
"""
|
||||
Ban an entity from the room
|
||||
@param entity_jid (JID): bare jid of the entity to be banned
|
||||
@param room_jid_s (JID): jid of the room
|
||||
@param options: attribute with extra info (reason, password) as in #XEP-0045
|
||||
@param profile_key (str): %(doc_profile_key)s
|
||||
"""
|
||||
assert(not entity_jid.resource)
|
||||
assert(not room_jid.resource)
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not self.__check_profile(profile):
|
||||
raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
|
||||
if room_jid.userhost() not in self.clients[profile].joined_rooms:
|
||||
raise UnknownRoom("This room has not been joined")
|
||||
return self.clients[profile].ban(room_jid, entity_jid, reason=options.get('reason', None))
|
||||
|
||||
def affiliate(self, entity_jid, room_jid, options=None, profile_key=C.PROF_KEY_NONE):
|
||||
"""
|
||||
Change the affiliation of an entity
|
||||
@param entity_jid (JID): bare jid of the entity
|
||||
@param room_jid_s (JID): jid of the room
|
||||
@param options: attribute with extra info (reason, nick) as in #XEP-0045
|
||||
@param profile_key (str): %(doc_profile_key)s
|
||||
"""
|
||||
assert(not entity_jid.resource)
|
||||
assert(not room_jid.resource)
|
||||
assert('affiliation' in options)
|
||||
profile = self.host.memory.getProfileName(profile_key)
|
||||
if not self.__check_profile(profile):
|
||||
raise exceptions.ProfileUnknownError("Unknown or disconnected profile")
|
||||
if room_jid.userhost() not in self.clients[profile].joined_rooms:
|
||||
raise UnknownRoom("This room has not been joined")
|
||||
# TODO: handles reason and nick
|
||||
return self.clients[profile].modifyAffiliationList(room_jid, [entity_jid], options['affiliation'])
|
||||
|
||||
# Text commands #
|
||||
|
||||
def cmd_nick(self, mess_data, profile):
|
||||
|
|
@ -429,6 +488,113 @@ class XEP_0045(object):
|
|||
"""just a synonym of /leave"""
|
||||
return self.cmd_leave(mess_data, profile)
|
||||
|
||||
def cmd_kick(self, mess_data, profile):
|
||||
"""kick a room member
|
||||
|
||||
@command (group): (nick)
|
||||
- nick: the nick of the person to kick
|
||||
"""
|
||||
log.debug("Catched kick command")
|
||||
|
||||
if mess_data['type'] != "groupchat":
|
||||
self.host.plugins[C.TEXT_CMDS].feedBackWrongContext('kick', 'groupchat', mess_data, profile)
|
||||
return False
|
||||
|
||||
options = mess_data["unparsed"].strip().split()
|
||||
try:
|
||||
nick = options[0]
|
||||
assert(self.isNickInRoom(mess_data["to"], nick, profile))
|
||||
except (IndexError, AssertionError):
|
||||
feedback = _(u"You must provide a member's nick to kick.")
|
||||
self.host.plugins[C.TEXT_CMDS].feedBack(feedback, mess_data, profile)
|
||||
return False
|
||||
|
||||
d = self.kick(nick, mess_data["to"], {} if len(options) == 1 else {'reason': options[1]}, profile)
|
||||
|
||||
def cb(dummy):
|
||||
mess_data['message'] = _('%s has been kicked') % nick
|
||||
if len(options) > 1:
|
||||
mess_data['message'] += _(' for the following reason: %s') % options[1]
|
||||
return True
|
||||
d.addCallback(cb)
|
||||
return d
|
||||
|
||||
def cmd_ban(self, mess_data, profile):
|
||||
"""ban an entity from the room
|
||||
|
||||
@command (group): (JID) [reason]
|
||||
- JID: the JID of the entity to ban
|
||||
- reason: the reason why this entity is being banned
|
||||
"""
|
||||
log.debug("Catched ban command")
|
||||
|
||||
if mess_data['type'] != "groupchat":
|
||||
self.host.plugins[C.TEXT_CMDS].feedBackWrongContext('ban', 'groupchat', mess_data, profile)
|
||||
return False
|
||||
|
||||
options = mess_data["unparsed"].strip().split()
|
||||
try:
|
||||
jid_s = options[0]
|
||||
entity_jid = jid.JID(jid_s).userhostJID()
|
||||
assert(entity_jid.user)
|
||||
assert(entity_jid.host)
|
||||
except (IndexError, jid.InvalidFormat, AssertionError):
|
||||
feedback = _(u"You must provide a valid JID to ban, like in '/ban contact@example.net'")
|
||||
self.host.plugins[C.TEXT_CMDS].feedBack(feedback, mess_data, profile)
|
||||
return False
|
||||
|
||||
d = self.ban(entity_jid, mess_data["to"], {} if len(options) == 1 else {'reason': options[1]}, profile)
|
||||
|
||||
def cb(dummy):
|
||||
mess_data['message'] = _('%s has been banned') % entity_jid
|
||||
if len(options) > 1:
|
||||
mess_data['message'] += _(' for the following reason: %s') % options[1]
|
||||
return True
|
||||
d.addCallback(cb)
|
||||
return d
|
||||
|
||||
def cmd_affiliate(self, mess_data, profile):
|
||||
"""affiliate an entity to the room
|
||||
|
||||
@command (group): (JID) [owner|admin|member|none|outcast]
|
||||
- JID: the JID of the entity to affiliate
|
||||
- owner: grant owner privileges
|
||||
- admin: grant admin privileges
|
||||
- member: grant member privileges
|
||||
- none: reset entity privileges
|
||||
- outcast: ban entity
|
||||
"""
|
||||
log.debug("Catched affiliate command")
|
||||
|
||||
if mess_data['type'] != "groupchat":
|
||||
self.host.plugins[C.TEXT_CMDS].feedBackWrongContext('affiliate', 'groupchat', mess_data, profile)
|
||||
return False
|
||||
|
||||
options = mess_data["unparsed"].strip().split()
|
||||
try:
|
||||
jid_s = options[0]
|
||||
entity_jid = jid.JID(jid_s).userhostJID()
|
||||
assert(entity_jid.user)
|
||||
assert(entity_jid.host)
|
||||
except (IndexError, jid.InvalidFormat, AssertionError):
|
||||
feedback = _(u"You must provide a valid JID to affiliate, like in '/affiliate contact@example.net member'")
|
||||
self.host.plugins[C.TEXT_CMDS].feedBack(feedback, mess_data, profile)
|
||||
return False
|
||||
|
||||
affiliation = options[1] if len(options) > 1 else 'none'
|
||||
if affiliation not in AFFILIATIONS:
|
||||
feedback = _(u"You must provide a valid affiliation: %s") % ' '.join(AFFILIATIONS)
|
||||
self.host.plugins[C.TEXT_CMDS].feedBack(feedback, mess_data, profile)
|
||||
return False
|
||||
|
||||
d = self.affiliate(entity_jid, mess_data["to"], {'affiliation': affiliation}, profile)
|
||||
|
||||
def cb(dummy):
|
||||
mess_data['message'] = _('New affiliation for %(entity)s: %(affiliation)s') % {'entity': entity_jid, 'affiliation': affiliation}
|
||||
return True
|
||||
d.addCallback(cb)
|
||||
return d
|
||||
|
||||
def cmd_title(self, mess_data, profile):
|
||||
"""change room's subject"""
|
||||
log.debug("Catched title command")
|
||||
|
|
@ -530,7 +696,7 @@ class SatMUCClient (muc.MUCClient):
|
|||
room_jid_s = room.roomJID.userhost()
|
||||
log.info(_("Room [%(room)s] left (%(profile)s))") % {"room": room_jid_s,
|
||||
"profile": self.parent.profile})
|
||||
self.host.memory.delEntityCache(room.roomJID, self.parent.profile)
|
||||
self.host.memory.delEntityCache(room.roomJID, profile_key=self.parent.profile)
|
||||
del self.plugin_parent.clients[self.parent.profile].joined_rooms[room_jid_s]
|
||||
self.host.bridge.roomLeft(room.roomJID.userhost(), self.parent.profile)
|
||||
else:
|
||||
|
|
|
|||
Loading…
Reference in a new issue