Skip to content

Instantly share code, notes, and snippets.

@jbarrett
Last active December 14, 2015 20:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jbarrett/5142315 to your computer and use it in GitHub Desktop.
Save jbarrett/5142315 to your computer and use it in GitHub Desktop.
Very quick first pass at WWW::QDB, quote retrieval from qdb.us and bash.org with cache for random quotes.
package WWW::QDB;
use v5.10.1;
use strict;
use warnings;
use HTTP::Tiny;
use HTML::TreeBuilder::XPath;
use Scalar::Util qw/looks_like_number/;
use Carp;
our $VERSION = '0.01';
=encoding utf8
=head1 NAME
WWW::QDB - retrieve quotes from bash.org / qdb.us
=head1 SYNOPSIS
use WWW::QDB;
my $qdb = WWW::QDB->new( timeout => 5, safe => 0, site => 'bash' ); # defaults
my $random_quote = $qdb->get_random; # default is bash.org
my $random_qdb_quote = $qdb->get_random('qdb');
my $specific_bash_quote = $qdb->get_quote(240849, 'bash');
=cut
sub _normalise_site {
my ($site) = @_;
$$site = ($$site =~ /^q/i) ? 'qdb' : 'bash';
}
sub _get {
my ($self, $site, $quote) = @_;
$site ||= $self->{'site'};
_normalise_site(\$site);
(($quote) && (looks_like_number($quote))) || ($quote = 'random' . (($self->{'safe'}) ? '1' : ''));
my $tree = HTML::TreeBuilder::XPath->new()
or croak("Unable to create HTML::TreeBuilder::XPath instance");
my $url = (($site =~ /^q/) ? 'http://qdb.us/' : 'http://bash.org/?' ) . $quote;
my $tag = ($site =~ /^q/) ? '/html/body//p[@class="q"]' : '/html/body//p[@class="qt"]';
my $response = $self->{'http'}->get($url) or croak ("Unable to retrieve $url : $!");
$tree->parse_content($response->{'content'});
my @quotes = $tree->findvalues($tag);
($site =~ /^q/) && s/^#[0-9]+// for @quotes;
return @quotes;
}
sub _top_up {
my ($self, $site, $quote) = @_;
$site ||= $self->{'site'};
_normalise_site(\$site);
my $buf = ($site =~ /^q/) ? 'qbuf' : 'bbuf';
@{ $self->{$buf} } = $self->_get($site);
}
sub new {
my ($class, %args) = @_;
$args{'site'} ||= 'bash';
$args{'timeout'} ||= 5;
$args{'http'} = HTTP::Tiny->new( timeout => $args{'timeout'} )
or croak("Unable to create HTTP::Tiny instance");
return bless \%args, $class;
}
sub get_random {
my ($self, $site) = @_;
$site ||= $self->{'site'};
_normalise_site(\$site);
my $buf = ($site =~ /^q/) ? 'qbuf' : 'bbuf';
((!$self->{$buf}) || (scalar @{ $self->{$buf} } < 1)) && $self->_top_up($site);
return pop @{ $self->{$buf} };
}
sub get_quote {
my ($self, $quote, $site) = @_;
$site ||= $self->{'site'};
_normalise_site(\$site);
return ($self->_get($site, $quote))[0];
}
1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment