WME Review Edits

copies information from WME and adds to google sheet for record of reviewed edits.

当前为 2023-10-07 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         WME Review Edits 
// @namespace    https://greasyfork.org/en/scripts/382070-wme-reviewedits
// @version      2023-Oct-07
// @description  copies information from WME and adds to google sheet for record of reviewed edits.
// @author       ramblinwreck_81
// @match     https://www.waze.com/en-US/editor*
// @exclude      https://www.waze.com/user/editor*
// @grant        none
// @require      https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js

// ==/UserScript==
//  Much credit to crazycaveman's form filler script where a lot of this code came from./*global W, $, WazeWrap */

(function() {
    'use strict';

    var RE_Name = GM_info.script.name;
    var RE_Version = GM_info.script.version;
    var settings = {};
    var venuesObject;
    var eID;
    var rank;
    var geoOffset = 'nada';
    var objectType = '';
    var RE_Element = "";
    var maxSelectedSegments = 0;

    const objEditor = {
        name: "",
        iD: "",
        rank: "",
    }
    //var ourEditor = '';
    function RE_log(message) {
        console.log(`Review Edits: ${message}`);
    }
    debugger;


    if(W?.userscripts?.state.isReady) {
        console.log("user:", W.loginManager.user);
        console.log("segments", W.model.segments.getObjectArray());
    } else {
        document.addEventListener("wme-ready", RE_init, {
            once: true,})
    }
    function RE_init(){
        console.log('good results');
        const { tabLabel, tabPane } = W.userscripts.registerSidebarTab("SER Review Edits");

        tabLabel.innerText = 'SER Review Edits';
        //    tabLabel.title = 'Cool script';
        tabPane.innerHTML = tabBuilder();
        //    tabPane.innerHTML = "<h1>HELLO WORLD!</h1>";

        tabPane.addEventListener("element-connected", () => {
            // at this point the tabPane is in the DOM
            RE_log('tab pane added')
            RE_addUserTab();
        }, { once: true });


        var newEdName = "";
        var editorURL = '';
        var RE_Element;
         W.selectionManager.events.on('selectionchanged', evt => {
             RE_Element = document.getElementById("reviewEditsDiv");
             if(!(RE_Element)) {
                 const model = evt.selected[0]?.attributes?.wazeFeature?._wmeObject;
                 if(model?.type === 'segment') {
                     objectType = 'segment';
 //                    if (evt.selected.length === 1){ // && maxSelectedSegments === 1) {
                         RE_waitForSegmentEditDiv(RE_addFormBtn);
//                     } else {
//                     }
                 }
                 if(model?.type === 'venue' || model?.type === 'residential') {
                     if (evt.selected.length === 1) {

                         objectType = 'venue';
                         RE_waitForSegmentEditDiv(RE_addFormBtn);

                     }
                 }
             }
         });
        function RE_waitForSegmentEditDiv(callback, callCount = 0) {
            const div_S = $('div.segment-edit-section');
            const div_V = $('div.venue-edit-section');
            if ((div_S.length) || (div_V.length)) {
                RE_log('div_S: ' + div_S.length + 'div_V.length: ' + div_V.length);
                const selection = W.selectionManager.getSelectedFeatures()[0];
                callback();
                RE_log('callcount: ' + callCount);
            } else if (callCount < 30) {
                setTimeout(() => RE_waitForSegmentEditDiv(callback, ++callCount), 100);
            }
        }
        function RE_addFormBtn() {
            RE_log(`adding form button`);
//            var selection = W.selectionManager.getSelectedFeatures();
            const selection = W.selectionManager.getSelectedFeatures();
            var REDiv = document.createElement("div"),
                REMnu = document.createElement("select"),
                REBtn = document.createElement("button");
            var formWindowName = "Review Edits result",
                formWindowSpecs = "resizable=1,menubar=0,scrollbars=1,status=0,toolbar=0";
            var editPanel,
                selElem,
                formLink;
            REDiv.id = "reviewEditsDiv";
            REDiv.className = "reviewEditsWrapper";
            //          REDiv.id = "reviewEditsDiv";
            editPanel = document.getElementById("edit-panel");
            RE_Element = "div." + objectType + "-feature-editor";
            selElem = document.querySelector(RE_Element);
debugger;
            if (selection.length === 0) {
                console.log('no selection has been made');
            }
            if (document.getElementById("reviewEditsDiv") !='undefined' && document.getElementById("reviewEditsDiv") != null) {
                RE_log('element reviewEditsDiv already exists and you are adding another.')
            }

            var forms = [{
                name: "SER Editor Review",
                // testing url: "https://docs.google.com/forms/d/e/1FAIpQLSepKZpDjeHySl95eArUn5iwTuOTUPvpz0ZvqaHg7LbvmBB1Lw/viewform",
                url: "https://docs.google.com/forms/d/e/1FAIpQLSfc27FGWsN2RoX8WXYAYZ2xVIkJ1cI8u85ezV--AYsBCVuVKg/viewform",
                fields: {
                    editDate: "150500272",
                    specificPermalink: "760385393",
                    reviewingEditor: "1935699410",
                    sentToEditorPL: "325109063",
                    editorName: "343499315",
                    nameOfVenue: "418181794",
                    editorRank: "986567855"
                }
            }];

            forms.forEach(function (key, i) {
                REMnu.options.add(new Option(forms[i].name, i));
            });
            REBtn.innerHTML = "Go to Form";
            REBtn.onclick = function () {
                //alert(ffMnu.options[ffMnu.selectedIndex].value+": "+forms[ffMnu.options[ffMnu.selectedIndex].value].name);
                RE_saveSettings();
                formLink = RE_createFormLink(forms[REMnu.options[REMnu.selectedIndex].value]);
                if (typeof formLink === "undefined") {
                    return;
                }

                if ($("#RE-open-in-tab").prop("checked")) {
                    window.open(formLink, "_blank");
                } else {
                    window.open(formLink, formWindowName, formWindowSpecs);
                }
            };
            if (selection.length > 0) {
                REDiv.appendChild(REMnu);
                REDiv.appendChild(REBtn);
                $(RE_Element)[0].prepend(REDiv);

                //                return;
            }
        } // end of RE_addFormBtn
        function createURL(selected)
        {
            var permalink = "https://www.waze.com/en-US/editor?",
            segIDs = [];
            var latLon;
            var lat;
            var lon;
            var glat;
            var glon;
            var env = W.location ? W.location.code : W.app.getAppRegionCode();
            var zoom = W.map.olMap.zoom;
            var latOffset;
            var lonOffset;
            var zoomOffset;
            var type;
//            var rank = venuesObject.rank + 1;
            geoOffset = setGeoOffset(rank);
            zoomOffset = 17;
            if (selected.attributes.wazeFeature._wmeObject.type === "venue") { // code for selection is a place venue
                RE_log(`Venue selected!`)
                // works for point and area places
                glat = selected.geometry.bounds.bottom;
                glon = selected.geometry.bounds.left;
                latLon = WazeWrap.Geometry.ConvertTo4326(glon, glat);
                lat = latLon.lat;
                lon = latLon.lon;
                permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoomLevel=" + zoom.toString() + "&venues=" + W.selectionManager.getSelectedFeatures()[0].attributes.wazeFeature._wmeObject.attributes.id;

            } else { // code for if selection is a segment(s)
                type = 'segments'
                var i;
//                if (selection.length === 1) {
//                   latLon = selection[0].model.getCenter().clone();
//                    latLon = WazeWrap.Geometry.ConvertTo4326(latLon.x,latLon.y)

                    latLon = WazeWrap.Geometry.ConvertTo4326(W.map.getOLMap().center.lon, W.map.getOLMap().center.lat);
                    lat = latLon.lat;
                    lon = latLon.lon;
//                }

                var zoomToRoadType = function (e) {
                    switch (e) {
                        case 12:
                        case 13:
                            return [];
                        case 14:
                            return [2, 3, 4, 6, 7, 15];
                        case 15:
                            return [2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
                        case 16:
                        case 17:
                        case 18:
                        case 19:
                        case 20:
                        case 21:
                        case 22:
                        default:
                            return [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22];
                   }
                };
                for (i = 0; i < selected.length; i += 1) {
                    var segment = selected[i].attributes.wazeFeature._wmeObject;
                    if (segment.type === "segment")
                    {
                        segIDs.push(segment.attributes.id);
                        if (zoomToRoadType(zoom) === 0 || zoomToRoadType(zoom).indexOf(segment.attributes.roadType) === -1)
                        {
                            alert("This zoom level (" + zoom.toString() + ") cannot be used for this road type! Please increase your zoom:\n" +
                                  "Streets: 16+\nOther drivable and Non-drivable: 15+\nHighways and PS: 14+");
                            RE_log("Zoom level not correct for segment: " + zoom.toString() + " " + segment.attributes.roadType.toString());
                            return;
                        }
                    }
                }
                permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoomLevel=" + zoom.toString() + "&" + type + "=" + segIDs.join();
            } // end of model.type if test
            latOffset = lat + geoOffset;
            lonOffset = lon - geoOffset;
            function setZoom(level)
            {
                switch (level)
                {
                    case 1:
                    case 2:
                        zoomOffset = 7;
                        break;
                    case 3:
                        zoomOffset = 6;
                        break;
                    case 4:
                        zoomOffset = 6;
                        break;
                    case 5:
                    case 6:
                        zoomOffset = 6;
                        break;
                }
                return zoomOffset;
            }
            function setGeoOffset(level)
            {
                // Added 1/3/20
                geoOffset = 0;
                return geoOffset;
                switch (level)
                {
                    case 1:
                    case 2 :
                        geoOffset = .003;
                        break;
                    case 3:
                        geoOffset = .004
                        break;
                    case 4:
                        geoOffset = .005
                        break;
                    case 5:
                    case 6:
                        geoOffset = .006
                        break;
                }
                return geoOffset;
            }
            var strStartURL = 'https://www.waze.com/en-US/editor?env=usa&lon=';
            var correctURL;
            var newURL;
            editorURL = strStartURL + lonOffset + '&lat=' + latOffset + '&zoomLevel=' + zoomOffset;
            return permalink;
        } // end of createURL function

        function RE_getLastEditor(selection) {
            var editorNames = "";
            if(selection[0].attributes.wazeFeature._wmeObject.type === "venue") {
                if(selection[0].attributes.wazeFeature._wmeObject.attributes.residential) {
                    return ourEditor;

                } else { // it's a venue but not an RPP
 //                   editorNameConcat(selection);
                    return venuesObject.attributes.userName;
                }
            } else { // it's not a venue, it's a segment or segments
                editorNameConcat(selection[0])
                return editorNames;
            }

            function editorNameConcat(mapObject){
                mapObject.forEach(function (selected) {
                    eID = selected.attributes.wazeFeature._wmeObject.attributes.updatedBy;
                    if (eID === null) {
                        RE_log(`Unable to get updatedBy on ${selected.attributes.wazeFeature._wmeObject.attributes.id}`);
                        eID = selected.attributes.wazeFeature._wmeObject.attributes.createdBy;
                    }
                    newEdName = W.model.users.getObjectById(eID).attributes.userName;
                    if (editorNames.indexOf(newEdName) === -1) {
                        editorNames += ", " + newEdName;
                    }
                });
                editorNames = editorNames.substr(2);
                return editorNames;
            }
        }
        function RE_createFormLink(formSel) {
        const selection = W.selectionManager.getSelectedFeatures();
        var formValues = {};
        var formFields = formSel.fields;
        var formLink = formSel.url + "?entry.";
        var formArgs = [];
        if (selection.length === 0) { // || selection[0].model.type !== "segment") {
            RE_log(`Nothing selected.`);
            return;
        } else
        {
            venuesObject = obtainVenuesObject();
            debugger;
            checkForVenue();
        }
        function checkForVenue()
        {
            if (venuesObject === undefined)
            {
                setTimeout (function()
                            {
                               checkForVenue();
                            }, 200);
            } else
            {
                completeForm();
                return;
            }
        }

        function obtainVenuesObject()
        {
//           var venueEditor;
           var a;
//           var selection = W.selectionManager.getSelectedFeatures();
//           var eID;
           if(selection[0].attributes.wazeFeature._wmeObject.type === "venue" && (selection[0].attributes.wazeFeature._wmeObject.attributes.residential)) {
               console.log('RPP');
               var objId = selection[0].attributes.wazeFeature.id;
               var objUrl = "https://www.waze.com/Descartes/app/ElementHistory?objectType=venue&objectID=" + objId;
               a = $.ajax({
                   url:objUrl,
                   datatype: 'json',
                   success: function(data) {
                       RE_log('Descartes API call complete. Returned was: ' + a)
                   },
                   async: false
               }).responseJSON.users.objects[0];
               console.log(a);
               debugger;
               objEditor.rank = a.rank + 1;
               objEditor.iD = a.id;
               objEditor.name = a.userName
               eID = a.id;
  //             return a;
            } else { // it's either a point place, area place or segment but not an RPP
                eID = selection[0].attributes.wazeFeature._wmeObject.attributes.updatedBy;
                if (eID === null) {
                    RE_log(`Unable to get updatedBy on ${selection[0].attributes.wazeFeature._wmeObject.attributes.id}`);
                    eID = selection[0].attributes.wazeFeature._wmeObject.attributes.createdBy;
                    objEditor.iD = eID;
                    objEditor.name = W.model.users.getObjectById(eID).attributes.userName;
                    objEditor.rank = W.model.users.getObjectById(eID).attributes.rank + 1;
                }
             
           }
             return objEditor
        }
        function completeForm()
        {
            var onePL;
            Object.keys(formFields).forEach(function (key, index) {
                switch (key) {

                    case "reviewingEditor":
                        formValues[key] = W.loginManager.user.attributes.userName;
                        break;
                    case "specificPermalink":
                        onePL = createURL(selection[0]);
                        formValues[key] = onePL;
                        if (typeof formValues.specificPermalink === "undefined") {
                            RE_log(`No permalink generated`);
                            return;
                        }
                        break;
                    case "sentToEditorPL":
                        formValues[key] = onePL;
                        break;
                    case "editDate":
                        var a;
 //                       if(selection[0].attributes.wazeFeature._wmeObject.attributes.updatedOn === undefined)
                        if(W.selectionManager.getSelectedFeatures()[0].attributes.wazeFeature._wmeObject.attributes.updatedOn === null)
                        {
                            a = W.selectionManager.getSelectedFeatures()[0].attributes.wazeFeature._wmeObject.attributes.createdOn;
                        } else
                        {
                            a = W.selectionManager.getSelectedFeatures()[0].attributes.wazeFeature._wmeObject.attributes.updatedOn;
                        }
                        var b = new Date(a).toLocaleDateString();
 //                       var b = new(Date(a).toLocaleDateString();
                        formValues[key] = b;
                        break;
                    case "editorName":
                        debugger;
 //                       var c = RE_getLastEditor(selection);
                        formValues[key] = objEditor.name;
                        break;
                    case "nameOfVenue":
                        if(selection[0].attributes.wazeFeature._wmeObject.type === 'venue')
                        {
                            if(selection[0].attributes.wazeFeature._wmeObject.attributes.residential === true)
                            {
                                formValues[key] = 'RPP';
                            } else
                            {
                                formValues[key] = selection[0].attributes.wazeFeature._wmeObject.attributes.name;
                            }
                        } else {
                            formValues[key] = 'N/A';
                        }
                        break;
                    case "editorRank":
                        debugger;
                        formValues[key] = objEditor.rank;
//                         if(selection[0].attributes.wazeFeature._wmeObject.type === 'venue')
//                         {
//                             formValues[key] = venuesObject.rank + 1;
//                         } else
//                         {
//                             formValues[key] = W.model.users.getObjectById(eID).rank + 1;
//                         }
                        break;
                    default:
                        RE_log(`Nothing defined for ${key}`);
                        break;
                }

                //Add entry to form URL, if there's something to add
                if (typeof formValues[key] !== "undefined" && formValues[key] !== "") {
                    formArgs[index] = formFields[key] + "=" + encodeURIComponent(formValues[key]);
                }
            });
        }
        formLink += formArgs.join("&entry.");

        RE_log(`${formLink}`);
        return formLink;
    } // end of createFormLink


        // Unit switched (imperial/metric)
        if (W.prefs) {
            W.prefs.on("change:isImperial", RE_addUserTab);
        }

        if (!W.selectionManager.getSelectedFeatures) {
            W.selectionManager.getSelectedFeatures = W.selectionManager.getSelectedItems;
        }
        RE_log(`Init done`);
        return;
    } //end of RE_init
    function tabBuilder()
    {
        var $section = $("<div>");
        $section.html([
            '<div id="SER Review Edits">',
            '<h2>Review Edits</h2>',
            '<input type="checkbox" id="RE_Enabled" class="RE_SettingsCheckbox"><label for="RE_Enabled">Enable This Script</label>',
            '<hr>',
            '<hr>',
            '<div>',
            '</div>',
            '</div>'
        ].join(' '));
        return $section.html();
    } // end of tabBuilder function

    function RE_addUserTab() {
        RE_log(`adding tab`);
        var userInfo = document.getElementById("SER Review Edits"),
            REPanel = document.createElement("div"),
            RENewTabBox = document.createElement("input"),
            RENewTabLabel = document.createElement("label"),
            RETabInfo = document.createElement("div");
        REPanel.id = "sidepanel-reviewEdits";
        REPanel.className = "tab-pane";
        RE_log(`name: ${RE_Name}, Version: ${RE_Version}`);
        RETabInfo.innerHTML = '<b>' + RE_Name + '</b> v' + RE_Version;
        RENewTabBox.id = "RE-open-in-tab";
        RENewTabBox.type = "checkbox";
        RENewTabBox.name = "RE_open_tab";
        RENewTabLabel.innerHTML = "Open form in new tab";
        RENewTabLabel.for = "RE_open_tab";
        REPanel.appendChild(RETabInfo);
        REPanel.appendChild(RENewTabBox);
        REPanel.appendChild(RENewTabLabel);
        userInfo.appendChild(REPanel);
        RE_loadSettings();

    }
    function RE_loadSettings() {

        var REOpenInTab = localStorage.getItem("RE-open-in-tab");
        if (REOpenInTab === "1") {
            $("#RE-open-in-tab").trigger("click");
        }
        return;
    }

    function RE_saveSettings() {
        if ($("#RE-open-in-tab").prop("checked")) {
            localStorage.setItem("RE-open-in-tab", "1");
        } else {
            localStorage.setItem("RE-open-in-tab", "0");
        }
        return;
    }
})();