Large Wiki Export 2

Last modified by Ludovic Dubost on 2026/06/02 17:54

cogScript allowing a large Wiki export with failsafe mecanism
Type
Category
Developed by

Ludovic Dubost

Rating
0 Votes
LicenseGNU Lesser General Public License 2.1

Table of contents

Description

This code will use the XWiki standard export API including versioning but running it page by page and saving each file as an individual file on disk.

It also includes some failsafe mecanism:

  • It continues in case of exception for one specific page
  • It will not retry exporting if the file already exists on disk, thus allowing to restart in case of failure (after Wiki crash) or run in multiple batches
  • It logs in the app server log in case of timeout if the export process is too long

You can specific a maximum number of pages to include in the export (this allows to test for 10 pages and/or run in multiple steps by increasing the number progressively)

An alternate version using the filter streams API has also been published.

This export has been tested in a 7.4 XWiki

{{groovy}}

import com.xpn.xwiki.*;
import com.xpn.xwiki.doc.*;
import com.xpn.xwiki.plugin.packaging.*;
import java.util.zip.*;
import com.xpn.xwiki.util.Util;

def getXAR(String filename, XWikiContext context, nb) { 
    def request = xcontext.getRequest();
    def count = 0;
    def fail = 0;
    def fdir = new File(filename)
    query = services.query.xwql('where 1=1').setLimit(nb)
    def list = query.execute()
    System.out.println("Exporting ${list.size()} pages");
        for(docName in list){
            count++;
            try { 
              println "* Exporting ${count} ${docName}"
              System.out.println("Exporting ${count} ${docName}")
              def docName2 = docName
              docName2 = docName2.replaceAll("\\.","/")
              def docFile = new File(fdir, docName2 + ".xml")
              System.out.println(docFile)
              if (!docFile.exists()) { 
                def export = xcontext.getXWiki().getPluginApi("package", xcontext.getContext());
                export.setWithVersions(true);
                export.setAuthorName("XWiki.Admin");
                export.setDescription("");
                export.setLicence("");
                export.setVersion("");
                export.setBackupPack(true);
                export.setName("backup");
                def pack = export.getPackage();
                pack.add(docName, com.xpn.xwiki.plugin.packaging.DocumentInfo.ACTION_OVERWRITE, xcontext.getContext());
                pack.exportToDir(fdir, xcontext.getContext());
                println "* Exported ${count} ${docName}"
                System.out.println("Exported ${count} ${docName}")
              } else {
                println "* Already exported ${count} ${docName}"
                System.out.println("Already exported ${count} ${docName}")
              }
            } catch (e) {
              fail++;
              println "* Failed to export ${count} ${docName}."
              System.out.println("Failed to export ${count} ${docName}")
              e.printStackTrace()
              System.out.println("${fail} failed documents")
            } 
        }
        System.out.println("${count} exported documents")
        System.out.println("${fail} failed documents")
}

if (request.filename) {
 def nb = 200
 if (request.nb)
  nb = Integer.parseInt(request.nb)
 getXAR(request.filename,xcontext.getContext(), nb)
 println "{{success}}Export is now finished. Check in the logs for any error{{/success}}"
} else {
 println "== Large Export =="
}
{{/groovy}}


 {{html clean="false" wiki="true"}}
 <form action="" method="post">
 <table border="0">
 <tr>
 <td>File/directory to write to:</td><td><input type="text" name="filename" size="60" /></td>
 </tr>
 <tr>
 <td>Nb:</td><td><input type="text" name="nb" size="10" value="200" /></td>
 </tr>
 </table>
 <input type="submit" name="Export" />
 </form>
 {{/html}}

Get Connected