Refactor.
This commit is contained in:
parent
a7739727b6
commit
1b8dc8d9e4
|
@ -26,9 +26,7 @@ has last_invalid_card => (
|
|||
has _ua => ( is => 'lazy', );
|
||||
|
||||
sub _build__ua {
|
||||
my $ua = Mojo::UserAgent->new->with_roles('+Queued');
|
||||
$ua->max_active(20);
|
||||
$ua->inactivity_timeout(60);
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
return $ua;
|
||||
}
|
||||
|
||||
|
@ -43,14 +41,21 @@ sub _build__db_all_printings ($self) {
|
|||
|
||||
sub from_text ( $self, $text ) {
|
||||
my $promise = Mojo::Promise->new;
|
||||
{
|
||||
FUNCTION: {
|
||||
my @lines = split /\n+/, $text;
|
||||
@lines = grep { $self->_filter_lines($_); } @lines;
|
||||
if ( scalar @lines > $MAX_CARDS ) {
|
||||
$promise->reject($ERR_TOO_MANY_CARDS);
|
||||
next;
|
||||
}
|
||||
my @cards = map { s/^\s*(.*?)\s*$/$1/; $self->_parse_card($_) } @lines;
|
||||
my @cards;
|
||||
eval {
|
||||
@cards = map { s/^\s*(.*?)\s*$/$1/; $self->_parse_card($_) } @lines;
|
||||
};
|
||||
if ($@) {
|
||||
$promise->reject($@);
|
||||
next;
|
||||
}
|
||||
my $n_cards = 0;
|
||||
for my $card (@cards) {
|
||||
$n_cards += $card->{quantity};
|
||||
|
@ -59,13 +64,13 @@ sub from_text ( $self, $text ) {
|
|||
$promise->reject($ERR_TOO_MANY_CARDS);
|
||||
next;
|
||||
}
|
||||
eval {
|
||||
@cards = map { $self->_fill_scryfall_id($_) } @cards;
|
||||
};
|
||||
if ($@) {
|
||||
say $@;
|
||||
$promise->reject($@);
|
||||
next;
|
||||
for my $card (@cards) {
|
||||
my $err;
|
||||
$self->_fill_scryfall_id($card, \$err);
|
||||
if (defined $err) {
|
||||
$promise->reject($err);
|
||||
last FUNCTION;
|
||||
}
|
||||
}
|
||||
$self->_get_cards_images( \@cards )->then(
|
||||
sub ($images) {
|
||||
|
@ -76,6 +81,7 @@ sub from_text ( $self, $text ) {
|
|||
}
|
||||
if ( $real_number_of_cards > $MAX_CARDS ) {
|
||||
$promise->reject($ERR_TOO_MANY_CARDS);
|
||||
return;
|
||||
}
|
||||
my $pdf = $self->_generate_pdf( \@cards, $images );
|
||||
$promise->resolve($pdf);
|
||||
|
@ -144,7 +150,7 @@ sub _generate_pdf ( $self, $cards, $images ) {
|
|||
for my $page (@pages) {
|
||||
my $font = $pdf->font('Courier');
|
||||
my $content = $page->text;
|
||||
$content->position(0, $height_paper - 5);
|
||||
$content->position(25, $height_paper - 25);
|
||||
$content->font($font, 5);
|
||||
$content->text(decode 'utf-8', "The price of a colour printed page in Spain is around 0.50€, "
|
||||
. "your pdf has @{[scalar @pages]} pages, that would be "
|
||||
|
@ -153,7 +159,7 @@ sub _generate_pdf ( $self, $cards, $images ) {
|
|||
|
||||
$content = $page->text;
|
||||
|
||||
$content->position(0, $height_paper - 10);
|
||||
$content->position(25, $height_paper - 30);
|
||||
$content->font($font, 5);
|
||||
$content->text(decode 'utf-8', "developed and the developer would be "
|
||||
. "very grateful. I encourage you to donate "
|
||||
|
@ -162,7 +168,7 @@ sub _generate_pdf ( $self, $cards, $images ) {
|
|||
|
||||
$content = $page->text;
|
||||
|
||||
$content->position(0, $height_paper - 15);
|
||||
$content->position(25, $height_paper - 35);
|
||||
$content->font($font, 5);
|
||||
$content->text("https://paypal.me/sergiotarxz. Thank you very much for your support!!");
|
||||
}
|
||||
|
@ -232,14 +238,14 @@ sub _get_cards_images ( $self, $cards ) {
|
|||
return $final_promise;
|
||||
}
|
||||
|
||||
sub _fill_scryfall_id ( $self, $card ) {
|
||||
sub _fill_scryfall_id ( $self, $card, $err) {
|
||||
if ( $card->{type} eq 'token' ) {
|
||||
return $self->_fill_scryfall_id_token($card);
|
||||
return $self->_fill_scryfall_id_token($card, $err);
|
||||
}
|
||||
return $self->_fill_scryfall_id_card($card);
|
||||
return $self->_fill_scryfall_id_card($card, $err);
|
||||
}
|
||||
|
||||
sub _fill_scryfall_id_card ( $self, $card ) {
|
||||
sub _fill_scryfall_id_card ( $self, $card, $err ) {
|
||||
my $db = $self->_db_all_printings;
|
||||
my $query = <<'EOF';
|
||||
select scryfallId
|
||||
|
@ -255,13 +261,16 @@ EOF
|
|||
$self->last_invalid_card(
|
||||
"@{[$card->{quantity}]} @{[$card->{name}]} @{[$card->{set_code}]} @{[$card->{number}]}"
|
||||
);
|
||||
die $ERR_INVALID_CARD;
|
||||
if (defined $err) {
|
||||
$$err = $ERR_INVALID_CARD;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$card->{scryfallId} = $result->{scryfallId};
|
||||
return { %$card, };
|
||||
return;
|
||||
}
|
||||
|
||||
sub _fill_scryfall_id_token ( $self, $token ) {
|
||||
sub _fill_scryfall_id_token ( $self, $token, $err ) {
|
||||
my $db = $self->_db_all_printings;
|
||||
my $query = <<'EOF';
|
||||
SELECT scryfallId
|
||||
|
@ -281,10 +290,13 @@ EOF
|
|||
$last_invalid_card .= " @{[$token->{set_code}]}"
|
||||
if defined $token->{set_code};
|
||||
$self->last_invalid_card($last_invalid_card);
|
||||
die $ERR_INVALID_CARD;
|
||||
if (defined $err) {
|
||||
$$err = $ERR_INVALID_CARD;
|
||||
return;
|
||||
}
|
||||
}
|
||||
$token->{scryfallId} = $result->{scryfallId};
|
||||
return {%$token};
|
||||
return;
|
||||
}
|
||||
|
||||
sub _filter_lines ( $self, $arg ) {
|
||||
|
|
|
@ -25,10 +25,11 @@ has _ua => ( is => 'lazy', );
|
|||
has _last_offset_update => ( is => 'rw', );
|
||||
|
||||
has _used_cores => ( is => 'rw', default => sub { 0 } );
|
||||
|
||||
# We try 10 request at once in the crappy hardware.
|
||||
has _cores => ( is => 'rw', default => sub { 10 } );
|
||||
has _updates => ( is => 'rw' );
|
||||
has _ioloop => ( is => 'rw' );
|
||||
has _cores => ( is => 'rw', default => sub { 10 } );
|
||||
has _updates => ( is => 'rw' );
|
||||
has _ioloop => ( is => 'rw' );
|
||||
|
||||
sub _build__token ($self) {
|
||||
require TgMagicPdf;
|
||||
|
@ -39,6 +40,67 @@ sub run ($self) {
|
|||
$self->_dispatch_updates;
|
||||
}
|
||||
|
||||
sub _are_cores_available($self) {
|
||||
if ( $self->_used_cores >= $self->_cores ) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _core_start ( $self, $n_core, $update ) {
|
||||
say "Process $n_core active";
|
||||
$self->_dispatch_update($update)->then(
|
||||
sub {
|
||||
my $message = $update->{message};
|
||||
say 'Generated pdf for '
|
||||
. ( Data::Dumper::Dumper $message->{from} ) . ' '
|
||||
. $message->{date};
|
||||
}
|
||||
)->catch(
|
||||
sub ($err) {
|
||||
{
|
||||
if ( !defined $err ) {
|
||||
next;
|
||||
}
|
||||
my $message = $update->{message};
|
||||
say 'Could not generate anything for '
|
||||
. ( Data::Dumper::Dumper $message->{from} ) . ' '
|
||||
. $message->{date};
|
||||
}
|
||||
}
|
||||
)->wait;
|
||||
}
|
||||
|
||||
sub _get_next_update($self) {
|
||||
if ( !defined $self->_updates
|
||||
|| scalar @{ $self->_updates } == 0 )
|
||||
{
|
||||
my $res = $self->_get_updates;
|
||||
my $updates = $res->json->{result};
|
||||
$self->_updates($updates);
|
||||
}
|
||||
my $update = shift $self->_updates->@*;
|
||||
return $update;
|
||||
}
|
||||
|
||||
sub _attemp_core_start( $self, $n_core ) {
|
||||
my $update = $self->_get_next_update;
|
||||
if ( !defined $update ) {
|
||||
return 0;
|
||||
}
|
||||
$self->_used_cores( $self->_used_cores + 1 );
|
||||
Mojo::IOLoop->subprocess->run(
|
||||
sub {
|
||||
$self->_core_start( $n_core, $update );
|
||||
},
|
||||
sub {
|
||||
say "Process $n_core ended";
|
||||
$self->_used_cores( $self->_used_cores - 1 );
|
||||
}
|
||||
);
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _dispatch_updates ($self) {
|
||||
my $in_process = 0;
|
||||
Mojo::IOLoop->recurring(
|
||||
|
@ -48,60 +110,14 @@ sub _dispatch_updates ($self) {
|
|||
return;
|
||||
}
|
||||
$in_process = 1;
|
||||
if ( $self->_used_cores >= $self->_cores ) {
|
||||
if ( !$self->_are_cores_available ) {
|
||||
$in_process = 0;
|
||||
return;
|
||||
}
|
||||
for ( my $i = $self->_used_cores ; $i <= $self->_cores ; $i++ ) {
|
||||
if ( !defined $self->_updates
|
||||
|| scalar @{ $self->_updates } == 0 )
|
||||
{
|
||||
my $res = $self->_get_updates;
|
||||
my $updates = $res->json->{result};
|
||||
$self->_updates($updates);
|
||||
}
|
||||
my $update = shift $self->_updates->@*;
|
||||
if ( !defined $update ) {
|
||||
if ( $self->_attemp_core_start($i) == 0 ) {
|
||||
last;
|
||||
}
|
||||
$self->_used_cores( $self->_used_cores + 1 );
|
||||
Mojo::IOLoop->subprocess->run(
|
||||
sub {
|
||||
say "Proccess $i active";
|
||||
$self->_dispatch_update($update)->then(
|
||||
sub {
|
||||
my $message = $update->{message};
|
||||
say 'Generated pdf for '
|
||||
. ( Data::Dumper::Dumper $message->{from} )
|
||||
. ' '
|
||||
. $message->{date};
|
||||
Mojo::IOLoop->stop;
|
||||
}
|
||||
)->catch(
|
||||
sub ($err) {
|
||||
{
|
||||
if ( !defined $err ) {
|
||||
next;
|
||||
}
|
||||
my $message = $update->{message};
|
||||
say 'Could not generate anything for '
|
||||
. (
|
||||
Data::Dumper::Dumper $message->{from} )
|
||||
. ' '
|
||||
. $message->{date};
|
||||
}
|
||||
Mojo::IOLoop->stop;
|
||||
}
|
||||
);
|
||||
Mojo::IOLoop->start;
|
||||
return;
|
||||
},
|
||||
sub {
|
||||
say "Proccess $i ended";
|
||||
$self->_used_cores( $self->_used_cores - 1 );
|
||||
}
|
||||
);
|
||||
say $i;
|
||||
}
|
||||
$in_process = 0;
|
||||
}
|
||||
|
@ -110,18 +126,22 @@ sub _dispatch_updates ($self) {
|
|||
|
||||
sub _dispatch_update ( $self, $update ) {
|
||||
my $promise = Mojo::Promise->new;
|
||||
my $handle_message_promise;
|
||||
{
|
||||
if ( !defined $update->{message} ) {
|
||||
$promise->reject;
|
||||
next;
|
||||
}
|
||||
$self->_handle_message( $update->{message} )->then(
|
||||
$handle_message_promise = $self->_handle_message( $update->{message} );
|
||||
$handle_message_promise->then(
|
||||
sub {
|
||||
$promise->resolve;
|
||||
}
|
||||
)->catch(
|
||||
sub ($err) {
|
||||
sub {
|
||||
my $err = shift;
|
||||
$promise->reject($err);
|
||||
return 1;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -136,82 +156,106 @@ sub sendMessage ( $self, $chat_id, $text ) {
|
|||
return $promise;
|
||||
}
|
||||
|
||||
sub _is_message_valid_for_bot( $self, $chat_type, $text ) {
|
||||
if ( $chat_type ne 'private' ) {
|
||||
return;
|
||||
}
|
||||
if ( !defined $text ) {
|
||||
return;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub _send_pdf( $self, $promise, $chat_id, $pdf ) {
|
||||
$self->sendDocument( $chat_id, 'mtgprint.pdf', $pdf )->then(
|
||||
sub {
|
||||
$promise->resolve;
|
||||
}
|
||||
)->catch(
|
||||
sub {
|
||||
$promise->reject;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _on_pdf_generation_error( $self, $promise, $pdf_builder, $chat_id, $err ) {
|
||||
my @error_promises;
|
||||
{
|
||||
my $match = 0;
|
||||
for my $known_error (
|
||||
$TgMagicPdf::PdfBuilder::ERR_INVALID_CARD,
|
||||
$TgMagicPdf::PdfBuilder::ERR_UNABLE_TO_FIND_IMAGE,
|
||||
$TgMagicPdf::PdfBuilder::ERR_TOO_MANY_CARDS
|
||||
)
|
||||
{
|
||||
$match = 1
|
||||
if ( index( $err, $known_error ) != -1 );
|
||||
}
|
||||
if ($match) {
|
||||
my $error_to_user = $self->_remove_stack_trace($err);
|
||||
if ( $error_to_user eq $TgMagicPdf::PdfBuilder::ERR_INVALID_CARD ) {
|
||||
$error_to_user .= ' ' . $pdf_builder->last_invalid_card;
|
||||
}
|
||||
if ( $error_to_user eq $TgMagicPdf::PdfBuilder::ERR_UNABLE_TO_FIND_IMAGE )
|
||||
{
|
||||
$error_to_user .= ' ' . $pdf_builder->last_invalid_card;
|
||||
}
|
||||
push @error_promises,
|
||||
$self->sendMessage( $chat_id,
|
||||
'I could not process your deck take a look to this details: '
|
||||
. $error_to_user );
|
||||
next;
|
||||
}
|
||||
push @error_promises,
|
||||
$self->sendMessage( $chat_id,
|
||||
'I could not process your deck because of a server error' );
|
||||
}
|
||||
Mojo::Promise->all(@error_promises)->finally( sub { $promise->reject(1) } );
|
||||
}
|
||||
|
||||
sub _remove_stack_trace($self, $err) {
|
||||
my $new_error;
|
||||
if(!(($new_error) = $err =~ /^(.*?)\s*at.*$/m)) {
|
||||
return $err;
|
||||
}
|
||||
chomp $new_error;
|
||||
return $new_error;
|
||||
}
|
||||
|
||||
sub _after_first_reply_to_user( $self, $promise, $chat_id, $text ) {
|
||||
my $pdf_builder = TgMagicPdf::PdfBuilder->new;
|
||||
$pdf_builder->from_text($text)->then(
|
||||
sub ($pdf) {
|
||||
$self->_send_pdf( $promise, $chat_id, $pdf );
|
||||
}
|
||||
)->catch(
|
||||
sub ($err) {
|
||||
$self->_on_pdf_generation_error( $promise, $pdf_builder, $chat_id,
|
||||
$err );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
sub _handle_message ( $self, $message ) {
|
||||
my $promise = Mojo::Promise->new;
|
||||
{
|
||||
my $chat_type = $message->{chat}{type};
|
||||
if ( $chat_type ne 'private' ) {
|
||||
my $chat_id = $message->{chat}{id};
|
||||
my $text = $message->{text};
|
||||
if ( !$self->_is_message_valid_for_bot( $chat_type, $text ) ) {
|
||||
$promise->reject;
|
||||
next;
|
||||
}
|
||||
my $chat_id = $message->{chat}{id};
|
||||
my $text = $message->{text};
|
||||
if ( !defined $text ) {
|
||||
$promise->reject;
|
||||
next;
|
||||
}
|
||||
$self->sendMessage( $chat_id,
|
||||
'Got your message, attempting to generate a pdf.' )->then(
|
||||
my $promise_send_message = $self->sendMessage( $chat_id,
|
||||
'Got your message, attempting to generate a pdf.' );
|
||||
$promise_send_message->then(
|
||||
sub {
|
||||
my $pdf_builder = TgMagicPdf::PdfBuilder->new;
|
||||
$pdf_builder->from_text($text)->then(
|
||||
sub ($pdf) {
|
||||
$self->sendDocument( $chat_id, 'mtgprint.pdf', $pdf )
|
||||
->then(
|
||||
sub {
|
||||
$promise->resolve;
|
||||
}
|
||||
);
|
||||
}
|
||||
)->catch(
|
||||
sub ($err) {
|
||||
my @error_promises;
|
||||
{
|
||||
my $match = 0;
|
||||
for my $known_error (
|
||||
$TgMagicPdf::PdfBuilder::ERR_INVALID_CARD,
|
||||
$TgMagicPdf::PdfBuilder::ERR_UNABLE_TO_FIND_IMAGE,
|
||||
$TgMagicPdf::PdfBuilder::ERR_TOO_MANY_CARDS
|
||||
)
|
||||
{
|
||||
$match = 1
|
||||
if ( index( $err, $known_error ) != -1 );
|
||||
}
|
||||
if ($match) {
|
||||
my $error_to_user = $err =~ s/^(.*?)\s*at.*$/$1/mr;
|
||||
chomp $error_to_user;
|
||||
if ( -1 != index $err,
|
||||
$TgMagicPdf::PdfBuilder::ERR_INVALID_CARD )
|
||||
{
|
||||
$error_to_user .=
|
||||
' ' . $pdf_builder->last_invalid_card;
|
||||
}
|
||||
if ( -1 != index $err,
|
||||
$TgMagicPdf::PdfBuilder::ERR_UNABLE_TO_FIND_IMAGE
|
||||
)
|
||||
{
|
||||
$error_to_user .=
|
||||
' ' . $pdf_builder->last_invalid_card;
|
||||
}
|
||||
push @error_promises,
|
||||
$self->sendMessage(
|
||||
$chat_id,
|
||||
'I could not process your deck take a look to this details: '
|
||||
. $error_to_user
|
||||
);
|
||||
next;
|
||||
}
|
||||
push @error_promises,
|
||||
$self->sendMessage( $chat_id,
|
||||
'I could not process your deck because of a server error'
|
||||
);
|
||||
}
|
||||
Mojo::Promise->all(@error_promises)
|
||||
->finally( sub { $promise->reject(1) } );
|
||||
}
|
||||
);
|
||||
$self->_after_first_reply_to_user( $promise, $chat_id, $text );
|
||||
}
|
||||
)->catch( sub ($err) { warn $err } );
|
||||
)->catch(sub ($err) {
|
||||
$promise->reject($err);
|
||||
return 1;
|
||||
});
|
||||
}
|
||||
return $promise;
|
||||
}
|
||||
|
@ -239,7 +283,6 @@ sub _pdf_builder {
|
|||
|
||||
sub _build__ua ($self) {
|
||||
my $ua = Mojo::UserAgent->new;
|
||||
$ua->inactivity_timeout(5);
|
||||
return $ua;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue