BusyBird
view release on metacpan or search on metacpan
lib/BusyBird/Util.pm view on Meta::CPAN
package BusyBird::Util;
use v5.8.0;
use strict;
use warnings;
use Scalar::Util qw(blessed weaken);
use Carp;
use Exporter 5.57 qw(import);
use BusyBird::DateTime::Format;
use BusyBird::Log qw(bblog);
use BusyBird::SafeData qw(safed);
use DateTime;
use Future::Q 0.040;
use File::HomeDir;
use File::Spec;
our @EXPORT_OK =
qw(set_param expand_param config_directory config_file_path sort_statuses
split_with_entities future_of make_tracking vivifiable_as);
our @CARP_NOT = qw(Future::Q);
sub set_param {
my ($hashref, $params_ref, $key, $default, $is_mandatory) = @_;
if($is_mandatory && !defined($params_ref->{$key})) {
my $classname = blessed $hashref;
croak "ERROR: set_param in $classname: Parameter for '$key' is mandatory, but not supplied.";
}
$hashref->{$key} = (defined($params_ref->{$key}) ? $params_ref->{$key} : $default);
}
sub export_ok_all_tags {
no strict "refs";
my ($caller_package) = caller;
my $export_ok = \@{"${caller_package}::EXPORT_OK"};
my $export_tags = \%{"${caller_package}::EXPORT_TAGS"};
my @all = @$export_ok;
foreach my $tag (keys %$export_tags) {
my $exported = $export_tags->{$tag};
push(@all, @$exported);
push(@$export_ok, @$exported);
}
$export_tags->{all} = \@all;
}
sub expand_param {
my ($param, @names) = @_;
my $refparam = ref($param);
my @result = ();
if($refparam eq 'ARRAY') {
@result = @$param;
}elsif($refparam eq 'HASH') {
@result = @{$param}{@names};
}else {
$result[0] = $param;
}
return wantarray ? @result : $result[0];
}
sub config_directory {
return File::Spec->catfile(File::HomeDir->my_home, ".busybird");
}
sub config_file_path {
my (@paths) = @_;
return File::Spec->catfile(config_directory, @paths);
}
lib/BusyBird/Util.pm view on Meta::CPAN
$text, $start, $end, $entity_type, $entity
));
}
}
}
@entity_segments = sort { $a->{start} <=> $b->{start} } @entity_segments;
## combine entity_segments with non-entity segments
my $pos = 0;
my @final_segments = ();
foreach my $entity_segment (@entity_segments) {
if($pos < $entity_segment->{start}) {
push(@final_segments, _create_text_segment(
$text, $pos, $entity_segment->{start}
));
}
push(@final_segments, $entity_segment);
$pos = $entity_segment->{end};
}
if($pos < length($text)) {
push(@final_segments, _create_text_segment(
$text, $pos, length($text)
));
}
return \@final_segments;
}
sub future_of {
my ($invocant, $method, %args) = @_;
return Future::Q->try(sub {
croak "invocant parameter is mandatory" if not defined $invocant;
croak "method parameter is mandatory" if not defined $method;
croak "invocant is not blessed" if not blessed $invocant;
croak "no such method as $method" if not $invocant->can($method);
my $f = Future::Q->new();
$invocant->$method(%args, callback => sub {
my ($error, @results) = @_;
if($error) {
$f->reject($error, 1);
}else {
$f->fulfill(@results);
}
});
return $f;
});
}
sub make_tracking {
my ($tracking_timeline, $main_timeline) = @_;
if(!blessed($tracking_timeline) || !$tracking_timeline->isa("BusyBird::Timeline")) {
croak "tracking_timeline must be a BusyBird::Timeline.";
}
if(!blessed($main_timeline) || !$main_timeline->isa("BusyBird::Timeline")) {
croak "main_timeline must be a BusyBird::Timeline.";
}
my $name_tracking = $tracking_timeline->name;
my $name_main = $main_timeline->name;
if($name_tracking eq $name_main) {
croak "tracking_timeline and main_timeline must be different timelines.";
}
weaken(my $track = $tracking_timeline);
$tracking_timeline->add_filter_async(sub {
my ($statuses, $done) = @_;
if(!defined($track)) {
$done->($statuses);
return;
}
$track->contains(query => $statuses, callback => sub {
my ($error, $contained, $not_contained) = @_;
if(defined($error)) {
bblog("error", "tracking timeline '$name_tracking' contains() error: $error");
$done->($statuses);
return;
}
$main_timeline->add($not_contained, sub {
my ($error, $count) = @_;
if(defined($error)) {
bblog("error", "main timeline '$name_main' add() error: $error");
}
$done->($statuses);
});
});
});
return $tracking_timeline;
}
1;
__END__
=pod
=head1 NAME
BusyBird::Util - utility functions for BusyBird
=head1 SYNOPSIS
use BusyBird::Util qw(sort_statuses split_with_entities future_of);
future_of($timeline, "get_statuses", count => 100)->then(sub {
my ($statuses) = @_;
my $sorted_statuses = sort_statuses($statuses);
my $status = $sorted_statuses->[0];
my $segments_arrayref = split_with_entities($status->{text}, $status->{entities});
return $segments_arrayref;
})->catch(sub {
my ($error, $is_normal_error) = @_;
warn $error;
});
=head1 DESCRIPTION
This module provides some utility functions useful in L<BusyBird>.
=head1 EXPORTABLE FUNCTIONS
The following functions are exported only by request.
=head2 $sorted = sort_statuses($statuses)
( run in 2.725 seconds using v1.01-cache-2.11-cpan-5837b0d9d2c )