<commit_before>package Command::Duolingo;
use feature 'say';

use Moo;
use strictures 2;

use Component::Duolingo;
use Mojo::Promise;
use DateTime;
use Data::Dumper;

use namespace::clean;

use Exporter qw(import);
our @EXPORT_OK = qw(cmd_template);

has bot                 => ( is => 'ro' );
has discord             => ( is => 'lazy', builder => sub { shift->bot->discord } );
has log                 => ( is => 'lazy', builder => sub { shift->bot->log } );
has duo                 => ( is => 'lazy', builder => sub { shift->bot->duolingo } );
has db                  => ( is => 'lazy', builder => sub { shift->bot->db } );

has name                => ( is => 'ro', default => 'Duolingo' );
has access              => ( is => 'ro', default => 0 ); # 0 = Public, 1 = Bot-Owner Only
has description         => ( is => 'ro', default => 'Look up Duolingo profile information' );
has pattern             => ( is => 'ro', default => '^duo(?:lingo)? ?' );
has function            => ( is => 'ro', default => sub { \&cmd_duolingo } );
has usage               => ( is => 'ro', default => <<EOF
Look up user profile information on Duolingo

Set your username: !duo set <your duolingo username>

Get your own info: !duo
Get someone else's info: !duo <duolingo username>
EOF
);

sub cmd_duolingo
{
    my ($self, $msg) = @_;

    # Check for login
    unless ( $self->duo->jwt )
    {
        $self->duo->login_p()->then(sub{ $self->cmd_duolingo($msg) });
        return undef;
    }


    my $channel = $msg->{'channel_id'};
    my $author = $msg->{'author'};

    my $args = $msg->{'content'};
    
    my $pattern = $self->pattern;
    $args =~ s/$pattern//;

    my $duo_user;

    # !duo
    if ( length $args == 0 )
    {
        # Stored ID
        if ( my $duo_id = $self->_get_stored_id($author->{'id'}) )
        {
            $self->log->debug('[Duolingo.pm] [cmd_duolingo] Found stored Duolingo ID (' . $duo_id . ') for Discord ID ' . $author->{'id'});
            $duo_user = $duo_id;
        }
        # Not stored
        else
        {
            $self->discord->send_message($channel, "Sorry, I don't have your duolingo username on file.");
            $self->discord->send_dm($author->{'id'}, <<EOF
To set your Duolingo username use the following command: `!duo set <your username>`

For example, `!duo set TheLegend27`

You can do that here or in a public channel. Once set you'll be able to use `!duo`.
EOF
);
        }
    }
    # !duo top##
    elsif ( $args =~ /^top ?(\d+)$/ )
    {
        my $num = ( $1 > 0 and $1 <= 10 ? $1 : 10 );

        say "Displaying the Top $num people on the leaderboard";

        my $dt = DateTime->now;
        #        $dt->set_timezone('America/Winnipeg');

        my $timestamp = $dt->strftime("%Y.%m.%d %H:%M:%S");
        say "Timestamp: $timestamp";
        $self->duo->leaderboard_p('week', $timestamp)->then(sub
        { 
            my $json = shift;

            say Data::Dumper->Dump([$json], ['json']);
        });
    }
    # !duo set <username>
    elsif ( $args =~ /^set (.+)$/ )
    {
        $self->duo->user_info_p($1)->then(sub
        {
            my $json = shift;
            my $duo_id = $json->{'id'};

            $self->db->query('INSERT INTO duolingo VALUES ( ?, ? )', $author->{'id'}, $duo_id);
            $self->discord->send_message($channel, "Your Duolingo account info has been updated.");
        });
    }
    else
    {
        $duo_user = $args;
    }

    # We have a username/id, whether it was stored or passed
    if ( defined $duo_user )
    {
        $self->duo->user_info_p($duo_user)->then(sub
        {
            my $json = shift;
            my $content = $self->_build_message($json);     # Pull out certain fields and format it for Discord

            if (my $hook = $self->bot->has_webhook($channel) )
            {
                my $message = {
                    'content' => $content,
                    'username' => $json->{'fullname'},
                    'avatar_url' => 'http://i.imgur.com/EdGBXeW.png', # Duolingo owl
                };

                $self->discord->send_webhook($channel, $hook, $message);
            }
            else
            {
                my $message = $content;
                $self->discord->send_message($channel, $message);
            }
        });
    }
}

# Takes a language code and returns a flag emoji
sub _flag
{
    my ($self, $lang) = @_;

    my %flags = (
        'nn'    => 'no', # Nynorsk -> Norway
        'nb'    => 'no', # Bokmål -> Norway<commit_msg>ja to jp flag mapping<commit_after>package Command::Duolingo;
use feature 'say';

use Moo;
use strictures 2;

use Component::Duolingo;
use Mojo::Promise;
use DateTime;
use Data::Dumper;

use namespace::clean;

use Exporter qw(import);
our @EXPORT_OK = qw(cmd_template);

has bot                 => ( is => 'ro' );
has discord             => ( is => 'lazy', builder => sub { shift->bot->discord } );
has log                 => ( is => 'lazy', builder => sub { shift->bot->log } );
has duo                 => ( is => 'lazy', builder => sub { shift->bot->duolingo } );
has db                  => ( is => 'lazy', builder => sub { shift->bot->db } );

has name                => ( is => 'ro', default => 'Duolingo' );
has access              => ( is => 'ro', default => 0 ); # 0 = Public, 1 = Bot-Owner Only
has description         => ( is => 'ro', default => 'Look up Duolingo profile information' );
has pattern             => ( is => 'ro', default => '^duo(?:lingo)? ?' );
has function            => ( is => 'ro', default => sub { \&cmd_duolingo } );
has usage               => ( is => 'ro', default => <<EOF
Look up user profile information on Duolingo

Set your username: !duo set <your duolingo username>

Get your own info: !duo
Get someone else's info: !duo <duolingo username>
EOF
);

sub cmd_duolingo
{
    my ($self, $msg) = @_;

    # Check for login
    unless ( $self->duo->jwt )
    {
        $self->duo->login_p()->then(sub{ $self->cmd_duolingo($msg) });
        return undef;
    }


    my $channel = $msg->{'channel_id'};
    my $author = $msg->{'author'};

    my $args = $msg->{'content'};
    
    my $pattern = $self->pattern;
    $args =~ s/$pattern//;

    my $duo_user;

    # !duo
    if ( length $args == 0 )
    {
        # Stored ID
        if ( my $duo_id = $self->_get_stored_id($author->{'id'}) )
        {
            $self->log->debug('[Duolingo.pm] [cmd_duolingo] Found stored Duolingo ID (' . $duo_id . ') for Discord ID ' . $author->{'id'});
            $duo_user = $duo_id;
        }
        # Not stored
        else
        {
            $self->discord->send_message($channel, "Sorry, I don't have your duolingo username on file.");
            $self->discord->send_dm($author->{'id'}, <<EOF
To set your Duolingo username use the following command: `!duo set <your username>`

For example, `!duo set TheLegend27`

You can do that here or in a public channel. Once set you'll be able to use `!duo`.
EOF
);
        }
    }
    # !duo top##
    elsif ( $args =~ /^top ?(\d+)$/ )
    {
        my $num = ( $1 > 0 and $1 <= 10 ? $1 : 10 );

        say "Displaying the Top $num people on the leaderboard";

        my $dt = DateTime->now;
        #        $dt->set_timezone('America/Winnipeg');

        my $timestamp = $dt->strftime("%Y.%m.%d %H:%M:%S");
        say "Timestamp: $timestamp";
        $self->duo->leaderboard_p('week', $timestamp)->then(sub
        { 
            my $json = shift;

            say Data::Dumper->Dump([$json], ['json']);
        });
    }
    # !duo set <username>
    elsif ( $args =~ /^set (.+)$/ )
    {
        $self->duo->user_info_p($1)->then(sub
        {
            my $json = shift;
            my $duo_id = $json->{'id'};

            $self->db->query('INSERT INTO duolingo VALUES ( ?, ? )', $author->{'id'}, $duo_id);
            $self->discord->send_message($channel, "Your Duolingo account info has been updated.");
        });
    }
    else
    {
        $duo_user = $args;
    }

    # We have a username/id, whether it was stored or passed
    if ( defined $duo_user )
    {
        $self->duo->user_info_p($duo_user)->then(sub
        {
            my $json = shift;
            my $content = $self->_build_message($json);     # Pull out certain fields and format it for Discord

            if (my $hook = $self->bot->has_webhook($channel) )
            {
                my $message = {
                    'content' => $content,
                    'username' => $json->{'fullname'},
                    'avatar_url' => 'http://i.imgur.com/EdGBXeW.png', # Duolingo owl
                };

                $self->discord->send_webhook($channel, $hook, $message);
            }
            else
            {
                my $message = $content;
                $self->discord->send_message($channel, $message);
            }
        });
    }
}

# Takes a language code and returns a flag emoji
sub _flag
{
    my ($self, $lang) = @_;

    my %flags = (
        'nn'    => 'no', # Nynorsk -> Norway
        'nb'    => 'no', # Bokmål -> Norway
        'ja'    => 'jp', # Japanese -> Japan
{'fraction_non_alphanumeric': 0.1717049576783555, 'fraction_numerical': 0.003517643179070023, 'mean_word_length': 1.893765903307888, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 203, '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': '2063501', 'n_tokens_mistral': 3049, 'n_tokens_neox': 2943, 'n_words': 781}