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("
"