1#!/usr/bin/perl -w
2#
3# This file is part of the LibreOffice project.
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, You can obtain one at http://mozilla.org/MPL/2.0/.
8#
9
10use MediaWiki::API;
11use File::Find();
12use File::Slurp;
13use Getopt::Std;
14use Digest::SHA1 qw(sha1 sha1_hex sha1_base64);
15
16# help
17sub usage {
18    print <<EOM;
19upload-wiki.pl [...] - Uploads the wiki/ subdir to a real wiki installation.
20
21  -i - Upload also the images
22  -p - Don't upload the pages themselves
23  -r - Upload also the redirects
24
25You need a wikisetup.txt in this directory, to be able to authenticate you.
26The content should be:
27
28wiki=<url of the api.php on the wiki>
29upload=<url of the Special:Upload page>
30name=<the user name>
31password=<the appropriate password>
32
33upload-wiki.pl operates on the output of help-to-wiki.py, needing particularly
34these:
35
36wiki/      - directory with all the pages generated out of the help .xhp files
37images.txt - list of the images used in help
38
39Additionally you need:
40
41images/    - directory with an unpack of images_tango.zip
42
43EOM
44    exit 1;
45}
46
47%options = ();
48getopts( "hipr", \%options );
49
50usage() if ( defined $options{h} );
51
52my $upload_images = 0;
53my $upload_pages = 1;
54my $upload_redirects = 0;
55$upload_images = 1 if ( defined $options{i} );
56$upload_pages = 0 if ( defined $options{p} );
57$upload_redirects = 1 if ( defined $options{r} );
58
59# first of all, read the configuration from wikisetup.txt
60my ( $url, $upload_url, $name, $password );
61if ( ! open( IN, "wikisetup.txt" ) ) {
62    print "Missing wikisetup.txt\n\n";
63    usage();
64}
65while ( my $line = <IN> ) {
66    if ( $line =~ /^([^=]*)=(.*)$/ ) {
67        my $k = $1;
68        my $v = $2;
69        chomp $k;
70        chomp $v;
71        if ( $k eq 'wiki' ) {
72            $url = $v;
73        }
74        elsif ( $k eq 'upload' ) {
75            $upload_url = $v;
76        }
77        elsif ( $k eq 'name' ) {
78            $name = $v;
79        }
80        elsif ( $k eq 'password' ) {
81            $password = $v;
82        }
83    }
84}
85close( IN );
86
87if ( !defined( $url ) || !defined( $upload_url ) || !defined( $name ) || !defined( $password ) ) {
88    print "wikisetup.txt does not contain all the info.\n\n";
89    usage();
90}
91
92if ( ! -d 'wiki' ) {
93    print "Missing the wiki/ subdir, re-run help-to-wiki.py.\n\n";
94    usage();
95}
96
97if ( $upload_images ) {
98    if ( ! -f 'images.txt' ) {
99        print "Missing images.txt, re-run help-to-wiki.py.\n\n";
100        usage();
101    }
102
103    if ( ! -d 'images' ) {
104        print "Missing images/ subdir - mkdir images ; cd images ; unzip /path/to/images_tango.zip\n\n";
105        usage();
106    }
107}
108
109$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME}=0;
110
111# initialize the wiki
112my $mw = MediaWiki::API->new();
113$mw->{config}->{api_url} = $url;
114$mw->{config}->{upload_url} = $upload_url;
115
116# log in to the wiki
117$mw->login( { lgname => $name, lgpassword => $password } ) || die $mw->{error}->{code} . ': ' . $mw->{error}->{details};
118
119# upload the articles
120sub upload_article {
121    -f || return;
122
123    my $pagename = $File::Find::name;
124    $pagename =~ s/^wiki\///;
125    $pagename =~ s/\/MAIN$//;
126    $pagename =~ s/%2F/\//g;
127
128    # pages starting with lowercase 's' are redirects
129    if ( $pagename =~ /^s/ ) {
130        return if ( !$upload_redirects );
131    }
132    else {
133        return if ( !$upload_pages );
134    }
135
136    my $text = read_file( $_ );
137
138    RETRY:
139    print "Uploading page '$pagename'\n";
140    unless ( $mw->edit( {
141            action => 'edit',
142            title => $pagename,
143            text => $text }, { skip_encoding => 1 } ) )
144    {
145        print 'Error: ' . $mw->{error}->{code} . ': ' . $mw->{error}->{details} . "\n";
146        print "Waiting for 10 seconds...\n";
147        sleep 10;
148        print "Retry!\n";
149        goto RETRY;
150    }
151}
152File::Find::find( {wanted => \&upload_article}, 'wiki/' );
153
154# upload the images
155if ( $upload_images ) {
156    open( IN, "images.txt" ) || usage();
157    my $imagename = '';
158    my $imageuploadmsg = '';
159    my $image = '';
160    while ( my $line = <IN> ) {
161        chomp( $line );
162        my $fname = "images/$line";
163        if ( ! -f $fname ) {
164            print "Image '$fname' not found, skipped.\n";
165            next;
166        }
167        if ( ! $fname =~ /\.(png|gif|jpg|jpeg)$/ ) {
168            print "Image '$line' ignored, not a jpg/png/gif.\n";
169            next;
170        }
171
172        $imagename = $line;
173        if ( $line =~ /\/([^\/]*)$/ ) {
174            $imagename = $1;
175        }
176        sub upload_file_to_mw {
177            $mw->upload( {
178                title => 'File:'.$imagename,
179                summary => $imageuploadmsg,
180                data => $image } ) || die $mw->{error}->{code} . ': ' . $mw->{error}->{details};
181        }
182
183        $image = read_file( $fname );
184
185        # don't reupload an image if it is already present - otherwise it only bloats the wiki
186        my $imagesha1 = sha1_hex($image);
187        # get the sha1 request directly from the wiki
188        my $mwquery = $mw->api( {
189            action => 'query',
190            prop => 'imageinfo',
191            iiprop => 'sha1',
192            titles => 'File:'.$imagename } );
193        my $mwimagesha1 = "";
194        #FIXME: bad style, this foreach should consist only ONE imageid --> do that nicelier
195        foreach my $imageid (keys $mwquery->{'query'}{'pages'}) {
196            $mwimagesha1 = $mwquery->{'query'}{'pages'}{$imageid}{'imageinfo'}->[0]->{'sha1'};
197        }
198
199        if (($imagesha1 ne $mwimagesha1) and ($mwimagesha1 ne '')) {
200            print "Updating image '$imagename', sha1 is different from already uploaded image.\n";
201            $imageuploadmsg = 'Updating image.';
202            upload_file_to_mw();
203        } elsif ($mwimagesha1 eq '') {
204            print "Initial upload of  image '$imagename'\n";
205            $imageuploadmsg = 'Initial upload.';
206            upload_file_to_mw();
207        } else {
208            print "Skipping image '$imagename', sha1 identically to already uploaded image.\n";
209        }
210    }
211}
212
213# clean up
214$mw->logout();
215
216# vim:set shiftwidth=4 softtabstop=4 expandtab:
217