WME Review Edits

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         WME Review Edits
// @namespace    https://greasyfork.org/en/scripts/382070-wme-reviewedits
// @version      2024-09-25
// @description  copies information from WME and adds to google sheet for record of reviewed edits.
// @author       ramblinwreck_81
// @match         https://*.waze.com/*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: "",
        date: ""
    }

    function RE_log(message) {
        console.log(`Review Edits: ${message}`);
    }


    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,})
    }
    getUserName(); // looks on editor profile page for reviewed editor info
    function getUserName(tries = 0) {
        if (window.location.href.indexOf("https://www.waze.com/user/editor/") > -1)
        {
            if ((W.EditorProfile.data == undefined) && tries < 30) {
                setTimeout(() => getUserName(++tries), 100);

            } else {
                localStorage.setItem("reviewEditsEditor", W.EditorProfile.data.username);
                localStorage.setItem("RE_rank", W.EditorProfile.data.rank + 1);
                localStorage.setItem("RE_eID", W.EditorProfile.data.userID);
 //               profilePageTested = 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.detail.selected[0]?._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.detail.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.getSelectedWMEFeatures()[0];
                callback();
                RE_log('callcount: ' + callCount);
            } else if (callCount < 30) {
                setTimeout(() => RE_waitForSegmentEditDiv(callback, ++callCount), 100);
            }
        }
        function RE_addFormBtn() {
            RE_log(`adding form button`);
            const selection = W.selectionManager.getSelectedWMEFeatures();
            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);
            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();
                if (localStorage.getItem("reviewEditsEditor") !== "")
                {
                    objEditor.name = localStorage.getItem("reviewEditsEditor");
                    objEditor.iD = localStorage.getItem("RE_eID");
                    objEditor.rank = localStorage.getItem("RE_rank");
                } else
                {
                    alert("No editor information is available.  Before attempting to open the review edits form, open " +
                          "the respective editor profile page. Keep the profile page open while conducting the review." );
                    RE_log("No information available for reviewed editor.");
                    return;
                }
                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);
                }
            }; // end of onclick function
            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[0]._wmeObject.type === "venue")
                { // code for selection is a place venue
                    RE_log(`Venue selected!`)
                    // works for point and area places
//                     glat = selected[0]._wmeObject.attributes.geometry.y;
//                     glon = selected[0]._wmeObject.attributes.geometry.x;
//                     latLon = WazeWrap.Geometry.ConvertTo4326(glon, glat);
//                     lat = latLon.lat;
//                     lon = latLon.lon;
                    latLon = WazeWrap.Geometry.ConvertTo4326(W.map.getOLMap().center.lon, W.map.getOLMap().center.lat)
                    lat = latLon.lat;
                    lon = latLon.lon;
                    permalink += "env=" + env + "&lon=" + lon + "&lat=" + lat + "&zoomLevel=" + zoom.toString() + "&venues=" + selected[0].id;
                } else
                { // code for if selection is a segment(s)
                    type = 'segments'
                    var i;

                    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]._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_createFormLink(formSel)
        {
            const selection = W.selectionManager.getSelectedWMEFeatures();
            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();
                checkForVenue();
            }
        function checkForVenue()
        {
            if (venuesObject === undefined)
            {
                setTimeout (function()
                            {
                               checkForVenue();
                            }, 200);
            } else
            {
                completeForm();
                return;

            }
        }

        function obtainVenuesObject()
        {
           var editorActivities = [];
           var lastDate;
           var a;
           var selection = W.selectionManager.getSelectedWMEFeatures();
//           var eID;
           var selectedObject = W.selectionManager.getSelectedWMEFeatures()[0]._wmeObject.type;
//               console.log('RPP');
               var objId = selection[0]._wmeObject.attributes.id;
               var objUrl = "https://www.waze.com/Descartes/app/ElementHistory?objectType=" + selectedObject + "&objectID=" + objId;
               a = $.ajax(
                   {
                   url:objUrl,
                   datatype: 'json',
                   data: {},
                   success: function(data)
                       {
                          console.log('Descartes API call complete.')
                       },
//                   async: true
                   }).responseJSON.transactions.objects;
               console.log(a);
               // now compare username in "objEditor" to the API returned list of usernames.
               if (objEditor.name !== "")
               {
                   a.forEach((element, index) =>
                         {
                             if ((a[index].userID).toString() === objEditor.iD )
                                 {
                                     editorActivities.push(a[index].date)
                                 }

                        });
                   console.log(editorActivities);
                   switch (editorActivities.length)
                   {
                       case 0:
                       // editor name is not on the Waze map object
                           alert("The editor under review was not located on the selected map object.  Make sure " +
                                 "the editor you are reviewing has an open profile page, and if it is already open, " +
                                 "reload the profile page and try again.  Or, search for this editor on a different map object.")
                           lastDate = 0;
                           break;
                       case 1:
                           lastDate = editorActivities[0];
                           break;
                       default:
                       // editor's name appears more than once so get the most recent edit date
                       lastDate = editorActivities[0]
                       editorActivities.forEach((element, index) =>
                           {
                               if (element > lastDate)
                           {
                               lastDate = element;
                           }
                       });
                   } // end switch
               } // end of if objEditor.name is undefined
               const date = new Date(lastDate);
               const formattedDate = date.toLocaleDateString('en-US', { year: 'numeric', month: 'numeric', day: 'numeric'})
               objEditor.date = formattedDate;


//             { // 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
        } // end of obtainVenuesObject
        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);
                            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] = objEditor.date;
                        break;
                    case "editorName":
 //                       var c = RE_getLastEditor(selection);
                        formValues[key] = objEditor.name;
                        break;
                    case "nameOfVenue":
                        if(selection[0]._wmeObject.type === 'venue')
                        {
                            if(selection[0]._wmeObject.attributes.residential === true)
                            {
                                formValues[key] = 'RPP';
                            } else
                            {
                                formValues[key] = selection[0]._wmeObject.attributes.name;
                            }
                        } else
                        {
                            formValues[key] = 'N/A';
                        }
                        break;
                    case "editorRank":
                        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;
                } // end of switch

                //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]);
                }
            });
        } // end of completeForm
        formLink += formArgs.join("&entry.");
        if (objEditor.date === "12/31/1969")
        {
            return;
        } else
        {
            RE_log(`${formLink}`);
            objEditor.name = '';
            objEditor.rank = '';
            objEditor.iD = '';
            return formLink;
        }
    } // end of createFormLink


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

        if (!W.selectionManager.getSelectedWMEFeatures)
        {
            W.selectionManager.getSelectedWMEFeatures = 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;
    }
})();