github.com/containers/libpod@v1.9.4-0.20220419124438-4284fd425507/contrib/cirrus/podbot.py (about) 1 #!/usr/bin/env python3 2 3 # Simple and dumb script to send a message to the #podman IRC channel on frenode 4 # Based on example from: https://pythonspot.com/building-an-irc-bot/ 5 6 import os 7 import time 8 import random 9 import errno 10 import socket 11 import sys 12 13 class IRC: 14 15 response_timeout = 30 # seconds 16 irc = socket.socket() 17 18 def __init__(self, server, nickname, channel): 19 self.server = server 20 self.nickname = nickname 21 self.channel = channel 22 self.irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 23 24 def _send(self, cmdstr): 25 self.irc.send(bytes(cmdstr + '\r\n', 'utf-8')) 26 27 def message(self, msg): 28 data = 'PRIVMSG {0} :{1}\r\n'.format(self.channel, msg) 29 print(data) 30 self._send(data) 31 32 @staticmethod 33 def fix_newlines(bufr): 34 return bufr.replace('\\r\\n', '\n') 35 36 def _required_response(self, needle, haystack): 37 start = time.time() 38 end = start + self.response_timeout 39 while time.time() < end: 40 if haystack.find(needle) != -1: 41 return (False, haystack) 42 time.sleep(0.1) 43 try: 44 haystack += str(self.irc.recv(4096, socket.MSG_DONTWAIT)) 45 except socket.error as serr: 46 if serr.errno == errno.EWOULDBLOCK: 47 continue 48 raise # can't handle this 49 return (True, haystack) # Error 50 51 def connect(self, username, password): 52 # This is ugly as sin, but seems to be a working send/expect sequence 53 54 print("connecting to: {0}".format(self.server)) 55 self.irc.connect((self.server, 6667)) #connects to the server 56 self._send("USER {0} {0} {0} :I am {0}".format(self.nickname)) 57 self._send("NICK {0}".format(self.nickname)) 58 59 err, haystack = self._required_response('End of /MOTD command.' 60 ''.format(self.nickname), "") 61 if err: 62 print(self.fix_newlines(haystack)) 63 print("Error connecting to {0}".format(self.server)) 64 return True 65 66 print("Logging in as {0}".format(username)) 67 self._send("PRIVMSG NickServ :IDENTIFY {0} {1}".format(username, password)) 68 err, _ = self._required_response("You are now identified for", "") 69 if err: 70 print("Error logging in to {0} as {1}".format(self.server, username)) 71 return True 72 73 print("Joining {0}".format(self.channel)) 74 self._send("JOIN {0}".format(self.channel)) 75 err, haystack = self._required_response("{0} {1} :End of /NAMES list." 76 "".format(self.nickname, self.channel), 77 haystack) 78 print(self.fix_newlines(haystack)) 79 if err: 80 print("Error joining {0}".format(self.channel)) 81 return True 82 return False 83 84 def quit(self): 85 print("Quitting") 86 self._send("QUIT :my work is done here") 87 self.irc.close() 88 89 90 if len(sys.argv) < 3: 91 print("Error: Must pass desired nick and message as parameters") 92 else: 93 for try_again in (True,False): 94 irc = IRC("irc.freenode.net", sys.argv[1], "#podman") 95 err = irc.connect(*os.environ.get('IRCID', 'Big Bug').split(" ", 2)) 96 if err and try_again: 97 print("Trying again in 5 seconds...") 98 time.sleep(5) 99 continue 100 elif err: 101 break 102 irc.message(" ".join(sys.argv[2:])) 103 time.sleep(5.0) # avoid join/quit spam 104 irc.quit() 105 break