/*
* WPCleaner: A tool to help on Wikipedia maintenance tasks.
* Copyright (C) 2013 Nicolas Vervelle
*
* See README.txt file for licensing information.
*/
package org.wikipediacleaner.gui.swing.bot;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import org.wikipediacleaner.api.API;
import org.wikipediacleaner.api.APIException;
import org.wikipediacleaner.api.APIFactory;
import org.wikipediacleaner.api.MediaWiki;
import org.wikipediacleaner.api.check.CheckError;
import org.wikipediacleaner.api.check.CheckErrorPage;
import org.wikipediacleaner.api.check.CheckWiki;
import org.wikipediacleaner.api.check.algorithm.CheckErrorAlgorithm;
import org.wikipediacleaner.api.check.algorithm.CheckErrorAlgorithms;
import org.wikipediacleaner.api.constants.CWConfigurationError;
import org.wikipediacleaner.api.constants.EnumWikipedia;
import org.wikipediacleaner.api.constants.WPCConfigurationString;
import org.wikipediacleaner.api.data.DataManager;
import org.wikipediacleaner.api.data.Page;
import org.wikipediacleaner.api.data.PageAnalysis;
import org.wikipediacleaner.api.data.PageElementInternalLink;
import org.wikipediacleaner.gui.swing.InformationWindow;
import org.wikipediacleaner.gui.swing.basic.BasicWindow;
import org.wikipediacleaner.gui.swing.basic.BasicWorker;
import org.wikipediacleaner.i18n.GT;
/**
* SwingWorker for checking white lists for Check Wiki.
*/
class CWCheckWhiteListsWorker extends BasicWorker {
/**
* @param wiki Wiki.
* @param window Window.
*/
public CWCheckWhiteListsWorker(
EnumWikipedia wiki, BasicWindow window) {
super(wiki, window);
}
/**
* Compute the value to be returned by the <code>get</code> method.
*
* @return Object returned by the <code>get</code> method.
* @see org.wikipediacleaner.gui.swing.basic.BasicWorker#construct()
*/
@Override
public Object construct() {
try {
CheckWiki checkWiki = APIFactory.getCheckWiki();
MediaWiki mw = MediaWiki.getMediaWikiAccess(this);
API api = APIFactory.getAPI();
EnumWikipedia wiki = getWikipedia();
StringBuilder result = new StringBuilder();
StringBuilder details = new StringBuilder();
List<CheckErrorAlgorithm> algorithms = CheckErrorAlgorithms.getAlgorithms(wiki);
for (CheckErrorAlgorithm algorithm : algorithms) {
int errorNumber = algorithm.getErrorNumber();
if (algorithm.isAvailable() &&
CheckErrorAlgorithms.isAlgorithmActive(wiki, errorNumber)) {
setText(GT._("Checking whitelist for error {0}", String.valueOf(errorNumber)));
CWConfigurationError cwConfig = wiki.getCWConfiguration().getErrorConfiguration(errorNumber);
Set<String> whiteList = cwConfig.getWhiteList();
if (whiteList != null) {
List<Page> unnecessaryPages = new ArrayList<>();
details.setLength(0);
if (whiteList.size() > 0) {
// Prepare list of pages to check
List<Page> pages = new ArrayList<>(whiteList.size());
for (String pageName : whiteList) {
Page page = DataManager.getPage(wiki, pageName, null, null, null);
pages.add(page);
}
Collections.sort(pages);
mw.retrieveContents(wiki, pages, true, false, false, false);
// Check each page
for (Page page : pages) {
if (Boolean.FALSE.equals(page.isExisting())) {
details.append("<li>");
details.append(GT._("The page {0} doesn''t exist on Wikipedia", page.getTitle()));
details.append("</li>");
unnecessaryPages.add(page);
} else {
CheckErrorPage errorPage = CheckError.analyzeError(
algorithm, page.getAnalysis(page.getContents(), true));
if ((errorPage == null) || (!errorPage.getErrorFound())) {
details.append("<li>");
String pageLink =
"<a href=\"" +
wiki.getSettings().getURL(page.getTitle(), false, true) +
"\">" +
page.getTitle() +
"</a>";
details.append(GT._("The error hasn''t been detected in page {0}.", pageLink));
Boolean errorDetected = checkWiki.isErrorDetected(page, errorNumber);
if (errorDetected != null) {
details.append(" ");
if (Boolean.TRUE.equals(errorDetected)) {
details.append(GT._("It's still being detected by CheckWiki."));
} else {
details.append(GT._("It's not detected either by CheckWiki."));
unnecessaryPages.add(page);
}
}
details.append("</li>");
}
}
}
}
// Take results into account
if (details.length() > 0) {
// Establish a report
String pageLink = String.valueOf(errorNumber);
String whiteListPageName = cwConfig.getWhiteListPageName();
if (whiteListPageName != null) {
pageLink =
"<a href=\"" +
wiki.getSettings().getURL(cwConfig.getWhiteListPageName(), false, true) +
"\">" +
String.valueOf(errorNumber) +
"</a>";
}
result.append(GT._(
"The following problems were detected on the whitelist for error {0}:",
pageLink));
result.append("<ul>");
result.append(details.toString());
result.append("</ul>");
// Update white list
String comment = wiki.getConfiguration().getString(WPCConfigurationString.CW_WHITELISTE_COMMENT);
if (!unnecessaryPages.isEmpty() &&
(whiteListPageName != null) &&
(comment != null)) {
Page whiteListPage = DataManager.getPage(wiki, whiteListPageName, null, null, null);
api.retrieveContents(wiki, Collections.singletonList(whiteListPage), false, false);
String initialContents = whiteListPage.getContents();
String contents = initialContents;
for (Page page : unnecessaryPages) {
PageAnalysis analysis = whiteListPage.getAnalysis(contents, false);
List<PageElementInternalLink> links = analysis.getInternalLinks();
for (int linkNumber = links.size(); linkNumber > 0; linkNumber--) {
PageElementInternalLink link = links.get(linkNumber - 1);
if (Page.areSameTitle(page.getTitle(), link.getLink())) {
int lineBegin = link.getBeginIndex();
while ((lineBegin > 0) && (contents.charAt(lineBegin) != '\n')) {
lineBegin--;
}
int lineEnd = link.getEndIndex();
while ((lineEnd < contents.length()) && (contents.charAt(lineEnd) != '\n')) {
lineEnd++;
}
boolean lineOk = true;
for (PageElementInternalLink tmpLink : links) {
if ((tmpLink != link) &&
(tmpLink.getBeginIndex() < lineEnd) &&
(tmpLink.getEndIndex() > lineBegin)) {
lineOk = false;
}
}
if (lineOk) {
contents = contents.substring(0, lineBegin) + contents.substring(lineEnd);
}
}
}
}
if (!contents.equals(initialContents)) {
api.updatePage(wiki, whiteListPage, contents, comment, true, false);
}
}
}
}
}
}
return result.toString();
} catch (APIException e) {
return e;
}
}
/**
* Called on the event dispatching thread (not on the worker thread)
* after the <code>construct</code> method has returned.
*
* @see org.wikipediacleaner.gui.swing.basic.BasicWorker#finished()
*/
@Override
public void finished() {
super.finished();
if (getWindow() != null) {
InformationWindow.createInformationWindow(
GT._("Whitelists"), get().toString(), true, getWikipedia());
}
}
}