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