<commit_before># -*- coding: utf-8  -*-
#
# Copyright (C) 2009-2012 <NAME> <<EMAIL>>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import socket
from threading import Lock
from time import sleep, time

from earwigbot.exceptions import BrokenSocketError

__all__ = ["IRCConnection"]

class IRCConnection(object):
    """Interface with an IRC server."""

    def __init__(self, host, port, nick, ident, realname):
        self._host = host
        self._port = port
        self._nick = nick
        self._ident = ident
        self._realname = realname

        self._is_running = False
        self._send_lock = Lock()

        self._last_recv = time()
        self._last_ping = 0

    def __repr__(self):
        """Return the canonical string representation of the IRCConnection."""
        res = "IRCConnection(host={0!r}, port={1!r}, nick={2!r}, ident={3!r}, realname={4!r})"
        return res.format(self.host, self.port, self.nick, self.ident,
                          self.realname)

    def __str__(self):
        """Return a nice string representation of the IRCConnection."""
        res = "<IRCConnection {0}!{1} at {2}:{3}>"
        return res.format(self.nick, self.ident, self.host, self.port)

    def _connect(self):
        """Connect to our IRC server."""
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self._sock.connect((self.host, self.port))
        except socket.error:
            self.logger.exception("Couldn't connect to IRC server; retrying")
            sleep(8)
            self._connect()
        self._send("NICK {0}".format(self.nick))
        self._send("USER {0} {1} * :{2}".format(self.ident, self.host, self.realname))

    def _close(self):
        """Completely close our connection with the IRC server."""
        try:
            self._sock.shutdown(socket.SHUT_RDWR)  # Shut down connection first
        except socket.error:
            pass  # Ignore if the socket is already down
        self._sock.close()

    def _get(self, size=4096):
        """Receive (i.e. get) data from the server."""
        data = self._sock.recv(size)
        if not data:
            # Socket isn't giving us any data, so it is dead or broken:
            raise BrokenSocketError()
        return data

    def _send(self, msg, hidelog=False):
        """Send data to the server."""
        with self._send_lock:
            try:
                self._sock.sendall(msg + "\r\n")
            except socket.error:
                self._is_running = False
            else:
                if not hidelog:
                    self.logger.debug(msg)

    def _quit(self, msg=None):
        """Issue a quit message to the server. Doesn't close the connection."""
        if msg:
            self._send("QUIT :{0}".format(msg))
        else:
            self._send("QUIT")

    def _process_defaults(self, line):
        """Default process hooks for lines received on IRC."""
        self._last_recv = time()
        if line[0] == "PING":  # If we are pinged, pong back
            self.pong(line[1][1:])

    @property
    def host(self):
        """The hostname of the IRC server, like ``"irc.freenode.net"``."""
        return self._host

    @property
    def port(self):
        """The port of the IRC server, like ``6667``."""
        return self._port

    @property
    def nick(self):
        """Our nickname on the server, like ``"EarwigBot"``."""
        return self._nick

    @property
    def ident(self):
        """Our ident on the server, like ``"earwig"``.

        See http://en.wikipedia.org/wiki/Ident.
        """
        return self._ident

    @property
    def realname(self):
        """Our realname (gecos field) on the server."""
        return self._realname

    def say(self, target, msg, hidelog=False):
        """Send a private message to a target on the server."""
        msg = "PRIVMSG {0} :{1}".format(target, msg)
        self._send(msg, hidelog)

    def reply(self, data, msg, hidelog=False):
        """Send a private message as a reply to a user on the server."""
        msg = "\x02{0}\x0F: {1}".format(data.nick, msg)
        self.say(data.chan, msg, hidelog)

    def action(self, target, msg, hidelog=False):
        """Send a private message to a target on the server as an action."""
        msg = "\x01ACTION {0}\x01".format(msg)
        self.say(target, msg, hidelog)

    def notice(self, target, msg, hidelog=False):<commit_msg>Don't ping in reply() if it's private.<commit_after># -*- coding: utf-8  -*-
#
# Copyright (C) 2009-2012 <NAME> <<EMAIL>>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

import socket
from threading import Lock
from time import sleep, time

from earwigbot.exceptions import BrokenSocketError

__all__ = ["IRCConnection"]

class IRCConnection(object):
    """Interface with an IRC server."""

    def __init__(self, host, port, nick, ident, realname):
        self._host = host
        self._port = port
        self._nick = nick
        self._ident = ident
        self._realname = realname

        self._is_running = False
        self._send_lock = Lock()

        self._last_recv = time()
        self._last_ping = 0

    def __repr__(self):
        """Return the canonical string representation of the IRCConnection."""
        res = "IRCConnection(host={0!r}, port={1!r}, nick={2!r}, ident={3!r}, realname={4!r})"
        return res.format(self.host, self.port, self.nick, self.ident,
                          self.realname)

    def __str__(self):
        """Return a nice string representation of the IRCConnection."""
        res = "<IRCConnection {0}!{1} at {2}:{3}>"
        return res.format(self.nick, self.ident, self.host, self.port)

    def _connect(self):
        """Connect to our IRC server."""
        self._sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            self._sock.connect((self.host, self.port))
        except socket.error:
            self.logger.exception("Couldn't connect to IRC server; retrying")
            sleep(8)
            self._connect()
        self._send("NICK {0}".format(self.nick))
        self._send("USER {0} {1} * :{2}".format(self.ident, self.host, self.realname))

    def _close(self):
        """Completely close our connection with the IRC server."""
        try:
            self._sock.shutdown(socket.SHUT_RDWR)  # Shut down connection first
        except socket.error:
            pass  # Ignore if the socket is already down
        self._sock.close()

    def _get(self, size=4096):
        """Receive (i.e. get) data from the server."""
        data = self._sock.recv(size)
        if not data:
            # Socket isn't giving us any data, so it is dead or broken:
            raise BrokenSocketError()
        return data

    def _send(self, msg, hidelog=False):
        """Send data to the server."""
        with self._send_lock:
            try:
                self._sock.sendall(msg + "\r\n")
            except socket.error:
                self._is_running = False
            else:
                if not hidelog:
                    self.logger.debug(msg)

    def _quit(self, msg=None):
        """Issue a quit message to the server. Doesn't close the connection."""
        if msg:
            self._send("QUIT :{0}".format(msg))
        else:
            self._send("QUIT")

    def _process_defaults(self, line):
        """Default process hooks for lines received on IRC."""
        self._last_recv = time()
        if line[0] == "PING":  # If we are pinged, pong back
            self.pong(line[1][1:])

    @property
    def host(self):
        """The hostname of the IRC server, like ``"irc.freenode.net"``."""
        return self._host

    @property
    def port(self):
        """The port of the IRC server, like ``6667``."""
        return self._port

    @property
    def nick(self):
        """Our nickname on the server, like ``"EarwigBot"``."""
        return self._nick

    @property
    def ident(self):
        """Our ident on the server, like ``"earwig"``.

        See http://en.wikipedia.org/wiki/Ident.
        """
        return self._ident

    @property
    def realname(self):
        """Our realname (gecos field) on the server."""
        return self._realname

    def say(self, target, msg, hidelog=False):
        """Send a private message to a target on the server."""
        msg = "PRIVMSG {0} :{1}".format(target, msg)
        self._send(msg, hidelog)

    def reply(self, data, msg, hidelog=False):
        """Send a private message as a reply to a user on the server."""
        if data.is_private:
            self.say(data.chan, msg, hidelog)
        else:
            msg = "\x02{0}\x0F: {1}".format(data.nick, msg)
            self.say(data.chan, msg, hidelog)

    def action(self, target, msg, hidelog=False):
        """Send a private message to a target on the server as an action."""
        msg = "\x01ACTION {0}\x01".format(msg)
        self.say(target, msg, hidelog)

    def notice(self, target, msg, hidelog=False):
{'fraction_non_alphanumeric': 0.11568751697293383, 'fraction_numerical': 0.008690142120032588, 'mean_word_length': 2.451421430802874, 'pattern_counts': {'":': 2, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7559574', 'n_tokens_mistral': 3270, 'n_tokens_neox': 3114, 'n_words': 1123}