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

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

Classe para verificar estatísticas para as tarefas.

/*--------------------------------------------------------
 * 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.text.NumberFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TreeMap;

@Description(summary = "Classe para verificar estatísticas para as tarefas.")
public class Stats {
	private WikiSession m_wiki = null;
	private String m_listPage = null;

	private final static int AVG_PERIOD = 5;
	private final static int LIMIT_DECAY = 20;

	private TreeMap<String, TaskStats> m_taskStats = new TreeMap<String, TaskStats>();

	public Stats(WikiSession wiki) {
		m_wiki = wiki;

		String loginUser = m_wiki.getLoginUser();
		if (loginUser != null)
			m_listPage = "Utilizador:" + loginUser + "/Estatísticas";

		if (m_listPage != null)
			loadStats();
	}

	private void loadStats() {
		try {
			String text = m_wiki.getText(m_listPage);
			if (text == null)
				return;

			String[] lines = text.split("\\r?\\n");
			for (int i = 0; i < lines.length; i++) {
				String[] cols = lines[i].split("\\|\\|");
				if (cols.length < 6)
					continue;

				for (int j = 0; j < cols.length; j++) {
					cols[j] = cols[j].replaceFirst(".*\\|", "").trim();
				}

				String task = cols[0];
				Date when = m_wiki.parseDate(cols[1]);
				double last = Utils.parseDouble(cols[2], "", 0);
				double min = Utils.parseDouble(cols[3], "", 0);
				double avg = Utils.parseDouble(cols[4], "", 0);
				double max = Utils.parseDouble(cols[5], "", 0);

				TaskStats stats = new TaskStats(task, when, last, min, avg, max);

				m_taskStats.put(task, stats);
			}
		} catch (Exception ex) { }
	}

	public void setTaskStats(String task, Date started, Date finished) {
		double duration = (double) (finished.getTime() - started.getTime()) / 60000;

		// check if old stats entry exists
		TaskStats stats = m_taskStats.get(task);
		if (stats == null) {
			stats = new TaskStats(task);
			m_taskStats.put(task, stats);
		}
		stats.update(started, duration);
	}

	public void save() {
		if (m_listPage == null)
			return;

		StringBuilder newList = new StringBuilder();

		NumberFormat fmt = NumberFormat.getNumberInstance(Locale.UK);

		newList.append("== Número de Tarefas ==\n");
		newList.append("As seguintes estatísticas estão convertidas em minutos.\n");
		newList.append("{| class='wikitable'\n");
		newList.append("! Tarefa !! Data !! Última !! Mínimo !! Média !! Máximo\n");
		for (TaskStats stats : m_taskStats.values()) {
			double last = stats.getLast();
			int dp = last >= 100 ? 1 : last >= 10 ? 2 : 3;
			fmt.setMaximumFractionDigits(dp);

			newList.append("|-\n");
			newList.append("|style='text-align:center'| ").append(stats.getTask());
			newList.append(" ||style='text-align:center'| ");
			newList.append(m_wiki.formatDate(stats.getWhen()));
			newList.append(" ||style='text-align:center'| ");
			newList.append(fmt.format(stats.getLast()));
			newList.append(" ||style='text-align:center'| ");
			newList.append(fmt.format(stats.getMin()));
			newList.append(" ||style='text-align:center'| ");
			newList.append(fmt.format(stats.getAvg()));
			newList.append(" ||style='text-align:center'| ");
			newList.append(fmt.format(stats.getMax()));
			newList.append("\n");
		}
		newList.append("|}\n");

		String newText = newList.toString();

		try {
			String oldText = m_wiki.getText(m_listPage);
			if (!newText.equals(oldText)
					&& !m_wiki.editText(m_listPage, newText.toString(), "Estatísticas de tarefas atualizadas", true)) {
				Utils.log("AVISO: Falha ao atualizar as estatísticas da tarefas (possível conflicto)");
			}
		} catch (Exception ex) { }
	}

	private class TaskStats {
		private String m_task = null;
		private Date m_when = null;
		private double m_last = 0;
		private double m_min = 0;
		private double m_avg = 0;
		private double m_max = 0;

		public TaskStats(String task, Date when, double last, double min, double avg, double max) {
			m_task = task;
			m_when = when;
			m_last = last;
			m_min = min;
			m_avg = avg;
			m_max = max;
		}

		public TaskStats(String task) {
			m_task = task;
		}

		public void update(Date when, double duration) {
			if (m_when == null) {
				m_min = duration;
				m_avg = duration;
				m_max = duration;
			} else {
				m_min = Math.min(duration, ((LIMIT_DECAY - 1) * m_min + duration) / LIMIT_DECAY);
				m_avg = ((AVG_PERIOD - 1) * m_avg + duration) / AVG_PERIOD;
				m_max = Math.max(duration, ((LIMIT_DECAY - 1) * m_max + duration) / LIMIT_DECAY);
			}
			m_last = duration;
			m_when = when;
		}

		public String getTask() {
			return m_task;
		}

		public Date getWhen() {
			return m_when;
		}

		public double getLast() {
			return m_last;
		}

		public double getMin() {
			return m_min;
		}

		public double getAvg() {
			return m_avg;
		}

		public double getMax() {
			return m_max;
		}
	}
}