Port to modern irc module
This commit is contained in:
parent
8ae268911a
commit
451765625f
30
hybridbot.py
30
hybridbot.py
@ -2,13 +2,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
sys.path.append('lib')
|
|
||||||
import time
|
import time
|
||||||
import re
|
import re
|
||||||
import sleekxmpp
|
import sleekxmpp
|
||||||
from ircbot import SingleServerIRCBot
|
from irc.bot import SingleServerIRCBot
|
||||||
from ircbot import Channel
|
from irc.bot import Channel
|
||||||
from irclib import nm_to_n
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
if sys.version_info >= (3, 0):
|
if sys.version_info >= (3, 0):
|
||||||
from configparser import SafeConfigParser
|
from configparser import SafeConfigParser
|
||||||
@ -24,7 +22,7 @@ class IRCBot(SingleServerIRCBot):
|
|||||||
self.chanmuc = chanmuc
|
self.chanmuc = chanmuc
|
||||||
|
|
||||||
def _on_join(self, c, e):
|
def _on_join(self, c, e):
|
||||||
nick = nm_to_n(e.source())
|
nick = e.source.nick
|
||||||
|
|
||||||
if nick not in self.chanmuc.chan_users():
|
if nick not in self.chanmuc.chan_users():
|
||||||
self.chanmuc.chan_add_user(nick)
|
self.chanmuc.chan_add_user(nick)
|
||||||
@ -32,12 +30,12 @@ class IRCBot(SingleServerIRCBot):
|
|||||||
def _on_namreply(self, c, e):
|
def _on_namreply(self, c, e):
|
||||||
bot = c.get_nickname()
|
bot = c.get_nickname()
|
||||||
|
|
||||||
for nick in e.arguments()[2].split():
|
for nick in e.arguments[2].split():
|
||||||
if nick != c.get_nickname():
|
if nick != c.get_nickname():
|
||||||
self.chanmuc.chan_add_user(nick)
|
self.chanmuc.chan_add_user(nick)
|
||||||
|
|
||||||
def _on_part(self, c, e):
|
def _on_part(self, c, e):
|
||||||
nick = nm_to_n(e.source())
|
nick = e.source.nick
|
||||||
|
|
||||||
if nick in self.chanmuc.chan_users():
|
if nick in self.chanmuc.chan_users():
|
||||||
self.chanmuc.chan_remove_user(nick)
|
self.chanmuc.chan_remove_user(nick)
|
||||||
@ -51,9 +49,9 @@ class IRCBot(SingleServerIRCBot):
|
|||||||
c.join(self.channel)
|
c.join(self.channel)
|
||||||
|
|
||||||
def on_pubmsg(self, c, e):
|
def on_pubmsg(self, c, e):
|
||||||
from_nick = nm_to_n(e.source())
|
from_nick = e.source.split('!')[0]
|
||||||
|
|
||||||
if str(e.arguments()[0]) == '.users':
|
if str(e.arguments[0]) == '.users':
|
||||||
users = self.chanmuc.muc_users()
|
users = self.chanmuc.muc_users()
|
||||||
users = ', '.join(users)
|
users = ', '.join(users)
|
||||||
m = '[ XMPP Users ] ' + users
|
m = '[ XMPP Users ] ' + users
|
||||||
@ -62,7 +60,7 @@ class IRCBot(SingleServerIRCBot):
|
|||||||
for i in range(0, len(m), buffer):
|
for i in range(0, len(m), buffer):
|
||||||
inter.irc(m[i:i + buffer])
|
inter.irc(m[i:i + buffer])
|
||||||
|
|
||||||
elif str(e.arguments()[0]) == '.help':
|
elif str(e.arguments[0]) == '.help':
|
||||||
m = 'The only command I know is \'.users\'. Also, my owner is ' \
|
m = 'The only command I know is \'.users\'. Also, my owner is ' \
|
||||||
+ owner + '.'
|
+ owner + '.'
|
||||||
|
|
||||||
@ -71,17 +69,17 @@ class IRCBot(SingleServerIRCBot):
|
|||||||
inter.irc(m[i:i + buffer])
|
inter.irc(m[i:i + buffer])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
message = '[' + from_nick + '] ' + ''.join(e.arguments())
|
message = '[' + from_nick + '] ' + ''.join(e.arguments)
|
||||||
try:
|
try:
|
||||||
inter.xmpp(message)
|
inter.xmpp(message)
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def on_action(self, c, e):
|
def on_action(self, c, e):
|
||||||
from_nick = nm_to_n(e.source())
|
from_nick = e.source.split('!')[0]
|
||||||
|
|
||||||
if (from_nick != i_nick):
|
if (from_nick != i_nick):
|
||||||
message = '***' + from_nick + ' ' + ''.join(e.arguments())
|
message = '***' + from_nick + ' ' + ''.join(e.arguments)
|
||||||
try:
|
try:
|
||||||
inter.xmpp(message)
|
inter.xmpp(message)
|
||||||
except:
|
except:
|
||||||
@ -194,13 +192,15 @@ class ChannelAndMuc:
|
|||||||
self.c_users = []
|
self.c_users = []
|
||||||
|
|
||||||
def muc_add_user(self, user):
|
def muc_add_user(self, user):
|
||||||
self.m_users.append(user)
|
if user != m_nick:
|
||||||
|
self.m_users.append(user)
|
||||||
|
|
||||||
def muc_remove_user(self, user):
|
def muc_remove_user(self, user):
|
||||||
self.m_users.remove(user)
|
self.m_users.remove(user)
|
||||||
|
|
||||||
def chan_add_user(self, user):
|
def chan_add_user(self, user):
|
||||||
self.c_users.append(user)
|
if user != i_nick:
|
||||||
|
self.c_users.append(user)
|
||||||
|
|
||||||
def chan_remove_user(self, user):
|
def chan_remove_user(self, user):
|
||||||
self.c_users.remove(user)
|
self.c_users.remove(user)
|
||||||
|
446
lib/ircbot.py
446
lib/ircbot.py
@ -1,446 +0,0 @@
|
|||||||
# Copyright (C) 1999--2002 Joel Rosdahl
|
|
||||||
#
|
|
||||||
# This library is free software; you can redistribute it and/or
|
|
||||||
# modify it under the terms of the GNU Lesser General Public
|
|
||||||
# License as published by the Free Software Foundation; either
|
|
||||||
# version 2.1 of the License, or (at your option) any later version.
|
|
||||||
#
|
|
||||||
# This library is distributed in the hope that it will be useful,
|
|
||||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
# Lesser General Public License for more details.
|
|
||||||
#
|
|
||||||
# You should have received a copy of the GNU Lesser General Public
|
|
||||||
# License along with this library; if not, write to the Free Software
|
|
||||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
#
|
|
||||||
# Joel Rosdahl <joel@rosdahl.net>
|
|
||||||
#
|
|
||||||
# $Id: ircbot.py,v 1.21 2005/12/23 18:44:43 keltus Exp $
|
|
||||||
|
|
||||||
"""ircbot -- Simple IRC bot library.
|
|
||||||
|
|
||||||
This module contains a single-server IRC bot class that can be used to
|
|
||||||
write simpler bots.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
if sys.version_info >= (3, 0):
|
|
||||||
from collections import UserDict
|
|
||||||
else:
|
|
||||||
from UserDict import UserDict
|
|
||||||
|
|
||||||
from irclib import SimpleIRCClient
|
|
||||||
from irclib import nm_to_n, irc_lower, all_events
|
|
||||||
from irclib import parse_channel_modes, is_channel
|
|
||||||
from irclib import ServerConnectionError
|
|
||||||
|
|
||||||
class SingleServerIRCBot(SimpleIRCClient):
|
|
||||||
"""A single-server IRC bot class.
|
|
||||||
|
|
||||||
The bot tries to reconnect if it is disconnected.
|
|
||||||
|
|
||||||
The bot keeps track of the channels it has joined, the other
|
|
||||||
clients that are present in the channels and which of those that
|
|
||||||
have operator or voice modes. The "database" is kept in the
|
|
||||||
self.channels attribute, which is an IRCDict of Channels.
|
|
||||||
"""
|
|
||||||
def __init__(self, server_list, nickname, realname,
|
|
||||||
reconnection_interval=60, encoding="utf-8"):
|
|
||||||
"""Constructor for SingleServerIRCBot objects.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
server_list -- A list of tuples (server, port) that
|
|
||||||
defines which servers the bot should try to
|
|
||||||
connect to.
|
|
||||||
|
|
||||||
nickname -- The bot's nickname.
|
|
||||||
|
|
||||||
realname -- The bot's realname.
|
|
||||||
|
|
||||||
reconnection_interval -- How long the bot should wait
|
|
||||||
before trying to reconnect.
|
|
||||||
|
|
||||||
encoding -- An encoding to use.
|
|
||||||
|
|
||||||
dcc_connections -- A list of initiated/accepted DCC
|
|
||||||
connections.
|
|
||||||
"""
|
|
||||||
|
|
||||||
SimpleIRCClient.__init__(self)
|
|
||||||
self.channels = IRCDict()
|
|
||||||
self.server_list = server_list
|
|
||||||
if not reconnection_interval or reconnection_interval < 0:
|
|
||||||
reconnection_interval = 2**31
|
|
||||||
self.reconnection_interval = reconnection_interval
|
|
||||||
|
|
||||||
self._nickname = nickname
|
|
||||||
self._realname = realname
|
|
||||||
self._encoding = encoding
|
|
||||||
for i in ["disconnect", "join", "kick", "mode",
|
|
||||||
"namreply", "nick", "part", "quit"]:
|
|
||||||
self.connection.add_global_handler(i,
|
|
||||||
getattr(self, "_on_" + i),
|
|
||||||
-10)
|
|
||||||
def _connected_checker(self):
|
|
||||||
"""[Internal]"""
|
|
||||||
if not self.connection.is_connected():
|
|
||||||
self.connection.execute_delayed(self.reconnection_interval,
|
|
||||||
self._connected_checker)
|
|
||||||
self.jump_server()
|
|
||||||
|
|
||||||
def _connect(self):
|
|
||||||
"""[Internal]"""
|
|
||||||
password = None
|
|
||||||
if len(self.server_list[0]) > 2:
|
|
||||||
password = self.server_list[0][2]
|
|
||||||
try:
|
|
||||||
self.connect(self.server_list[0][0],
|
|
||||||
self.server_list[0][1],
|
|
||||||
self._nickname,
|
|
||||||
password,
|
|
||||||
ircname=self._realname,
|
|
||||||
encoding=self._encoding)
|
|
||||||
except ServerConnectionError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_disconnect(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
self.channels = IRCDict()
|
|
||||||
self.connection.execute_delayed(self.reconnection_interval,
|
|
||||||
self._connected_checker)
|
|
||||||
|
|
||||||
def _on_join(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
ch = e.target()
|
|
||||||
nick = nm_to_n(e.source())
|
|
||||||
if nick == c.get_nickname():
|
|
||||||
self.channels[ch] = Channel()
|
|
||||||
self.channels[ch].add_user(nick)
|
|
||||||
|
|
||||||
def _on_kick(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
nick = e.arguments()[0]
|
|
||||||
channel = e.target()
|
|
||||||
|
|
||||||
if nick == c.get_nickname():
|
|
||||||
del self.channels[channel]
|
|
||||||
else:
|
|
||||||
self.channels[channel].remove_user(nick)
|
|
||||||
|
|
||||||
def _on_mode(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
modes = parse_channel_modes(" ".join(e.arguments()))
|
|
||||||
t = e.target()
|
|
||||||
if is_channel(t):
|
|
||||||
ch = self.channels[t]
|
|
||||||
for mode in modes:
|
|
||||||
if mode[0] == "+":
|
|
||||||
f = ch.set_mode
|
|
||||||
else:
|
|
||||||
f = ch.clear_mode
|
|
||||||
f(mode[1], mode[2])
|
|
||||||
else:
|
|
||||||
# Mode on self... XXX
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _on_namreply(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
|
|
||||||
# e.arguments()[0] == "@" for secret channels,
|
|
||||||
# "*" for private channels,
|
|
||||||
# "=" for others (public channels)
|
|
||||||
# e.arguments()[1] == channel
|
|
||||||
# e.arguments()[2] == nick list
|
|
||||||
|
|
||||||
ch = e.arguments()[1]
|
|
||||||
for nick in e.arguments()[2].split():
|
|
||||||
if nick[0] == "@":
|
|
||||||
nick = nick[1:]
|
|
||||||
self.channels[ch].set_mode("o", nick)
|
|
||||||
elif nick[0] == "+":
|
|
||||||
nick = nick[1:]
|
|
||||||
self.channels[ch].set_mode("v", nick)
|
|
||||||
self.channels[ch].add_user(nick)
|
|
||||||
|
|
||||||
def _on_nick(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
before = nm_to_n(e.source())
|
|
||||||
after = e.target()
|
|
||||||
for ch in list(self.channels.values()):
|
|
||||||
if ch.has_user(before):
|
|
||||||
ch.change_nick(before, after)
|
|
||||||
|
|
||||||
def _on_part(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
nick = nm_to_n(e.source())
|
|
||||||
channel = e.target()
|
|
||||||
|
|
||||||
if nick == c.get_nickname():
|
|
||||||
del self.channels[channel]
|
|
||||||
else:
|
|
||||||
self.channels[channel].remove_user(nick)
|
|
||||||
|
|
||||||
def _on_quit(self, c, e):
|
|
||||||
"""[Internal]"""
|
|
||||||
nick = nm_to_n(e.source())
|
|
||||||
for ch in list(self.channels.values()):
|
|
||||||
if ch.has_user(nick):
|
|
||||||
ch.remove_user(nick)
|
|
||||||
|
|
||||||
def die(self, msg="Bye, cruel world!"):
|
|
||||||
"""Let the bot die.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
msg -- Quit message.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.connection.disconnect(msg)
|
|
||||||
sys.exit(0)
|
|
||||||
|
|
||||||
def disconnect(self, msg="I'll be back!"):
|
|
||||||
"""Disconnect the bot.
|
|
||||||
|
|
||||||
The bot will try to reconnect after a while.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
msg -- Quit message.
|
|
||||||
"""
|
|
||||||
self.connection.disconnect(msg)
|
|
||||||
|
|
||||||
def get_version(self):
|
|
||||||
"""Returns the bot version.
|
|
||||||
|
|
||||||
Used when answering a CTCP VERSION request.
|
|
||||||
"""
|
|
||||||
return "ircbot.py by Joel Rosdahl <joel@rosdahl.net>"
|
|
||||||
|
|
||||||
def jump_server(self, msg="Changing servers"):
|
|
||||||
"""Connect to a new server, possibly disconnecting from the current.
|
|
||||||
|
|
||||||
The bot will skip to next server in the server_list each time
|
|
||||||
jump_server is called.
|
|
||||||
"""
|
|
||||||
if self.connection.is_connected():
|
|
||||||
self.connection.disconnect(msg)
|
|
||||||
|
|
||||||
self.server_list.append(self.server_list.pop(0))
|
|
||||||
self._connect()
|
|
||||||
|
|
||||||
def on_ctcp(self, c, e):
|
|
||||||
"""Default handler for ctcp events.
|
|
||||||
|
|
||||||
Replies to VERSION and PING requests and relays DCC requests
|
|
||||||
to the on_dccchat method.
|
|
||||||
"""
|
|
||||||
if e.arguments()[0] == "VERSION":
|
|
||||||
c.ctcp_reply(nm_to_n(e.source()),
|
|
||||||
"VERSION " + self.get_version())
|
|
||||||
elif e.arguments()[0] == "PING":
|
|
||||||
if len(e.arguments()) > 1:
|
|
||||||
c.ctcp_reply(nm_to_n(e.source()),
|
|
||||||
"PING " + e.arguments()[1])
|
|
||||||
elif e.arguments()[0] == "DCC" and e.arguments()[1].split(" ", 1)[0] == "CHAT":
|
|
||||||
self.on_dccchat(c, e)
|
|
||||||
|
|
||||||
def on_dccchat(self, c, e):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def start(self):
|
|
||||||
"""Start the bot."""
|
|
||||||
self._connect()
|
|
||||||
SimpleIRCClient.start(self)
|
|
||||||
|
|
||||||
|
|
||||||
class IRCDict:
|
|
||||||
"""A dictionary suitable for storing IRC-related things.
|
|
||||||
|
|
||||||
Dictionary keys a and b are considered equal if and only if
|
|
||||||
irc_lower(a) == irc_lower(b)
|
|
||||||
|
|
||||||
Otherwise, it should behave exactly as a normal dictionary.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, dict=None):
|
|
||||||
self.data = {}
|
|
||||||
self.canon_keys = {} # Canonical keys
|
|
||||||
if dict is not None:
|
|
||||||
self.update(dict)
|
|
||||||
def __repr__(self):
|
|
||||||
return repr(self.data)
|
|
||||||
def __cmp__(self, dict):
|
|
||||||
if isinstance(dict, IRCDict):
|
|
||||||
return cmp(self.data, dict.data)
|
|
||||||
else:
|
|
||||||
return cmp(self.data, dict)
|
|
||||||
def __len__(self):
|
|
||||||
return len(self.data)
|
|
||||||
def __getitem__(self, key):
|
|
||||||
return self.data[self.canon_keys[irc_lower(key)]]
|
|
||||||
def __setitem__(self, key, item):
|
|
||||||
if key in self:
|
|
||||||
del self[key]
|
|
||||||
self.data[key] = item
|
|
||||||
self.canon_keys[irc_lower(key)] = key
|
|
||||||
def __delitem__(self, key):
|
|
||||||
ck = irc_lower(key)
|
|
||||||
del self.data[self.canon_keys[ck]]
|
|
||||||
del self.canon_keys[ck]
|
|
||||||
def __iter__(self):
|
|
||||||
return iter(self.data)
|
|
||||||
def __contains__(self, key):
|
|
||||||
return key in self
|
|
||||||
def clear(self):
|
|
||||||
self.data.clear()
|
|
||||||
self.canon_keys.clear()
|
|
||||||
def copy(self):
|
|
||||||
if self.__class__ is UserDict:
|
|
||||||
return UserDict(self.data)
|
|
||||||
import copy
|
|
||||||
return copy.copy(self)
|
|
||||||
def keys(self):
|
|
||||||
return list(self.data.keys())
|
|
||||||
def items(self):
|
|
||||||
return list(self.data.items())
|
|
||||||
def values(self):
|
|
||||||
return list(self.data.values())
|
|
||||||
def has_key(self, key):
|
|
||||||
return irc_lower(key) in self.canon_keys
|
|
||||||
def update(self, dict):
|
|
||||||
for k, v in list(dict.items()):
|
|
||||||
self.data[k] = v
|
|
||||||
def get(self, key, failobj=None):
|
|
||||||
return self.data.get(key, failobj)
|
|
||||||
|
|
||||||
|
|
||||||
class Channel:
|
|
||||||
"""A class for keeping information about an IRC channel.
|
|
||||||
|
|
||||||
This class can be improved a lot.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.userdict = IRCDict()
|
|
||||||
self.operdict = IRCDict()
|
|
||||||
self.voiceddict = IRCDict()
|
|
||||||
self.modes = {}
|
|
||||||
|
|
||||||
def users(self):
|
|
||||||
"""Returns an unsorted list of the channel's users."""
|
|
||||||
return list(self.userdict.keys())
|
|
||||||
|
|
||||||
def opers(self):
|
|
||||||
"""Returns an unsorted list of the channel's operators."""
|
|
||||||
return list(self.operdict.keys())
|
|
||||||
|
|
||||||
def voiced(self):
|
|
||||||
"""Returns an unsorted list of the persons that have voice
|
|
||||||
mode set in the channel."""
|
|
||||||
return list(self.voiceddict.keys())
|
|
||||||
|
|
||||||
def has_user(self, nick):
|
|
||||||
"""Check whether the channel has a user."""
|
|
||||||
return nick in self.userdict
|
|
||||||
|
|
||||||
def is_oper(self, nick):
|
|
||||||
"""Check whether a user has operator status in the channel."""
|
|
||||||
return nick in self.operdict
|
|
||||||
|
|
||||||
def is_voiced(self, nick):
|
|
||||||
"""Check whether a user has voice mode set in the channel."""
|
|
||||||
return nick in self.voiceddict
|
|
||||||
|
|
||||||
def add_user(self, nick):
|
|
||||||
self.userdict[nick] = 1
|
|
||||||
|
|
||||||
def remove_user(self, nick):
|
|
||||||
for d in self.userdict, self.operdict, self.voiceddict:
|
|
||||||
if nick in d:
|
|
||||||
del d[nick]
|
|
||||||
|
|
||||||
def change_nick(self, before, after):
|
|
||||||
self.userdict[after] = 1
|
|
||||||
del self.userdict[before]
|
|
||||||
if before in self.operdict:
|
|
||||||
self.operdict[after] = 1
|
|
||||||
del self.operdict[before]
|
|
||||||
if before in self.voiceddict:
|
|
||||||
self.voiceddict[after] = 1
|
|
||||||
del self.voiceddict[before]
|
|
||||||
|
|
||||||
def set_mode(self, mode, value=None):
|
|
||||||
"""Set mode on the channel.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
mode -- The mode (a single-character string).
|
|
||||||
|
|
||||||
value -- Value
|
|
||||||
"""
|
|
||||||
if mode == "o":
|
|
||||||
self.operdict[value] = 1
|
|
||||||
elif mode == "v":
|
|
||||||
self.voiceddict[value] = 1
|
|
||||||
else:
|
|
||||||
self.modes[mode] = value
|
|
||||||
|
|
||||||
def clear_mode(self, mode, value=None):
|
|
||||||
"""Clear mode on the channel.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
|
|
||||||
mode -- The mode (a single-character string).
|
|
||||||
|
|
||||||
value -- Value
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
if mode == "o":
|
|
||||||
del self.operdict[value]
|
|
||||||
elif mode == "v":
|
|
||||||
del self.voiceddict[value]
|
|
||||||
else:
|
|
||||||
del self.modes[mode]
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def has_mode(self, mode):
|
|
||||||
return mode in self.modes
|
|
||||||
|
|
||||||
def is_moderated(self):
|
|
||||||
return self.has_mode("m")
|
|
||||||
|
|
||||||
def is_secret(self):
|
|
||||||
return self.has_mode("s")
|
|
||||||
|
|
||||||
def is_protected(self):
|
|
||||||
return self.has_mode("p")
|
|
||||||
|
|
||||||
def has_topic_lock(self):
|
|
||||||
return self.has_mode("t")
|
|
||||||
|
|
||||||
def is_invite_only(self):
|
|
||||||
return self.has_mode("i")
|
|
||||||
|
|
||||||
def has_allow_external_messages(self):
|
|
||||||
return self.has_mode("n")
|
|
||||||
|
|
||||||
def has_limit(self):
|
|
||||||
return self.has_mode("l")
|
|
||||||
|
|
||||||
def limit(self):
|
|
||||||
if self.has_limit():
|
|
||||||
return self.modes[l]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def has_key(self):
|
|
||||||
return self.has_mode("k")
|
|
||||||
|
|
||||||
def key(self):
|
|
||||||
if self.has_key():
|
|
||||||
return self.modes["k"]
|
|
||||||
else:
|
|
||||||
return None
|
|
1573
lib/irclib.py
1573
lib/irclib.py
File diff suppressed because it is too large
Load Diff
@ -1 +1,2 @@
|
|||||||
sleekxmpp>=1.2.0
|
sleekxmpp>=1.2.0
|
||||||
|
irc>=5.0.1
|
||||||
|
Loading…
Reference in New Issue
Block a user