Attachments Checker

Last modified by Ecaterina Moraru (Valica) on 2021/03/18 11:28

cogChecks the declared sizes of the attachments in the database and compares them with the actual loadable attachments.
Type
Category
Developed by

Anca Luca, Guillaume Delhumeau

Rating
3 Votes
LicenseGNU Lesser General Public License 2.1

Table of contents

Description

This snippet was tested on XWiki version 5.4.7, on mysql database.

It works on multiple wikis (need to be installed on the main wiki) and it should work properly for file system attachments as well, as it tests by fetching the attachment content using the attachments API of the document.

For the cases when there are too many attachments to check, the page showing the results for this script can timeout in the browser. In that case, follow the execution in the logs of the server (e.g. catalina.out).

The script will log on INFO level all the verifications it does, and on WARN level all invalid attachments that it finds (you can grep the logs based on this to filter the output).

{{toc /}}

{{html clean='false'}}
<script type='text/javascript'>
function registerCheckboxSelectionListener(){
 $('selector').observe('click', function(){
   $('prepareform').select('.toggleable').each(function(item) {
     if (item.checked){
        item.checked=false;
      } else {
        item.checked=true;
      }
    });
  });
}

Event.observe(document, 'xwiki:dom:loaded', function() {
  registerCheckboxSelectionListener();
});
</script>
{{/html}}

{{groovy}}
import java.util.Collections;
import org.xwiki.wiki.descriptor.WikiDescriptor;

def wikis = request.getParameterValues('wikis');
def logger = org.slf4j.LoggerFactory.getLogger(doc.fullName);
services.logging.setLevel(doc.fullName, org.xwiki.logging.LogLevel.INFO);
if (wikis == null || wikis.size() == 0) {
 def allWikis = services.wiki.getAll();
 int aThirdOfWikis = Math.floor(allWikis.size() / 3);
 int twoThirdsOfWikis = aThirdOfWikis * 2;
  println "Compares the length of the content of attachments it loads for documents with the filesize stored in the database. For uncorrupted attachments, the 2 should be identical."
  println """{{html clean='false' wiki='false'}}
  <form id='prepareform' class='xform' method='post' action=''>
  <dl>
  <dt><label>Wikis:</label><dt>
  <dd>
  <div class='column third'>
  <ul>
  <li><input id='selector' type='checkbox' value='' /><strong>Select/Deselect all</strong></li>"""
;
  Collections.sort(allWikis, new Comparator<WikiDescriptor> () {
   int compare(WikiDescriptor w1, WikiDescriptor w2) {
     return w1.getId().compareTo(w2.getId());
    }

    boolean equals(WikiDescriptor w1, WikiDescriptor w2) {
     return w1.getId().equals(w2.getId());
    }
  });
 for (int i = 0; i < allWikis.size(); i++) {
   def w = allWikis.get(i);
    println "<li><input name='wikis' type='checkbox' value='" + w.getId() + "' class='toggleable'>" + w.getId() + "</input></li>";
   if (i == aThirdOfWikis || i == twoThirdsOfWikis) {
      println """</ul></div>
                 <div class='column third'><ul>"""
;
    }
  }
  println """</ul>
  </dd></dl>
  <div class='clearfloats'></div>
  <div class='buttonwrapper'><input class='button' type='submit' name='check' value='Check' /></div>
  </form>
  {{/html}}"""
;
} else {
    wikis.each{
   def db = it;
    println "== ${db} ==";
   def hql = "SELECT doc.fullName, att.filename FROM XWikiDocument doc, XWikiAttachment att WHERE doc.id = att.docId ORDER BY doc.id";
   def rows = services.query.hql(hql).setWiki(db).execute();
   int totalAttNo = rows.size();
    println "Total attachments: " + totalAttNo;
    logger.info("Wiki " + db + "Total attachments: " + totalAttNo);
   int no = 0;
    rows.each{
     def r = it;
      logger.info("Wiki " + db + " Checking attachment " + (++no) + "/" + totalAttNo + ": " + r[0] + "@" + r[1]);
     def document = xwiki.getDocument("${db}:${r[0]}");
     def att = document.getAttachment(r[1]);
     def valid = "undefined";
     try{
       def content = att.getContent()
        valid = "valid";
       if(content.length != att.getFilesize())
          valid = " not valid - wrong size";
      }catch(Exception e){
        valid = "**unvalid (exception " + e.getMessage() + ")**";
        e.printStackTrace();
      }
     if(valid != "valid") {
        println "* [[${r[0]}>>path:"+document.getURL('view','#Attachments')+"]] - [[${r[1]}>>path:" + xwiki.getAttachmentURL("${db}:${r[0]}",r[1])+"]] " + valid;
        logger.warn("Wiki " + db + " Attachment "+ r[0] + "@" + r[1] + " is invalid: " + valid);
      }
    }
  }
}
{{/groovy}}

Get Connected