Skip to content

Commit

Permalink
detect encoding and make portable commands easier
Browse files Browse the repository at this point in the history
  • Loading branch information
kraih committed Apr 19, 2013
1 parent 97f3e1d commit a593c4c
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 30 deletions.
54 changes: 48 additions & 6 deletions lib/Mojolicious/Command.pm
Expand Up @@ -6,21 +6,23 @@ use Cwd 'getcwd';
use File::Basename 'dirname';
use File::Path 'mkpath';
use File::Spec::Functions qw(catdir catfile);
use I18N::Langinfo qw(langinfo CODESET);
use Mojo::Loader;
use Mojo::Server;
use Mojo::Template;
use Mojo::Util 'spurt';
use Mojo::Util qw(encode spurt);

has app => sub { Mojo::Server->new->build_app('Mojo::HelloWorld') };
has description => 'No description.';
has encoding => sub { langinfo CODESET };
has quiet => 0;
has usage => "usage: $0\n";

sub chmod_file {
my ($self, $path, $mod) = @_;
chmod $mod, $path or croak qq{Can't chmod file "$path": $!};
$mod = sprintf '%lo', $mod;
say " [chmod] $path $mod" unless $self->quiet;
$self->enc_say(" [chmod] $path $mod") unless $self->quiet;
return $self;
}

Expand All @@ -32,10 +34,10 @@ sub chmod_rel_file {
sub create_dir {
my ($self, $path) = @_;

if (-d $path) { say " [exist] $path" unless $self->quiet }
if (-d $path) { $self->enc_say(" [exist] $path") unless $self->quiet }
else {
mkpath $path or croak qq{Can't make directory "$path": $!};
say " [mkdir] $path" unless $self->quiet;
$self->enc_say(" [mkdir] $path") unless $self->quiet;
}

return $self;
Expand All @@ -46,8 +48,15 @@ sub create_rel_dir {
$self->create_dir($self->rel_dir($path));
}

sub enc_print { print shift->_enc(@_) }

sub enc_say { shift->enc_print(@_, "\n") }

sub enc_warn { warn shift->_enc(@_) }

sub help {
print shift->usage;
my $self = shift;
$self->enc_print($self->usage);
exit 0;
}

Expand Down Expand Up @@ -77,7 +86,7 @@ sub write_file {
my ($self, $path, $data) = @_;
$self->create_dir(dirname $path);
spurt $data, $path;
say " [write] $path" unless $self->quiet;
$self->enc_say(" [write] $path") unless $self->quiet;
return $self;
}

Expand All @@ -86,8 +95,16 @@ sub write_rel_file {
$self->write_file($self->rel_file($path), $data);
}

sub _enc {
my ($self, @args) = @_;
return @args unless my $encoding = $self->encoding;
return map { encode $encoding, $_ } @args;
}

1;

=encoding utf8
=head1 NAME
Mojolicious::Command - Command base class
Expand Down Expand Up @@ -143,6 +160,13 @@ Application for command, defaults to a L<Mojo::HelloWorld> object.
Short description of command, used for the command list.
=head2 encoding
my $encoding = $command->encoding;
$command = $command->encoding('koi8-r');
Encoding to use for I/O, defaults to auto detection.
=head2 quiet
my $quiet = $command->quiet;
Expand Down Expand Up @@ -186,6 +210,24 @@ Create a directory.
Portably create a directory relative to the current working directory.
=head2 enc_print
$command->enc_print('I ♥ Mojolicious!');
Encode and C<print>.
=head2 enc_say
$command->enc_say('I ♥ Mojolicious!');
Encode and C<say>.
=head2 enc_warn
$command->enc_warn('I ♥ Mojolicious!');
Encode and C<warn>.
=head2 help
$command->help;
Expand Down
34 changes: 15 additions & 19 deletions lib/Mojolicious/Command/get.pm
Expand Up @@ -7,7 +7,7 @@ use Mojo::IOLoop;
use Mojo::JSON;
use Mojo::JSON::Pointer;
use Mojo::UserAgent;
use Mojo::Util qw(decode encode);
use Mojo::Util 'decode';

has description => "Perform HTTP request.\n";
has usage => <<"EOF";
Expand Down Expand Up @@ -45,8 +45,6 @@ sub run {
'M|method=s' => \(my $method = 'GET'),
'r|redirect' => \my $redirect,
'v|verbose' => \my $verbose;

@args = map { decode 'UTF-8', $_ } @args;
die $self->usage unless my $url = shift @args;
my $selector = shift @args;

Expand Down Expand Up @@ -99,7 +97,7 @@ sub run {

# Ignore intermediate content
return if $redirect && $res->is_status_class(300);
defined $selector ? ($buffer .= pop) : print(pop);
defined $selector ? ($buffer .= pop) : $self->enc_print(pop);
}
);
}
Expand All @@ -110,33 +108,31 @@ sub run {
STDOUT->autoflush(1);
my $tx = $ua->start($ua->build_tx($method, $url, \%headers, $content));
my ($err, $code) = $tx->error;
$url = encode 'UTF-8', $url;
warn qq{Problem loading URL "$url". ($err)\n} if $err && !$code;
$self->enc_warn(qq{Problem loading URL "$url". ($err)\n}) if $err && !$code;

# JSON Pointer
return unless defined $selector;
my $type = $tx->res->headers->content_type // '';
return _json($buffer, $selector) if $type =~ /json/i;
return $self->_json($buffer, $selector) if $type =~ /json/i;

# Selector
_select($buffer, $selector, $charset // $tx->res->content->charset, @args);
$self->_select($buffer, $selector, $charset // $tx->res->content->charset,
@args);
}

sub _json {
my $self = shift;

my $json = Mojo::JSON->new;
return unless my $data = $json->decode(shift);
return unless defined($data = Mojo::JSON::Pointer->new->get($data, shift));
return _say($data) unless ref $data eq 'HASH' || ref $data eq 'ARRAY';
say $json->encode($data);
}

sub _say {
return unless length(my $value = shift);
say encode('UTF-8', $value);
return $self->enc_say($data)
unless ref $data eq 'HASH' || ref $data eq 'ARRAY';
$self->enc_say(decode 'UTF-8', $json->encode($data));
}

sub _select {
my ($buffer, $selector, $charset, @args) = @_;
my ($self, $buffer, $selector, $charset, @args) = @_;

my $dom = Mojo::DOM->new->charset($charset)->parse($buffer);
my $results = $dom->find($selector);
Expand All @@ -151,15 +147,15 @@ sub _select {
}

# Text
elsif ($command eq 'text') { _say($_->text) for @$results }
elsif ($command eq 'text') { $self->enc_say($_->text) for @$results }

# All text
elsif ($command eq 'all') { _say($_->all_text) for @$results }
elsif ($command eq 'all') { $self->enc_say($_->all_text) for @$results }

# Attribute
elsif ($command eq 'attr') {
next unless my $name = shift @args;
_say($_->attrs->{$name}) for @$results;
$self->enc_say($_->attrs->{$name}) for @$results;
}

# Unknown
Expand Down
2 changes: 1 addition & 1 deletion lib/Mojolicious/Command/routes.pm
Expand Up @@ -73,7 +73,7 @@ sub _draw {
$format .= '?' if $format && $optional;
push @parts, $format ? "$regex$format" : $regex if $verbose;

say join(' ', @parts);
$self->enc_say(join ' ', @parts);
}
}

Expand Down
12 changes: 8 additions & 4 deletions lib/Mojolicious/Commands.pm
Expand Up @@ -4,6 +4,7 @@ use Mojo::Base 'Mojolicious::Command';
use Getopt::Long 'GetOptions';
use List::Util 'max';
use Mojo::Server;
use Mojo::Util 'decode';

has hint => <<"EOF";
Expand Down Expand Up @@ -60,6 +61,8 @@ sub run {
$name = $self->detect($name) unless $ENV{MOJO_NO_DETECT};

# Run command
my $encoding = $self->encoding;
@args = map { decode $encoding, $_ } @args if $encoding;
if ($name && $name =~ /^\w+$/ && ($name ne 'help' || $args[0])) {

# Help
Expand All @@ -74,7 +77,7 @@ sub run {
unless $module;

# Run command
my $command = $module->new(app => $self->app);
my $command = $module->new(app => $self->app, encoding => $encoding);
return $help ? $command->help(@args) : $command->run(@args);
}

Expand All @@ -94,13 +97,14 @@ sub run {

# Print list of all available commands
my $max = max map { length $_->[0] } @commands;
print $self->message;
$self->enc_print($self->message);
for my $command (@commands) {
my $name = $command->[0];
my $description = $command->[1]->new->description;
print " $name", (' ' x ($max - length $name)), " $description";
my $cmd = " $name" . (' ' x ($max - length $name)) . " $description";
$self->enc_print($cmd);
}
return print $self->hint;
return $self->enc_print($self->hint);
}

sub start_app {
Expand Down

0 comments on commit a593c4c

Please sign in to comment.