Usuário:SandroHcBot/Código Fonte/SavesourceTask

De RuneScape Wiki
Ir para: navegação, pesquisa

Atualiza o código fonte do bot na wiki.

/*--------------------------------------------------------
 * AmauriceBot - RuneScape Wikia update task robot
 * Copyright (c) 2009-2012  Maurice Abraham.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Contributors:
 *   None
 *------------------------------------------------------*/

package amauricebot;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.regex.Pattern;

@Description(summary = "Atualiza o código fonte do bot na wiki.")
public class SavesourceTask implements BotTask {
	private WikiSession m_wiki = null;

	private final static String SOURCE_PATH = "src/amauricebot";
	private final static boolean CHECK_ONLY = false;

	private final Pattern m_dplPattern = Pattern.compile("\n\\|-"
			+ "\n\\|\\[\\[([^\\]\\|]+).*" + "\n\\|(.*)" + "\n\\|(.*)"
			+ "\n\\|(.*)");

	public SavesourceTask(WikiSession wiki) {
		m_wiki = wiki;
	}

	public void perform() throws IOException {
		File sourceDir = new File(SOURCE_PATH);
		if (!sourceDir.exists() || !sourceDir.isDirectory()) {
			Utils.log("ERRO: Nenhum diretório em " + sourceDir.getCanonicalPath());
			return;
		}

		String saveBase = "Utilizador:" + m_wiki.getLoginUser() + "/Código Fonte/";

		File files[] = sourceDir.listFiles();
		HashMap<String, String> classes = new HashMap<String, String>();
		for (int i = 0; i < files.length; i++) {
			String name = files[i].getName();
			if (!name.endsWith(".java"))
				continue;
			name = name.replaceAll("\\.java$", "");

			String summary = getClassSummary(name);
			if (summary.equals("TEST"))
				continue;

			saveSourceFile(saveBase + name, files[i], summary);
			classes.put(name, summary);
		}

		updateIndex(saveBase, classes);
		reportOldPages(saveBase, classes);
	}

	private void saveSourceFile(String wikiPage, File sourceFile, String summary)
			throws IOException {
		StringBuilder sourceCode = new StringBuilder();
		BufferedReader in = new BufferedReader(new FileReader(sourceFile));

		int c;
		while ((c = in.read()) != -1) {
			sourceCode.append((char) c);
		}
		in.close();

		String pageText = sourceCode.toString().replaceAll("\\&", "\\&amp;")
				.replaceAll("<", "\\&lt;").replaceAll(">", "\\&gt;");

		pageText = summary + "\n<pre>\n" + pageText + "</pre>";

		String oldText = m_wiki.getText(wikiPage);

		if (!pageText.equals(oldText)) {
			if (CHECK_ONLY) {
				Utils.log("O código [[" + wikiPage + "]] foi alterado!");
			} else if (m_wiki.editText(wikiPage, pageText, "Código atualizado", true)) {
				Utils.log("[[" + wikiPage + "]] atualizado");
			} else {
				Utils.log("ERRO: Falha ao atualizar [[" + wikiPage + "]] (possível conflicto)");
			}
		}
	}

	private void updateIndex(String saveBase, HashMap<String, String> classes)
			throws IOException {
		String indexPage = saveBase + "Index";

		StringBuilder pageBuilder = new StringBuilder();
		pageBuilder.append("=== Classes Gerais ===\n")
				.append(createIndexTable(saveBase, classes, false))
				.append("\n=== Classes de Tarefas ===\n")
				.append(createIndexTable(saveBase, classes, true));
		String pageText = pageBuilder.toString().trim();

		String oldText = m_wiki.getText(indexPage);

		if (!pageText.equals(oldText)) {
			if (CHECK_ONLY) {
				Utils.log("Index [[" + indexPage + "]] foi alterado!");
			} else if (m_wiki.editText(indexPage, pageText, "Código da index atualizado", true)) {
				Utils.log("[[" + indexPage + "]] atualizado");
			} else {
				Utils.log("ERRO: Falha para atualizar [[" + indexPage + "]] (possível conflicto)");
			}
		}
	}

	private String createIndexTable(String saveBase,
			HashMap<String, String> classes, boolean taskTable)
			throws IOException {
		StringBuilder table = new StringBuilder();
		table.append("{| class=\"wikitable\"\n").append("! Nome !! Propósito\n");

		ArrayList<String> classNames = new ArrayList<String>();
		classNames.addAll(classes.keySet());
		Collections.sort(classNames);

		for (String name : classNames) {
			boolean isTask = name.endsWith("Task") && !name.equals("BotTask");
			if (isTask != taskTable)
				continue;

			String summary = classes.get(name);

			table.append("|-\n").append("! [[").append(saveBase).append(name)
					.append("|").append(name).append("]]\n").append("| ")
					.append(summary).append("\n");
		}
		table.append("|}\n");

		return table.toString();
	}

	private void reportOldPages(String saveBase, HashMap<String, String> classes)
			throws IOException {
		String query = "{{#dpl:" + " | namespace = Utilizador"
				+ " | titlematch = %" + saveBase.replace("Utilizador:", "")
				+ "%" + " | redirects = exclude" + " | mode = userformat"
				+ " | listseparators = ,%PAGE%;,," + " }}";
		String text = m_wiki.subst(query);
		if (text == null) {
			Utils.log("ERRO: Falha ao obter as páginas do código fonte já existentes");
			return;
		}

		for (String page : text.split(";")) {
			String name = page.replace(saveBase, "");
			if (name.equals("Index"))
				continue;
			if (classes.containsKey(name))
				continue;

			Utils.log("AVISO: Página de código fonte antiga em [[" + page + "]]");
		}
	}

	private String getClassSummary(String name) {
		String summary = "???";
		try {
			Class<?> taskClass = Class.forName("amauricebot." + name);
			Description desc = taskClass.getAnnotation(Description.class);
			if (desc != null)
				summary = desc.summary();
		} catch (ClassNotFoundException ex) { }

		return summary;
	}
}