add -p: adjust offsets of subsequent hunks when one is skipped
[gitweb.git] / contrib / mw-to-git / git-remote-mediawiki.perl
index c9a4805ec1f0d5767af7a5f27428db5a02fa94a1..af9cbc9d0f7bc296ec728c3b965c26a057c8cf72 100755 (executable)
 my @tracked_categories = split(/[ \n]/, run_git("config --get-all remote.${remotename}.categories"));
 chomp(@tracked_categories);
 
+# Just like @tracked_categories, but for MediaWiki namespaces.
+my @tracked_namespaces = split(/[ \n]/, run_git("config --get-all remote.${remotename}.namespaces"));
+for (@tracked_namespaces) { s/_/ /g; }
+chomp(@tracked_namespaces);
+
 # Import media files on pull
 my $import_media = run_git("config --get --bool remote.${remotename}.mediaimport");
 chomp($import_media);
@@ -256,6 +261,32 @@ sub get_mw_tracked_categories {
        return;
 }
 
+sub get_mw_tracked_namespaces {
+    my $pages = shift;
+    foreach my $local_namespace (sort @tracked_namespaces) {
+        my $namespace_id;
+        if ($local_namespace eq "(Main)") {
+            $namespace_id = 0;
+        } else {
+            $namespace_id = get_mw_namespace_id($local_namespace);
+        }
+        # virtual namespaces don't support allpages
+        next if !defined($namespace_id) || $namespace_id < 0;
+        my $mw_pages = $mediawiki->list( {
+            action => 'query',
+            list => 'allpages',
+            apnamespace => $namespace_id,
+            aplimit => 'max' } )
+            || die $mediawiki->{error}->{code} . ': '
+                . $mediawiki->{error}->{details} . "\n";
+        print {*STDERR} "$#{$mw_pages} found in namespace $local_namespace ($namespace_id)\n";
+        foreach my $page (@{$mw_pages}) {
+            $pages->{$page->{title}} = $page;
+        }
+    }
+    return;
+}
+
 sub get_mw_all_pages {
        my $pages = shift;
        # No user-provided list, get the list of pages from the API.
@@ -319,6 +350,10 @@ sub get_mw_pages {
                $user_defined = 1;
                get_mw_tracked_categories(\%pages);
        }
+       if (@tracked_namespaces) {
+               $user_defined = 1;
+               get_mw_tracked_namespaces(\%pages);
+       }
        if (!$user_defined) {
                get_mw_all_pages(\%pages);
        }
@@ -461,7 +496,12 @@ sub download_mw_mediafile {
 
        my $response = $mediawiki->{ua}->get($download_url);
        if ($response->code == HTTP_CODE_OK) {
-               return $response->decoded_content;
+               # It is tempting to return
+               # $response->decoded_content({charset => "none"}), but
+               # when doing so, utf8::downgrade($content) fails with
+               # "Wide character in subroutine entry".
+               $response->decode();
+               return $response->content();
        } else {
                print {*STDERR} "Error downloading mediafile from :\n";
                print {*STDERR} "URL: ${download_url}\n";
@@ -625,6 +665,9 @@ sub fetch_mw_revisions_for_page {
                rvstartid => $fetch_from,
                rvlimit => 500,
                pageids => $id,
+
+               # Let MediaWiki know that we support the latest API.
+               continue => '',
        };
 
        my $revnum = 0;
@@ -640,8 +683,15 @@ sub fetch_mw_revisions_for_page {
                        push(@page_revs, $page_rev_ids);
                        $revnum++;
                }
-               last if (!$result->{'query-continue'});
-               $query->{rvstartid} = $result->{'query-continue'}->{revisions}->{rvstartid};
+
+               if ($result->{'query-continue'}) { # For legacy APIs
+                       $query->{rvstartid} = $result->{'query-continue'}->{revisions}->{rvstartid};
+               } elsif ($result->{continue}) { # For newer APIs
+                       $query->{rvstartid} = $result->{continue}->{rvcontinue};
+                       $query->{continue} = $result->{continue}->{continue};
+               } else {
+                       last;
+               }
        }
        if ($shallow_import && @page_revs) {
                print {*STDERR} "  Found 1 revision (shallow import).\n";
@@ -842,7 +892,7 @@ sub mw_import_revids {
 
        my $n = 0;
        my $n_actual = 0;
-       my $last_timestamp = 0; # Placeholer in case $rev->timestamp is undefined
+       my $last_timestamp = 0; # Placeholder in case $rev->timestamp is undefined
 
        foreach my $pagerevid (@{$revision_ids}) {
                # Count page even if we skip it, since we display
@@ -948,7 +998,7 @@ sub mw_upload_file {
                print {*STDERR} "Check the configuration of file uploads in your mediawiki.\n";
                return $newrevid;
        }
-       # Deleting and uploading a file requires a priviledged user
+       # Deleting and uploading a file requires a privileged user
        if ($file_deleted) {
                $mediawiki = connect_maybe($mediawiki, $remotename, $url);
                my $query = {
@@ -1293,7 +1343,8 @@ sub get_mw_namespace_id {
        my $id;
 
        if (!defined $ns) {
-               print {*STDERR} "No such namespace ${name} on MediaWiki.\n";
+               my @namespaces = map { s/ /_/g; $_; } sort keys %namespace_id;
+               print {*STDERR} "No such namespace ${name} on MediaWiki, known namespaces: @namespaces\n";
                $ns = {is_namespace => 0};
                $namespace_id{$name} = $ns;
        }
@@ -1305,7 +1356,7 @@ sub get_mw_namespace_id {
        # Store "notANameSpace" as special value for inexisting namespaces
        my $store_id = ($id || 'notANameSpace');
 
-       # Store explicitely requested namespaces on disk
+       # Store explicitly requested namespaces on disk
        if (!exists $cached_mw_namespace_id{$name}) {
                run_git(qq(config --add remote.${remotename}.namespaceCache "${name}:${store_id}"));
                $cached_mw_namespace_id{$name} = 1;