2024-06-29 23:16:03 +02:00
|
|
|
#!/usr/bin/env python3
|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
TODO
|
|
|
|
|
|
|
|
1) Send message to inviter that bot has joined to groupchat.
|
|
|
|
|
|
|
|
2) If groupchat requires captcha, send the consequent message.
|
|
|
|
|
|
|
|
3) If groupchat error is received, send that error message to inviter.
|
|
|
|
|
|
|
|
FIXME
|
|
|
|
|
|
|
|
1) Save name of groupchat instead of jid as name
|
|
|
|
|
|
|
|
"""
|
2024-11-19 11:11:10 +01:00
|
|
|
from asyncio import TimeoutError
|
2024-06-29 23:16:03 +02:00
|
|
|
from slixmpp.exceptions import IqError, IqTimeout, PresenceError
|
|
|
|
from kaikout.log import Logger
|
|
|
|
|
|
|
|
logger = Logger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
class XmppMuc:
|
2024-07-30 06:56:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_affiliation(self, room, alias):
|
|
|
|
"""Get an affiliation of a specified alias"""
|
|
|
|
affiliation = self.plugin['xep_0045'].get_jid_property(room, alias, 'affiliation')
|
|
|
|
return affiliation
|
2024-06-29 23:16:03 +02:00
|
|
|
|
|
|
|
|
2024-07-30 06:56:00 +02:00
|
|
|
async def get_affiliation_list(self, room, affiliation):
|
|
|
|
"""Get an affiliation list from groupchat config"""
|
|
|
|
try:
|
|
|
|
jids = await self.plugin['xep_0045'].get_affiliation_list(room, affiliation)
|
|
|
|
return jids
|
|
|
|
except Exception as e:
|
|
|
|
logger.error('KaikOut has failed to query the server for a list '
|
|
|
|
'of Jabber IDs with the affiliation "{}" for '
|
|
|
|
'groupchat {}'.format(affiliation, room))
|
|
|
|
logger.error(e)
|
2024-06-29 23:16:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_alias(self, room, jid):
|
|
|
|
alias = self.plugin['xep_0045'].get_nick(room, jid)
|
|
|
|
return alias
|
|
|
|
|
|
|
|
|
|
|
|
def get_full_jid(self, room, alias):
|
|
|
|
"""
|
|
|
|
Get full JId.
|
|
|
|
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
jid_full : str
|
|
|
|
Full Jabber ID.
|
|
|
|
"""
|
|
|
|
jid_full = self.plugin['xep_0045'].get_jid_property(room, alias, 'jid')
|
|
|
|
return jid_full
|
|
|
|
|
|
|
|
|
|
|
|
def get_joined_rooms(self):
|
|
|
|
rooms = self.plugin['xep_0045'].get_joined_rooms()
|
|
|
|
return rooms
|
2024-07-30 06:56:00 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_role(self, room, alias):
|
|
|
|
"""Get a role of a specified alias"""
|
|
|
|
role = self.plugin['xep_0045'].get_jid_property(room, alias, 'role')
|
|
|
|
return role
|
|
|
|
|
|
|
|
|
|
|
|
async def get_role_list(self, room, role):
|
|
|
|
"""Get a role list from groupchat config"""
|
|
|
|
try:
|
|
|
|
jids = await self.plugin['xep_0045'].get_roles_list(room, role)
|
|
|
|
return jids
|
|
|
|
except Exception as e:
|
|
|
|
logger.error('KaikOut has failed to query the server for a list '
|
|
|
|
'of Jabber IDs with the role "{}" for groupchat {}'
|
|
|
|
.format(role, room))
|
|
|
|
logger.error(e)
|
2024-06-29 23:16:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
def get_roster(self, room):
|
|
|
|
roster = self.plugin['xep_0045'].get_roster(room)
|
|
|
|
return roster
|
|
|
|
|
|
|
|
|
|
|
|
def is_moderator(self, room, alias):
|
|
|
|
"""Check if given JID is a moderator"""
|
|
|
|
role = self.plugin['xep_0045'].get_jid_property(room, alias, 'role')
|
2024-11-21 20:00:13 +01:00
|
|
|
result = True if role == 'moderator' else False
|
2024-06-29 23:16:03 +02:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
2024-11-21 20:00:13 +01:00
|
|
|
async def join(self, jid_bare, alias=None, password=None):
|
|
|
|
logger.info('Joining groupchat\nJID : {}\n'.format(jid_bare))
|
|
|
|
#jid_from = str(self.boundjid) if self.is_component else None
|
2024-06-29 23:16:03 +02:00
|
|
|
if not alias: alias = self.alias
|
|
|
|
try:
|
2024-11-21 20:00:13 +01:00
|
|
|
await self.plugin['xep_0045'].join_muc_wait(jid_bare,
|
2024-06-29 23:16:03 +02:00
|
|
|
alias,
|
2024-11-21 20:00:13 +01:00
|
|
|
#presence_options = {"pfrom" : jid_from},
|
2024-06-29 23:16:03 +02:00
|
|
|
password=password,
|
|
|
|
maxchars=0,
|
|
|
|
maxstanzas=0,
|
|
|
|
seconds=0,
|
|
|
|
since=0,
|
|
|
|
timeout=30)
|
|
|
|
result = 'success'
|
|
|
|
except IqError as e:
|
|
|
|
logger.error('Error XmppIQ')
|
|
|
|
logger.error(str(e))
|
2024-11-21 20:00:13 +01:00
|
|
|
logger.error(jid_bare)
|
2024-06-29 23:16:03 +02:00
|
|
|
result = 'error'
|
|
|
|
except IqTimeout as e:
|
|
|
|
logger.error('Timeout XmppIQ')
|
|
|
|
logger.error(str(e))
|
2024-11-21 20:00:13 +01:00
|
|
|
logger.error(jid_bare)
|
2024-06-29 23:16:03 +02:00
|
|
|
result = 'timeout'
|
2024-11-19 11:11:10 +01:00
|
|
|
except TimeoutError as e:
|
|
|
|
logger.error('Timeout AsyncIO')
|
|
|
|
logger.error(str(e))
|
2024-11-21 20:00:13 +01:00
|
|
|
logger.error(jid_bare)
|
2024-11-19 11:11:10 +01:00
|
|
|
result = 'timeout'
|
2024-06-29 23:16:03 +02:00
|
|
|
except PresenceError as e:
|
|
|
|
logger.error('Error Presence')
|
|
|
|
logger.error(str(e))
|
|
|
|
if (e.condition == 'forbidden' and
|
|
|
|
e.presence['error']['code'] == '403'):
|
2024-11-21 20:00:13 +01:00
|
|
|
logger.warning('{} is banned from {}'.format(self.alias, jid_bare))
|
2024-06-29 23:16:03 +02:00
|
|
|
result = 'ban'
|
2024-11-21 11:11:11 +01:00
|
|
|
elif e.condition == 'conflict':
|
|
|
|
logger.warning(e.presence['error']['text'])
|
|
|
|
result = 'conflict'
|
2024-06-29 23:16:03 +02:00
|
|
|
else:
|
|
|
|
result = 'error'
|
2024-11-19 11:11:10 +01:00
|
|
|
except Exception as e:
|
|
|
|
logger.error('Unknown error')
|
|
|
|
logger.error(str(e))
|
2024-11-21 20:00:13 +01:00
|
|
|
logger.error(jid_bare)
|
2024-11-19 11:11:10 +01:00
|
|
|
result = 'unknown'
|
2024-06-29 23:16:03 +02:00
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
def leave(self, jid):
|
|
|
|
jid_from = str(self.boundjid) if self.is_component else None
|
|
|
|
message = ('This news bot will now leave this groupchat.\n'
|
|
|
|
'The JID of this news bot is xmpp:{}?message'
|
|
|
|
.format(self.boundjid.bare))
|
|
|
|
status_message = ('This bot has left the group. '
|
|
|
|
'It can be reached directly via {}'
|
|
|
|
.format(self.boundjid.bare))
|
|
|
|
self.send_message(mto=jid,
|
|
|
|
mfrom=self.boundjid,
|
|
|
|
mbody=message,
|
|
|
|
mtype='groupchat')
|
|
|
|
self.plugin['xep_0045'].leave_muc(jid,
|
|
|
|
self.alias,
|
|
|
|
status_message,
|
|
|
|
jid_from)
|
|
|
|
|
|
|
|
|
|
|
|
async def set_affiliation(self, room, affiliation, jid=None, alias=None, reason=None):
|
|
|
|
jid_from = str(self.boundjid) if self.is_component else None
|
|
|
|
try:
|
|
|
|
await self.plugin['xep_0045'].set_affiliation(
|
|
|
|
room, affiliation, jid=jid, nick=alias, reason=reason, ifrom=jid_from)
|
|
|
|
except IqError as e:
|
|
|
|
logger.error('Error XmppIQ')
|
|
|
|
logger.error('Could not set affiliation at room: {}'.format(room))
|
|
|
|
logger.error(str(e))
|
|
|
|
logger.error(room)
|
2024-11-19 11:11:10 +01:00
|
|
|
except Exception as e:
|
|
|
|
logger.error('Unknown error')
|
|
|
|
logger.error('Could not set affiliation at room: {}'.format(room))
|
|
|
|
logger.error(str(e))
|
|
|
|
logger.error(room)
|
2024-06-29 23:16:03 +02:00
|
|
|
|
|
|
|
|
|
|
|
async def set_role(self, room, alias, role, reason=None):
|
|
|
|
jid_from = str(self.boundjid) if self.is_component else None
|
|
|
|
try:
|
|
|
|
await self.plugin['xep_0045'].set_role(
|
|
|
|
room, alias, role, reason=None, ifrom=jid_from)
|
|
|
|
except IqError as e:
|
|
|
|
logger.error('Error XmppIQ')
|
|
|
|
logger.error('Could not set role of alias: {}'.format(alias))
|
|
|
|
logger.error(str(e))
|
|
|
|
logger.error(room)
|
2024-11-19 11:11:10 +01:00
|
|
|
except Exception as e:
|
|
|
|
logger.error('Unknown error')
|
|
|
|
logger.error('Could not set role of alias: {}'.format(alias))
|
|
|
|
logger.error(str(e))
|
|
|
|
logger.error(room)
|