User:Dudemanfellabra/UpdateNRHPProgress.js

/*

The following script places a button at the top of the NRHP Progress page WP:NRHPPROGRESS. When the button is clicked,

the script begins to load each county list linked from the Progress page in the background, extract statistics about

sites in each list, and updates the Progress page with the fetched data.

  • /

var wikitext = 'error'

var ProgressStructure=[]; // ProgressStructure[table][row].StatName

var TotalToQuery=0;

var TotalQueried=0;

var ErrorCount=0;

var WarningCount="",0; // 0=status, 1=count

var InitialTime=0;

var ProgressDivTimer=0 // timer for updating ProgressDiv

var DefaultQueryPause=1 // number of milliseconds to wait between each API query; increased by code if rate limit reached

function ProgressButton() {

if (mw.config.get('wgPageName')!="Wikipedia:WikiProject_National_Register_of_Historic_Places/Progress"||location.href.indexOf('action')!=-1) return;

var button=document.createElement("input")

button.setAttribute("type", "button");

button.setAttribute("value", "Update Statistics");

button.setAttribute("id", "button2");

$(button).click( Click );

var content=document.getElementById('mw-content-text')

content.parentNode.insertBefore(button, content)

}

function Click() { // after button is clicked, disable it and fetch wikitext of Progress page

var button2 = document.getElementById('button2')

button2.disabled = true

var ProgressDiv = document.createElement("div")

ProgressDiv.setAttribute("id", "ProgressDiv")

ProgressDiv.setAttribute("style", "width:500px; border:1px solid black; padding:5px; background:#ffffff")

button2.parentNode.insertBefore(ProgressDiv, button2)

ProgressDiv.innerHTML = "Initializing..."

mw.loader.using( ['mediawiki.util', 'user.options'] ).then( function () {

getWikitext(mw.config.get('wgPageName')) // after wikitext fetched, SetupTables() is called

} );

}

// create array of table structure to be populated later

function SetupTables() {

var table=document.getElementsByClassName('wikitable sortable');

// set up national totals

var tr=table[0].getElementsByTagName("tr")

ProgressStructure[0]=[];

for (var j=1; j

var td=tr[j].getElementsByTagName("td")

ProgressStructure[0][j-1]={};

ProgressStructure[0][j-1].ID=td[0].innerHTML // state name

ProgressStructure[0][j-1].Total=0

ProgressStructure[0][j-1].Illustrated=0

ProgressStructure[0][j-1].Articled=0

ProgressStructure[0][j-1].Stubs=0

ProgressStructure[0][j-1].NRISonly=0

ProgressStructure[0][j-1].StartPlus=0

ProgressStructure[0][j-1].Unassessed=0

ProgressStructure[0][j-1].Untagged=0

}

// special row for Tangier, Morocco

var td=tr[tr.length-3].getElementsByTagName("td")

ProgressStructure[0][tr.length-4]={};

ProgressStructure[0][tr.length-4].ID="Tangier, Morocco"

ProgressStructure[0][tr.length-4].Total=parseFloat(td[1].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].Illustrated=parseFloat(td[2].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].Articled=parseFloat(td[4].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].Stubs=parseFloat(td[6].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].NRISonly=parseFloat(td[7].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].StartPlus=parseFloat(td[8].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].Unassessed=parseFloat(td[10].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-4].Untagged=parseFloat(td[11].innerHTML.replace(",",""))

// duplicates row

var td=tr[tr.length-2].getElementsByTagName("td")

ProgressStructure[0][tr.length-3]={};

ProgressStructure[0][tr.length-3].ID="National Duplicates"

ProgressStructure[0][tr.length-3].Total=parseFloat(td[0].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].Illustrated=parseFloat(td[1].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].Articled=parseFloat(td[3].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].Stubs=parseFloat(td[5].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].NRISonly=parseFloat(td[6].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].StartPlus=parseFloat(td[7].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].Unassessed=parseFloat(td[9].innerHTML.replace(",",""))

ProgressStructure[0][tr.length-3].Untagged=parseFloat(td[10].innerHTML.replace(",",""))

// national totals

ProgressStructure[0][tr.length-2]={};

ProgressStructure[0][tr.length-2].ID="National Totals"

ProgressStructure[0][tr.length-2].Total=0

ProgressStructure[0][tr.length-2].Illustrated=0

ProgressStructure[0][tr.length-2].Articled=0

ProgressStructure[0][tr.length-2].Stubs=0

ProgressStructure[0][tr.length-2].NRISonly=0

ProgressStructure[0][tr.length-2].StartPlus=0

ProgressStructure[0][tr.length-2].Unassessed=0

ProgressStructure[0][tr.length-2].Untagged=0

// now data for each state

for (var i=1; i

var tr=table[i].getElementsByTagName("tr")

ProgressStructure[i]=[];

for (var j=1; j

var td=tr[j].getElementsByTagName("td") // fill in existing data in case error

ProgressStructure[i][j-1]={};

ProgressStructure[i][j-1].ID=td[0].innerHTML.substr(0,5)

ProgressStructure[i][j-1].Total=parseFloat(td[3].innerHTML.replace(",",""))

ProgressStructure[i][j-1].Illustrated=parseFloat(td[4].innerHTML.replace(",",""))

ProgressStructure[i][j-1].Articled=parseFloat(td[6].innerHTML.replace(",",""))

ProgressStructure[i][j-1].Stubs=parseFloat(td[8].innerHTML.replace(",",""))

ProgressStructure[i][j-1].NRISonly=parseFloat(td[9].innerHTML.replace(",",""))

ProgressStructure[i][j-1].StartPlus=parseFloat(td[10].innerHTML.replace(",",""))

ProgressStructure[i][j-1].Unassessed=parseFloat(td[12].innerHTML.replace(",",""))

ProgressStructure[i][j-1].Untagged=parseFloat(td[13].innerHTML.replace(",",""))

var link=td[1].getElementsByTagName("a")

if (link.length!=0 && link[0].href.search("#")==-1) {

link=decodeURI(link[0].href).split("/")

link=link[link.length-1].replace(/_/g," ")

ProgressStructure[i][j-1].Link=link

ProgressStructure[i][j-1].ArticleQueried=0 // for querying later

ProgressStructure[i][j-1].TalkQueried=0

} else {

if (ProgressStructure[i][j-1].ID!="ddddd") { // if no link and not duplicate, must be totals row, so we can zero it

ProgressStructure[i][j-1].Total=0

ProgressStructure[i][j-1].Illustrated=0

ProgressStructure[i][j-1].Articled=0

ProgressStructure[i][j-1].Stubs=0

ProgressStructure[i][j-1].NRISonly=0

ProgressStructure[i][j-1].StartPlus=0

ProgressStructure[i][j-1].Unassessed=0

ProgressStructure[i][j-1].Untagged=0

}

}

}

// duplicates row

var td=tr[tr.length-2].getElementsByTagName("td")

ProgressStructure[i][tr.length-3]={};

ProgressStructure[i][tr.length-3].ID=ProgressStructure[0][i-1].ID+" Duplicates"

ProgressStructure[i][tr.length-3].Total=parseFloat(td[0].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].Illustrated=parseFloat(td[1].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].Articled=parseFloat(td[3].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].Stubs=parseFloat(td[5].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].NRISonly=parseFloat(td[6].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].StartPlus=parseFloat(td[7].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].Unassessed=parseFloat(td[9].innerHTML.replace(",",""))

ProgressStructure[i][tr.length-3].Untagged=parseFloat(td[10].innerHTML.replace(",",""))

// state totals

ProgressStructure[i][tr.length-2]={};

ProgressStructure[i][tr.length-2].ID=ProgressStructure[0][i-1].ID+" Totals"

ProgressStructure[i][tr.length-2].Total=0

ProgressStructure[i][tr.length-2].Illustrated=0

ProgressStructure[i][tr.length-2].Articled=0

ProgressStructure[i][tr.length-2].Stubs=0

ProgressStructure[i][tr.length-2].NRISonly=0

ProgressStructure[i][tr.length-2].StartPlus=0

ProgressStructure[i][tr.length-2].Unassessed=0

ProgressStructure[i][tr.length-2].Untagged=0

}

for (var i=1; i

for (var j=0; j

if (typeof ProgressStructure[i][j].Link!="undefined") TotalToQuery++ // don't count duplicates and total rows

}

}

TotalQueried=0;

var ProgressDiv=document.getElementById("ProgressDiv")

ProgressDiv.innerHTML+=" Done!
"

var ProgressSpan=document.createElement("span")

ProgressSpan.setAttribute("id", "ProgressSpan")

ProgressDiv.appendChild(ProgressSpan)

ProgressSpan.innerHTML = "Querying county data... 0 (0%) of "+TotalToQuery+" lists checked."

var TimeSpan=document.createElement("span")

TimeSpan.setAttribute("id", "TimeSpan")

ProgressDiv.appendChild(TimeSpan)

TimeSpan.innerHTML = ""

InitialTime=new Date() // record starting time

UpdateProgressDiv();

LoadList(1,0); // begin querying first page

}

// load next list to query

function LoadList(currentTable,currentRow) {

// check if we need to go to the next table

if (currentRow>ProgressStructure[currentTable].length-3) {

currentRow=0

currentTable++

}

// check if there are no more tables

if (currentTable>ProgressStructure.length-1) return;

if (typeof ProgressStructure[currentTable][currentRow].Link=="undefined") { // skip duplicate and total rows

LoadList(currentTable,currentRow+1)

return;

}

var title=ProgressStructure[currentTable][currentRow].Link

setTimeout(function(){ // short delay to prevent API overload

getProgressListWikitext(title,currentTable,currentRow);

LoadList(currentTable,currentRow+1);

}, DefaultQueryPause);

return;

}

function WikitextFetched(ajaxResponse,status,title,currentTable,currentRow) {

if (status!="success") {

NewWarning("Wikitext "+ajaxResponse.errorThrown)

setTimeout(function(){ // try again after delay if rate limit reached

getProgressListWikitext(title,currentTable,currentRow);

}, 250);

return;

}

// won't get here unless successful

var responseText=JSON.parse(ajaxResponse.responseText)

var pagetext=responseText.query.pages[responseText.query.pageids[0]].revisions[0]["*"]

if (responseText.query.redirects) { // if redirect, find section

var SectionName="Undefined"

for (var r in responseText.query.redirects) {

if (typeof responseText.query.redirects[r].tofragment!="undefined") SectionName=responseText.query.redirects[r].tofragment.replace(/.27/g,"'")

}

var regex = new RegExp("=[ ]*(\\[\\[(.*?\\|)?[ ]*)?"+SectionName+"([ ]*\\]\\])?[ ]*=", "g")

var sectionheader=pagetext.match(regex)

if (sectionheader == null) { // if no section found, check if one of known empty counties

var EmptyCounties=["02270", "12067", "42023", "48017", "48023", "48033", "48069", "48075", "48079", "48083", "48103", "48107", "48119", "48131", "48155", "48165", "48195", "48207", "48219", "48247", "48269", "48279", "48341", "48369", "48389", "48415", "48421", "48431", "48433", "48437", "48445", "48461", "48475", "48501", "51735"]

var ID = ProgressStructure[currentTable][currentRow].ID

var errorcode = 0

for (var k=0; k

if (ID==EmptyCounties[k]) {errorcode=-1}

}

if (errorcode!=0) { // must be an empty county

ProgressStructure[currentTable][currentRow].Total=0

ProgressStructure[currentTable][currentRow].Illustrated=0

ProgressStructure[currentTable][currentRow].Articled=0

ProgressStructure[currentTable][currentRow].Stubs=0

ProgressStructure[currentTable][currentRow].NRISonly=0

ProgressStructure[currentTable][currentRow].StartPlus=0

ProgressStructure[currentTable][currentRow].Unassessed=0

ProgressStructure[currentTable][currentRow].Untagged=0

ProgressStructure[currentTable][currentRow].Link=title

TotalQueried++

if (TotalQueried==TotalToQuery) CalculateProgressTotals()

return;

}

// if we're here, must have been a redirect with no section, and not a known empty county

sectionheader=pagetext.match(/{{NRHP header/g) // then look for tables without a section

if (sectionheader==null||sectionheader.length>1) { // if still can't find a table or find multiple tables, fatal error

ProgressFatalError(0,title,currentTable,currentRow)

}

}

var StartIndex=pagetext.indexOf(sectionheader[0])

var sectiontext=pagetext.substr(StartIndex,pagetext.indexOf("\n==",StartIndex)-StartIndex) // only look at relevant section

StartIndex=sectiontext.indexOf("{{NRHP header")

if (StartIndex==-1) {

if (sectiontext.indexOf("{{NRHP row")!=-1) {

ProgressFatalError(2,title,currentTable,currentRow) // incorrectly formatted table

} else { // must be an empty county

ProgressStructure[currentTable][currentRow].Total=0

ProgressStructure[currentTable][currentRow].Illustrated=0

ProgressStructure[currentTable][currentRow].Articled=0

ProgressStructure[currentTable][currentRow].Stubs=0

ProgressStructure[currentTable][currentRow].NRISonly=0

ProgressStructure[currentTable][currentRow].StartPlus=0

ProgressStructure[currentTable][currentRow].Unassessed=0

ProgressStructure[currentTable][currentRow].Untagged=0

ProgressStructure[currentTable][currentRow].Link=title

TotalQueried++

if (TotalQueried==TotalToQuery) CalculateProgressTotals()

return;

}

}

var tabletext=sectiontext.substr(StartIndex,sectiontext.indexOf("\n|}",StartIndex)-StartIndex)

} else { // if not a redirect, default to first table on page

var StartIndex=pagetext.indexOf("{{NRHP header")

if (StartIndex==-1) {

ProgressFatalError(1,title,currentTable,currentRow) // no list found

return;

}

var tabletext=pagetext.substr(StartIndex,pagetext.indexOf("\n|}",StartIndex)-StartIndex)

}

// now that tabletext has only relevant table, extract rows

var Rows=[]

var str = "{{"

var start=0

var commentstart=0

while (true) {

commentstart=tabletext.indexOf("",commentstart)

commentstart=tabletext.indexOf("