您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
makes working spreadsheet projects easier
// ==UserScript== // @name Spreadsheet Worker // @namespace https://greasyfork.org/en/users/77740-nathan-fastestbeef-fastestbeef // @version 2023.03.17 // @description makes working spreadsheet projects easier // @author FastestBeef // @include https://www.waze.com/editor* // @include https://www.waze.com/*/editor* // @include https://beta.waze.com/editor* // @include https://beta.waze.com/*/editor* // @exclude https://www.waze.com/*user/editor* // @grant none // @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js // ==/UserScript== /* global W */ /* ecmaVersion 2017 */ /* global $ */ /* global WazeWrap */ /* global OpenLayers */ (function() { 'use strict'; const VERSION = GM_info.script.version; const SCRIPT_NAME = GM_info.script.name; const UPDATE_NOTES = ` <p> <ul> <li>Bug Fix.</li> </ul> </p>`; const CAMPAIGN_SHEET_ID = "1vy_28mDW8CDIUUXbUG0XZgCNX7iJ6sdPEtbCvQvXrLs"; const STATES = [ { "name": "Alabama", "abbreviation": "AL" }, { "name": "Alaska", "abbreviation": "AK" }, // { "name": "American Samoa", "abbreviation": "AS" }, { "name": "Arizona", "abbreviation": "AZ" }, { "name": "Arkansas", "abbreviation": "AR" }, { "name": "California", "abbreviation": "CA" }, { "name": "Colorado", "abbreviation": "CO" }, { "name": "Connecticut", "abbreviation": "CT" }, { "name": "Delaware", "abbreviation": "DE" }, { "name": "District Of Columbia", "abbreviation": "DC" }, // { "name": "Federated States Of Micronesia", "abbreviation": "FM" }, { "name": "Florida", "abbreviation": "FL" }, { "name": "Georgia", "abbreviation": "GA" }, // { "name": "Guam Gu", "abbreviation": "GU" }, { "name": "Hawaii", "abbreviation": "HI" }, { "name": "Idaho", "abbreviation": "ID" }, { "name": "Illinois", "abbreviation": "IL" }, { "name": "Indiana", "abbreviation": "IN" }, { "name": "Iowa", "abbreviation": "IA" }, { "name": "Kansas", "abbreviation": "KS" }, { "name": "Kentucky", "abbreviation": "KY" }, { "name": "Louisiana", "abbreviation": "LA" }, { "name": "Maine", "abbreviation": "ME" }, // { "name": "Marshall Islands", "abbreviation": "MH" }, { "name": "Maryland", "abbreviation": "MD" }, { "name": "Massachusetts", "abbreviation": "MA" }, { "name": "Michigan", "abbreviation": "MI" }, { "name": "Minnesota", "abbreviation": "MN" }, { "name": "Mississippi", "abbreviation": "MS" }, { "name": "Missouri", "abbreviation": "MO" }, { "name": "Montana", "abbreviation": "MT" }, { "name": "Nebraska", "abbreviation": "NE" }, { "name": "Nevada", "abbreviation": "NV" }, { "name": "New Hampshire", "abbreviation": "NH" }, { "name": "New Jersey", "abbreviation": "NJ" }, { "name": "New Mexico", "abbreviation": "NM" }, { "name": "New York", "abbreviation": "NY" }, { "name": "North Carolina", "abbreviation": "NC" }, { "name": "North Dakota", "abbreviation": "ND" }, // { "name": "Northern Mariana Islands", "abbreviation": "MP" }, { "name": "Ohio", "abbreviation": "OH" }, { "name": "Oklahoma", "abbreviation": "OK" }, { "name": "Oregon", "abbreviation": "OR" }, // { "name": "Palau", "abbreviation": "PW" }, { "name": "Pennsylvania", "abbreviation": "PA" }, // { "name": "Puerto Rico", "abbreviation": "PR" }, { "name": "Rhode Island", "abbreviation": "RI" }, { "name": "South Carolina", "abbreviation": "SC" }, { "name": "South Dakota", "abbreviation": "SD" }, { "name": "Tennessee", "abbreviation": "TN" }, { "name": "Texas", "abbreviation": "TX" }, { "name": "Utah", "abbreviation": "UT" }, { "name": "Vermont", "abbreviation": "VT" }, // { "name": "Virgin Islands", "abbreviation": "VI" }, { "name": "Virginia", "abbreviation": "VA" }, { "name": "Washington", "abbreviation": "WA" }, { "name": "West Virginia", "abbreviation": "WV" }, { "name": "Wisconsin", "abbreviation": "WI" }, { "name": "Wyoming", "abbreviation": "WY" } ]; let settings = {}; let sheetData = {}; let tab = {}; let campaigns = []; let pgMaxX = 0; let pgMinX = 0; let pgMaxY = 0; let pgMinY = 0; function getCampaignData() { if( settings.apiKey === '' ) { WazeWrap.Alerts.error('Spreadsheet Worker', 'You must set an API key before using this script'); return; } let url = "https://sheets.googleapis.com/v4/spreadsheets/"+CAMPAIGN_SHEET_ID+"/values/Sheet1!A1:L500?key="+settings.apiKey; console.log("SW: getting sheet info ("+url+")"); $.ajax({ url: url, success: function(data){ $('#swCampaignSelect') .empty() .append('<wz-option selected="selected" value="">Select</wz-option>'); data.values.shift(); // Kill header row data.values.forEach(function(item, i){ let campaignRow = {campaignName:item[0], spreadsheetId:item[1], sheetName:item[2], maxRows:item[3], lonCol:item[4], latCol:item[5], stateCol:item[6], completeCol:item[7], betaOnly:(item[8]==='TRUE'), active:(item[9]==='TRUE'), test:(item[9]==='TEST'), plCol:item[10], startingRow:item[11]-1}; if(!campaignRow.startingRow) { campaignRow.startingRow = 1; } campaigns.push(campaignRow); if(campaignRow.active || (campaignRow.test && WazeWrap.User.Username() === 'FastestBeef')){ $('#swCampaignSelect').append(`<wz-option selected="selected" value="${i}">${item[0]}</wz-option>`); }; }); }, dataType: 'JSON' }); } function getAllRowData() { let campaignRow=document.getElementById('swCampaignSelect').value; let spreadsheetId=campaigns[campaignRow].spreadsheetId; let sheetName=campaigns[campaignRow].sheetName; let maxRows=campaigns[campaignRow].maxRows; if( settings.apiKey === '' ) { WazeWrap.Alerts.error('Spreadsheet Worker', 'You must set an API key before using this script'); return; } let url = encodeURI("https://sheets.googleapis.com/v4/spreadsheets/"+spreadsheetId+"/values/"+sheetName+"!A1:P"+maxRows+"?key="+settings.apiKey); console.log("SW: getting sheet info ("+url+")"); $.ajax({ url: url, success: function(data){ sheetData = data; }, dataType: 'JSON' }); document.querySelector("#swCurRow").value = campaigns[campaignRow].startingRow; } function getPrev() { $('#swCurRow').val( function(i, oldval) { return parseInt(oldval, 10) - 2; }); getNext(); } function stateFilterPass(state) { //console.log(`state=${state} stateFilter=${$('#swStateFilter').val()}`); return state.toLowerCase() === document.querySelector("#swStateFilter").value.toLowerCase() || state.toLowerCase() === Array.from(document.querySelectorAll("#swStateFilter > wz-option")).filter(option => option.value == document.querySelector("#swStateFilter").value)[0].getAttribute("name").toLowerCase() || '' === document.querySelector("#swStateFilter").value } function polygonPass(xCoord, yCoord) { return true; if( xCoord < pgMinX || xCoord > pgMaxX || yCoord < pgMinY || yCoord > pgMaxY) { return false; } return true; } function getNext() { let campaignRow = $('#swCampaignSelect').val(); if (campaignRow === '') { WazeWrap.Alerts.error('Spreadsheet Worker', 'You must select a campaign first.'); } let completeCol = campaigns[campaignRow].completeCol.toUpperCase().charCodeAt(0) - 65; let stateCol = campaigns[campaignRow].stateCol.toUpperCase().charCodeAt(0) - 65; let lonCol = campaigns[campaignRow].lonCol.toUpperCase().charCodeAt(0) - 65; let latCol = campaigns[campaignRow].latCol.toUpperCase().charCodeAt(0) - 65; let plCol = campaigns[campaignRow].plCol.toUpperCase().charCodeAt(0) - 65; let currentRow = parseInt(document.querySelector("#swCurRow").value, 10); while(typeof sheetData.values[currentRow] !== "undefined" && currentRow < 500000 ) { let lon = getLon(currentRow, lonCol, plCol); let lat = getLat(currentRow, latCol, plCol); if( (typeof sheetData.values[currentRow][completeCol] === "undefined" || sheetData.values[currentRow][completeCol] === "" || sheetData.values[currentRow][completeCol] === "FALSE") && stateFilterPass(sheetData.values[currentRow][stateCol]) && polygonPass(lon, lat) ) { var location = OpenLayers.Layer.SphericalMercator.forwardMercator(parseFloat(lon), parseFloat(lat)); //W.map.getOLMap().zoomTo(9); W.map.setCenter(location); document.querySelector("#swCurRow").value = currentRow+1; return; } currentRow++; } WazeWrap.Alerts.info("Spreadsheet Worker", "No more rows found."); } function getLat(currentRow, latCol, plCol) { let permalink = sheetData.values[currentRow][plCol]; if(typeof permalink === 'string' && permalink !== '') { let result = permalink.match(/lat=([0-9\-\.]*)/); return result[1]; } else { return sheetData.values[currentRow][latCol]; } } function getLon(currentRow, lonCol, plCol) { let permalink = sheetData.values[currentRow][plCol]; if(typeof permalink === 'string' && permalink !== '') { let result = permalink.match(/lon=([0-9\-\.]*)/); return result[1]; } else { return sheetData.values[currentRow][lonCol]; } } function updateAPIKey() { settings.apiKey = $('#swAPIKey').val(); saveSettings(); } function openSheetAtCurRow() { let campaignRow = $('#swCampaignSelect').val(); if (campaignRow === '') { WazeWrap.Alerts.error('Spreadsheet Worker', 'You must select a campaign first.'); return; } let spreadsheetId=campaigns[campaignRow].spreadsheetId; let row = $('#swCurRow').val(); let url = encodeURI("https://docs.google.com/spreadsheets/d/"+spreadsheetId+"/edit#gid=0&range=A"+row); window.open(url, "_blank"); } function bootstrap(tries = 1) { if (W && W.map && W.model && W.loginManager.user && $ && WazeWrap.Ready) { init(); } else if (tries < 1000) { setTimeout(function () {bootstrap(tries++);}, 200); } } bootstrap(); async function init(){ console.log("SW: Spreadsheet Worker Initializing."); tab = WazeWrap.Interface.Tab("SW", tabHTML(), function (){ $("#swGetNextBtn").click(()=>{getNext()}); STATES.forEach(function(item, i){ $('#swStateFilter').append(`<wz-option value="${item.abbreviation}" name="${item.name}">${item.name}</wz-option>`); }); $("#swStateFilter").change(()=>{ let campaignRow = $('#swCampaignSelect').val(); let startRow = 1; if (campaignRow !== '') { startRow = campaigns[campaignRow].startingRow; } document.querySelector("#swCurRow").value = startRow; }); $("#swCampaignSelect").change(()=>{getAllRowData()}); $("#swAPIKeyUpdate").click(function(){updateAPIKey();}); $("#refreshCampaign").click(function(){getCampaignData();}); $("#swLink").click(function(){openSheetAtCurRow();}); }); await loadSettings(); getCampaignData(); new WazeWrap.Interface.Shortcut("nextRowShortcut", "Get next row from spreadsheet worker script", "wmessw", "WME Spreadsheet Worker", settings.nextRowShortcut, function(){getNext();}, null).add(); new WazeWrap.Interface.Shortcut("prevRowShortcut", "Get previous row from spreadsheet worker script", "wmessw", "WME Spreadsheet Worker", settings.prevRowShortcut, function(){getPrev();}, null).add(); window.addEventListener("beforeunload", function() { checkShortcutsChanged(); }, false); WazeWrap.Interface.ShowScriptUpdate(SCRIPT_NAME, VERSION, UPDATE_NOTES, "https://greasyfork.org/en/scripts/401655-spreadsheet-worker", "https://www.waze.com/forum/viewtopic.php?f=819&t=301076"); console.log("SW: Spreadsheet Worker Initialized."); } function tabHTML(){ return `<wz-tabs fixed="true"> <wz-tab is-active="" label="General" class="sw-tab" style="overflow:inherit;"> <div> <div class="form-group" style="z-index: 13;"> <wz-label html-for="swCurRow">Campaign</wz-label> <div style="align-items: center;display: flex;gap: 5px;margin-bottom: 16px;width: 100%;"> <wz-select disabled="false" value="" name="" id="swCampaignSelect"> <wz-option value="">Select</wz-option> </wz-select> <wz-button id="refreshCampaign" color="primary" size="sm" disabled="false" class="overlay-button reload-button"><i class="w-icon w-icon-refresh"></i></wz-button> </div> </div> <div class="form-group" style="z-index: 12;"> <wz-select label="Filter State" disabled="false" value="" name="" id="swStateFilter"> <wz-option value="" name="">None</wz-option> </wz-select> </div> <div class="form-group" style="z-index: 11;"> <wz-label html-for="swCurRow">Current Row</wz-label> <div style="align-items: center;display: flex;gap: 5px;margin-bottom: 16px;"> <wz-button id="swLink" disabled="false" size="sm" color="shadowed"><i class="w-icon w-icon-link"></i></wz-button> <wz-text-input size="sm" type="number" style="min-width: auto;" name="swCurRow" id="swCurRow" placeholder="" autocomplete="on" value=""> <input name="swCurRow" style="display: none; visibility: hidden;"> </wz-text-input> <wz-button color="primary" size="sm" disabled="false" id="swGetNextBtn">Next</wz-button> </div> </div> </div> </wz-tab> <wz-tab is-active="false" label="Settings" class="sw-settings-tab"> <div style='display: block' > <wz-label html-for="swAPIKey">API Key</wz-label> <div style="align-items: center;display: flex;gap: 5px;margin-bottom: 16px;width: 100%;"> <wz-text-input name="swAPIKey" id="swAPIKey" value="" placeholder="Paste API Key" autocomplete="off"> <input name="swAPIKey" style="display: none; visibility: hidden;"> </wz-text-input> <wz-button color="primary" size="sm" disabled="false" id="swAPIKeyUpdate">Update</wz-button> </div> </div> <wz-label html-for="">Instructions</wz-label> <div class="form-group"> <ol> <li>Go to <a href='https://console.cloud.google.com/projectselector2/apis/credentials'>Google Cloud Console</a></li> <li>Select create a project</li> <li>Give it any name you want and click create</li> <li>Click create credentials -> API Key</li> <li>Click Dashboard on the left</li> <li>Click enable APIs and Services</li> <li>Find Google Sheets API and click it</li> <li>Click Enable.</li> <li>Click the back arrow on the top left twice.</li> <li>Click 'Credentials' on the left side</li <li>Copy the generated key, paste it into the above box, and click 'Update API Key'</li> <li>Done. You should be able to use the script. It may take a few minutes for the changes to take effect</li> <li>If the campaign select box is not populating, try refreshing the list</li> </ol> </div> <div class="form-group"> <div style="text-align: center;padding-top: 20px;"> <i class="fa fa-github" style="font-size: 13px; padding-right:5px"></i> <div style="display: inline-block;"> <a target="_blank" href="https://github.com/nschremp/WME-SpreadsheetWorker/issues/new" id="csReportAnIssue">Report an Issue on GitHub</a> </div> </div> </div> </wz-tab> </wz-tabs>`; } async function loadSettings() { let loadedSettings = $.parseJSON(localStorage.getItem("WMESSW_Settings")); let defaultSettings = { filterState: "", nextRowShortcut: "N", prevRowShortcut: "S+N", apiKey: "", lastSaved: 0 }; settings = $.extend({}, defaultSettings, loadedSettings); let serverSettings = await WazeWrap.Remote.RetrieveSettings("WME_SSW"); if(serverSettings && serverSettings.lastSaved > settings.lastSaved) $.extend(settings, serverSettings); //moved where I store this. Need to pull it from old and store in new. if (localStorage.getItem('SW_API_KEY')) { settings.apiKey = localStorage.getItem('SW_API_KEY'); localStorage.removeItem('SW_API_KEY'); saveSettings(); } } function saveSettings() { if (localStorage) { var localsettings = { filterState: settings.filterState, apiKey: settings.apiKey, lastSaved: Date.now() }; for (var name in W.accelerators.Actions) { let TempKeys = ""; if (W.accelerators.Actions[name].group == 'wmessw') { if (W.accelerators.Actions[name].shortcut) { if (W.accelerators.Actions[name].shortcut.altKey === true) TempKeys += 'A'; if (W.accelerators.Actions[name].shortcut.shiftKey === true) TempKeys += 'S'; if (W.accelerators.Actions[name].shortcut.ctrlKey === true) TempKeys += 'C'; if (TempKeys !== "") TempKeys += '+'; if (W.accelerators.Actions[name].shortcut.keyCode) TempKeys += W.accelerators.Actions[name].shortcut.keyCode; } else { TempKeys = "-1"; } localsettings[name] = TempKeys; } } localStorage.setItem("WMESSW_Settings", JSON.stringify(localsettings)); WazeWrap.Remote.SaveSettings("WME_SSW", localsettings); } } function checkShortcutsChanged(){ let triggerSave = false; for (let name in W.accelerators.Actions) { let TempKeys = ""; if (W.accelerators.Actions[name].group == 'wmepie') { if (W.accelerators.Actions[name].shortcut) { if (W.accelerators.Actions[name].shortcut.altKey === true) TempKeys += 'A'; if (W.accelerators.Actions[name].shortcut.shiftKey === true) TempKeys += 'S'; if (W.accelerators.Actions[name].shortcut.ctrlKey === true) TempKeys += 'C'; if (TempKeys !== "") TempKeys += '+'; if (W.accelerators.Actions[name].shortcut.keyCode) TempKeys += W.accelerators.Actions[name].shortcut.keyCode; } else { TempKeys = "-1"; } if(settings[name] != Tempkeys){ triggerSave = true; break; } } } if(triggerSave) saveSettings(); } })();