Como adicionar conteúdo a todas as páginas em um mediawiki?

3

TL; DR: Como faço para adicionar um texto (aviso) ao conteúdo (não um cabeçalho ou modelo global) de todas as páginas?

(muito) longa pergunta com histórico: Estou planejando migrar um MediaWiki para outro wiki. O conteúdo do wiki foi migrado de um wiki ainda mais antigo antes (onde erros de formatação foram gerados), cresceu ao longo do tempo e agora está desatualizado em grandes partes. É por isso que queremos começar com um wiki em branco e migrar o conteúdo manualmente, descartando e / ou atualizando páginas desatualizadas.

Para facilitar, quero adicionar um bloco de texto ao topo de cada página existente, especificamente um modelo com um aviso de que esta página ainda não foi migrada ou descartada e uma categoria em que todas essas páginas foram coletadas (por exemplo, categoria : migration_pending). Cada usuário deve, então, examinar as páginas pelas quais é responsável, copiar o conteúdo para o novo wiki e alterar o modelo para outro marcando a página como migrado (category: migration_done) ou descartado (category: migration_discarded). Desta forma, deve ser possível obter um wiki limpo e atualizado sem esquecer nada importante.

    
por Gerald Schneider 04.07.2013 / 11:54

1 resposta

0

A extensão Replace_Text não teve sucesso, então terminei de escrever meu próprio script que usa a API MediaWiki.

Comecei com o loginscript aqui e escrevi este script:

#!/usr/bin/php
<?php

$settings['wikiroot'] = "https://server/mediawiki";
$settings['user'] =  "username";
$settings['pass'] =  "password";
// $settings['domain'] = 'Windows';
$settings['cookiefile'] = "cookies.tmp";

$prepend = "{{migration_pending}}\n\n";


function httpRequest($url, $post="") {
        global $settings;

        $ch = curl_init();
        //Change the user agent below suitably
        curl_setopt($ch, CURLOPT_USERAGENT, 'MediaWiki Migration Script 0.1');
        curl_setopt($ch, CURLOPT_URL, ($url));
        curl_setopt($ch, CURLOPT_ENCODING, "UTF-8" );
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_COOKIEFILE, $settings['cookiefile']);
        curl_setopt($ch, CURLOPT_COOKIEJAR, $settings['cookiefile']);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        if (!empty($post)) curl_setopt($ch,CURLOPT_POSTFIELDS,$post);
        //UNCOMMENT TO DEBUG TO output.tmp
        //curl_setopt($ch, CURLOPT_VERBOSE, true); // Display communication with server
        //$fp = fopen("output.tmp", "w");
        //curl_setopt($ch, CURLOPT_STDERR, $fp); // Display communication with server

        $xml = curl_exec($ch);

        if (!$xml) {
                throw new Exception("Error getting data from server ($url): " . curl_error($ch));
        }

        //var_dump($xml);

        curl_close($ch);

        return $xml;
}


function login ($user, $pass, $token='') {
        global $settings;

        $url = $settings['wikiroot'] . "/api.php?action=login&format=xml";

        $params = "action=login&lgname=$user&lgpassword=$pass";
        if (!empty($settings['domain'])) {
            $params .= "&lgdomain=" . $settings['domain'];
        }
        if (!empty($token)) {
                $params .= "&lgtoken=$token";
        }

        $data = httpRequest($url, $params);

        if (empty($data)) {
                throw new Exception("No data received from server. Check that API is enabled.");
        }

        $xml = simplexml_load_string($data);

        if (!empty($token)) {
                //Check for successful login
                $expr = "/api/login[@result='Success']";
                $result = $xml->xpath($expr);

                if(!count($result)) {
                        throw new Exception("Login failed");
                }
        } else {
                $expr = "/api/login[@token]";
                $result = $xml->xpath($expr);

                if(!count($result)) {
                        throw new Exception("Login token not found in XML");
                }
        }

        return $result[0]->attributes()->token;
}


try {
        global $settings;
        $token = login($settings['user'], $settings['pass']);
        login($settings['user'], $settings['pass'], $token);

        $star = "*";
        $dash1 = "-1";

        // get edit token
        $result = httpRequest($settings['wikiroot'] . "/api.php?action=query&format=json&prop=info|revisions&intoken=edit&titles=Main%20Page");
        $result = json_decode($result);
        $editToken = $result->query->pages->$dash1->edittoken;

        // only from namespace: apnamespace=100
        $result = httpRequest($settings['wikiroot'] . "/api.php?action=query&list=allpages&format=json&aplimit=5000&apnamespace=100");
        $result = json_decode($result);
        $allpages = $result->query->allpages;

        foreach ($allpages as $page) {
            echo "Fetching '{$page->title}' ({$page->pageid})...\n";
            $revisions = httpRequest(sprintf($settings['wikiroot'] . "/api.php?action=query&prop=revisions&rvlimit=1&format=json&rvprop=content&titles=%s", urlencode($page->title)));
            $revisions = json_decode($revisions);
            if (isset($revisions->error)) {
                echo "ERROR: " . $revisions->error->info . "\n";
                continue;
            }
            $content = $revisions->query->pages->{$page->pageid}->revisions[0]->$star;
            if (preg_match("/\{\{migration_/", $content)) {
                echo "Already marked ... skipping.\n";
                continue;
            }
            echo "Updating...";
            // add text to content and edit page
            $content = $prepend . $content;
            $post = sprintf("title=%s&text=%s&token=%s", urlencode($page->title), urlencode($content), urlencode($editToken));
            $result = httpRequest($settings['wikiroot'] . "/api.php?action=edit&format=json", $post);
            echo "done\n";
        }
        echo ("Finished (".sizeof($allpages)." pages).\n");
} catch (Exception $e) {
        die("FAILED: " . $e->getMessage());
}

?>

O que o script basicamente faz é:

  • Fazer login com uma conta existente
  • obtenha um token que permita fazer operações de edição
  • recupera uma lista de todas as páginas dentro de um determinado namespace
  • para todas as páginas:
    • obtenha o conteúdo da última revisão
    • adicione um texto predefinido ao conteúdo
    • salve a página com o novo conteúdo

Algumas notas adicionais:

  • Certifique-se de que o usuário que você deseja usar exista e tenha acesso de gravação a todos os namespaces necessários.
  • Adicione o usuário ao grupo "Bot". Isso removerá algumas restrições, por exemplo, um bot pode fazer operações em massa em grupos de 5000, em vez de 500, como um usuário normal. Não tenho certeza se é necessário para este script, mas não pode prejudicar.
  • Quando uma extensão de autenticação como LdapAuthentication está em uso, o parâmetro domain precisa ser definido. E tem que ser definido para o nome da origem do LDAP como é configurado em LocalSettings.php , não o nome real do domínio.
  • Desative as notificações por e-mail antes de executar o script. Caso contrário, todos que assistem a páginas no wiki receberão notificações para cada página alterada que ele estiver assistindo. Para mim isso foi $wgEnableEmail = false; e $wgEnotifWatchlist = false; in LocalSettings.php .
  • Eu corri o script pela linha de comando, não é rápido e leva alguns minutos para mais de 1000 páginas. Ele definitivamente seria executado em um tempo limite se eu o executasse no servidor da Web.

Por último, mas não menos importante, o modelo migration_pending I foi adicionado ao MediaWiki:

{|class=warningbox
 | [[Image:Emblem-important.png]]
 | This page hasn't been audited yet, the information on it could be outdated. If you are responsible for this page, please check it's content. If it is still current, add it to the new wiki and change this template to <nowiki>{{Migration_done}}</nowiki>. If the information on this page is not needed anymore change the template to <nowiki>{{Migration_discarded}}</nowiki>
 |}

[[Category:MigrationPending]]

Isso usa uma classe CSS para as tabelas que usamos antes e adiciona a página a uma categoria específica. Eu adicionei modelos semelhantes como migration_done e migration_discarded com as categorias correspondentes.

    
por 12.03.2014 / 15:16