#!/usr/bin/perl -w
use strict;
use Term::ReadKey;
use Getopt::Long;
use Pod::Usage;
use LWP;
use HTTP::Request::Common;
use HTML::TokeParser;
use constant URL => 'http://www.perlmonks.org/';
use vars qw(
%ESC $ua $cont $user $pass $file
$read $append $prepend $code $help
);
%ESC = (
'&' => '&',
'<' => '<',
'>' => '>',
'"' => '"',
);
GetOptions(
'user|u=s' => \$user,
'pass|p=s' => \$pass,
'file|f=s' => \$file,
'code|c' => \$code,
'read|r' => \$read,
'append|app' => \$append,
'prepend|pre' => \$prepend,
'help|h|?' => \$help,
);
pod2usage(-verbose=>1) if $help;
pod2usage(-verbose=>2) unless $file or $read;
$user ||= ''; # insert default user name here
pod2usage(-verbose=>2) unless $user;
$pass ||= ''; # insert default password here
$pass ||= &read_pass();
pod2usage(-verbose=>2) unless $pass;
unless ($read) {
open FH, $file or die "can't open $file: $!";
$cont = do {local $/; <FH>};
close FH;
}
$cont = "<code>\n$cont<\/code>\n" if $code;
$ua = LWP::UserAgent->new;
$ua->agent("scratchpad_poster/1.0 (@{[$ua->agent]})");
if ($read or $append or $prepend) {
my $pad = &parse_pad(&post());
print $pad and exit if $read;
$cont = $pad . $cont if $append;
$cont = $cont . $pad if $prepend;
}
&post(
user_scratchpad => $cont,
sexisgood => 'stumbit',
setscratchpublic => 'on',
);
sub post {
my %attr = @_;
my $request = POST(URL,
Content => [
op => 'login',
user => $user,
passwd => $pass,
displaytype => 'edit',
node => $user,
%attr
]
);
my $response = $ua->request($request);
my $content = $response->content;
die "error posting page" if $response->is_error;
die "Invalid user or password" if $content =~ /Permission Denied/;
return $content;
}
sub parse_pad {
my $raw = shift;
my $pad;
my $parser = HTML::TokeParser->new(\$raw);
while (my $tag = $parser->get_tag('textarea')) {
if ($tag->[1]->{name} eq 'user_scratchpad') {
$pad = $parser->get_text;
}
}
$pad =~ s/(&\w+;)/$ESC{$1}/ge;
return $pad;
}
sub read_pass {
my $pass;
print "Enter password: ";
ReadMode 'noecho';
chomp($pass = ReadLine 0);
ReadMode 'normal';
print "\n";
return $pass;
}
__END__
=head1 NAME
scratchpad_poster.pl - updates user's scratch pad
=head1 SYNOPSIS
scratchpad_poster.pl -file [-user -pass -append -prepend -code]
Options:
-user -u user's name
-pass -p user's password
-file -f file to post (- for STDIN)
-read -r returns current contents instead
-append -app appends file to scratch pad
-prepend -pre prepends file to scratch pad
-code -c wraps entire file in code tags
-help -h -? brief help message
=head1 DESCRIPTION
B<This program> will read the given input file and post
it to your scratch pad. Simply specify - for the file
name to read from STDIN. Your user name is required,
as well as the password. These values can be hard-coded
into the code in the appropriate places if you know
that no one else will see this script. If the password
argument is not supplied, then you will be prompted
with an non-echoed prompt for security. Also required
is the file to be uploaded to your scratch pad, unless
you specify the read option, which will print your
current scratch pad to STDOUT without uploading any
new content.
Not required is the code option, which will wrap the
entire file to be posted with code tags; the append
option, which will append the file to be posted; and
the prepend option, which will prepend the file to be
posted. If either the append or prepend option are
true, two requests will be posted - one to retrieve
the current contens of your scratch pad and one to
post the new contents. Make sure you spell append
and prepend correctly, or else you will wipe out
your scratchpad with the new content.
=head1 EXAMPLES
0 - backup your scratch pad to an HTML file:
./scratchpad_poster.pl -user jeffa -read > pad.html
1 - post simple html file:
./scratchpad_poster.pl -user jeffa -file=foo.html
2 - append a perl script:
./scratchpad_poster.pl -u jeffa -f=foo.pl -c -append
3 - prepend 'on the fly' STDIN content
./scratchpad_poster.pl -u jeffa -f=- -prepend
[type away - hit CNTRL-D when finished]
4 - append errors from perl script, notice that you
have to give password as arg (or alternatively
hard code it):
./error.pl 2>&1>/dev/null | ./scratchpad_poster.pl -u jeffa -p pass -f
+=- -c -app
=cut
|