Guest User

Untitled

a guest
Mar 29th, 2018
38
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 4.92 KB | None | 0 0
  1. import re
  2. import socket
  3.  
  4. '''
  5.  
  6. IRC Client: Mikey Mike
  7.  
  8. Intended to be used for a Twitch.tv IRC bot.
  9.  
  10. '''
  11.  
  12.  
  13. class IRC(object):
  14.     def __init__(self, parent, username, password, channel, server='irc.twitch.tv', port=6667):
  15.         """
  16.         :param parent: Parent object (used for debugging)
  17.         :param username: Twitch.tv username
  18.         :param password: Twitch.tv oauth password
  19.         :param channel: IRC channel the bot should join
  20.         :param server:  IRC server
  21.         :param port: IRC port
  22.         """
  23.         # Parent object.
  24.         self.parent = parent
  25.  
  26.         # Twitch IRC login credentials
  27.         self.username = username
  28.         self.password = password
  29.  
  30.         # IRC connection details
  31.         self.server = server
  32.         self.port = port
  33.         self.channel = channel
  34.  
  35.         # Socket for IRC client
  36.         self.sock = None
  37.         self.socket_buffer = 2048
  38.         self.connected = False
  39.         self.timeout = 5
  40.  
  41.     def get_socket(self):
  42.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  43.         sock.settimeout(self.timeout)
  44.  
  45.         self.sock = sock
  46.         self.parent.log("** Connecting to IRC Server: %s" % self.server)
  47.  
  48.         try:
  49.             sock.connect((self.server, self.port))
  50.         except:
  51.             self.parent.log('** Failed to Connect to Server: %s, Port: %s.' % (self.server, self.port))
  52.             return None
  53.  
  54.         sock.settimeout(self.timeout)
  55.  
  56.         data = 'USER %s\r\n' % self.username
  57.         sock.send(data.encode())
  58.  
  59.         data = 'PASS %s\r\n' % self.password
  60.         sock.send(data.encode())
  61.  
  62.         data = 'NICK %s\r\n' % self.username
  63.         sock.send(data.encode())
  64.  
  65.         if self.check_login_status(sock.recv(1024).decode()):
  66.             self.parent.log('** Successfully Logged into Server: %s' % self.server)
  67.         else:
  68.             self.parent.log('** Unsuccessful Login Attempt on Server: %s' % self.server)
  69.             return None
  70.  
  71.         self.join_channel(self.channel)
  72.         self.connected = True
  73.  
  74.         data = 'CAP REQ :twitch.tv/commands\r\n'
  75.         self.sock.send(data.encode())
  76.  
  77.         return sock
  78.  
  79.     @staticmethod
  80.     def check_login_status(socket_data):
  81.         if re.match(r'^:(testserver\.local|tmi\.twitch\.tv) NOTICE \* :Login unsuccessful\r\n$', socket_data):
  82.             return False
  83.         else:
  84.             return True
  85.  
  86.     def join_channel(self, channel):
  87.         self.parent.log("** Joining Channel: %s" % channel)
  88.  
  89.         try:
  90.             data = 'JOIN %s\r\n' % channel
  91.             self.sock.send(data.encode())
  92.         except Exception:
  93.             self.parent.log('** Failed to Join Channel: %s' % channel)
  94.             self.connected = False
  95.  
  96.         self.parent.log("** Successfully Joined Channel: %s" % channel)
  97.  
  98.     def send_chat_message(self, channel, message):
  99.         try:
  100.             data = 'PRIVMSG %s :%s\r\n' % (channel, message)
  101.             self.sock.send(data.encode())
  102.         except Exception:
  103.             self.parent.log('** Error Sending Message to Channel: %s' % channel)
  104.             self.connected = False
  105.  
  106.     def ping(self):
  107.         data = 'PING \r\n'
  108.         self.sock.send(data.encode())
  109.  
  110.     def pong(self, data):
  111.         if data[:4] == "PING":
  112.             data = 'PONG \r\n'
  113.             self.sock.send(data.encode())
  114.  
  115.     @staticmethod
  116.     def incoming_chat(data):
  117.         try:
  118.             data = data.decode()
  119.         except Exception:
  120.             data = data
  121.  
  122.         if re.match(r'^:[a-zA-Z0-9_]+\![a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.tmi\.twitch\.tv|\.testserver\.local) PRIVMSG #[a-zA-Z0-9_]+ :.+$', data):
  123.             return True
  124.         else:
  125.             return False
  126.  
  127.     @staticmethod
  128.     def incoming_whisper(data):
  129.         try:
  130.             data = data.decode()
  131.         except Exception:
  132.             data = data
  133.  
  134.         if re.match(r'^:[a-zA-Z0-9_]+\![a-zA-Z0-9_]+@[a-zA-Z0-9_]+(\.tmi\.twitch\.tv|\.testserver\.local) WHISPER [a-zA-Z0-9_]+ :.+$', data):
  135.             return True
  136.         else:
  137.             return False
  138.  
  139.     @staticmethod
  140.     def parse_chat_message(data):
  141.         return {
  142.             'channel': re.findall(r'^:.+\![a-zA-Z0-9_]+@[a-zA-Z0-9_]+.+ PRIVMSG (.*?) :', data.decode())[0],
  143.             'username': re.findall(r'^:([a-zA-Z0-9_]+)\!', data.decode())[0],
  144.             'message': re.findall(r'PRIVMSG #[a-zA-Z0-9_]+ :(.+)', data.decode())[0]
  145.         }
  146.  
  147.     @staticmethod
  148.     def parse_whisper_message(data):
  149.         return {
  150.             'channel': re.findall(r'^:.+\![a-zA-Z0-9_]+@[a-zA-Z0-9_]+.+ WHISPER (.*?) :', data.decode())[0],
  151.             'username': re.findall(r'^:([a-zA-Z0-9_]+)\!', data.decode())[0],
  152.             'message': re.findall(r'WHISPER [a-zA-Z0-9_]+ :(.+)', data.decode())[0]
  153.         }
  154.  
  155.  
  156. class MessageParser(object):
  157.  
  158.     @staticmethod
  159.     def is_bot_command(message):
  160.         """
  161.  
  162.         :param message: Entire chat message
  163.         :return: True if the chat message is a bot command
  164.         """
  165.         if message is None:
  166.             return False
  167.  
  168.         try:
  169.             if message[0] == "!":
  170.                 return True
  171.             else:
  172.                 return False
  173.         except Exception:
  174.             return False
  175.  
  176.     @staticmethod
  177.     def get_bot_command(message):
  178.         """
  179.  
  180.         :param message: Entire chat message
  181.         :return: A string representing a valid bot command, otherwise None
  182.         """
  183.         if message is None:
  184.             return None
  185.  
  186.         if '!' not in message:
  187.             return None
  188.  
  189.         try:
  190.             bot_command = message[message.index('!') + 1:].lower()
  191.  
  192.             if ' ' in bot_command:
  193.                 bot_command = bot_command[:bot_command.index(' ')]
  194.  
  195.             if '\n' in bot_command:
  196.                 bot_command = bot_command[:bot_command.index('\n')]
  197.  
  198.         except Exception:
  199.             bot_command = None
  200.  
  201.         return bot_command
Add Comment
Please, Sign In to add comment