2

I'm trying to upload an image to the mediawiki using the Mediawiki::API->upload. To do so, i'm using this code:

use strict;
use MediaWiki::API;
use DateTime::Format::ISO8601;
use encoding 'utf8';
binmode STDERR, ":utf8"; 
use URI::Escape;
use warnings;
use MediaWiki::API;

 my $url="http://localhost/mediawiki";
 my $wiki_login="nguyenki";
 my $wiki_passwd="linh";
 my $wiki_domain="";
 chomp($wiki_login);
 chomp($wiki_passwd);
 chomp($wiki_domain);
 my $mediawiki;
 mw_connect_maybe();  
 # configure the special upload location.
 $mediawiki->{config}->{upload_url} = "$url/index.php/Special:Upload";

 my $name="fl.png"; # Name of fichier to upload

  # upload a file to MediaWiki
  open (my $toi, $name) or die "can't open UTF-8 encoded filename: $!";
  binmode $toi;
  my ($buffer, $data);
  while (my $n=read($toi, $buffer, 65536) )  {
    $data .= $buffer;
    print STDERR "$n bytes read\n";
  }
  close($toi);

  $mediawiki->upload( { title => $name,
                 summary => 'This is the summary to go on the Image:file.jpg page',
                 data => $data } ) || die $mediawiki->{error}->{code} . ': ' . $mediawiki->{error}->{details};


#To login to the wiki page
sub mw_connect_maybe {

    if ($mediawiki) {
        return;
    }
    $mediawiki = MediaWiki::API->new;
    $mediawiki->{config}->{api_url} = "$url/api.php";

    if ($wiki_login) {
        if (!$mediawiki->login({
            lgname => $wiki_login,
            lgpassword => $wiki_passwd,
            lgdomain => $wiki_domain,
        })) {
            print STDERR "Failed to log in mediawiki user \"$wiki_login\" on $url\n";
            print STDERR "(error " .
                $mediawiki->{error}->{code} . ': ' .
                $mediawiki->{error}->{details} . ")\n";
            exit 1;
        } else {
            print STDERR "Logged in with user \"$wiki_login\".\n";
        }
    }
}

And it generated an error: HTTP::Message content must be bytes at /usr/share/perl5/HTTP/Request/Common.pm line 91 I don't know how to correct it. Any suggestion?

Thank.

Christian
  • 1,830
  • 15
  • 26
nguyenki
  • 21
  • 2
  • Works for me, show your whole code. – daxim May 27 '12 at 14:31
  • Do you know something about the git-remote-mediawiki? I'm trying to to upload a file via the Mediawiki::API. The part that i didn't show is the part to create the instance of mediawiki and the login . I can just upload the text file but not with the .png or .jpg or .doc... Is there any problem with the version of perl? – nguyenki May 27 '12 at 16:53
  • I know nothing about git-remote-mediawiki. I have uploaded a file with MediaWiki::API. [Show your whole code](http://sscce.org) and the file you attempt to upload, else it is impossible to [reproduce your problem](http://www.chiark.greenend.org.uk/~sgtatham/bugs.html#showmehow). – daxim May 28 '12 at 12:20
  • Now i can upload the text file, but not the .png or .jpg. It generate always the error: Logged in with user "nguyenki". 44906 bytes read HTTP::Message content must be bytes at /usr/share/perl5/HTTP/Request/Common.pm line 91 – nguyenki May 28 '12 at 14:05
  • Sorry, i can't upload the file "fl.png" here because i'm just a newbie in this forum. – nguyenki May 28 '12 at 14:14
  • Hey, i can upload the file .png and .jpg now. Just delete the line: use encoding 'utf8'; Do you know how to delete the upload files via the mediawiki API? – nguyenki May 28 '12 at 14:33

2 Answers2

0

The pragma encoding breaks your code, remove it.

Community
  • 1
  • 1
daxim
  • 39,270
  • 4
  • 65
  • 132
0

Mediawiki::API has a bug. well, probably a few bugs, but at least this one (or that one?): it hasn't been ported to the 1.22+ CSRF protection login system. To login to a MediaWiki site now, you need to do it in two steps: first get a token, then use that token to login. This is to protect poor web browser users, but unfortunately that means more pain for us bot writers.

The MediaWiki::Bot project suffered from the same issue, and solved it with this commit, which is a great example of how to fix your code. I was able to build a simple working login script bypassing the builtin MediaWiki::API login mechanism with this:

#!/usr/bin/perl -w

use MediaWiki::API;

my $wiki = MediaWiki::API->new;
my $remote_url = 'http://localhost:1234/wiki';
my $username = 'WikiAdmin';
my $password = 'AdminPass';
my $wiki_domain = 'localhost';

$wiki->{config}->{api_url} = "${remote_url}/api.php";

print "getting a CSRF token\n";
my $query = {action => 'query',
             meta => 'tokens',
             type => 'login'};
my $ref = $wiki->api( $query );
my $token;
if ($ref) {
    $token = $ref->{query}->{tokens}->{logintoken};
} else {
    print 'failed: (error ' . $wiki->{error}->{code} . ': ' .
                    $wiki->{error}->{details} . ")\n";
}

$query = {action => 'login',
          lgtoken => $token,
          lgname => $username,
          lgpassword => $password,
          lgdomain => $wiki_domain,
};
$ref = $wiki->api( $query );
if ($ref && $ref->{login}->{result} eq "Success") {
    print "login worked\n";
} else {
    print 'failed: (error ' . $wiki->{error}->{code} . ': ' .
                    $wiki->{error}->{details} . ")\n";
}

Obviously, this should be patched upstream, but hopefully it should get you going.

anarcat
  • 5,605
  • 4
  • 32
  • 38