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

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

Experimental Task

/*--------------------------------------------------------
 * 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.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Description(summary = "Experimental Task")
public class DevTask implements BotTask
{
    private WikiSession m_wiki = null;
    private DateFormat m_dateFmt = null;
    
    private final static int QUERY_DELAY = 5*1000;

    private final Pattern m_hsPattern = Pattern.compile("#default=([^}]+)");
    private final Pattern m_dplPattern = Pattern.compile("\n\\|-"
                                        + "\n\\|\\[\\[([^\\]\\|]+).*"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)"
                                        + "\n\\|(.*)");
    
    public DevTask(WikiSession wiki)
    {
        m_wiki = wiki;
        m_dateFmt = new SimpleDateFormat("d-MMM-yyyy", Locale.ENGLISH);
        m_dateFmt.setTimeZone(TimeZone.getTimeZone("UTC"));
    }

    public void perform()
            throws IOException
    {
        int updated = 0;
        int pagesize = 500;
        for (int i = 0; i < 100; i ++)
        {
            String query = "{{#dpl:"
                        + " | uses = User:Amaurice/Sandbox2"
                        + " | namespace = User"
                        + " | offset = " + (i*pagesize)
                        + " | count = " + pagesize
                        + " | include = {User:Amaurice/Sandbox2}:graph:hspage:skill:field:progressgoal:barcolor:abovecolor:belowcolor"
                        + " | table = class=wikitable,,graph,hspage,skill,field,progressgoal,barcolor,abovecolor,belowcolor"
                        + " | tablerow = %%,%%,%%,%%,%%,%%,%%,%%"
                        + " }}";

            String text = m_wiki.subst(query);
            if (text == null)
            {
                Utils.log("ERROR: Failed to get progress gragh pages");
                return;
            }

            if (!text.contains("{|"))
                break; // no more callers

            Matcher matcher = m_dplPattern.matcher(text);
            while (matcher.find())
            {
                String reqPage = matcher.group(1);
                String graphPage = matcher.group(2);
                String dataPage = matcher.group(3);
                String skill = matcher.group(4);
                String field = matcher.group(5);
                String progressGoal = matcher.group(6);
                String barColor = matcher.group(7);
                String aboveColor = matcher.group(8);
                String belowColor = matcher.group(9);
                
                String lcUser = reqPage.toLowerCase().replaceFirst("/.*", "");
                graphPage = graphPage.replace('_',' ');
                dataPage = dataPage.replace('_',' ');

                if (graphPage.toLowerCase().equals(reqPage.toLowerCase())
                        || !graphPage.toLowerCase().startsWith(lcUser+"/"))
                    continue; // bad graph subpage
                
                if (updateProgressGraph(graphPage, dataPage,
                                        getSkillNum(skill),
                                        Utils.parseNum(field, null, 1),
                                        Utils.parseNum(progressGoal, null, 0),
                                        barColor, aboveColor, belowColor))
                    updated ++;
            }

            try
            {
                Thread.sleep(QUERY_DELAY);
            }
            catch (Exception ex)
            {
                // ignore exception
            }
        }

        if (updated > 0)
        {
            Utils.log("Updated " + updated + " progress graph pages");
        }
    }

    private long getSkillNum(String skill)
    {
        skill = skill.trim();
        if (skill.matches("\\d+"))
        {
            return Utils.parseNum(skill, null, 0);
        }

        // try using ParseHiscoreData to map
        StringBuilder lookup = new StringBuilder();
        lookup.append("{{ParseHiscoreData|");
        for (int i = 0; i < 99; i ++)
        {
            lookup.append(i).append(" ");
        }
        lookup.append("|").append(skill).append("|0}}");
        try {
            String text = m_wiki.subst(lookup.toString());
            return Utils.parseNum(text, null, -1);
        } catch (Exception ex) {}
        
        return 0;
    }
    
    private boolean updateProgressGraph(String graphPage, String dataPage,
                                        long skillNum, long fieldNum,
                                        long progressGoal, String barColor,
                                        String aboveColor, String belowColor)
            throws IOException
    {
        WikiSession.PageRevision[] revisions = m_wiki.getHistory(dataPage, 50);
        if (revisions.length < 1)
        {
            Utils.log("ERROR: Could not get history of [[" + dataPage + "]]");
            return false;
        }

        BarGraph graph = new BarGraph();
        graph.setProgressGoal(progressGoal);
        Date startDate = revisions[revisions.length-1].getTimestamp();
        graph.setMinXLabel(m_dateFmt.format(startDate));
        Date endDate = revisions[0].getTimestamp();
        graph.setMaxXLabel(m_dateFmt.format(endDate));
        
        if (!barColor.isEmpty())
            graph.setBarColor(barColor);
        if (!aboveColor.isEmpty())
            graph.setAboveColor(aboveColor);
        if (!belowColor.isEmpty())
            graph.setBelowColor(belowColor);

        for (int i = revisions.length-1; i >= 0; i --)
        {
            Matcher m = m_hsPattern.matcher(revisions[i].getContent());
            if (!m.find())
                continue;
            String scores[] = m.group(1).split(" ");
            int row = (skillNum < scores.length ? (int)skillNum : 0);
            String fields[] = scores[row].split(",");
            int col = (fieldNum < fields.length ? (int)fieldNum : 0);
            long value = Utils.parseNum(fields[col], null, 0);
            
            graph.addValue(value);
        }
        
        String newText = graph.getAsHtml();
        String oldText = m_wiki.getText(graphPage);
        if (oldText == null || !newText.trim().equals(oldText.trim()))
        {
            if (!m_wiki.editText(graphPage, newText,
                                    "Updated progress graph", true))
            {
                Utils.log("WARNING: Failed to update progress graph (possible conflict)");
                return false;
            }
            return true;
        }
        
        return false;
    }
}