updateEditorProgress

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

目前為 2018-09-22 提交的版本,檢視 最新版本

// //// // ==UserScript==
// @name         updateEditorProgress
// @namespace    http://tampermonkey.net/
// @version      2018.09.22.03
// @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://gf.qytechs.cn/scripts/24851-wazewrap/code/WazeWrap.js?version=229392
// @grant        none
// ==/UserScript==


// TO DO:
// filter out >R4
// add code that removes editors based on inactivity
// fix bot code to avoid editor name errors



(function() {
  'use strict';
  var discordEditors = [];
  var tableUnlockedEditors = [];
  var tableLockedEditors = [];
  var API_KEY ='AIzaSyDOdMtqjg0CUHMeFt29GeQzrR0__0hr5YQ'
  var CLIENT_ID = '533057355164-2m80uia4u5pedq0dteiia47k3ff6als8.apps.googleusercontent.com'
  var DISCOVERY_DOCS = ["https://sheets.googleapis.com/$discovery/rest?version=v4"];
  var SCOPES = "https://www.googleapis.com/auth/spreadsheets";
  var spreadsheetId = '15TYXaO7iYRNNDUkkavG-2X75yP6iPobPV-VNBGhVjIU';
  var ssRange = 'discordEditors!A:C';
  var authorizeButton;
  var signoutButton;
  var blnReadyToBuildTable = false;
  var blnWrite = false;
  var blnLockChange = false;
  var blnHomeRegionChange = false;
  var blnNotHomeRegion = false;
  var homeRegion = [];
  var notHomeRegion = [];
  var regionSpecificEditors = true;
  function bootstrap(tries) {
      if (W && W.Map &&
          W.Model  &&
          $ ) {
          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 z=document.createElement("button");
             z.setAttribute("type", "button");
             z.setAttribute("value", "Run");
             z.setAttribute("id","run-editor-update");
             var aa=document.createTextNode("Editor Update");
             z.appendChild(aa);
             document.getElementById("csv-info").appendChild(z);
            document.getElementById("run-editor-update").style.height="20px";
            document.getElementById("run-editor-update").style.width="100px";
          var node = document.createElement('div');
        node.innerHTML = '<input type="checkbox" id="select-region" name="check"><label for="region-specific">My Region Only</label>';
        document.getElementById('csv-info').appendChild(node);
          $('#select-region').attr('autofocus', 'true')
      //    $('#select-region').attr('label','Only SER Editors?');
          $('#select-region').attr('checked', 'true');
          $('#csv-info').append('<button id="authorize_button" style="display: none;">Authorize</button><button id="signout_button" style="display: none;">Sign Out</button>');
   authorizeButton = document.getElementById('authorize_button');
   signoutButton = document.getElementById('signout_button');
      } // end of createUploadElements
      document.getElementById("select-region").addEventListener("click",setEditorFilter,false);
      document.getElementById("run-editor-update").addEventListener("click",handleClientLoad,false);

  } // end of init
  function handleClientLoad() {
      gapi.load('client:auth2', initClient);
  }
  function initClient() {
        gapi.client.init({
          //apiKey: API_KEY,
          clientId: CLIENT_ID,
          discoveryDocs: DISCOVERY_DOCS,
          scope: SCOPES
        }).then(function () {
          // Listen for sign-in state changes.
          gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus);

          // Handle the initial sign-in state.
          updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get());
          authorizeButton.onclick = handleAuthClick;
          signoutButton.onclick = handleSignoutClick;
        });
  }
  function updateSigninStatus(isSignedIn) {
        if (isSignedIn) {
          authorizeButton.style.display = 'none';
          signoutButton.style.display = 'block';
          if (blnWrite === false) {
              executionSequence();
          } else {
             if((blnHomeRegionChange) && (blnLockChange === false)) {
                 handleNonRegionEditors();
                 blnHomeRegionChange = false;
             } else if ((blnLockChange) && (blnHomeRegionChange === false)) {
                 blnLockChange = false;
                 addLockedEditors();
             } else {
                 addLockedEditors();
                 blnLockChange = false;
                 handleNonRegionEditors();
                 blnHomeRegionChange = false;
             }
          }
        } else {
          authorizeButton.style.display = 'block';
          signoutButton.style.display = 'none';
        }
  }
  function handleAuthClick(event) {
        gapi.auth2.getAuthInstance().signIn();
  }

      /**
       *  Sign out the user upon button click.
       */
  function handleSignoutClick(event) {
        gapi.auth2.getAuthInstance().signOut();
  }

  $('body').append('<script async defer src="https://apis.google.com/js/api.js" onload="this.onload=function(){};handleClientLoad()" onreadystatechange="if (this.readyState === complete) this.onload()"></script>');
    function setEditorFilter() {
       if( $('#select-region').prop('checked')) {
               regionSpecificEditors = true;
           } else {
               regionSpecificEditors = false;
           }
       };
  function executionSequence() {
    let lockedArray = localStorage.getItem('lockedEditors') ? JSON.parse(localStorage.getItem('lockedEditors')) : [];
    var validatedProfileCount = 0;
    var profilePageErrors =0;
    var editors =[];
    var rangeLength = 0;
    var seniorEditor = 0;
    var inactiveEditors = 0;
    var L1Editors = 0;
    var L2Editors = 0;
    var L3Editors = 0;
    var L4Editors = 0;
    var L5Editors = 0;
    var totalEditors = 0;
    var L1Edits = 0;
    var L2Edits = 0;
    var L3Edits =0;
    var L4Edits = 0;
    var L5Edits = 0;
    var alreadyWarned = false;
    var totalNotInRegion = 0;
    var duplicatesRemoved = 0;
    connectGoogleAPI();
    function connectGoogleAPI() {
      var params = {
        // The ID of the spreadsheet to retrieve data from.
        spreadsheetId: spreadsheetId, //TODO: Update placeholder value.

        // The A1 notation of the values to retrieve.
        ranges: ssRange,

        // How values should be represented in the output.
        // The default render option is ValueRenderOption.FORMATTED_VALUE.
        valueRenderOption: 'UNFORMATTED_VALUE',  // TODO: Update placeholder value.

        // How dates, times, and durations should be represented in the output.
        // This is ignored if value_render_option is
        // FORMATTED_VALUE.
        // The default dateTime render option is [DateTimeRenderOption.SERIAL_NUMBER].
        dateTimeRenderOption: 'FORMATTED_STRING',  // TODO: Update placeholder value.
      };

      var request = gapi.client.sheets.spreadsheets.values.batchGet(params);
      request.then(function(response) {
        var apiEditors = response.result.valueRanges[0].values
        rangeLength = response.result.valueRanges[0].values.length;
        if(regionSpecificEditors) {
            var filteredArr = apiEditors.filter(setFilter);
            function setFilter(element, index, array) {
                return array[index][2] !== true;
            }
            apiEditors = filteredArr;
        }
        apiEditors.forEach(function(element,index,array){
 console.log(element);
            discordEditors.push(array[index]);
            if(apiEditors[index][1] === true) {
            }
            if(apiEditors[index][1] === true) {
                discordEditors[index][1] = true;
            } else {
                discordEditors[index][1] = '';
            }
            if(regionSpecificEditors === false) {
                if(apiEditors[index][2] === true) {
                    discordEditors[index][2] = true;
                } else {
                    discordEditors[index][2] = '';
                }
            }

        });
  debugger;
      totalNotInRegion = rangeLength - discordEditors.length;
 console.log(discordEditors + ' and discord editor length is ' + discordEditors.length);
      var stringArr = [];
      var testArr = [];
      var a = discordEditors.reduce(function(accum, value, idx, array)
        {
          var string = array[idx][0].toString().trim().toLowerCase();
          if(stringArr.indexOf(string)<0) {
              stringArr.push(string);
              testArr.push(value);
              accum = testArr;
              return accum;
          }
        },[]);
      duplicatesRemoved = discordEditors.length - testArr.length;
      discordEditors = testArr;
debugger;
      }, function(reason) {
        console.error('error: ' + reason.result.error.message);
      });
    }
      var timeoutCounter=0;
    c();
    function c() {
        var waitTime=400;

        var g_Wait;
debugger;
        if((discordEditors.length + totalNotInRegion + duplicatesRemoved) === rangeLength && rangeLength > 300) {
            clearTimeout(g_Wait);
            connectWazeAPI();
        } else {
            timeoutCounter += 1;
            g_Wait = setTimeout(function d() {
            c();},400);
        }
    }
    timeoutCounter =0;
    a();
    function a() {
      var wait;
      var waitTime=1000;
      if (profilePageErrors + validatedProfileCount + seniorEditor + inactiveEditors === discordEditors.length && discordEditors.length > 0) {
        clearTimeout(wait);
        blnReadyToBuildTable = true;
        buildWebDisplay();
      } else {
          wait = setTimeout(function b() {
          timeoutCounter += 1;
          a();}, 1000);
      }
    }
    function connectWazeAPI() {
      function Editor(name, rank, firstEditDate, totalEdits,editHistory, milestone, rate, lastEditDate, milliFirstEditDate, sevenDayEdits,rankLocked, blnNotHomeRegion)
        {
            console.log('at connect waze api');
          this.name = name;
          this.rank = rank;
          this.firstEditDate = firstEditDate;
          this.totalEdits = totalEdits;
          this.editHistory = editHistory;
          this.sevenDayEdits = sevenDayEdits;
          this.milestone = milestone;
          this.rate = rate;
          this.lastEditDate = lastEditDate;
          this.milliFirstEditDate = milliFirstEditDate;
          this.rankLocked = rankLocked;
          this.notHomeRegion = blnNotHomeRegion;
        }
      function pullEditorInfo(element, index, array) {

        var wazeURL = 'https://www.waze.com/user/editor/';
        $.ajax({
          url: wazeURL + array[index][0],
          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;
            if(cdata.firstEditDate === undefined) {
                profilePageErrors += 1;
                console.log(`${cdata.username} has no valid date.`);
                return;
            }
            editors[validatedProfileCount] = new Editor(cdata.username, parseInt(cdata.rank + 1), cdata.firstEditDate, cdata.edits, cdata.editingActivity);
            var active = -1;
            editors[validatedProfileCount].lastEditDate = findLastEditDate(editors[validatedProfileCount]);
            editors[validatedProfileCount].milliFirstEditDate = cdata.firstEditDate;
            if (array[index][1] === true) {
                editors[validatedProfileCount].rankLocked = true;
            } else {
                editors[validatedProfileCount].rankLocked = false;
            }
            if (array[index][2] === true) {
                editors[validatedProfileCount].notHomeRegion = true;
            } else {
                editors[validatedProfileCount].notHomeRegion = false;
            }
            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;
                  active = index;
                }
              });
              var today = new Date();
              var lastDayMS = 0;
              if (active > -1) {
                  lastDayMS = active * 24 * 60 * 60 * 1000;
              } else {
                  lastDayMS = 92 * 24 * 60 * 60 * 1000;
                  inactiveEditors += 1;
              }
              var lastDate = new Date(today - lastDayMS);
              return lastDate.toLocaleDateString();

            } // end of findLastEditDate
            if (active > -1) {
                validatedProfileCount += 1;
                switch (parseInt(cdata.rank + 1)) {
                    case 1:
                        L1Editors += 1;
                        L1Edits += cdata.editingActivity.reduce(reducer);
                        break;
                    case 2:
                        L2Editors += 1;
                        L2Edits += cdata.editingActivity.reduce(reducer, 0);
                        break;
                    case 3:
                        L3Editors += 1;
                        L3Edits += cdata.editingActivity.reduce(reducer, 0);
                        break;
                    case 4:
                        L4Editors +=1;
                        L4Edits += cdata.editingActivity.reduce(reducer, 0);
                        break;
                    case 5:
                        L5Editors +=1;
                        L5Edits += cdata.editingActivity.reduce(reducer, 0);
                        return;
                        break;
                    case 6:
                    case 7:
                        return;
                        break;
                }
                function reducer(accumulator, value) {
                    return accumulator + value;
                }
                totalEditors = L1Editors + L2Editors + L3Editors + L4Editors + L5Editors;
            }
          },
          error: function(XMLHttpRequest, textStatus, errorThrown) {
            profilePageErrors += 1;
          }
        }); // end of ajax

      } // end of pullEditorInfo
      discordEditors.forEach(pullEditorInfo);
    } // end of connectWazeAPI

    function buildWebDisplay()
    {
      var editorHTML='';
      var regionEditorsHTML = '<div class = "table-area1"><button  type = "button" id = "save-locked">Save Locked Editors</button>'
      + '<button type ="button" id = "save-nonRegion">Save Non-region Editors</button><div id = "total-editors">'
      + '</div><div id = regions-edits></div>'
      + '<pre tr:nth-child(even) {background: #CCC} tr:nth-child(odd) {background: #FFF}</pre> <table id= "region-table">'
      + '<thead id = "the-head"><tr><th id= "name" class = "col1 columz"><button type="button" id="sort-name" '
      + '>Name</button></th><th id="level" class = "col2 columz"><button type = "button" id = "sort-level">Level</button></th><th id= "locked" class = '
      + '"col3 columz"><button type = "button" id = "sort-locked">Locked</button></th><th id="began" class = "col4 columz">'
      + '<button type = "button" id= "sort-began">Editing Since</button>'
      + '</th><th id="total-edits" class = "col5 columz"><button type = "button" id= "sort-edits">Total Edits</button>'
      + '</th><th id="milestone" class = "col6 columz"><button type = "button" id = "sort-milestone">Milestone</button></th>'
      + '<th id = "last-edit" class = "col6A columz"><button type = "button" id = "sort-last-edit-date">Last Edit Date</button></th>'
      + '<th id="rate" class = "col7 columz"><button type = "button" id = "sort-rate">Edits(L1:7 days, >L1:30 days)</button></th>'
      + '<th id = "outside-SER" class = "col7A columz"><button type = "button" id = "sort-outsideSER">Not Normally a SER Editor</button></th>'
      + '<th id = "milliDate" class = "col8 columz">msDate</tr></thead><tbody id = "theTable-body">';

      editors.forEach(addStatsToTable);
      function addStatsToTable(element, index, array)
      {
        function convertSecondsToDate(sec) {
          var a = new Date(sec).toLocaleDateString();
          if (array[index].firstEditDate !== NaN){
              array[index].firstEditDate = a;
              return a;
          } else {
              console.log( `array[index] first edit date is not a number. array[index].name`);

          }
        }
        var startDate = convertSecondsToDate(editors[index].firstEditDate);
        var rate = editRate(editors[index]);
        function editRate(rateEditor)
        {
          var period;
          if (rateEditor.rank !== NaN) {
              if (rateEditor.rank=== 1) {
                  period = 7;
              } else if (rateEditor.rank >= 2) {
                  period = 30;
              }
          } else {
              console.log(rateEditor.name + ' does not have a valid rank.');
          }
          function sumEdits(accumulator, currentValue) {
            return accumulator + currentValue;
          }
          if (rateEditor.editHistory.length === 0) {
              console.log(rateEditor.name + 'does not have a valid edit history. ' );
          } else {
              var a = rateEditor.editHistory.slice(rateEditor.editHistory.length - period);
//              console.log(rateEditor.name, rateEditor.editHistory.length, "period: " + period, rateEditor.editHistory.length-period);
              var b = a.reduce(sumEdits);
//              console.log('edit rate is ' + b);
              rateEditor.rate = b;
              return b;
          }
        } // end of editRate function
        var mileStr = milestone(editors[index]);
        function milestone(curEditor)
        {
          switch (curEditor.rank) {
            case 1:
              if(curEditor.totalEdits > 1000) {
                return curEditor.milestone = 'true, total edits';
              } else if ((curEditor.totalEdits + rate)>3000) {
                return curEditor.milestone = 'true, edit rate';
              } else if (rate > 1000) {
                return curEditor.milestone = 'true, edit rate';
              } else if (curEditor.totalEdits > 400) {
                  return curEditor.milestone = 'initial review required';
              } else {
                return curEditor.milestone = 'false';
              }
            break;
            case 2:
              if (curEditor.totalEdits>20000) {
                return curEditor.milestone = 'true, edits';
              } else if ((curEditor.totalEdits + rate)>25000) {
                return curEditor.milestone = 'true, 30 day edit rate'
              } else {
                return curEditor.milestone = 'false';
              }

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

          }

        }  // end of milestone function
        var regionStatus = '';
        if(editors[index].notHomeRegion === true) {
            regionStatus = 'not-home';
        } else {
            regionStatus = 'home';
        }

        var lockStatus = '';
        if(editors[index].rankLocked === true) {
            lockStatus = 'locked';
        } else {
            lockStatus = 'not-locked';
        }
        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 = "locked" class = "col3" ><input class = ' + lockStatus + ' type = "checkbox" /><td headers="began" class = "col4">' + startDate + '</td><td headers="total-edits" '
         + 'class = "col5">' + editors[index].totalEdits
         + '</td>' + '<td headers="milestone" class = "col6">' + mileStr + '</td><td headers = "last-edit" class = "col6A">' + editors[index].lastEditDate + '<td headers="rate" class = "col7">' + rate + '</td>'
         + '<td headers = "outside-SER" class = "col7A"><input class = ' + regionStatus + ' type = "checkbox" />'
         + '<td headers="msDate" class = "col8">' + editors[index].milliFirstEditDate + '</td></tr>';
//console.log('editor HTML follows:')
//          console.log(`<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 = "locked" class = "col3"><input type = "checkbox" /><td headers="began" class = "col4"> ${startDate} </td><td headers="total-edits"
//class = "col5"> ${editors[index].totalEdits}
//</td><td headers="milestone" class = "col6"> ${mileStr} </td><td headers="rate" class = "col7"> ${rate}  </td>
//`);
      } // end of addStatsToTable

      var closingHTML ='</tbody></table></div>';
      $(".recent-edits-content").remove()
      $('#recent-edits').append(regionEditorsHTML + editorHTML + closingHTML);
 //     $('#header').after(regionEditorsHTML + editorHTML + closingHTML);
      $('.tbl-link').attr('target', '_blank');
      $('.table-area1').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":"25px"});
       $('.col4').css({"width":"30px"});
       $('.col5').css({"width":"35px"});
       $('.col6').css({"width":"30px"});
       $('.col6A').css({"width":"30px"});
       $('.col7').css({"width":"30px"});
       $('.col7A').css({"width":"35px"});
       $('.col8').css({"width":"20px", "display": "none"});
       $('.table-rows').css({"border": "solid thin"});
       $('#sort-rate').css('fontSize', '8px');
       $('.columz').attr('title', 'Click to sort.  After the sort is complete, a second click will sort in reverse order.');
       $("tr:even").css("background-color", "#CCC");
       $('#total-editors').html(`Total Editors: ${totalEditors} (L1: ${L1Editors}, L2: ${L2Editors}, L3: ${L3Editors}, L4: ${L4Editors}, L5: ${L5Editors})`);
       $('#regions-edits').html(`Total Edits last 90 days... (L1: ${L1Edits.toLocaleString()}, L2: ${L2Edits.toLocaleString()}, L3: ${L3Edits.toLocaleString()}, L4: ${L4Edits.toLocaleString()}, L5: ${L5Edits.toLocaleString()})`);
       $('.locked').prop('checked', true);
       $('.not-locked').prop('checked', false);
       $('.not-home').prop('checked',true);
       $('.home').prop('checked', false);
       $(document).on('change', '.locked', function () {
           if ($(this).prop('checked')) {
               blnLockChange = true;
           } else {
               blnLockChange = true;
           }
           beCareful();
       });
       $(document).on('change', '.not-locked', function () {
           if ($(this).prop('checked')) {
               blnLockChange = true;
           } else {
               blnLockChange = true;
           }
           beCareful();
       });
       $(document).on('change', '.not-home', function () {
           if ($(this).prop('checked')) {
               blnHomeRegionChange = true;
           } else {
               blnHomeRegionChange = true;
           }
           beCareful();
       });
       $(document).on('change', '.home', function () {
           if ($(this).prop('checked')) {
               blnHomeRegionChange = true;
           } else {
               blnHomeRegionChange = true;
           }
           beCareful();
       });
      function beCareful() {
          if (alreadyWarned === false) {
              alert('Changes will not be saved unless you click on the Save Locked Editors or Save Non-Region Editors buttons as appropriate before refreshing this page!');
              alreadyWarned = true;
          }
      }
      var nameAscending = false;
      var levelAscending = false;
      var startAscending = false;
      var totalAscending = false;
      var milestoneAscending = true;
      var rateAscending = false;
      var lockedAscending = false;
      var insideOutsideAsc = false;
      var lastEditAsc = 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, 'col8','region-table');
      },false);
      document.getElementById("sort-locked").addEventListener("click", function() {
          if (lockedAscending) {
              lockedAscending = false;
          } else {
              lockedAscending = true;
          }
          sort(lockedAscending, 'col3', 'region-table');
      }, false);
      document.getElementById("total-edits").addEventListener("click",function() {
        if (totalAscending) {
          totalAscending = false;
        } else {
          totalAscending = true;
        }
        sort(totalAscending,'col5','region-table');
      },false);
      document.getElementById("milestone").addEventListener("click",function() {
        if(milestoneAscending) {
          milestoneAscending = false;
        } else {
          milestoneAscending = true;
        }
        sort(milestoneAscending, 'col6', 'region-table');
      },false);
      document.getElementById("rate").addEventListener("click",function(){
        if (rateAscending) {
          rateAscending = false;
        } else {
          rateAscending = true;
        }
        sort(rateAscending, 'col7', 'region-table');
      },false);
        //last-edit outside-SER
      document.getElementById('last-edit').addEventListener('click', function(){
          if (lastEditAsc){
              lastEditAsc = false;
          } else {
              lastEditAsc = true;
          }
          sort(lastEditAsc, 'col6A', 'region-table');
      }, false);
      document.getElementById('outside-SER').addEventListener('click', function(){
          if (insideOutsideAsc){
              insideOutsideAsc = false;
          } else {
              insideOutsideAsc = true;
          }
          sort(insideOutsideAsc, 'col7A', '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];
                  if(columnClassName !== 'col3') {
                      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);
                      }
                  } else { // element is a checkbox
                      var chk= row.getElementsByClassName(columnClassName)[0];
                      var nextChk = nextRow.getElementsByClassName(columnClassName)[0];
                      if(chk.querySelector("input[type=checkbox]") !== null) { // checkbox case
                          value = chk.querySelector('input[type=checkbox]').checked;
 //                console.log('value is ' + value);
                          nextValue = nextChk.querySelector("input[type=checkbox]").checked;
//                 console.log('nextValue is ' + nextValue);
                      }
                  }

                  if (ascending ? value > nextValue : value < nextValue) {
                      tbody.insertBefore(nextRow, row);
                      unsorted = true;
                  }
              } // end of for
          } // end of while
          $("tr:even").css("background-color", "#CCC");
          $("tr:odd").css("background-color","#fff");
      } //end of sort function


        function storageSave()
        {
            lockedArray = [];
            localStorage.setItem('lockedEditors', JSON.stringify(lockedArray));
            var a = $('.col3 input:checked').map(function() {
                return $(this).closest('tr').find('td:eq(0)').text();
            }).get();
            if (a.length>0) {
                a.forEach(function (element, index, array) {
                    lockedArray.push(array[index]);
                });
            }
            localStorage.setItem('lockedEditors', JSON.stringify(lockedArray));
        } // end of storageSave

    } // end of buildWebDisplay

//       // NO LONGER USED:**********************************************************
//     function makeCSV(arr)
//     {
//       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 make CSV


console.log('end of function executionSequence');
  } // end of executionSequence
  listenMore();
  function listenMore()
  {
      console.log('listenMore');
      if(blnReadyToBuildTable) {
          console.log('save button loaded');
          blnWrite = true;
          document.getElementById("save-locked").addEventListener("click", handleClientLoad);
          document.getElementById("save-nonRegion").addEventListener("click",handleClientLoad);
      } else {
          setTimeout(function() {
              listenMore();
          },10000);
     }
  }
  function addLockedEditors()
    {
 //       console.log(discordEditors);
        if(document.getElementById('save-locked') !== null) {
            idLockedEditors();
        } else {
            setTimeout(function() {
                addLockedEditors();
            },500);
        }
        function idLockedEditors() {
            var pleaseConfirm = false;
            tableUnlockedEditors = [];
            tableLockedEditors = [];
            $.each($("input[class = 'not-locked']:checked"),function () {
                tableLockedEditors.push($(this).closest('tr').find('td:eq(0)').text());
            });
            $.each($("input[class = 'not-locked']:not(:checked"), function() {
                tableUnlockedEditors.push($(this).closest('tr').find('td:eq(0)').text());
            });
            $.each($("input[class = 'locked']:not(:checked)"), function() {
                tableUnlockedEditors.push($(this).closest('tr').find('td:eq(0)').text());
            });
            $.each($("input[class = 'locked']:checked"), function () {
                tableLockedEditors.push($(this).closest('tr').find('td:eq(0)').text());
            });
//            console.log('unlocked edits is ' + tableUnlockedEditors + ' and locked editors is ' + tableLockedEditors);
            var introText = '';
            var moreText = '';

            if(tableLockedEditors.length>0 && tableUnlockedEditors.length === 0) {
//                console.log('locked > 0 and unlocked = 0')
                introText = 'You are about to change the lock status of editors.  With your changes, the following editors will be locked: ' + tableLockedEditors.join(", ") + ".  ";

            }
            if(tableUnlockedEditors.length>0 && tableLockedEditors.length>0) {
//                console.log('unlocked > 0 and locked >0');
                introText = 'You are about to change the lock status of editors.  With your changes, the following editors will be locked: ' + tableLockedEditors.join(", ") + ".  ";
                moreText = 'Additionally, the following editors will be annotated as unlocked: ' + tableUnlockedEditors.join(",");
//             if(tableLockedEditors.length > 0) {
//                 $.each($("input[class= 'locked']:checked"),
//                        function() {
//                     tableLockedEditors.push($(this).closest('tr').find('td:eq(0)').text());
//                 });
            } else if(tableUnlockedEditors.length > 0 && tableLockedEditors.length === 0) {
//                console.log('unlocked > 0 locked = 0');
                introText = 'You are about to change the lock status of editors.  With your changes, the following editors will be unlocked: ' + tableUnlockedEditors.join(", ") + ".  ";
            }
            var finishText = 'Please do not make these changes unless you are absolutely certain of these editors lock status. Click cancel to remove these changes.  ';

            pleaseConfirm = window.confirm(introText + moreText + finishText);
            var blnMatch = false;
            if(pleaseConfirm) {
                if(tableLockedEditors.length > 0) {
//                    console.log('changing lock status');
                    tableLockedEditors.forEach(function (element, index, array) {
                        var test = element.trim();
                        test = test.toLowerCase();
                        //                console.log('...' + test + '...');
                        discordEditors.map(function(element1, index1, array1) {
                            if(array1[index1][0]) {
                                var test1 = array1[index1][0].trim();
                                test1 = test1.toLowerCase();
                                //  var test1 = array1[index1].trim();
                                //                    console.log('...' + test1 + '...');
                                if(test === test1) {
                                    //                        console.log ('string match with ' + test);
                                    var testArr = [test1, true, array1[index1][2]];
                                    array1.splice(index1, 1, testArr);
                                    blnMatch = true;
                                    return;
                                }
                            }
                        }); // end of discordEditors map function
                        if(blnMatch=== false) {
                            console.log('no match found for ...' + array[index] + '...');
                        } else {
                            blnMatch = false;
                        }
                    }); // end of tableLockedEditors forEach function
               } // end of tableLockedEditors > 0 if statement
               if(tableUnlockedEditors.length > 0) {

                    tableUnlockedEditors.forEach(function (element, index, array) {
                        var test = element.trim();
                        test = test.toLowerCase();
                        discordEditors.map(function(element1, index1, array1) {
                            if(array1[index1][0]) {

                                var test1 = array1[index1][0].trim();
                                test1 = test1.toLowerCase();
                                if(test === test1) {
                                    //                        console.log ('string match with ' + test);
                                    var testArr = [test1,'', array1[index1][2]];
                                    array1.splice(index1, 1, testArr);
                                    blnMatch = true;
 //                                   console.log('match');
                                    return;
                                }
                            }
                        }); // end of discordEditors map function
                        if(blnMatch=== false) {
                            console.log('no match found for ...' + array[index] + '...');
                        } else {
                            blnMatch = false;
                        }
                    }); // end of tableUnlockedEditors forEach function
               } // end of tableUnlockedEditors > 0 if statement
               tableLockedEditors = [];
               tableUnlockedEditors = [];

            } else {
                $('.locked').prop('checked', true);
                $('.not-locked').prop('checked', false);
                tableLockedEditors = [];
                tableUnlockedEditors = [];
            }
            console.log(discordEditors);



    } // end of idLockedEditors
    var valueRangeBody = {
        values: discordEditors
    };
    var params = {
        spreadsheetId: spreadsheetId, //TODO: Update placeholder value.
        range: ssRange,
        valueInputOption: 'RAW'
    };
//            console.log(params);
//            console.log(valueRangeBody);
    var request = gapi.client.sheets.spreadsheets.values.update(params, valueRangeBody);
    console.log('here');
    request.then(function(response) {
        // TODO: Change code below to process the `response` object:
        console.log('response is ' + response.result);
    }, function(reason) {
         console.error('google sheets error: ' + reason.result.error.message);
    });
    } // end of addLockedEditors
  function handleNonRegionEditors()
    {

 //       console.log(discordEditors);
        if(document.getElementById('save-nonRegion') !== null) {
            idNonRegionEditors();
        } else {
            setTimeout(function() {
                handleNonRegionEditors();
            },500);
        }
        function idNonRegionEditors() {
            var pleaseConfirm = false;
            homeRegion = [];
            notHomeRegion = [];
            $.each($("input[class = 'not-home']:not(:checked)"), function () {
                notHomeRegion.push($(this).closest('tr').find('td:eq(0)').text());  // these are editors moving back into SER as primary region
            });
            $.each($("input[class = 'not-home']:checked"), function () {
                homeRegion.push($(this).closest('tr').find('td:eq(0)').text());  // these are editors moving out of the SER as primary region
            });
            $.each($("input[class = 'home']:checked"),function() {
                homeRegion.push($(this).closest('tr').find('td:eq(0)').text()); // these are editors moving out of the SER as their primary region
            });
            $.each($("input[class = 'home']:not(:checked)"),function() {
                notHomeRegion.push($(this).closest('tr').find('td:eq(0)').text()); // these are editors moving back into the SER as their primary region
            });
            var introText = '';
            var moreText = '';

            if(notHomeRegion.length>0 && homeRegion.length === 0) {

//                console.log('locked > 0 and unlocked = 0')
                introText = 'You are about to change the status of editors that edit primarily in the SER.  ';
                moreText = '';
            }
            if(homeRegion.length>0 && notHomeRegion.length>0) {

//                console.log('unlocked > 0 and locked >0');
                introText = 'You are about to change the status of editors, indicating additional editors that do not edit primarily in the SER. ';
                moreText = 'Additional changes will add editors to the list of those that primarily edit in the SER.  '

            } else if(homeRegion.length > 0 && notHomeRegion.length === 0) {

//                console.log('unlocked > 0 locked = 0');
                introText = 'You are about to change the status of editors, indicating additional editors that do not edit primarily in the SER. ';
                moreText = '';
            }
            var finishText = 'Please do not make these changes unless you are absolutely certain of these editors status.  Click cancel to remove these changes.  '

            pleaseConfirm = window.confirm(introText + moreText + finishText);

            var blnMatch = false;
            if(pleaseConfirm) {
                if(notHomeRegion.length > 0) { // deal with editors that were intially not primary to SER but are now.
//
                    notHomeRegion.forEach(function (element, index, array) {
                        var test = element.trim();
                        test = test.toLowerCase();
                        discordEditors.map(function(element1, index1, array1) {
                            if(array1[index1][0]) {
                                var test1 = array1[index1][0].trim();
                                test1 = test1.toLowerCase();
                                if(test === test1) {
                                    console.log ('string match with ' + test);

                                    var testArr = [test1,array1[index1][1],''];
                                    array1.splice(index1, 1, testArr);
                                    blnMatch = true;
                                    return;
                                } else {
                                    console.log('no match found for ' + test);
                                }
                            }
                        }); // end of discordEditors map function
                        if(blnMatch=== false) {
console.log('no match found for ...' + array[index] + '...');
                        } else {
                            blnMatch = false;
                        }
                    }); // end of notHomeRegion forEach function
               } // end of notHomeRegion > 0 if statement
               if(homeRegion.length > 0) { // deal with editors that were initally SER as primary but are no more

                    homeRegion.forEach(function (element, index, array) {
                        var test = element.trim();
                        test = test.toLowerCase();
                        discordEditors.map(function(element1, index1, array1) {
                            if(array1[index1][0]) {

                                var test1 = array1[index1][0].trim();
                                test1 = test1.toLowerCase();
                                if(test === test1) {
                                    var testArr = [test1,array1[index1][1],true];
                                    array1.splice(index1, 1, testArr);
                                    blnMatch = true;
                                    console.log('match for' + test);
                                    return;
                                } else {
                                    console.log('no match for ' + test);
                                }
                            }
                        }); // end of discordEditors map function
                        if(blnMatch=== false) {
                            console.log('no match found for ...' + array[index] + '...');
                        } else {
                            blnMatch = false;
                        }
                    }); // end of tableUnlockedEditors forEach function
               } // end of tableUnlockedEditors > 0 if statement
               notHomeRegion = [];
               homeRegion = [];

            } else {
                $('.not-home').prop('checked', true);
                $('.home').prop('checked', false);
                homeRegion = [];
                notHomeRegion = [];
            }
            console.log(discordEditors);


    } // end of idNonRegionEditors
    var valueRangeBody = {
        values: discordEditors
    };
    var params = {
        spreadsheetId: spreadsheetId, //TODO: Update placeholder value.
        range: ssRange,
        valueInputOption: 'RAW'
    };
//            console.log(params);
//            console.log(valueRangeBody);
    var request = gapi.client.sheets.spreadsheets.values.update(params, valueRangeBody);
    console.log('here');
    request.then(function(response) {
        // TODO: Change code below to process the `response` object:
        console.log('response is ' + response.result);
    }, function(reason) {
         console.error('google sheets error: ' + reason.result.error.message);
    });
    } // end of handleNonRegionEditors


bootstrap();
console.log('finished the script');
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址