<commit_before>package RoboBot::Network::IRC;

use v5.20;

use namespace::autoclean;

use Moose;
use MooseX::SetOnce;

use AnyEvent;
use AnyEvent::IRC::Client;
use Data::Dumper;
use Text::Wrap qw( wrap );
use Time::HiRes qw( usleep );

use RoboBot::Channel;
use RoboBot::Message;
use RoboBot::Nick;

extends 'RoboBot::Network';

has '+type' => (
    default => 'irc',
);

has 'host' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'port' => (
    is      => 'ro',
    isa     => 'Int',
    default => 6667,
);

has 'ssl' => (
    is      => 'ro',
    isa     => 'Bool',
    default => 0,
);

has 'username' => (
    is  => 'ro',
    isa => 'Str',
);

has 'password' => (
    is  => 'ro',
    isa => 'Str',
);

has 'client' => (
    is      => 'ro',
    isa     => 'AnyEvent::IRC::Client',
    default => sub { AnyEvent::IRC::Client->new },
);

has 'nick_cache' => (
    is      => 'rw',
    isa     => 'HashRef',
    default => sub { {} },
);

sub BUILD {
    my ($self) = @_;

    $self->client->enable_ssl() if $self->ssl;
}

sub connect {
    my ($self) = @_;

    $self->client->reg_cb( registered => sub {
        my ($con) = @_;

        $self->client->enable_ping(30, sub {});
    });

    $self->client->reg_cb( publicmsg => sub {
        my ($con, $chan, $msg_h) = @_;
        $self->handle_message($msg_h);
    });

    $self->client->reg_cb( privatemsg => sub {
        my ($con, $sender, $msg_h) = @_;
        $self->handle_message($msg_h);
    });

    $self->client->connect($self->host, $self->port, { nick => $self->nick->name });
    $_->join for @{$self->channels};
}

sub disconnect {
    # TODO: remove callbacks
    #       call client->disconnect
}

sub send {
    my ($self, $response) = @_;

    local $Text::Wrap::columns = 400;

    # Make sure that linebreaks are treated as separators for "line" output in IRC,
    # since that isn't always the case for every protocol.
    my @output = ();
    foreach my $l (map { wrap('', '', $_) } @{$response->content}) {
        push(@output, grep { defined $_ && $_ =~ m{.+} } split(/\n/, $l));
    }

    # TODO: Move maximum number of output lines into a config var for each IRC
    #       network (with a default).
    my $max_lines = 12;

    if (@output > $max_lines) {
        my $n = scalar @output;
        my $split_at = int($max_lines / 2) - 2;

        @output = (
            @output[0..$split_at],
            '... Output Truncated (' . ($n - (($split_at + 1) * 2)) . ' lines removed) ...',
            @output[($n - ($split_at + 1))..($n - 1)]
        );
    }

    my $recipient = $response->has_channel ? '#' . $response->channel->name : $response->nick->name;

    my $d = 0;
    for (my $i = 0; $i <= $#output; $i++) {
        my $line = $output[$i];

        $self->client->send_srv( PRIVMSG => $recipient, $line);<commit_msg>fix long line wrapping and add /me action support for IRC connections<commit_after>package RoboBot::Network::IRC;

use v5.20;

use namespace::autoclean;

use Moose;
use MooseX::SetOnce;

use AnyEvent;
use AnyEvent::IRC::Client;
use Data::Dumper;
use Text::Wrap qw( wrap );
use Time::HiRes qw( usleep );

use RoboBot::Channel;
use RoboBot::Message;
use RoboBot::Nick;

extends 'RoboBot::Network';

has '+type' => (
    default => 'irc',
);

has 'host' => (
    is       => 'ro',
    isa      => 'Str',
    required => 1,
);

has 'port' => (
    is      => 'ro',
    isa     => 'Int',
    default => 6667,
);

has 'ssl' => (
    is      => 'ro',
    isa     => 'Bool',
    default => 0,
);

has 'username' => (
    is  => 'ro',
    isa => 'Str',
);

has 'password' => (
    is  => 'ro',
    isa => 'Str',
);

has 'client' => (
    is      => 'ro',
    isa     => 'AnyEvent::IRC::Client',
    default => sub { AnyEvent::IRC::Client->new },
);

has 'nick_cache' => (
    is      => 'rw',
    isa     => 'HashRef',
    default => sub { {} },
);

sub BUILD {
    my ($self) = @_;

    $self->client->enable_ssl() if $self->ssl;
}

sub connect {
    my ($self) = @_;

    $self->client->reg_cb( registered => sub {
        my ($con) = @_;

        $self->client->enable_ping(30, sub {});
    });

    $self->client->reg_cb( publicmsg => sub {
        my ($con, $chan, $msg_h) = @_;
        $self->handle_message($msg_h);
    });

    $self->client->reg_cb( privatemsg => sub {
        my ($con, $sender, $msg_h) = @_;
        $self->handle_message($msg_h);
    });

    $self->client->connect($self->host, $self->port, { nick => $self->nick->name });
    $_->join for @{$self->channels};
}

sub disconnect {
    # TODO: remove callbacks
    #       call client->disconnect
}

sub send {
    my ($self, $response) = @_;

    local $Text::Wrap::columns = 400;

    # Make sure that linebreaks are treated as separators for "line" output in IRC,
    # since that isn't always the case for every protocol. And re-wrap any long
    # lines.
    my @output =
        map { length($_) > 300 ? split(/\n/, wrap('', '', $_)) : $_ }
        grep { defined $_ && $_ =~ m{\S+} }
        map { split(/\n/, $_) }
        @{$response->content};

    # TODO: Move maximum number of output lines into a config var for each IRC
    #       network (with a default).
    my $max_lines = 12;

    if (@output > $max_lines) {
        my $n = scalar @output;
        my $split_at = int($max_lines / 2) - 2;

        @output = (
            @output[0..$split_at],
            '... Output Truncated (' . ($n - (($split_at + 1) * 2)) . ' lines removed) ...',
            @output[($n - ($split_at + 1))..($n - 1)]
        );
    }

    my $recipient = $response->has_channel ? '#' . $response->channel->name : $response->nick->name;

    my $d = 0;
    for (my $i = 0; $i <= $#output; $i++) {
        my $line = $output[$i];

        if ($line =~ m{^/me\s+(.+)}) {
            $self->client->send_long_message('utf8', 0, "PRIVMSG\001ACTION", $recipient, $1);
        } else {
            $self->client->send_long_message('utf8', 0, "PRIVMSG", $recipient, $line);
            #$self->client->send_srv( PRIVMSG => $recipient, $line);
        }
{'fraction_non_alphanumeric': 0.20426375805651958, 'fraction_numerical': 0.010080978350685837, 'mean_word_length': 2.250268528464017, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 138, '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': '2329851', 'n_tokens_mistral': 2254, 'n_tokens_neox': 2138, 'n_words': 528}