NAME

Bot::Cobalt::Utils - Utilities for Cobalt plugins

DESCRIPTION

Bot::Cobalt::Utils provides a set of simple utility functions for the Bot::Cobalt core and plugins.

Plugin authors may wish to make use of these; importing the :ALL tag from Bot::Cobalt::Utils will give you access to the entirety of this utility module, including useful string formatting tools, safe password hashing functions, etc.

You may also want to look at Bot::Cobalt::Common, which exports most of this module.

USAGE

Import nothing:

use Bot::Cobalt::Utils;

my $hash = Bot::Cobalt::Utils::mkpasswd('things');

Import some things:

use Bot::Cobalt::Utils qw/ mkpasswd passwdcmp /;

my $hash = mkpasswd('things');

Import all the things:

use Bot::Cobalt::Utils qw/ :ALL /;

my $hash = mkpasswd('things', 'sha512');
my $secs = timestr_to_secs('3h30m');
. . .

See below for a list of exportable functions.

FUNCTIONS

Exportable functions

"timestr_to_secs" - Convert a string into seconds
"secs_to_timestr" - Convert seconds back into timestr
"secs_to_str" - Convert seconds into a 'readable' string
"color" - Add format/color to IRC messages
"glob_to_re_str" - Convert Cobalt-style globs to regex strings
"glob_to_re" - Convert Cobalt-style globs to compiled regexes
"glob_grep" - Search an array or arrayref by glob
"rplprintf" - Format portable langset reply strings
"mkpasswd" - Create crypted passwords
"passwdcmp" - Compare crypted passwords

Date and Time

timestr_to_secs

Convert a string such as "2h10m" into seconds.

my $delay_s = timestr_to_secs '1h33m10s';

Useful for dealing with timers.

secs_to_timestr

Turns seconds back into a timestring suitable for feeding to "timestr_to_secs":

my $timestr = secs_to_timestr 820; ## -> 13m40s

secs_to_str

Convert a timestamp delta into a string.

Useful for uptime reporting, for example:

my $delta = time() - $your_start_TS;
my $uptime_str = secs_to_str $delta;

Returns time formatted as: <D> day(s), <H>:<M>:<S>

secs_to_str_y

Like "secs_to_str", but includes year calculation and returns time formatted as: <Y> year(s), <D> day(s), <H>:<M>:<S> if there are more than 365 days; otherwise the same format as "secs_to_str" is returned.

(Added in v0.18.1)

String Formatting

color

Add mIRC formatting and color codes to a string.

Valid formatting codes:

NORMAL BOLD UNDERLINE REVERSE ITALIC

Valid color codes:

WHITE BLACK BLUE GREEN RED BROWN PURPLE ORANGE YELLOW TEAL PINK
LIGHT_CYAN LIGHT_BLUE LIGHT_GRAY LIGHT_GREEN

Format/color type can be passed in upper or lower case.

If passed just a color or format name, returns the control code.

If passed nothing at all, returns the 'NORMAL' reset code:

my $str = color('bold') . "bold text" . color() . "normal text";

If passed a color or format name and a string, returns the formatted string, terminated by NORMAL:

my $formatted = color('red', "red text") . "normal text";

If you need to retrieve (or alter via local, for example) the actual control characters themselves, they are accessible via the %Bot::Cobalt::Utils::COLORS hash:

my $red = $Bot::Cobalt::Utils::COLORS{RED}

glob_to_re_str

glob_to_re_str() converts Cobalt-style globs to regex strings.

my $re = glob_to_re_str "th?ngs*stuff";
## or perhaps compile it:
my $compiled_re = qr/$re/;

Perl regular expressions are very convenient and powerful. Unfortunately, that also means it's easy to make them eat up all of your CPU and thereby possibly break your system (or at least be annoying!)

For string search functions, it's better to use Cobalt-style globs:

* == match any number of any character
? == match any single character
+ == match any single space
leading ^  == anchor at start of string
trailing $ == anchor at end of string

Standard regex syntax will be escaped and a translated regex returned.

The only exception is character classes; this is valid, for example:

^[a-z0-9]*$

glob_to_re

glob_to_re() converts Cobalt-style globs to compiled regexes (qr//)

Using a compiled regex for matching is faster. Note that compiled regexes can also be serialized to YAML using Bot::Cobalt::Serializer.

See "glob_to_re_str" for details on globs. This function shares the same syntax.

glob_grep

glob_grep() can be used to search an array or an array reference for strings matching the specified glob:

my @matches = glob_grep($glob, @array) || 'No matches!';
my @matches = glob_grep($glob, $array_ref);

Returns the output of grep, which will be a list in list context or the number of matches in scalar context.

rplprintf

rplprintf() provides string formatting with replacement of arbitrary variables.

rplprintf( $string, %vars_hash );
rplprintf( $string, $vars_ref  );

The first argument to rplprintf should be the template string. It may contain variables in the form of %var or %var% to be replaced.

The second argument is the hash (or hash reference) mapping %var variables to strings.

For example:

$string = "Access denied for %user (%host%)";
$response = rplprintf(  $string,
    user => "Joe",
    host => "joe!joe@example.org",
);  
## $response = 'Access denied for Joe (joe!joe@example.org)'

Intended for formatting langset RPLs before sending, but can be used for any simple string template.

Variable names can be terminated with a space or % -- both are demonstrated in the example above. You'll need to terminate with a trailing % if there are non-space characters following, as in the above example: (%host%)

The same color/format strings as "color" can be applied via %C_* vars:

$string = "Access %C_BOLD%denied%C_NORMAL";
$response = rplprintf( $string );

Password handling

mkpasswd

Simple interface for creating hashed passwords.

Defaults to creating a password using Crypt::Eksblowfish::Bcrypt with a random salt and bcrypt work cost '08' -- this is a pretty sane default.

See App::bmkpasswd for details; the built-in hash generation sugar was moved to that package.

bcrypt is strongly recommended; SHA and MD5 methods are also supported. Salts are always random.

## create a bcrypted password (work cost 08)
## bcrypt is blowfish with a work cost factor.
## if hashes are stolen, they'll be slow to break
## see http://codahale.com/how-to-safely-store-a-password/
my $hashed = mkpasswd $password;

## you can specify method options . . .
## here's bcrypt with a lower work cost factor.
## (must be a two-digit power of 2, possibly padded with 0)
my $hashed = mkpasswd $password, 'bcrypt', '06';

## Available methods:
##  bcrypt (preferred)
##  SHA-256 or -512 (req. modern libc or Crypt::Passwd::XS)
##  MD5 (fast, portable, weak)
my $sha_passwd = mkpasswd $password, 'sha512';
## same as:
my $sha_passwd = mkpasswd $password, 'SHA-512';

passwdcmp

Compare hashed passwords via App::bmkpasswd.

Compatible with whatever methods mkpasswd supports on the current system.

return passwdcmp $password, $hashed;

Returns the hash if the cleartext password is a match. Otherwise returns boolean false.

AUTHOR

Jon Portnoy (avenj)