IRCBot.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. #!/usr/bin/env python3
  2. # -*- encoding: utf-8 -*-
  3. __Author__ = "Haelwenn Monnier (lanodan) <haelwenn.monnier@gmail.com>"
  4. __License__ = "CC-BY-SA"
  5. import socket, sys, re, time, urllib
  6. tetris=0
  7. urlRegex = re.compile('(https?|ftp)://', flags=re.IGNORECASE)
  8. # Load config
  9. try:
  10. import conf
  11. except Exception as e:
  12. print('Exception: {}'.format(str(e)))
  13. print('Exiting…')
  14. sys.exit(1)
  15. def get_element(dataInput, elem):
  16. idx1=dataInput.find('<{}>'.format(elem))
  17. idx2=dataInput.find('</{}>'.format(elem))
  18. return dataInput[idx1+len('<{}>'.format(elem)):idx2].strip()
  19. # Output to the channel and console
  20. def privmsg(msg, destination = conf.channel):
  21. irc.send('PRIVMSG {}: {}\r\n'.format(destination, msg))
  22. print('PRIVMSG {}: {}'.format(destination, msg))
  23. #line: append to the log (output it to the console too)
  24. def log(line):
  25. print('[LOG]'+line)
  26. log = open('IRCBot.log', 'a')
  27. log.write('{}\n'.format(line))
  28. log.close()
  29. def sendCommand(command, docrlf=True):
  30. if docrlf:
  31. irc.send('{command}\r\n'.format_map())
  32. print('{}\r\n'.format(command))
  33. else:
  34. irc.send(command)
  35. print(command)
  36. # === Main script ===
  37. irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  38. irc.connect((conf.server, conf.port))
  39. #if SSLEnabled:
  40. # irc = ssl.wrap_socket(irc)
  41. #
  42. if conf.passwd is not None:
  43. sendCommand('PASS {}'.format(conf.passwd))
  44. if conf.nick is not None:
  45. sendCommand('NICK {}'.format(conf.nick))
  46. sendCommand('USER {} irc bot :Bot made by lanodan using python3!'.format(conf.nick))
  47. else:
  48. print('You must define a nick, see conf.py.example')
  49. sys.exit(1)
  50. #while 1:
  51. # if irc.recv(2048).find('372') != -1:
  52. if conf.channel is not None:
  53. sendCommand('JOIN {}'.format(conf.channel))
  54. # break
  55. time.sleep(1.5) # Random wait time, feel free to adjust it
  56. #while 1:
  57. # if irc.recv(2048).find('JOIN '+channel) != -1:
  58. if conf.welcomeMsg is not None:
  59. privmsg(conf.welcomeMsg)
  60. # break
  61. # Make a while loop to alway parse input
  62. while 1:
  63. data = irc.recv(2048) # text is the socket input (I use text because input is already taken)
  64. text = data.lower() # text is the socket input (I use text because input is already taken)
  65. print(data) # print the input for debugging purpose
  66. data_splitted = data[1:].split(' ', 3)
  67. if data[0] == ':':
  68. data_usermask = data_splitted[0]
  69. data_username = data_usermask.split('!')[0]
  70. data_command = data_splitted[1]
  71. data_origin = data_splitted[2]
  72. data_msg = ''.join(data_splitted[3][1:]).strip()
  73. print('[DEBUG] data_msg =', data_msg)
  74. if conf.separator in data_msg[0]: # "in" allows to put multiple separators
  75. command_arg = data_msg[1:].split(' ')
  76. print('[DEBUG] command_arg =', command_arg)
  77. if 'hi' == command_arg[0]:
  78. try:
  79. print(len(command_arg[1]))
  80. type(command_arg[1])
  81. if len(command_arg[1]) is not None:
  82. name = ''.join(command_arg[1:])
  83. except IndexError:
  84. name = data_username
  85. print('[DEBUG] name =', name)
  86. privmsg('{}: {}'.format(''.join(command_arg[1:]), conf.welcomeMsg), destination = data_origin)
  87. elif 'say' == command_arg[0]:
  88. privmsg(''.join(command_arg[1:]), destination = data_origin)
  89. elif 'action' == command_arg[0]:
  90. privmsg('\x01ACTION {} \x01'.format(''.join(command_arg[1:])), destination = data_origin)
  91. elif 'source' == command_arg[0]:
  92. privmsg(conf.source, destination = data_origin)
  93. elif 'tetris' in data_msg:
  94. privmsg('Never gonna give you up.')
  95. privmsg('Never gonna let you down.')
  96. privmsg('Never gonna run around and desert you.')
  97. privmsg('Never gonna make you cry.')
  98. privmsg('Never gonna say goodbye.')
  99. privmsg('Never gonna tell a lie and hurt you.')
  100. tetris=1 # Prevent another rick roll
  101. elif 'nsidentify' == command_arg[0]:
  102. sendCommand('NS identify {}'.format(conf.passwd))
  103. elif 'msgidentify' == command_arg[0]:
  104. privmsg('identify {}'.format(conf.passwd), destination = conf.NickServ)
  105. elif urlRegex.search(data_msg) is not None: # Use httpRegex on input
  106. url = re.findall('(?:https?|ftp)://[\w\$-_.+!*\'(),;\/\?\:\@\=\&]+', data, flags=re.IGNORECASE)[0] # parse URL
  107. print('Url:', url)
  108. try:
  109. if (len(url) > 8): # I assume a link is more than 8 characters long
  110. try:
  111. get = urllib.request.urlopen(url) # Open the link
  112. wget = get.read() # Read the input of the url
  113. print(get.info()) # Print Headers
  114. mimeType = get.info().type # Get the Content-Type
  115. get.close() # Close the connection
  116. # find the title
  117. if wget.find('<title>') != -1:
  118. title = get_element(wget, 'title')
  119. privmsg('Title: '+title)
  120. log('{}; {}; {}'.format(url, str(mimeType), title))
  121. elif wget.find('<TITLE>') != -1:
  122. title = get_element(wget, 'TITLE')
  123. privmsg('Title: '+title)
  124. log('{}; {}; {}'.format(url, str(mimeType), title))
  125. #If we can't find the title print the Content-Type
  126. else:
  127. privmsg('Content-Type: '+mimeType)
  128. log('{}; {}'.format(url, str(mimeType)))
  129. except Exception as e:
  130. privmsg('Exception: {}'.format(str(e)))
  131. else:
  132. privmsg('Link too short (not more than 8)')
  133. except Exception as e:
  134. privmsg('Exception: {}'.format(str(e)))
  135. elif 'JOIN' == data_command:
  136. if ('fuyuneko', 'lanodan') in data_username:
  137. privmsg('{}: Okaeri-nasai hime-sama'.format(data_username))
  138. else:
  139. privmsg('{}: '.format(data_username, conf.welcomeMsg))
  140. elif 'KICK' == data_command and conf.nick == data_username:
  141. time.sleep(5)
  142. sendCommand('JOIN '+conf.channel) #re-join the chan
  143. privmsg(welcomeMsg) # Say hello
  144. elif 'stop in the name of sey' == ''.join(command_arg[0:]):
  145. sendCommand('QUIT :{}'.format(conf.quitMsg))
  146. time.sleep(1)
  147. break
  148. else:
  149. if data_splitted[0] == 'PING':
  150. sendCommand('PONG {} {}'.format(conf.nick, ''.join(data.split(': '))))
  151. elif data is None:
  152. sendCommand('QUIT :Empty socket input')
  153. time.sleep(1)
  154. break
  155. irc.close()
  156. sys.exit()