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

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

Obtem o preço dos items do Mercado Geral

/*--------------------------------------------------------
 * 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.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.TreeMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Description(summary = "Obtem o preço dos items do Mercado Geral")
public class GEItems {
	private WikiSession m_wiki = null;
	private String m_listPage = null;
	private TreeMap<Long, Item> m_items = null;
	private long m_lastQueryTime = 0;

	public static enum ItemStatus {NEW, OLD, OK};

	private Pattern m_dailyPattern = Pattern.compile("daily[^{]*\\{([^{]+)\\}");
	private Pattern m_pricePattern = Pattern.compile("(\\d+)\"?:(\\d+)");

	private final static int GE_DELAY = 5 * 1000; // for Jagex throttling
	private final static int GE_RETRY = 4;

	private final static String GE_GRAPH_URL = "http://services.runescape.com/m=itemdb_rs/api/graph/";

	public GEItems(WikiSession wiki) {
		m_wiki = wiki;

		String loginUser = m_wiki.getLoginUser();
		if (loginUser != null)
			m_listPage = "Utilizador:" + loginUser + "/MG_Items";
	}

	public String getListPage() {
		return m_listPage;
	}

	public void load() throws IOException {
		m_items = new TreeMap<Long, Item>();
		if (m_listPage == null)
			return;

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

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

			try {
				long id = Utils.parseNum(cols[0], "", 0);
				String name = cols[1];
				ItemStatus status = ItemStatus.valueOf(cols[2]);
				long price = Utils.parseNum(cols[3], "", 0);
				Date when = m_wiki.parseDate(cols[4]);
				long daysSame = (cols.length >= 6 ? Utils.parseNum(cols[5], "",
						0) : 0);

				// assume old unless we see again
				if (status == ItemStatus.OK)
					status = ItemStatus.OLD;

				Item item = new Item(name, status, price, when, daysSame);
				m_items.put(id, item);
			} catch (Exception ex) {
				// ignore bad entries
			}
		}
	}

	public long save() throws IOException {
		long numNew = 0;

		if (m_listPage == null)
			return numNew;

		StringBuilder newList = new StringBuilder();
		newList.append("Items totais = ").append(m_items.size()).append("\n");
		newList.append("{| class='wikitable'\n");
		newList.append("! Id !! Nome !! Estado !! Preço !! Data !! Dias c/ mesmo preço\n");

		for (ItemStatus status : Arrays.asList(ItemStatus.values())) {
			for (Long id : m_items.keySet()) {
				Item item = m_items.get(id);
				if (item.getStatus() != status)
					continue;
				newList.append("|-");
				if (item.getStatus() != ItemStatus.OK)
					newList.append(" bgcolor='#FFCC99'");
				newList.append("\n");
				newList.append("| ").append(id);
				newList.append(" || ").append(item.getName());
				newList.append(" || ").append(item.getStatus());
				newList.append(" || ").append(item.getPrice());
				newList.append(" || ")
						.append(m_wiki.formatDate(item.getWhen()));
				newList.append(" || ").append(item.getDaysSame());
				newList.append("\n");

				if (item.getStatus() != ItemStatus.OK)
					numNew++;
			}
		}
		newList.append("|}\n");

		String newText = newList.toString();
		String oldText = m_wiki.getText(m_listPage);
		if (!newText.equals(oldText)) {
			if (!m_wiki.editText(m_listPage, newText.toString(), "Lista de objetos do MG atualizada", true))
				Utils.log("ERRO: Falha ao atualizar a lista de objetos do MG (possível conflicto)");
		}

		return numNew;
	}

	public boolean checkName(long id, String name) {
		if (id <= 0)
			return false;

		Item item = m_items.get(id);
		if (item != null) {
			if (!item.getName().equals(name))
				return false;

			if (item.getStatus() != ItemStatus.NEW)
				item.setStatus(ItemStatus.OK);
		} else {
			item = new Item(name, ItemStatus.NEW, 0, null, 0);
			m_items.put(id, item);
		}

		return true;
	}

	public long getPrice(long id) throws IOException {
		for (int i = 0; i < GE_RETRY; i++) {
			long now = System.currentTimeMillis();
			long delay = (m_lastQueryTime + GE_DELAY) - now;

			if (delay > 0) {
				try {
					Thread.sleep(delay);
				} catch (Exception ex) { }
			}
			m_lastQueryTime = System.currentTimeMillis();

			String url = GE_GRAPH_URL + id + ".json";
			String data = Utils.getInternetPage(url, null, null);
			String[] toks = Utils.extract(m_dailyPattern, data);
			if (toks == null)
				continue;
			String daily = toks[1];

			long price = 0;
			long daysSame = 0;
			Matcher priceMatcher = m_pricePattern.matcher(daily);
			while (priceMatcher.find()) {
				long nextPrice = Utils.parseNum(priceMatcher.group(2), "", 0);
				daysSame = (nextPrice == price ? daysSame + 1 : 0);
				price = nextPrice;
			}

			Item item = m_items.get(id);
			if (item != null)
				item.setPrice(price, new Date(m_lastQueryTime), daysSame);

			return price;
		}
		return 0;
	}

	public long getPrevPrice(long id) {
		Item item = m_items.get(id);
		if (item == null || item.getWhen() == null)
			return 0;

		// previous price expires if more than half days it is same
		long prevPriceExpiry = item.getWhen().getTime()
				+ (item.getDaysSame() * 86400 * 1000 / 2);
		if (System.currentTimeMillis() > prevPriceExpiry)
			return 0;

		return item.getPrice();
	}

	private class Item {
		private String m_name = null;
		private ItemStatus m_status = ItemStatus.OK;
		private long m_price = 0;
		private Date m_when = null;
		private long m_daysSame = 0;

		private Item(String name, ItemStatus status, long price, Date when, long daysSame) {
			m_name = name;
			m_status = status;
			m_price = price;
			m_when = when;
			m_daysSame = daysSame;
		}

		public String getName() {
			return m_name;
		}

		public ItemStatus getStatus() {
			return m_status;
		}

		public long getPrice() {
			return m_price;
		}

		public Date getWhen() {
			return m_when;
		}

		public long getDaysSame() {
			return m_daysSame;
		}

		public void setStatus(ItemStatus status) {
			m_status = status;
		}

		public void setPrice(long price, Date when, long daysSame) {
			m_price = price;
			m_when = when;
			m_daysSame = daysSame;
		}
	}
}