Permalink
Fetching contributors…
Cannot retrieve contributors at this time
169 lines (142 sloc) 4.94 KB
package Mojolicious::Command::nopaste::Service;
use Mojo::Base 'Mojolicious::Command';
use Mojo::UserAgent;
use Mojo::Util qw/decode monkey_patch/;
use Getopt::Long qw(GetOptionsFromArray :config no_ignore_case); # no_auto_abbrev
our $USAGE = <<END;
USAGE:
$0 command SERVICE [OPTIONS] [FILES]
OPTIONS:
Note that not all options are relevant for all services.
--channel, -c The channel for the service's pastebot or to post via Mojo::IRC
e.g. perl, #perl, irc://irc.perl.org:6667/perl
--copy, -x Copy the resulting URL to the clipboard (requires Clipboard.pm)
--description, -d Description or title of the nopaste
--name, -n Your name or nick, used for the pastebin and/or IRC
--language, -l Language for syntax highlighting, defaults to 'perl'
--open, -o Open a browser to the url (requires Browser::Open)
--paste, -p Read contents from clipboard (requires Clipboard.pm)
--private, -P Mark the paste as private (note: silently ignored if not relevant for service)
--token, -t A file containing an access token, or else the token string itself
--update, -u Update a paste of a given id
END
has usage => sub {
my $self = shift;
my $usage = $USAGE;
if (my $add = $self->service_usage) {
$usage .= "\n$add";
}
return $usage;
};
has [qw/channel name desc service_usage token update/];
has [qw/copy open private irc_handled/] => 0;
has clip => sub {
die "Clipboard module not available. Do you need to install it?\n"
unless eval 'use Clipboard; 1';
monkey_patch 'Clipboard::Xclip',
copy => \&_xclip_copy,
paste => \&_xclip_paste;
return 'Clipboard';
};
has files => sub { [] };
has language => 'perl';
has text => sub { shift->slurp };
has ua => sub { Mojo::UserAgent->new->max_redirects(10) };
sub run {
my ($self, @args) = @_;
GetOptionsFromArray( \@args,
'channel|c=s' => sub { $self->channel($_[1]) },
'copy|x' => sub { $self->copy($_[1]) },
'description|d=s' => sub { $self->desc($_[1]) },
'name|n=s' => sub { $self->name($_[1]) },
'language|l=s' => sub { $self->language($_[1]) },
'open|o' => sub { $self->open($_[1]) },
'paste|p' => sub { $self->text($self->clip->paste) },
'private|P' => sub { $self->private($_[1]) },
'token|t=s' => sub { $self->add_token($_[1]) },
'update|u=s' => sub { $self->update($_[1]) },
);
$self->files(\@args);
my $url = $self->paste or return;
say $url;
$self->clip->copy($url) if $self->copy;
if ($self->open) {
die "Browser::Open module not available. Do you need to install it?\n"
unless eval { require Browser::Open; 1 };
Browser::Open::open_browser($url);
}
if ($self->channel and not $self->irc_handled) {
$self->post_to_irc($url);
}
}
sub add_token {
my ($self, $token) = @_;
if (-e $token) {
$token = $self->slurp($token);
}
chomp $token;
$self->token($token);
}
sub paste { die 'Not implemented' }
sub slurp {
my ($self, @files) = @_;
@files = @{ $self->files } unless @files;
my $content = do {
local $/;
local @ARGV = @files;
decode 'UTF-8', <>;
};
# Remove trailing newline as some sites won't do it for us
chomp $content;
return $content;
}
sub post_to_irc {
my ($self, $paste) = @_;
die "This service requires Mojo::IRC to post to IRC, but it is not available. Do you need to install it?\n"
unless eval { require Mojo::IRC; 1 };
require Mojo::IOLoop;
require Mojo::URL;
my $url = Mojo::URL->new($self->channel);
my $chan = $url->fragment || $url->path->[-1];
die "Could not parse IRC channel\n" unless $chan;
my $server = $url->host_port || 'irc.perl.org:6667';
my $irc = Mojo::IRC->new(server => $server, nick => 'MojoNoPaste', user => 'MojoNoPaste');
$irc->register_default_event_handlers;
my $name = $self->name || 'someone';
my $err;
my $catch = sub { $err = pop; Mojo::IOLoop->stop };
$irc->on(error => $catch);
$irc->on(irc_error => $catch);
$irc->on(irc_join => sub {
my ($irc, $message) = @_;
my $chan = $message->{params}[0];
my $delay = Mojo::IOLoop->delay(
sub { $irc->write( privmsg => $chan, ":$name pasted $paste", shift->begin ) },
sub { $irc->disconnect( shift->begin ) },
sub { Mojo::IOLoop->stop },
);
$delay->catch($catch);
});
$irc->connect(sub{
my ($irc, $err) = @_;
die $err if $err;
say 'Connected to IRC';
$irc->write(join => "#$chan");
});
Mojo::IOLoop->start;
die $err if $err;
}
sub _xclip_copy {
my ($self, $input) = @_;
eval { $self->copy_to_selection($_, $input) } for $self->all_selections();
}
sub _xclip_paste {
my $self = shift;
my $data;
for my $sel ($self->all_selections) {
$data = eval { $self->paste_from_selection($sel) };
last if $data;
}
return decode 'UTF-8', $data || '';
}
1;