111updateEditorProgress

for each discord editor in your region's channel, this script will open the associated editor's profile, capture relevant information, and download that information into

As of 2018-07-22. See the latest version.

// ==UserScript==
// @name         111updateEditorProgress
// @namespace    http://tampermonkey.net/
// @version      2018.07.22.01
// @description  for each discord editor in your region's channel, this script will open the associated editor's profile, capture relevant information, and download that information into
// @description  comma separated value (CSV) file.  The contents of the file can then be programmaticaly added to a google sheet (using a separate script)
// @description  With the script installed, open any WME editor profile page to execute the script.
// @author       ramblinwreck_81
// @match        https://www.waze.com/user/editor*
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js?version=229392
// @grant        none
// ==/UserScript==

(function() {
  'use strict';
  var discordEditors = [];
  function bootstrap(tries) {
      //console.log(tries);
      tries = tries || 1;
     // console.log(tries);
     // console.log(W,W.Map,W.Model,$);

      if (W && W.Map &&
          W.Model  &&
          $ ) {
         // console.log('passed load check');
          init();
      } else if (tries < 100) {
          setTimeout(function () {
          tries += 1;
          bootstrap(tries);}, 200);
      }
  } // end of bootstrap

  function init()
  {
      console.log("initializing editor progress script");
      createUploadElements();
      function createUploadElements() {
          var y=document.createElement("div");
          y.setAttribute("id", "csv-info");
          document.getElementsByClassName("user-headline")[0].appendChild(y);
          var x = document.createElement("INPUT");
          x.setAttribute("type", "file");
          x.setAttribute("id","fileUpload");
          document.getElementById("csv-info").appendChild(x);
          var z=document.createElement("button");
          z.setAttribute("type", "button");
          z.setAttribute("value", "Upload");
          z.setAttribute("id","import-csv");
          var aa=document.createTextNode("Upload");
          z.appendChild(aa);
          document.getElementById("csv-info").appendChild(z);
          document.getElementById("import-csv").style.height="20px";
          document.getElementById("import-csv").style.width="100px";
      } // end of createUploadElements
      document.getElementById("import-csv").addEventListener("click",upload,false);
  } // end of init
  function upload()
  {
    var blnKeepWaiting = true;
    var fileTimer;
    console.log('uploading');
    var fileUpload = document.getElementById("fileUpload");
    var regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
    if (regex.test(fileUpload.value.toLowerCase())) {
        if (typeof (FileReader) !== "undefined") {
          console.log('fileReader!==undefined');
          var reader = new FileReader();
          reader.onload = function (e) {
            if (fileTimer !==undefined) {
              clearInterval(fileTimer);
              var editorStr = reader.result;
//get rid of duplicate editor names...
              var dups = editorStr.split(',');
              console.log('editor array length ' + dups.length);
              var modDups = dups.forEach(function(element, index, array) {
                array[index] = array[index].toLowerCase().trim();
              });
              //console.log(dups);
              discordEditors = dups.reduce(function(a,currentValue) {
                if (a.indexOf(currentValue) <0){
                  a.push(currentValue);
                }
                return a;
              }, []);
              console.log('editor array length after no dups ' + discordEditors.length);
              console.log('discordEditors: ' + discordEditors);
              executionSequence();
            }
            blnKeepWaiting=false;
           };
          reader.readAsText(fileUpload.files[0]);
          //console.log('file uploaded');
          fileTimer=setInterval(checkAgain,40);
        } else {
            alert("This browser does not support HTML5.");
        }
    } else {
        alert("Please upload a valid CSV file.");
    }
  } // end of upload
  function checkAgain()
  {
    if (blnKeepWaiting===false) {
    } else {
        console.log("still waiting for file upload...");
    }
  } //end of checkAgain
  function executionSequence() {
    var validatedProfileCount = 0;
    var profilePageErrors =0;
    var editors =[];
    //upload();
    connectAPI();
   // console.log('profilepageErrors: ' + profilePageErrors + 'validatedProfileCount: ' + validatedProfileCount);
    a();
    function a() {
      var wait;
      if (profilePageErrors + validatedProfileCount === discordEditors.length) {
        clearTimeout(wait);
        buildWebDisplay();
      } else {
          wait = setTimeout(function b() {
          console.log('profilePageErrors + vaildatedProfileCount: ', profilePageErrors + validatedProfileCount, ' discordEditor.length: ', discordEditors.length);
          a();}, 1000);
      }
    }
    function connectAPI() {
      function Editor(name, rank, firstEditDate, totalEdits,editHistory, milestone, rate, lastEditDate)
        {
          this.name = name;
          this.rank = rank;
          this.firstEditDate = firstEditDate;
          this.totalEdits = totalEdits;
          this.editHistory = editHistory;
          this.milestone = milestone;
          this.rate = rate;
          this.lastEditDate = lastEditDate;
        }
      function pullEditorInfo(element, index, array) {

        var wazeURL = 'https://www.waze.com/user/editor/';
        $.ajax({
          url: wazeURL + element,
          success: function (data, status, xhr) {
            var $result = $.parseHTML(xhr.responseText,true)[9].text;
            var cdata = JSON.parse($result.split(";")[1].replace("gon.data=",""));
            var userdata = "\nUsername: " + cdata.username + "\nRank: " + parseInt(cdata.rank + 1) + "\nEdits: " + cdata.edits + "\nFirst Edit Date: " + cdata.firstEditDate;
  //          console.log("CDATA Section:" + $result,"\ngon.data: " + JSON.stringify(cdata), "\n\nUser Data: " + userdata, "\n\nUrl is " + wazeURL + element);
            editors[validatedProfileCount] = new Editor(cdata.username, parseInt(cdata.rank + 1), cdata.firstEditDate, cdata.edits, cdata.editingActivity);
            console.log('current editor is ' + editors[validatedProfileCount].name + ' editHistory: ' + editors[validatedProfileCount].editHistory);
            var active;
            editors[validatedProfileCount].lastEditDate = findLastEditDate(editors[validatedProfileCount]);
            console.log('editor last edit date is ' + editors[validatedProfileCount].lastEditDate);

            function findLastEditDate(curEditor){
              var arr = curEditor.editHistory;
              var foundFirst = false;
              var lastDay;
              arr = arr.reverse();
              arr.forEach(function(element, index, array) {
                if((array[index]>0) && (foundFirst === false)) {
                  foundFirst = true;
                  console.log('index is ' + index + ' and edits were ' + array[index]);
                  active = index;
                }
              });
              var today = new Date();
              console.log('today is ' + today);
              var lastDayMS = active * 24 * 60 * 60 * 1000;
              var lastDate = new Date(today - lastDayMS);
              console.log('last edit date is ' + lastDate);
              return lastDate.toLocaleDateString();

            }
            validatedProfileCount += 1;
//            console.log(validatedProfileCount);
          },
          error: function(XMLHttpRequest, textStatus, errorThrown) {
            console.log("Status: " + textStatus + " and Error: " + errorThrown);
            profilePageErrors += 1;
            //validatedProfileCount += -1;
          }
        }); // end of ajax

      } // end of pullEditorInfo
      discordEditors.forEach(pullEditorInfo);
      // var jnrEditors = Editors.filter(function(element,index, array) {
      //   return array[index].rank <= 4;
      // });
      // discordEditors = jnrDiscordEditors;
    } // end of connectAPI
    function buildWebDisplay()
    {
      var editorHTML;
      var regionEditorsHTML = '<div class = region-editors id = region>'
      + '<div class = table-area><table id=region-table>'
      + '<thead id = the-head>'
      + '<tr>'
      + '<th id= "name" class = "col1">Name</th><th id="level" class = "col2">Level</th><th id="began" class = "col3">'
      + 'Editing Since</th><th id="total-edits" class = "col4">Total Edits</th><th id="milestone" class = "col5">Approaching Milestone</th><th id="rate" class = "col6">Edit Rate</th>'
      + '</tr>'
      + '</thead><tbody id = theTable-body>';
      makeCSV(editors);
      editors.forEach(addStatsToTable);
      function addStatsToTable(element, index, array)
      {
        function convertSecondsToDate(sec) {
          var a = new Date(sec).toLocaleDateString();
          array[index].firstEditDate = a;
          console.log('changed editors.firsteditdate to ' + array[index].firstEditDate);
          return a;
        }
        var startDate = convertSecondsToDate(editors[index].firstEditDate);
        //editors[index].firstEditDate = startDate;
        var rate = editRate(editors[index]);
        console.log('rate is ' + rate, 'editor is ' + editors[index].name);
        function editRate(rateEditor)
        {
          var period;
          if (rateEditor.rank=== 1) {
            period = 7;
          } else if (rateEditor.rank >= 2) {
            period = 30;
          }
          function sumEdits(accumulator, currentValue) {
            return accumulator + currentValue;
          }
          var a = rateEditor.editHistory.slice(rateEditor.editHistory.length - period);
          console.log('rate editor is ' + rateEditor + ' and edit history length - period is ' + rateEditor.editHistory.length - period);
          console.log('applicable edit history is ' + a);
          var b = a.reduce(sumEdits);
          return b;
        } // end of editRate function
        var mileStr = milestone(editors[index]);
        console.log('mileStr is ' + mileStr, 'editor is ' + editors[index].name);
        function milestone(curEditor)
        {
          switch (curEditor.rank) {
            case 1:
              if(curEditor.totalEdits > 500) {
                return curEditor.milestone = 'true, based on total edits';
              } else if ((curEditor.totalEdits + rate)>1000) {
                return curEditor.milestone = 'true, based on 7 day edit rate';
              } else {
                return curEditor.milestone = 'false';
              }
            break;
            case 2:
              if (curEditor.totalEdits>20000) {
                return curEditor.milestone = 'true, based on edits';
              } else if ((curEditor.totalEdits + rate)>25000) {
                return curEditor.milestone = 'true, based on 30 day edit rate'
              } else {
                return curEditor.milestone = 'false';
              }

            break;
            default:
              return curEditor.milestone = 'false';

          }

        }  // end of milestone function
        editorHTML += '<tr class = "table-rows"><td headers= "name" class = "col1 all-cells"><a class= tbl-link href=https://www.waze.com/user/editor/'
        + editors[index].name + '>' + editors[index].name + "</a>" + '</td><td headers = "level" class = "col2">' + editors[index].rank
         + '</td><td headers="began" class = "col3">' + startDate + '</td><td headers="total-edits" class = "col4">' + editors[index].totalEdits
         + '</td>' + '<td headers="milestone" class = "col5">' + mileStr + '</td><td headers="rate" class = "col6">' + rate + '</td></tr>';

      } // end of addStatsToTable
      var closingHTML = + '</tbody></table></div></div>';

      $('#editing-activity').append(regionEditorsHTML + editorHTML + closingHTML);
      $('.tbl-link').attr('target', '_blank');
      $('.table-area').css({"display": "inline-block", "max-height": "500px", "overflow": "auto"});
      $('#the-head').css({"max-height": "50px","display":"table-header-group","margin-bottom":"5px"});
      $('#theTable-body').css({"max-height":  "500px","margin-bottom":"50px"});
      $('#region-table').css({"table-layout": "fixed", "width": "100%","white-space": "nowrap", "border": "3","border-style": "solid","border-collapse": "collapse"});
      $('.all-cells').css({"white-space": "nowrap", "overflow": "hidden", "text-overflow": "ellipsis"});
       $('.col1').css({"width":"20px"});
       $('.col2').css({"width":"25px"});
       $('.col3').css({"width":"40px"});
       $('.col4').css({"width":"30px"});
       $('.col5').css({"width":"35px"});
       $('.col6').css({"width":"30px"});
       $('.table-rows').css({"border": "solid thin"});
       console.log("first discord editor name is " + discordEditors[0]);
      console.log('finished building table');
      var nameAscending = false;
      var levelAscending = false;
      var startAscending = false;
      var totalAscending = false;
      var milestoneAscending = false;
      var rateAscending = false;
      document.getElementById("name").addEventListener("click",function() {
        if (nameAscending) {
          nameAscending = false;
        } else {
          nameAscending = true;
        }
        sort(nameAscending,'col1','region-table');
      },false);
      document.getElementById("level").addEventListener("click",function() {
        if (levelAscending) {
          levelAscending = false;
        } else {
          levelAscending = true;
        }
        sort(levelAscending, 'col2', 'region-table');
      },false);
      document.getElementById("began").addEventListener("click",function() {
        if (startAscending) {
          startAscending = false;
        } else {
          startAscending = true;
        }
        sort(startAscending, 'col3','region-table');
      },false);
      document.getElementById("total-edits").addEventListener("click",function() {
        if (totalAscending) {
          totalAscending = false;
        } else {
          totalAscending = true;
        }
        sort(totalAscending,'col4','region-table');
      },false);
      document.getElementById("milestone").addEventListener("click",function() {
        if(milestoneAscending) {
          milestoneAscending = false;
        } else {
          milestoneAscending = true;
        }
        sort(milestoneAscending, 'col5', 'region-table');
      },false);
      document.getElementById("rate").addEventListener("click",function(){
        if (rateAscending) {
          rateAscending = false;
        } else {
          rateAscending = true;
        }
        sort(rateAscending, 'col6', 'region-table');
      },false);
      function sort(ascending, columnClassName, tableId)
      {
          var tbody = document.getElementById(tableId).getElementsByTagName(
                  "tbody")[0];
          var rows = tbody.getElementsByTagName("tr");

          var unsorted = true;

          while (unsorted) {
              unsorted = false;

              for (var r = 0; r < rows.length - 1; r++) {
                  var row = rows[r];
                  var nextRow = rows[r + 1];

                  var value = row.getElementsByClassName(columnClassName)[0].innerHTML;
                  var nextValue = nextRow.getElementsByClassName(columnClassName)[0].innerHTML;

                  value = value.replace(',', '.'); // in case a comma is used in float number
                  nextValue = nextValue.replace(',', '.');

                  if (!isNaN(value)) {
                      value = parseFloat(value);
                      nextValue = parseFloat(nextValue);
                  }

                  if (ascending ? value > nextValue : value < nextValue) {
                      tbody.insertBefore(nextRow, row);
                      unsorted = true;
                  }
              } // end of for
          } // end of while
      } //end of sort function
    } // end of buildWebDisplay
    function makeCSV(arr)
    {
console.log('array length for download file is ' + arr.length);
      var csvContent="";
      arr.forEach(function(element, index, array) {
          if (csvContent !== '') {
            csvContent += '\n';
          }

          csvContent += array[index].name + ',' + new Date(array[index].firstEditDate)+ ',' + array[index].lastEditDate + ','
          + array[index].rank + ',' + array[index].totalEdits + ',' + 'none';
      });
      var linkElement= document.createElement('a');
      linkElement.setAttribute("id", "csv-download");
      var encodedUri=encodeURI(csvContent);
      linkElement.setAttribute('href', "data:text/csv;charset=utf-8," + encodedUri);
      linkElement.innerHTML= "Download SER Editor CSV file";
      document.getElementById("csv-info").appendChild(linkElement);
      document.getElementById("import-csv").disabled = true;
    }
  } // end of executionSequence





bootstrap();

})();