def on_welcome(self, c: ServerConnection, e: Event) -> None:
        if len(self.nickserv_password) > 0:
            msg = 'identify %s' % (self.nickserv_password,)
            c.privmsg('NickServ', msg)
        c.join(self.channel)

        def forward_to_irc(msg: Dict[str, Any]) -> None:
            not_from_zulip_bot = msg["sender_email"] != self.zulip_client.email
            if not not_from_zulip_bot:
                # Do not forward echo
                return
            is_a_stream = msg["type"] == "stream"
            if is_a_stream:
                in_the_specified_stream = msg["display_recipient"] == self.stream
                at_the_specified_subject = msg["subject"].casefold() == self.topic.casefold()
                if in_the_specified_stream and at_the_specified_subject:
                    msg["content"] = ("@**%s**: " % (msg["sender_full_name"],)) + msg["content"]
                    send = lambda x: self.c.privmsg(self.channel, x)
                else:
                    return
            else:
                recipients = [u["short_name"] for u in msg["display_recipient"] if
                              u["email"] != msg["sender_email"]]
                if len(recipients) == 1:
                    send = lambda x: self.c.privmsg(recipients[0], x)
                else:
                    send = lambda x: self.c.privmsg_many(recipients, x)
            for line in msg["content"].split("\n"):
                send(line)

        z2i = mp.Process(target=self.zulip_client.call_on_each_message, args=(forward_to_irc,))
        z2i.start()
Beispiel #2
0
 def on_nicknameinuse(self, conn:ServerConnection, event:Event)->str:
     """
     Trigered if username is take. Changes the username by appending
     69 to it
     :param conn: ServerConnection to irc server
     :param event: Event
     :return: str containing new username
     """
     conn.nick(conn.get_nickname() + "69")
Beispiel #3
0
 def on_welcome(self, conn:ServerConnection, event:Event):
     """
     Triggered when a welcome message is received meaning
     that the server connections has been established. Joins the channel
     specified by self.channel.
     :param conn: ServerConnection
     :param event: Event
     :return: None
     """
     conn.join(self.channel)
Beispiel #4
0
 def on_welcome(self, conn: ServerConnection, _: Event):
     """
     The 'welcome' event indicates a successful connection to the server
     Sends a whois command to find the bot on the server
     :param conn: The connection
     :param _: The 'welcome' event
     :return: None
     """
     self.logger.info("Connected to server")
     conn.whois(self.pack.bot)
Beispiel #5
0
 def _send_xdcc_request_message(self, conn: ServerConnection):
     """
     Sends an XDCC request message
     :param conn: The connection to use
     :return: None
     """
     msg = self.pack.get_request_message()
     self.logger.info("Send XDCC Message: " + msg)
     self.message_sent = True
     conn.privmsg(self.pack.bot, msg)
Beispiel #6
0
 def on_dccmsg(self, conn:ServerConnection, event:Event):
     """
     Triggered when a non-chat DCC message has been received. DCC messages
     are raw bytes so there's potential for using this for file transfer. Currently
     for testing we merely decode them as text messages
     :param conn: ServerConnection
     :param event: Event
     :return:None
     """
     text = event.arguments[0].decode('utf-8')
     conn.privmsg("You said: " + text)
Beispiel #7
0
 def handler(self, connection: ServerConnection, event: Event):
     if event.arguments:
         occurrence_key = connection.server, event.target
         if not self.throttle.is_throttled(*occurrence_key):
             for pattern, response in self.responses:
                 if pattern.match(event.arguments[0]):
                     if not self.throttle.occurrence(*occurrence_key):
                         if event.type == "privmsg":
                             target = event.source.nick
                         else:
                             target = event.target
                         connection.privmsg(target, response)
                     break
Beispiel #8
0
    def _send_xdcc_request_message(self, conn: ServerConnection):
        """
        Sends an XDCC request message
        :param conn: The connection to use
        :return: None
        """
        self.logger.info("Waiting for {}s before sending message".format(
            self.wait_time))
        time.sleep(self.wait_time)

        msg = self.pack.get_request_message()
        self.logger.info("Send XDCC Message: " + msg)
        self.message_sent = True
        conn.privmsg(self.pack.bot, msg)
Beispiel #9
0
def test_channel_joins(config, bot, nickmask, monkeypatch):
    class FakeSocket:
        def getpeername(self):
            return ('10.0.0.99', 6667)

    socket = FakeSocket()
    conn = ServerConnection(None)

    welcome_event = Event(type='welcome',
                          source=config.server.host,
                          target=config.nickname)

    def join(self, channel, key=''):
        join_event = Event(type='join', source=nickmask, target=channel)
        bot.on_join(conn, join_event)

    received_signal_data = []

    @irc_channel_joined.connect
    def handle_irc_channel_joined(sender, **data):
        received_signal_data.append(data)

    with monkeypatch.context() as mpc:
        mpc.setattr(ServerConnection, 'socket', socket)
        mpc.setattr(ServerConnection, 'join', join)
        bot.on_welcome(conn, welcome_event)

    assert received_signal_data == [
        {
            'channel_name': '#one'
        },
        {
            'channel_name': '#two'
        },
    ]
Beispiel #10
0
    def on_whoischannels(self, conn: ServerConnection, event: Event):
        """
        The 'whoischannels' event indicates that a whois request has found
        channels that the bot is a part of.
        Channels that the bot has joined will be joined as well.
        :param conn: The connection
        :param event: The 'whoischannels' event
        :return: None
        """
        self.logger.info("WHOIS: " + str(event.arguments))
        channels = event.arguments[1].split("#")
        channels.pop(0)
        channels = list(map(lambda x: "#" + x.split(" ")[0], channels))
        self.channels = channels

        for channel in self.channels:
            # Join all channels to avoid only joining a members-only channel
            conn.join(channel)
Beispiel #11
0
 def on_endofwhois(self, conn: ServerConnection, _: Event):
     """
     The 'endofwhois' event indicates the end of a whois request.
     This manually calls on_join in case the bot
     has not joined any channels.
     :param conn: The connection
     :param _: The 'endofwhois' event
     :return: None
     """
     self.logger.info("WHOIS End")
     if self.channels is None:
         if self.fallback_channel is not None:
             channel = self.fallback_channel
             if not channel.startswith("#"):
                 channel = "#" + channel
             conn.join(channel)
             return
         else:
             self.on_join(conn, _, True)
    def on_welcome(self, connection: ServerConnection, event: Event):
        """Callback for when connection has been established

        Joins the Twitch chat and sends a message to confirm
        connection.

        Parameters
        ----------
        connection : ServerConnection
            Connection to Twitch server
        event : Event
            Event object for connection
        """

        for req in ("membership", "tags", "commands"):
            connection.cap("REQ", f":twitch.tv/{req}")

        connection.join(self.CHANNEL)
        self.send_message("Connected")
        LOG.info(
            f"Connected user {self.USERNAME} to twitch channel {self.CHANNEL[1:]}."
        )
Beispiel #13
0
    def handle_command(self, conn: ServerConnection, channel: str, message: str, tags: TwitchTags) -> None:
        """Command Handler for the chat bot"""
        try:
            command_name, *msg = message[1:].split()
            command_name = command_name.lower()
            msg = ' '.join(msg)

            if command_name == 'me':
                self._command_manager.store(
                    command_name=tags.user.lower(),
                    message=msg
                )
                conn.privmsg(channel, f'The command !{tags.user.lower()} has been updated!')
                return

            command = self._command_manager.get(command_name)
            if not command:
                return

            command.handle(tags.permission, msg)
            if command and command.response:
                conn.privmsg(channel, command.response)
        except Exception as e:
            print(f"Uh Oh: {e}")
Beispiel #14
0
 def on_nicknameinuse(self, connection: ServerConnection, event: Event):
     connection.nick("{}_".format(connection.get_nickname()))
 def on_pubmsg(self, conn: ServerConnection, event: Event):
     if event.arguments[0] == 'test123':
         conn.privmsg(CHANNEL, '#familyfriendly, bitte!')
Beispiel #16
0
 def on_nicknameinuse(connection: ServerConnection, *_):
     connection.nick(connection.nickname + '_')
 def on_nicknameinuse(self, c: ServerConnection, e: Event) -> None:
     c.nick(c.get_nickname().replace("_zulip", "__zulip"))
 def on_dccmsg(self, c: ServerConnection, e: Event) -> None:
     c.privmsg("You said: " + e.arguments[0])
Beispiel #19
0
 def on_invite(self, connection: ServerConnection, event: Event):
     if event.target == connection.get_nickname() and event.arguments:
         if event.arguments[0] not in self.channels:
             connection.join(event.arguments[0])
Beispiel #20
0
 def on_kick(self, connection: ServerConnection, event: Event):
     if event.arguments and connection.get_nickname() in event.arguments:
         connection.join(event.target)
 def on_endofmotd(self, conn: ServerConnection, event: Event):
     print('Well, we are done here.')
     conn.join(CHANNEL)
Beispiel #22
0
    def on_ctcp(self, conn: ServerConnection, event: Event):
        """
        The 'ctcp' event indicates that a CTCP message was received.
        The downloader receives a CTCP from the bot to initialize the
        XDCC file transfer.
        Handles DCC ACCEPT and SEND messages. Other DCC messages will result
        in a raised InvalidCTCP exception.
        DCC ACCEPT will only occur when a resume request was sent successfully.
        DCC SEND will occur when the bot offers a file.
        :param conn: The connection
        :param event: The 'ctcp' event
        :return: None
        :raise InvalidCTCPException: In case no valid DCC message was received
        """

        def start_download(append: bool = False):
            """
            Helper method that starts the download of an XDCC pack
            :param append: If set to True, opens the file in append mode
            :return: None
            """
            self.downloading = True
            self.xdcc_timestamp = time.time()
            mode = "ab" if append else "wb"
            self.logger.info("Starting Download (" + mode + ")")
            self.xdcc_file = open(self.pack.get_filepath(), mode)
            self.xdcc_connection = \
                self.dcc_connect(self.peer_address, self.peer_port, "raw")
            self.xdcc_connection.socket.settimeout(5)

        self.logger.info("CTCP Message: " + str(event.arguments))
        if event.arguments[0] == "DCC":
            payload = shlex.split(event.arguments[1])

            if payload[0] == "SEND":

                filename = payload[1]
                self.peer_address = ip_numstr_to_quad(payload[2])
                self.peer_port = int(payload[3])
                self.filesize = int(payload[4])

                self.pack.set_filename(filename)

                if os.path.isfile(self.pack.get_filepath()):

                    position = os.path.getsize(self.pack.get_filepath())

                    if position >= self.filesize:
                        raise AlreadyDownloadedException(self.pack.filename)

                    self.logger.info("Requesting Resume")
                    self.progress = position
                    bot = event.source.split("!")[0]
                    resume_param = "\"" + filename + "\" " + \
                                   str(self.peer_port) + " " + str(position)
                    conn.ctcp("DCC RESUME", bot, resume_param)

                else:
                    start_download()

            elif payload[0] == "ACCEPT":
                start_download(append=True)

            else:
                raise InvalidCTCPException(payload[0])
Beispiel #23
0
 def on_welcome(self, c: ServerConnection, e: Event):
     logger.info(f"Successfully joined irc!")
     c.join(self.channel)
Beispiel #24
0
 def on_welcome(self, connection: ServerConnection, event: Event):
     for channel in self.initial_channels:
         connection.join(channel)
Beispiel #25
0
 def on_welcome(self, connection: client.ServerConnection,
                _: client.Event) -> None:
     if self.capabilities:
         connection.cap('REQ', *self.capabilities)
         connection.cap('END')
     connection.join(self.channel)