123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- # -*- coding:utf-8 -*-
- import socket
- import re
- from time import sleep
- class noaIRC(object):
- def __init__(self, host, port, user, key, channel):
- """
- Authentificate the bot over Twitch IRC
- """
- self.__channel = channel
- self.__compiledBanWords = []
- # configure socket and try to join IRC channel
- self.__sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.__sock.connect((host, port))
- self.__sock.settimeout(1)
- self.__sock.send("PASS {}\r\n".format(key).encode("utf-8"))
- self.__sock.send("NICK {}\r\n".format(user).encode("utf-8"))
- self.__sock.send("JOIN {}\r\n".format(channel).encode("utf-8"))
- def setPattern(self, pattern):
- """
- Allow to set message pattern in order to check whether the posted message
- is a real message and not service message
- """
- self.__message_pattern = re.compile(r"%s" % pattern)
- def setMySQLconnector(self, connector):
- """
- Allow to set mysql connector get persistance
- """
- self.__mysql = connector
- def __getAllowedCommands(self, command):
- rights = {
- "ban" : ["admin"],
- "rban" : ["admin"],
- "quote" : ["admin", "default"]
- }
- return rights[command] if command in rights.keys() else None
- def __isAuthorized(self, command, username):
- """
- Return whether user is authorized to use command
- """
- # Get user role
- allowedGroups = self.__getAllowedCommands(command)
- if not allowedGroups:
- return False
- if 'default' in allowedGroups:
- return True
- for allowedGroup in allowedGroups:
- if username in self.__mysql.getUsers()[allowedGroup]:
- return True
-
- def __chat(self, msg):
- """
- Send a chat message to the server.
- Keyword arguments:
- sock -- the socket over which to send the message
- msg -- the message to be sent
- """
- self.__sock.send("PRIVMSG %s :%s\r\n" % (self.__channel, msg.encode('utf-8')))
- def __timeout(self, username, timeout=5):
- """
- Timeout a user
- """
- self.__chat(u"Timeout %ds %s (warning)" % (timeout, username))
- self.__sock.send("PRIVMSG %s :/timeout %s 5 \r\n" % (self.__channel, username))
- def __call(self, command, parameters, username):
- """
- Execute a command
- """
- if not self.__isAuthorized(command, username):
- return
- # Remove final carriage return
- parameters = parameters.replace("\r", "")
- # Moderation
- if command == 'ban' and len(parameters) :
- banword = parameters.split(' ')[0].replace("\r", "")
- if banword in ['***', '']:
- return
- self.__compiledBanWords.append(re.compile(r'%s'%(banword)))
- self.__mysql.addSwearword(banword)
- self.__chat(u"Mot interdit ajouté")
- if command == "rban" and len(parameters):
- banword = parameters.split(' ')[0]
- index = self.__mysql.delSwearword(banword)
- if index is not None:
- del self.__compiledBanWords[index]
- self.__chat(u"Mot interdit supprimé")
- # Quoting system
- if command == 'quote' and len(parameters) :
- if parameters.startswith("#"):
- index = int(parameters[1:]) - 1
- if index < 0:
- return
- message = self.__mysql.getQuote(index)
- if message:
- self.__chat(message)
- else:
- self.__mysql.addQuote(parameters)
- def __parseMessage(self, message, username):
- """
- Check message
- """
- # check swearword
- groups = self.__mysql.getUsers()
- for swearword in self.__compiledBanWords:
- if swearword.search(message) is not None and not username in groups['admin'] and not username in groups['moderator']:
- self.__timeout(username)
- # command pattern
- command_pattern = re.compile(r'^!(\w+)\s?(.*)')
- matches = re.search(command_pattern, message)
- if matches:
- command = matches.group(1)
- parameters = matches.group(2)
- self.__call(command, parameters, username)
- def run(self):
- """
- Core loop
- """
- # Compile ban patterns
- for banword in self.__mysql.getSwearwords():
- self.__compiledBanWords.append(re.compile(r'%s'%(banword)))
- while True:
- try:
- response = self.__sock.recv(1024).decode("utf-8")
- except socket.error, e:
- continue
- else:
- if response == "PING :tmi.twitch.tv\r\n":
- self.__sock.send("PONG :tmi.twitch.tv\r\n".encode("utf-8"))
- print "pong"
- else:
- matches = re.search(self.__message_pattern, response)
- if matches:
- username = matches.group(1)
- message = matches.group(2)
- self.__parseMessage(message, username)
- sleep(0.1)
|