Wiki-image-upload.pl
From [1]
<source lang="perl">
- !perl -w
use strict;
- this script takes pairs of filename, description as parameters, and
- uploads them to the wiki.
- example:
- perl wiki-upload.pl image.jpg "first image" image2.jpg "second image"
- you need to create a file c:\local\etc\wiki.cfg
- containing 2 lines:
- user=USERNAME
- pass=PASSWORD
- some included support nodules
package WebServer; use strict; use warnings; use HTTP::Request::Common qw(POST GET); use LWP::UserAgent; use HTTP::Cookies;
use List::Util qw(first);
sub new {
my ($class, $baseurl)= @_;
my $ua= LWP::UserAgent->new(agent=>'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040501'); $ua->cookie_jar(HTTP::Cookies->new(hide_cookie2=>1)); $ua->env_proxy();
return bless { ua=>$ua, baseurl=>$baseurl, }, $class;
} sub clearcookies {
my $self= shift;
$self->{ua}->cookie_jar(HTTP::Cookies->new(hide_cookie2=>1));
}
- almost interface compatible with httpost
- - optional hashref with parameters is merged with parameters.
- httpget("/some.cgi", key1=>123, key2=>455);
- httpget("/some.cgi", { urlkey1=>999 }, key1=>123, key2=>455);
sub httpget {
my $self= shift; my $path= shift;
my $query; if (@_) { $query= shift; if (ref $query ne "HASH") { unshift @_, $query; $query=undef; } } my %params= @_;
my $uri= URI->new($self->{baseurl}); $uri->path($path); $uri->query_form($query?%$query:(), %params); my $rq= GET $uri;
# todo: get rid of 'TE' header, and 'Connection'-TE flag. and 'Cookie2' header $rq->header( 'User-Agent'=> 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040501', 'Accept'=> ($path =~ /\.aspx|\.htm/ ? 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5' : $path =~ /\.css/ ? 'text/css,*/*;q=0.1' : '*/*') , 'Accept-Language'=> 'en-us,en;q=0.5', #'Accept-Encoding'=> 'gzip,deflate', 'Accept-Charset'=> 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', ); #print "request:\n", $rq->as_string, "\n"; #warn "network access disabled\n"; #return; my $rp= $self->{ua}->request($rq) or die "httperror: $@\n";
return $rp->content;
}
- can be called in several ways:
- httppost("/some.cgi", key1=>123, key2=>455);
- -> just form values
- httppost("/some.cgi", { urlkey1=>999 }, key1=>123, key2=>455);
- -> both url and form params
- httppost("/some.cgi", key1=>123, key2=>455, file1=>["filename"]);
- -> form-data file upload
sub httppost {
my $self= shift; my $path= shift;
my $query; if (@_) { $query= shift; if (ref $query ne "HASH") { unshift @_, $query; $query=undef; } } my %params= @_;
my $useformdata= grep { defined ref $_ && ref $_ eq "ARRAY" } values %params;
my $uri= URI->new($self->{baseurl}); $uri->path($path); $uri->query_form(%$query) if ($query); my $rq; if ( $useformdata ) { $rq = POST $uri, Content_Type=>"form-data", Content=>[ %params ]; } else { $rq = POST $uri, [ %params ]; }
# -- for http uploads : # ( Content_Type=>"form-data", Content=>[ %params ]); $rq->header( 'User-Agent'=> 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7) Gecko/20040501', 'Accept'=> 'text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5', 'Accept-Language'=> 'en-us,en;q=0.5', #'Accept-Encoding'=> 'gzip,deflate', 'Accept-Charset'=> 'ISO-8859-1,utf-8;q=0.7,*;q=0.7', ); #print "request:\n", $rq->as_string, "\n"; #warn "network access disabled\n"; #return; my $rp= $self->{ua}->request($rq) or die "httperror: $@\n";
#print $rp->status_line, "\n"; #print $rp->headers->as_string();
return $rp->content;
}
sub httprequest {
my ($self, $method, @params)= @_; if (lc($method) eq "get") { return $self->httpget(@params); } elsif (lc($method) eq "post") { return $self->httppost(@params); } else { die "invalid http request method '$method'\n"; }
}
package MediaWiki; use strict; use warnings; use HTML::TreeBuilder;
sub new {
my $class= shift;
my $self= bless { server=> WebServer->new("http://wiki.whatthehack.org"), url=> "/index.php", }, $class;
return $self;
} sub post {
my ($self, @params)= @_; $self->{server}->httppost($self->{url}, @params);
} sub get {
my ($self, @params)= @_; if (!$self->{loggedin}) { $self->login(); } $self->{server}->httpget($self->{url}, @params);
} sub cachedget {
my ($self, @params)= @_;
my $filename= encodeurlasfile(@params);
if (-e $filename) { return readfile($filename); }
my $data= $self->get(@params); savefile($filename, $data); return $data;
} sub DESTROY {
my $self= shift;
}
sub getwikisource {
my ($self, $page)= @_; my $xml= $self->post( title=>'Special:Export', action=>'submit', pages=>$page, curonly=>'true', ); if ($xml =~ /<text[^>]*>(.*?)<\/text>/s) { return $1; } die "could not find <text> xml tag in\n$xml\n";
} sub getcategoryitems {
my ($self, $page)= @_; my $html= $self->get( title=>$page, ); my $tree = HTML::TreeBuilder->new(); $tree->parse($html); $tree->eof();
my ($table)= $tree->look_down( "_tag"=>"table", ) or die "could not find category table for $page\n";
my @items; for $a ($table->look_down("_tag", "a")) { push @items, $a->as_text(); } return @items;
} sub uploadfile {
my ($self, $imgname, $imgdesc)= @_; $imgname =~ s/\\/\//g; ( my $imgdestname= $imgname ) =~ s/.*\///;
my $answer= $self->post( { title=>'Special:Upload', }, wpUploadFile=>[$imgname], wpDestFile=>$imgdestname, wpUploadDescription=>$imgdesc, wpUpload=>"Upload file", ); print $answer->content;
} sub logout {
my $self= shift; my $answer= $self->get(title=>'Special:Userlogout'); $self->{loggedin}= 0; $self->{server}->clearcookies();
} sub login {
my ($self, $username, $password)= @_;
my $answer= $self->post( { action=>'submitlogin', title=>'Special:Userlogin' }, wpName => $username, wpPassword => $password, wpLoginattempt => 'Log in', ); $self->{loggedin}= 1;
}
- title=>'Template:UpcomingTable'
- action=>'submit'
- text wpSummary
- flag wpMinoredit 1
- flag wpWatchthis
- button wpSave Save page
- button wpPreview Show preview
- button wpDiff Show changes
- hidden wpSection
- hidden wpEdittime 20050730124636
- hidden wpEditToken cd44d6f6003e41d1d44b9a79266a846f
- text wpTextbox1
sub geteditform {
my ($self, $page, $section)= @_; my $answer= $self->get( action=>'edit', title=>$page, defined $section ? ( section=>$section ) : (), ); my $tree = HTML::TreeBuilder->new(); $tree->parse($answer); $tree->eof();
my ($formtag)= $tree->look_down( "_tag"=>"form", "name"=>"editform", ); my @inputelements= $formtag->look_down( "_tag"=>"input", sub { $_[0]->attr('type') ne 'submit' && $_[0]->attr('type') ne 'radio' } ); my @textelements= $formtag->look_down( "_tag"=>"textarea", );
my %form; # not handling radio buttons yet. for my $field (@inputelements) { $form{$field->attr('name')}= $field->attr('value') } for my $field (@textelements) { $form{$field->attr('name')}= $field->as_text; } return \%form;
} sub saveeditform {
my ($self, $page, $form)= @_; my $answer= $self->post( { action=>'submit', title=>$page, }, wpSave=>"Save page", %$form, );
}
sub createpage {
my ($self, $page, $content)= @_;
my $f= $self->geteditform($page); if ($f->{wpTextbox1}) { print "----$page\n$f->{wpTextbox1}\n\n"; } $f->{wpTextbox1}= $content; print map { sprintf("%-20s= %s\n", $_, defined $f->{$_} ? "'$f->{$_}'":"<undef>") } keys %$f; $self->saveeditform($page, $f);
}
package main;
use strict; use warnings; use IO::File; $|=1; my $m= MediaWiki->new();
if (@ARGV%2) {
die "expected an even nr of params\n";
} my $config= readconfig(); $m->login($config->{user}, $config->{pass});
for (my $i=0 ; $i<@ARGV ; $i+=2) {
if (!-f $ARGV[$i]) { die "file $ARGV[$i] not found\n"; } $m->uploadfile($ARGV[$i], $ARGV[$i+1]);
} sub readconfig {
my %params; my $fh= IO::File->new("c:/local/etc/wiki.cfg", "r") or die "wiki.cfg: $!"; while (<$fh>) { s/\s+$//; if (/(\w+)\s*=\s*(.*)/) { my ($k, $v)= ($1, $2); $params{$k}= $v; } } $fh->close(); return \%params;
} </source>