Skip to content

Instantly share code, notes, and snippets.

@tyru
Created January 7, 2011 08:41
Show Gist options
  • Save tyru/769264 to your computer and use it in GitHub Desktop.
Save tyru/769264 to your computer and use it in GitHub Desktop.
#!/usr/bin/env perl
use common::sense;
use Getopt::Long qw(:config gnu_compat no_bundling no_ignore_case);
use Pod::Usage;
use WWW::Scraper::ISBN;
use Getopt::SubCommand;
use Path::Class;
use File::Basename qw(basename);
use IO::File;
use JSON qw(encode_json decode_json);
my $GETOPT = Getopt::SubCommand->new(
commands => {
init => {
sub => \&command_init,
usage => 'Initialize {isbn-dir}',
usage_args => '{isbn-dir}',
options => {
force => {name => [qw/f force/]},
},
},
summary => {
sub => \&command_summary,
usage => 'Show summary of isbn directories.',
usage_args => '[{isbn-dir1} {isbn-dir2} ...]',
},
search => {
sub => \&command_search,
usage => "Search {book-title} and show its information",
usage_args => '{book-title}',
},
},
);
sub command_init {
my $args = $GETOPT->get_command_args;
$GETOPT->show_command_usage unless @$args;
my $isbn_dir = $args->[0];
my $isbn = basename $isbn_dir;
my $scraper = WWW::Scraper::ISBN->new();
$scraper->drivers('GoogleBooks');
my $record = eval { $scraper->search($isbn) };
die "$isbn is not valid ISBN: $@\n" if $@;
die "'$isbn' is not found.\n" unless $record->found;
my $json = book_build_json($record->book, [$scraper->drivers]);
my $bookman = file($isbn_dir, '.bookman');
$bookman->dir->mkpath;
if (!$GETOPT->get_command_opts('force') && -e $bookman) {
die "Path '$bookman' exists. aborting...\n";
}
my $FH = $bookman->openw
or die "can't create .bookman file in '$isbn_dir': $!";
$FH->print($json);
$FH->close;
}
sub book_build_json {
my ($book, $drivers) = @_;
# convert blessed object to not show a conversion error.
$book->{book_link} = "$book->{book_link}";
encode_json {
version => 1, # version of structure
drivers => $drivers,
book => $book,
};
}
sub command_summary {
my $args = $GETOPT->get_command_args;
for my $dir (@$args ? @$args : glob '*') {
show_summary($dir);
}
}
sub show_summary {
my ($dir) = @_;
my $bookman = file $dir, '.bookman';
unless (-e $bookman) {
warn ".bookman does not exist in '$dir'.\n" ;
return;
}
my $json = decode_json scalar $bookman->slurp;
my $driver = $json->{drivers}[0];
# Show its title at first.
my $title = delete $json->{book}{title};
my @info = "title: $title";
push @info, map { "$_: $json->{book}{$_}" }
sort
grep { defined $json->{book}{$_} }
keys %{ $json->{book} };
# indent
@info = map { " $_" } @info;
print <<EOM
information by $driver.
@{[ join "\n", @info ]}
EOM
}
sub command_search {
my $args = $GETOPT->get_command_args;
$GETOPT->show_command_usage unless @$args;
# TODO: Search information by ISBN or title name
# and dump it to .bookman file.
}
if (not defined $GETOPT->get_command) {
$GETOPT->show_usage;
}
elsif ($GETOPT->can_invoke_command) {
$GETOPT->invoke_command;
}
else {
$_ = $GETOPT->get_command;
die "Unknown command '$_'.\n";
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment