AI-CleverbotIO

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

0.002  2017-01-06 19:39:15 CET
   - release after 111 PASSes on CPAN Testers (thanks!)

0.001  2017-01-04 00:43:07 CET
   - first test release

LICENSE  view on Meta::CPAN

This software is Copyright (c) 2017 by Flavio Poletti <polettix@cpan.org>.

This is free software, licensed under:

  The Artistic License 2.0 (GPL Compatible)

		       The Artistic License 2.0

	    Copyright (c) 2000-2006, The Perl Foundation.

     Everyone is permitted to copy and distribute verbatim copies
      of this license document, but changing it is not allowed.

Preamble

This license establishes the terms under which a given free software
Package may be copied, modified, distributed, and/or redistributed.
The intent is that the Copyright Holder maintains some artistic
control over the development of that Package while still keeping the
Package available as open source and free software.

You are always permitted to make arrangements wholly outside of this
license directly with the Copyright Holder of a given Package.  If the
terms of this license do not permit the full use that you propose to
make of the Package, you should contact the Copyright Holder and seek
a different licensing arrangement. 

Definitions

    "Copyright Holder" means the individual(s) or organization(s)
    named in the copyright notice for the entire Package.

    "Contributor" means any party that has contributed code or other
    material to the Package, in accordance with the Copyright Holder's
    procedures.

    "You" and "your" means any person who would like to copy,
    distribute, or modify the Package.

    "Package" means the collection of files distributed by the
    Copyright Holder, and derivatives of that collection and/or of
    those files. A given Package may consist of either the Standard
    Version, or a Modified Version.

    "Distribute" means providing a copy of the Package or making it
    accessible to anyone else, or in the case of a company or
    organization, to others outside of your company or organization.

    "Distributor Fee" means any fee that you charge for Distributing
    this Package or providing support for this Package to another
    party.  It does not mean licensing fees.

    "Standard Version" refers to the Package if it has not been
    modified, or has been modified only in ways explicitly requested
    by the Copyright Holder.

    "Modified Version" means the Package, if it has been changed, and
    such changes were not explicitly requested by the Copyright
    Holder. 

    "Original License" means this Artistic License as Distributed with
    the Standard Version of the Package, in its current version or as
    it may be modified by The Perl Foundation in the future.

    "Source" form means the source code, documentation source, and
    configuration files for the Package.

    "Compiled" form means the compiled bytecode, object code, binary,
    or any other form resulting from mechanical transformation or
    translation of the Source form.


Permission for Use and Modification Without Distribution

(1)  You are permitted to use the Standard Version and create and use
Modified Versions for any purpose without restriction, provided that
you do not Distribute the Modified Version.


Permissions for Redistribution of the Standard Version

META.yml  view on Meta::CPAN

---
abstract: 'A Perl wrapper for the cleverbot.io API'
author:
  - 'Flavio Poletti <polettix@cpan.org>'
build_requires:
  Path::Tiny: '0.096'
  Test::Exception: '0.43'
  Test::More: '0.88'
configure_requires:
  Module::Build::Tiny: '0.034'
dynamic_config: 0
generated_by: 'Dist::Zilla version 5.041, Dist::Milla version v1.0.15, CPAN::Meta::Converter version 2.150005'
license: artistic_2
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: '1.4'
name: AI-CleverbotIO
no_index:
  directory:
    - eg
    - examples
    - inc
    - share
    - t
    - xt
requires:
  HTTP::Tiny: '0.070'
  IO::Socket::SSL: '1.56'
  JSON::PP: '0'
  Log::Any: '1.045'
  Moo: '2.003000'
  Net::SSLeay: '1.49'
  Ouch: '0.0410'
  perl: '5.010'
resources:
  bugtracker: https://github.com/polettix/AI-CleverbotIO/issues
  homepage: https://github.com/polettix/AI-CleverbotIO
  repository: https://github.com/polettix/AI-CleverbotIO.git
version: '0.002'
x_contributors:
  - 'Flavio Poletti <flavio@polettix.it>'

README  view on Meta::CPAN

NAME

    AI::CleverbotIO - A Perl wrapper for the cleverbot.io API

VERSION

    This document describes AI::CleverbotIO version 0.002.

SYNOPSIS

       use AI::CleverbotIO;
    
       my $cleverbot = AI::CleverbotIO->new(
          key => $ENV{CLEVERBOT_API_KEY},
          nick => $ENV{CLEVERBOT_NICK},
          user => $ENV{CLEVERBOT_API_USER},
       );
    
       # call to create() is mostly safe, you might get an error
       # back but still 200 OK. You can avoid this (and wasting one
       # API call) if you know the nick is already active for these
       # API credentials.
       $cleverbot->create();
    
       # then, it's just... ask()
       my $answer = $cleverbot->ask('Hello darling!');
       say $answer->{response};

DESCRIPTION

    This module allows you to interact with the API served by
    https://cleverbot.io.

ACCESSORS

 key

       my $api_key = $obj->key;

    Read-only accessor to the API key. MUST be provided upon instantiation.

 endpoints

       my $endpoints_hashref = $obj->endpoints;

    Read-only accessor to a hash reference whose keys are the strings ask
    and create and the corresponding values are the API endoints (URIs).
    The default is:

       {
          ask    => 'https://cleverbot.io/1.0/ask',
          create => 'https://cleverbot.io/1.0/create',
       }

 logger

       my $logger = $obj->logger;

    Read-only accessor to the logger object (Log::Any compatible). See
    "BUILD_logger" for the default value.

 nick

       $obj->nick($some_string);
       my $nick = $obj->nick;

    Read-write accessor to the nick for invoking API calls. If not set, it
    is set after a call to "create". See also "has_nick".

 ua

       my $ua = $obj->ua;

    Read-only accessor to the user agent object (HTTP::Tiny compatible).
    See BUILD_ua for the default value.

 user

       my $api_user = $obj->user;

    Read-only accessor to the API user. MUST be provided upon
    instantiation.

METHODS

 BUILD_logger

    Called automatically if "logger" is not set. By default, it returns
    whatever "get_logger" in Log::Any provides, but you can easily override
    this in a derived class.

 BUILD_ua

    Called automatically if "ua" is not set. By default, it returns a plain
    new instance of HTTP::Tiny, without options.

 ask

       my $answer = $obj->ask($some_text);

    Send a ask API request. The returned $answer is a hash reference
    derived by the JSON decoding of the response body, e.g.:

       {
          status   => 'success',
          response => 'Hullo'
       }

 create

       my $answer = $obj->create();
       my $other  = $obj->create($other_nick);

    Send a create API request. The returned $answer is a hash reference
    derived by the JSON decoding of the response body, e.g.:

       {
          status => 'success',
          nick   => 'NickTheRobot',
       }

    If the current "nick" has already been used for creation, the API call
    will fail partially in that status 200 will be returned, but the status
    field in the answer will contain an error about the fact that the nick
    already exists (Error: reference name already exists). You can safely
    ignore this error.

    You can optionally pass a different other_nick. This will be set as
    "nick" and used for creation (this will overwrite whatever "nick"
    contains though).

 has_nick

       say $obj->nick if $obj->has_nick;
       say 'no nick yet' unless $obj->has_nick;

    Predicate to check whether a "nick" is already set or not.

BUGS AND LIMITATIONS

    Report bugs either through RT or GitHub (patches welcome).

SEE ALSO

    https://cleverbot.io.

AUTHOR

    Flavio Poletti <polettix@cpan.org>

COPYRIGHT AND LICENSE

    Copyright (C) 2017 by Flavio Poletti <polettix@cpan.org>

    This module is free software. You can redistribute it and/or modify it
    under the terms of the Artistic License 2.0.

    This program is distributed in the hope that it will be useful, but
    without any warranty; without even the implied warranty of
    merchantability or fitness for a particular purpose.

cpanfile  view on Meta::CPAN

requires 'perl',            '5.010';
requires 'HTTP::Tiny',      '0.070';
requires 'IO::Socket::SSL', '1.56';    # from HTTP::Tiny 0.070 docs
requires 'JSON::PP';                   # core from 5.14, any should do
requires 'Log::Any',    '1.045';
requires 'Moo',         '2.003000';
requires 'Net::SSLeay', '1.49';        # from HTTP::Tiny 0.070 docs
requires 'Ouch',        '0.0410';

on test => sub {
   requires 'Test::More',      '0.88';
   requires 'Path::Tiny',      '0.096';
   requires 'Test::Exception', '0.43';
};

on develop => sub {
   requires 'Path::Tiny',        '0.096';
   requires 'Template::Perlish', '1.52';
};

lib/AI/CleverbotIO.pm  view on Meta::CPAN

use warnings;
{ our $VERSION = '0.002'; }

use Moo;
use Ouch;
use Log::Any ();
use Data::Dumper;
use JSON::PP qw< decode_json >;

has endpoints => (
   is      => 'ro',
   default => sub {
      return {
         ask    => 'https://cleverbot.io/1.0/ask',
         create => 'https://cleverbot.io/1.0/create',
      };
   },
);

has key => (
   is       => 'ro',
   required => 1,
);

has logger => (
   is      => 'ro',
   lazy    => 1,
   builder => 'BUILD_logger',
);

has nick => (
   is        => 'rw',
   lazy      => 1,
   predicate => 1,
);

has user => (
   is       => 'ro',
   required => 1,
);

has ua => (
   is      => 'ro',
   lazy    => 1,
   builder => 'BUILD_ua',
);

sub BUILD_logger {
   return Log::Any->get_logger;
}

sub BUILD_ua {
   my $self = shift;
   require HTTP::Tiny;
   return HTTP::Tiny->new;
}

sub ask {
   my ($self, $question) = @_;
   my %ps = (
      key  => $self->key,
      text => $question,
      user => $self->user,
   );
   $ps{nick} = $self->nick if $self->has_nick;
   return $self->_parse_response(
      $self->ua->post_form($self->endpoints->{ask}, \%ps));
}

sub create {
   my $self = shift;
   $self->nick(shift) if @_;

   # build request parameters
   my %ps = (
      key  => $self->key,
      user => $self->user,
   );
   $ps{nick} = $self->nick if $self->has_nick && length $self->nick;

   my $data =
     $self->_parse_response(
      $self->ua->post_form($self->endpoints->{create}, \%ps));

   $self->nick($data->{nick}) if exists($data->{nick});

   return $data;
}

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

   {
      local $Data::Dumper::Indent = 1;
      $self->logger->debug('got response: ' . Dumper($response));
   }

   ouch 500, 'no response (possible bug in HTTP::Tiny though?)'
     unless ref($response) eq 'HASH';

   my $status = $response->{status};
   ouch $status, $response->{reason}
      if ($status != 200) && ($status != 400);

   my $data = __decode_content($response);
   return $data if $response->{success};
   ouch 400, $data->{status};
} ## end sub _parse_response

sub __decode_content {
   my $response = shift;
   my $encoded  = $response->{content};
   if (!$encoded) {
      my $url = $response->{url} // '*unknown url, check HTTP::Tiny*';
      ouch 500, "response status $response->{status}, nothing from $url)";
   }
   my $decoded = eval { decode_json($encoded) }
     or ouch 500, "response status $response->{status}, exception: $@";
   return $decoded;
} ## end sub __decode_content

1;

lib/AI/CleverbotIO.pod  view on Meta::CPAN

</a>

<a href="http://matrix.cpantesters.org/?dist=AI-CleverbotIO">
<img alt="CPAN Testers Matrix" src="https://img.shields.io/badge/matrix-@testers-blue.svg">
</a>

=end html

=head1 SYNOPSIS

   use AI::CleverbotIO;

   my $cleverbot = AI::CleverbotIO->new(
      key => $ENV{CLEVERBOT_API_KEY},
      nick => $ENV{CLEVERBOT_NICK},
      user => $ENV{CLEVERBOT_API_USER},
   );

   # call to create() is mostly safe, you might get an error
   # back but still 200 OK. You can avoid this (and wasting one
   # API call) if you know the nick is already active for these
   # API credentials.
   $cleverbot->create();

   # then, it's just... ask()
   my $answer = $cleverbot->ask('Hello darling!');
   say $answer->{response};

=head1 DESCRIPTION

This module allows you to interact with the API served by
L<https://cleverbot.io>.

=head1 ACCESSORS

=head2 key

   my $api_key = $obj->key;

Read-only accessor to the API key. MUST be provided upon instantiation.

=head2 endpoints

   my $endpoints_hashref = $obj->endpoints;

Read-only accessor to a hash reference whose keys are the strings C<ask>
and C<create> and the corresponding values are the API endoints (URIs).
The default is:

   {
      ask    => 'https://cleverbot.io/1.0/ask',
      create => 'https://cleverbot.io/1.0/create',
   }

=head2 logger

   my $logger = $obj->logger;

Read-only accessor to the logger object (L<Log::Any> compatible). See
L</BUILD_logger> for the default value.

=head2 nick

   $obj->nick($some_string);
   my $nick = $obj->nick;

Read-write accessor to the nick for invoking API calls. If not set, it
is set after a call to L</create>. See also L</has_nick>.

=head2 ua

   my $ua = $obj->ua;

Read-only accessor to the user agent object (L<HTTP::Tiny> compatible). See
L<BUILD_ua> for the default value.

=head2 user

   my $api_user = $obj->user;

Read-only accessor to the API user. MUST be provided upon instantiation.

=head1 METHODS

=head2 BUILD_logger

Called automatically if L</logger> is not set. By default, it
returns whatever L<Log::Any/get_logger> provides, but you can
easily override this in a derived class.

=head2 BUILD_ua

Called automatically if L</ua> is not set. By default, it returns
a plain new instance of L<HTTP::Tiny>, without options.

=head2 ask

   my $answer = $obj->ask($some_text);

Send a I<ask> API request. The returned C<$answer> is a hash reference
derived by the JSON decoding of the response body, e.g.:

   {
      status   => 'success',
      response => 'Hullo'
   }

=head2 create

   my $answer = $obj->create();
   my $other  = $obj->create($other_nick);

Send a I<create> API request. The returned C<$answer> is a hash reference
derived by the JSON decoding of the response body, e.g.:

   {
      status => 'success',
      nick   => 'NickTheRobot',
   }

If the current L</nick> has already been used for creation, the API call
will fail partially in that status 200 will be returned, but the C<status>
field in the answer will contain an error about the fact that the nick
already exists (C<Error: reference name already exists>). You can safely
ignore this error.

You can optionally pass a different C<other_nick>. This will be set as
L</nick> and used for creation (this will overwrite whatever L</nick>
contains though).

=head2 has_nick

   say $obj->nick if $obj->has_nick;
   say 'no nick yet' unless $obj->has_nick;

Predicate to check whether a L</nick> is already set or not.

=head1 BUGS AND LIMITATIONS

Report bugs either through RT or GitHub (patches welcome).

=head1 SEE ALSO

L<https://cleverbot.io>.

t/00-load.t  view on Meta::CPAN

# inspired by:
# http://perltricks.com/article/208/2016/1/5/Save-time-with-compile-tests
use strict;
use Test::More;
use Path::Tiny;

my $dir  = path(__FILE__)->parent(2)->child('lib');
my $iter = $dir->iterator(
   {
      recurse         => 1,
      follow_symlinks => 0,
   }
);
while (my $path = $iter->()) {
   next if $path->is_dir();    # avoid directories...
   next unless $path =~ /\.pm$/mxs;    # ... and non-module files
   my $module = $path->relative($dir); # get relative path...
   $module =~ s{ \.pm \z}{}gmxs;       # ... and transform it...
   $module =~ s{/}{::}gmxs;            # ... into a module name
   require_ok($module)
     or BAIL_OUT("can't load $module");
} ## end while (my $path = $iter->...)

diag("Testing AI::CleverbotIO $AI::CleverbotIO::VERSION");
done_testing();

t/01-basic.t  view on Meta::CPAN

use strict;
use warnings;
use Test::More;
use Test::Exception;
use Log::Any::Adapter;
use 5.010;

use AI::CleverbotIO;

plan skip_all => 'no CLEVERBOT_API_USER/CLEVERBOT_API_KEY pair set'
  unless exists($ENV{CLEVERBOT_API_USER})
  && exists($ENV{CLEVERBOT_API_KEY});

Log::Any::Adapter->set('Stderr') if $ENV{CLEVERBOT_STDERR};

my $cleverbot;
lives_ok {
   $cleverbot = AI::CleverbotIO->new(
      key  => $ENV{CLEVERBOT_API_KEY},
      nick => $ENV{CLEVERBOT_NICK} // "AI::CleverbotIO Tester",
      user => $ENV{CLEVERBOT_API_USER},
   );
} ## end lives_ok
'AI::CleverbotIO instantiation lives';

isa_ok $cleverbot, 'AI::CleverbotIO';

my $data;
lives_ok {
   $data = $cleverbot->create();
}
'create() lives';

like $data->{status}, qr{(?mxs:
      \A
      (?:
           success
         | Error:\ reference\ name\ already\ exists
      )
      \z
   )}, 'create() outcome';

diag 'real nick: ' . $cleverbot->nick;

my $answer;
lives_ok {
   $answer = $cleverbot->ask('Hi, I am ' . $cleverbot->nick)->{response};
}
'ask() lives';
like $answer, qr{(?imxs:[a-z])}, 'response has at least... one letter';
diag "received answer: $answer";

done_testing();

t/author-pod-coverage.t  view on Meta::CPAN

#!perl -T

BEGIN {
  unless ($ENV{AUTHOR_TESTING}) {
    require Test::More;
    Test::More::plan(skip_all => 'these tests are for testing by the author');
  }
}


use Test::More;

plan skip_all => "Test::Pod::Coverage - AUTHOR_TESTING not set"
  unless $ENV{AUTHOR_TESTING};

eval "use Test::Pod::Coverage 1.04";
plan skip_all =>
  "Test::Pod::Coverage 1.04 required for testing POD coverage"
  if $@;

all_pod_coverage_ok();

t/author-pod-syntax.t  view on Meta::CPAN

#!perl

BEGIN {
  unless ($ENV{AUTHOR_TESTING}) {
    require Test::More;
    Test::More::plan(skip_all => 'these tests are for testing by the author');
  }
}

# This file was automatically generated by Dist::Zilla::Plugin::PodSyntaxTests.
use strict; use warnings;
use Test::More;
use Test::Pod 1.41;

all_pod_files_ok();

t/release-pod-version.t  view on Meta::CPAN


BEGIN {
  unless ($ENV{RELEASE_TESTING}) {
    require Test::More;
    Test::More::plan(skip_all => 'these tests are for release candidate testing');
  }
}

use strict;
use Test::More tests => 1;

my $module = 'AI::CleverbotIO';

(my $packfile = "$module.pm") =~ s{::}{/}gmxs;
require $packfile;

(my $filename = $INC{$packfile}) =~ s{pm$}{pod};

my $pod_version;
{
   open my $fh, '<', $filename
     or BAIL_OUT "can't open '$filename'";
   binmode $fh, ':raw';
   local $/;
   my $module_text = <$fh>;
   ($pod_version) = $module_text =~ m{
      ^This\ document\ describes\ $module\ version\ (.*?)\.$
   }mxs;
}

my $version;
{
   no strict 'refs';
   $version = ${$module . '::VERSION'};
}

is $pod_version, $version, 'version in POD';

 view all matches for this distribution
 view release on metacpan -  search on metacpan

( run in 0.983 second using v1.00-cache-2.02-grep-82fe00e-cpan-2c419f77a38b )