An IRC bot built for tubes
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

139 Zeilen
3.9KB

  1. #!/usr/bin/python3
  2. # See the LICENSE file for licensing information
  3. import re
  4. nick = 'seddy'
  5. server = 'chat.freenode.net'
  6. channel = '#example'
  7. gecos = 'A text processing bot'
  8. receive = '/tmp/{0}.in'.format(server)
  9. send = '/tmp/{0}.out'.format(server)
  10. parse_msg = re.compile(channel + ' :(.*)')
  11. parse_sed = re.compile('(?<!\\\\)/')
  12. is_sed = re.compile('^s/.*/.*')
  13. ping = re.compile('PING :(.*)')
  14. class Queue:
  15. size = 0
  16. data = []
  17. head = 0
  18. tail = 0
  19. count = 0
  20. def __init__(self, size):
  21. self.size = size
  22. self.data = [None]*size
  23. def enqueue(self, s):
  24. if not self.full():
  25. self.count += 1
  26. self.data[self.tail] = s
  27. self.tail = (self.tail + 1) % self.size
  28. def dequeue(self):
  29. if not self.empty():
  30. self.count -= 1
  31. s = self.data[self.head]
  32. self.head = (self.head + 1) % self.size
  33. return s
  34. def full(self):
  35. return self.size == self.count
  36. def empty(self):
  37. return self.head == self.count
  38. def find(self, s, flags=0):
  39. i = self.tail-1
  40. while True:
  41. if i == -1:
  42. i = self.size-1
  43. if re.search(s, self.data[i], flags):
  44. return self.data[i]
  45. i -= 1
  46. if i == self.tail-1 or self.data[i] is None:
  47. return False
  48. def msg_replace(find, replace, msg, f, n=1):
  49. try:
  50. if msg[:7] == '\x01ACTION':
  51. res = '\x01ACTION {0}'.format(re.sub(find, replace, msg[8:], count=n, flags=f))
  52. else:
  53. res = re.sub(find, replace, msg, count=n, flags=f)
  54. except:
  55. return False
  56. return res
  57. def seddy(sed, history, parser):
  58. f = 0
  59. regex = parser.split(sed)
  60. if len(regex) < 4:
  61. return False
  62. if 'i' in regex[3]:
  63. f |= re.I
  64. try:
  65. msg = history.find(regex[1], f)
  66. except:
  67. return False
  68. if "g" in regex[3]:
  69. res = msg_replace(regex[1], regex[2], msg, 0, f)
  70. else:
  71. res = msg_replace(regex[1], regex[2], msg, 1, f)
  72. if res:
  73. res = res.replace('\0', re.search(regex[1], msg, f).group(0))
  74. return res
  75. def notice(msg, channel):
  76. with open(send, 'w', encoding='utf-8') as g:
  77. g.write('NOTICE ' + channel + ' :' + msg + '\r\n')
  78. def privmsg(msg, channel):
  79. if msg[:7] == '\x01ACTION':
  80. with open(send, 'w', encoding='utf-8') as g:
  81. g.write('PRIVMSG ' + channel + ' :' + '\x01' +
  82. ''.join(c for c in msg if c.isprintable()) + '\x01\r\n')
  83. else:
  84. with open(send, 'w', encoding='utf-8') as g:
  85. g.write('PRIVMSG ' + channel + ' :' +
  86. msg.replace('\n', ' ',).replace('\r', '') + '\r\n')
  87. if __name__ == "__main__":
  88. history = Queue(48)
  89. with open(send, 'w', encoding='utf-8') as f:
  90. f.write('NICK ' + nick + '\r\n')
  91. f.write('USER ' + nick + ' * 8 :' + gecos + '\r\n')
  92. sleep(5)
  93. f.write('JOIN ' + channel + '\r\n')
  94. with open(receive, 'r', encoding='utf-8') as f:
  95. for line in f:
  96. if 'PING' in line:
  97. with open(send, 'w', encoding='utf-8') as g:
  98. g.write('PONG {0}\r\n'.format(ping.split(line)[1]))
  99. continue
  100. m = parse_msg.match(line)
  101. try:
  102. channel = m.group(1)
  103. msg = m.group(2)
  104. except:
  105. continue
  106. if history.full():
  107. history.dequeue()
  108. if 'PRIVMSG' in line and not is_sed.match(msg):
  109. history.enqueue(msg)
  110. if '.bots' in msg[:5] or '.bot ' + nick in msg[:5 + len(nick)]:
  111. notice("I was written to correct your mistakes.")
  112. if '.source ' + nick in msg[:8 + len(nick)]:
  113. notice('[Python] https://github.com/sys-fs/seddy')
  114. elif is_sed.match(msg):
  115. res = seddy(msg, history)
  116. if res:
  117. privmsg(re.sub('\\\\/', '/', foo))