WME Requests

Opens the Requests module with precompiled fields to submit an request

Från och med 2014-09-16. Se den senaste versionen.

// ==UserScript==
// @name                WME Requests
// @namespace           WME-Requests
// @description         Opens the Requests module with precompiled fields to submit an request
// @include             https://*.waze.com/editor/*
// @include             https://*.waze.com/*/editor/*
// @include             https://*.waze.com/map-editor/*
// @include             https://*.waze.com/beta_editor/*
// @grant               none
// @author              skirda
// @version             1.9.1
// ==/UserScript==

var wmer_Version = '1.9.1';
var wmer_Form = 'https://docs.google.com/forms/d/1QzvF3-lH8MuuEaSw0GA6LgLW62EiSHzQXBmG5-rQdIQ/viewform';
var wmer_FormCL = 'https://docs.google.com/forms/d/1ck0cCIV6vPy16YQZJvfmM0clOdAE2Z-kDsXn06ZwQ1s/viewform';
var wmer_Docs="https://docs.google.com/spreadsheet/ccc?key=0AtcEFFDNcic4dEE2UFh5X0lDdlRZbno3YVFYUkg0Unc";
var wmer_DocsCL="https://docs.google.com/spreadsheets/d/1ddcW8EmNjojJp7EQ4AYPdfBqNWe28WqRaQ_RtkB8JAU";
var wmer_CountDays = 5;
var wmer_UserCache = new Array();
var wmer_LanguageRU = false;

function wmer_bootstrap()
{
	wmer_LanguageRU=window.location.href.indexOf("/ru/") > 0?true:false;

	if (typeof unsafeWindow === "undefined") {
		unsafeWindow    = ( function () {
			var dummyElem = document.createElement('p');
			dummyElem.setAttribute('onclick', 'return window;');
			return dummyElem.onclick();
		}) ();
	}

	/* begin running the code! */
	wmer_Init();
}

function consoleLog(text)
{
	console.log('WMEUnlockRequest v. ' + wmer_Version + ': ' + text);
}

function dump(obj)
{
	var out = "";
	if(obj && typeof(obj) == "object"){
		for (var i in obj) {
			out += i + ": " + obj[i] + "\n";
		}
	} else {
		out = obj;
	}
	return out;
}

function wmer_getUsername()
{
	var thisUser = Waze.loginManager.user;
	if (thisUser === null)
	{
		alert(wmer_LanguageRU?'Невозможно получить имя текущего пользователя':'Nobody\'s logged in.');
		return "";
	}
	return Waze.loginManager.user.userName;
}

function wmer_getCCSD(segment){ // BUBBUB!!! need use "hasOwnProperty" or "in"
	consoleLog("start wmer_getCCSD");

	var oID="";
	var streetName="";
	var sityName="";
	var countryName="";
	var description="";
	var typeName= "";
	var cityID="";
	var userID="";
	var forumUserID="";
	var userName="";

	try {
		typeName=segment.type;
		/*
		"segment"
		"landmark"
		"node"
		"camera" typeName: "Speed camera"
		*/
		oID=segment.fid;
		var attributesObj=segment.attributes;
		if (attributesObj.hasOwnProperty('primaryStreetID'))
		{
			consoleLog("found street");
			var sID=attributesObj.primaryStreetID;
			var streetsObj = wazeModel.streets.get(sID);
			cityID=streetsObj.cityID;
			streetName=streetsObj.name;
		}
		else if (typeName === "camera")
		{
			consoleLog("found camera");
			streetName=segment.typeName;
			description="speed="+attributesObj.speed+", validated="+attributesObj.validated;

		}
		else if (typeName === "node")
		{
			consoleLog("found node");
			//description="segments="+attributesObj.segIDs.length;
		}
		else
		{
			consoleLog("found POI ("+typeName+")");
//Waze.model.streets.get(Waze.selectionManager.selectedItems[0].attributes.primaryStreetID).cityID
//Waze.model.streets.get(Waze.selectionManager.selectedItems[0].attributes.streetID).cityID
			var sID=attributesObj.streetID;
			if (sID == null)
				cityID="";
			else
				cityID=wazeModel.streets.get(sID).cityID;

			if (sID == null)
				cityID="";

			description=attributesObj.description;
			if (attributesObj.mtfcc === "W0002") // Gas Station
				typeName="gas station"
			streetName=attributesObj.name;
		}

		if (!(typeName === "camera" || typeName === "node" || cityID === "")) // BUGBUG!!!
		{
			var cityObj=wazeModel.cities.get(cityID);
			var countryID=cityObj.countryID;
			sityName=cityObj.name;
			var countriesObj=wazeModel.countries.get(countryID);

			countryName = countriesObj.name;
		}

		userID=attributesObj.updatedBy;
		if (userID == null)
			userID=attributesObj.createdBy;

		if (userID==-1 || userID == null)
		{
			userID=attributesObj.createdBy;
			if (userID==-1)
			{
				consoleLog("Do not PM Admin!");
			}
		}
		consoleLog("userID=" +userID);

		userName=wazeModel.users.get(userID).userName;
		consoleLog("userName="+userName);
	}
	catch (err) {
		consoleLog("error: " +err.name);
	}

	consoleLog("return from wmer_getCCSD");
	return {
		objid       : oID,
		type        : typeName,
		street      : streetName,
		sity        : sityName,
		cityID      : cityID,
		country     : countryName,
		description : description,
	    username    : userName,
		userID      : userID,
		forumuserID : forumUserID
	};
}


function wmer_userRank(segment)
{
	var usrRank = 0;
	if (segment.attributes.lockRank)
	{
		var updatedBy = wazeModel.users.get(segment.attributes.updatedBy);
		return updatedBy != null ? updatedBy.rank : 0;
	}
	return 0;
}

//It returns the maximum lock level
function wmer_GetLevel() {
	//attributes.rank dovrebbe essere il road rank
	var sel = Waze.selectionManager.selectedItems;
	var maxR = wmer_userRank(sel[0]);
	for (i = 1; i < sel.length; i++)
	{
		if (maxR == 5)
		{
			return 6;
		}
		var usrRank = wmer_userRank(sel[i]);
		if (usrRank > maxR) {
			maxR = usrRank;
		}
	}
	return maxR + 1;
}

function click_WMERequest() {
	consoleLog("click_WMERequest()::Action: "+this.id);
	if (typeof Waze.selectionManager === "undefined")
	{
		consoleLog('Waze.selectionManager not found');
		return;
	}
	if (Waze.selectionManager.selectedItems.length == 0)
	{
		alert(wmer_LanguageRU?'Нет выделенных объектов':'No selected segments.');
		return;
	}
	if (Waze.selectionManager.selectedItems.length < 2 && this.id == 'wmerBtn_join')
	{
		alert(wmer_LanguageRU?'Вы должны выделить 2 сегмента':'You must select 2 segments.');
		return;
	}

	var username = wmer_getUsername();
	var sccObj = wmer_getCCSD(Waze.selectionManager.selectedItems[0]);

	var lockLevel = wmer_GetLevel();
	if (lockLevel == 1 && this.id == 'wmerBtn_lock')
	{
		alert(wmer_LanguageRU?'Выбранные сегменты уже разблокированы':'Selected segments are already unlocked');
		return;
	}

	consoleLog("My level: "+Waze.loginManager.user.normalizedLevel);
	consoleLog("Lock level: "+lockLevel);

	if (lockLevel <= Waze.loginManager.user.normalizedLevel && this.id == 'wmerBtn_lock') {
		alert(wmer_LanguageRU?'Выбранные сегменты имеют доступный вам уровень блокировки':'Selected segments have a lock level that is less or equal to yours')
		return;
	}

	var description='type: ' + sccObj.type + '\r' +
					'country: '+ sccObj.country + '\r' +
					'sity: ' + sccObj.sity + '\r' +
					'street/name: ' + sccObj.street + '\r' +
					'description: ' + sccObj.description;

	description = description.replace(/%/g, '%25');
	description = description.replace(/\+/g, '%2B');   // +
	description = description.replace(' ', '%20');   // ' '
	description = description.replace(/\r\n/g, '\r');  // '\r\n'
	description = description.replace(/\r/g, '%0A');  // '\n'
	description = description.replace(/&/g, '%26');
	description = description.replace(/</g, '%3C');
	description = description.replace(/\>/g, '%3E');
	description = description.replace(/\?/g, '%3F');
	description = description.replace(/=/g, '%3D');

	var permalink = wmer_generate_permalink();
	consoleLog("permalink=" + permalink);
	permalink = permalink.replace(/%/g, '%25'); //???
	permalink = permalink.replace(/&/g, '%26');
	permalink = permalink.replace(/\?/g, '%3F');
	permalink = permalink.replace(/=/g, '%3D');
	permalink = permalink.replace(/</g, '%3C');
	permalink = permalink.replace(/\>/g, '%3E');
	//You can get entry numbers in google stylesheet: "Answers->Get precompiled URL"
	var curDate=new Date();
	curDate.setDate(curDate.getDate() + wmer_CountDays);

	var action="";
	switch(this.id)
	{
		case 'wmerBtn_lock':
			action='lock';
			break;
		case 'wmerBtn_join':
			action='join';
			break;
		case 'wmerBtn_dir':
			action='direction';
			break;
	}

	function zero2(d){
		if((""+d).length == 1)
			d="0" + "" + d;
		return d;
	}

	var url = wmer_Form +
			'?entry.1230839078=' + username +
			'&entry.390417455=' + permalink +
			'&entry.1224334113=' + lockLevel +
			'&entry.1508498769=' + sccObj.country +
			'&entry.1856604039=' + action +
			'&entry.259824358=' + description +
			'&entry.571885954='+curDate.getFullYear()+'-'+zero2(curDate.getMonth()+1)+'-'+zero2(curDate.getDate());
	//entry.1797072526=e-mail


	// https://docs.google.com/forms/d/1ck0cCIV6vPy16YQZJvfmM0clOdAE2Z-kDsXn06ZwQ1s/viewform?
    /*
		entry.1109766685=skirda
		entry.1785513403=vskirdin@gmail.com
		entry.1300384005=http://permalink
		entry.1967623256=name
		entry.1408672148=%D0%B3%D0%BE%D1%80%D0%BE%D0%B4
		entry.327157830=state
		entry.677704585=region
    */
	var urlCL = wmer_FormCL +
			'?entry.1109766685=' + username +
			'&entry.1300384005=' + permalink +
			'';

	//consoleLog(url);
	window.open(this.id == 'wmerBtn_cl'?urlCL:url, '_blank');
}

function wmer_generate_permalink() {
  	var wcp=document.getElementsByClassName('WazeControlPermalink');
  	for(var i=0; i < wcp.length; ++i)
  		for (var j=0; j < wcp[i].getElementsByTagName('a').length;++j)
  		{
  			var href=wcp[i].getElementsByTagName('a')[j].href;
			if (href.indexOf(".waze.com/") > 0 && href.indexOf("/editor") > 0)
			{
				return href;
			}
		}
	return "";
}


function wmer_insertButton()
{
	if(document.getElementById('WME.Request_' + wmer_Version) != null)
		document.getElementById('WME.Request_' + wmer_Version).setAttribute('style', 'display:'+(Waze.selectionManager && Waze.selectionManager.selectedItems.length == 0?'none':'')+';');

	if(Waze.selectionManager.selectedItems.length == 0)
		return;

	var editPanelID='';
	var disabled=false;
	var disabledLock=false;
	var disabledPM=false;

	if (document.getElementById('segment-edit-general') != null)
	{
		editPanelID='segment-edit-general';
		disabled=false;
		disabledLock=false;
	}
	else if (document.getElementById('landmark-edit-general') != null)
	{
		editPanelID='landmark-edit-general';
		disabledLock=false;
		disabled=true;
	}
	else if (document.getElementById('node-edit-general') != null)
	{
		editPanelID='node-edit-general';
		disabled=true;
		disabledPM=true;
		disabledLock=true;
	}
	else if (document.getElementById('edit-panel') != null)
	{
		editPanelID='edit-panel';
		disabled=true;
		disabledLock=true;
	}

	if(document.getElementById('WME.Request_' + wmer_Version) == null)
	{
		srsCtrl = document.createElement('section');
		srsCtrl.id = 'WME.Request_' + wmer_Version;

		srsCtrl.innerHTML = '<hr>'+
			'<a href="' + wmer_Docs + '" target="_gdocRequest">Requests:</a> '+
			'(<a href="https://www.waze.com/forum/viewtopic.php?p=662218#p662218" title="WME Requests ' + wmer_Version + '" style="font-size: 10px" target="_blank">?</a>)</br>'+
			'<button id="wmerBtn_lock" class="btn" style="font-size:9px;padding:6px 10px" title="'+
				(wmer_LanguageRU?'Отправить запрос на изменение уровня блокировки объектов':'Send a request to lock/unlock segment(s)')+
				'"><i class="icon-unlock"></i>&nbsp;Lock</button>&nbsp;' +
			'<button id="wmerBtn_join" class="btn" style="font-size:9px;padding:6px 10px" title="'+
				(wmer_LanguageRU?'Отправить запрос на присоединение сегментов':'Send a request to join several segments')+
				'"><i class="icon-cogs"></i>&nbsp;Join</button>&nbsp;' +
			'<button id="wmerBtn_dir"  class="btn" style="font-size:9px;padding:6px 10px" title="'+
				(wmer_LanguageRU?'Отправить запрос на изменение направления движения сегментов':'Send a request to change the direction of segment(s)')+
				'"><i class="icon-random"></i>&nbsp;Dir</button>&nbsp;' +
			'<button id="wmerBtn_pm"   class="btn" style="font-size:9px;padding:6px 10px" title="'+
				(wmer_LanguageRU?'Отправить приватное сообщение в форум авторам выделенных объектов':'Send (in forum) a Private Message to the author of the segment')+
				'"><i class="icon-envelope"></i>&nbsp;PM</button>&nbsp;' +
			'<button id="wmerBtn_cl"   class="btn" style="font-size:9px;padding:6px 10px" title="'+
				(wmer_LanguageRU?'Отправить запрос на изменение наименования населенного пункта':'Send a request to CityLock')+
				'"><i class="icon-home"></i>&nbsp;City</button>' +
			'</br><span id="wmerCityID"></span>'+
			'<hr>';

		document.getElementById(editPanelID).appendChild(srsCtrl);

		document.getElementById('wmerBtn_lock').onclick = click_WMERequest;
		document.getElementById('wmerBtn_dir').onclick  = click_WMERequest;
		document.getElementById('wmerBtn_join').onclick = click_WMERequest;
		document.getElementById('wmerBtn_pm').onclick   = click_submitPMForm;
		document.getElementById('wmerBtn_cl').onclick   = click_WMERequest;

		var sccObj = wmer_getCCSD(Waze.selectionManager.selectedItems[0]);
		if (sccObj.type == "segment" || sccObj.type == "venue")
		{
			consoleLog("WME.Request_" + wmer_Version +": " + sccObj.cityID);
			document.getElementById('wmerCityID').innerHTML='<small>cityID: '+sccObj.cityID+'</small>';
		}

		consoleLog("WME.Request_" + wmer_Version +" initialised");

	}

	if(document.getElementById('WME.Request_' + wmer_Version) != null)
	{
		document.getElementById('wmerBtn_lock').disabled=disabledLock;
		document.getElementById('wmerBtn_dir').disabled=disabled;
		document.getElementById('wmerBtn_join').disabled=disabled;
		document.getElementById('wmerBtn_pm').disabled=disabledPM;
		document.getElementById('wmerBtn_cl').disabled=disabled;
	}
}


// <WME Fancy permalink> - http://userscripts.org/users/548866
function getId(node) {
  return document.getElementById(node);
}

function getForumUserIdFromID(wmeUserID)
{
	consoleLog("call getForumUserIdFromID(" + wmeUserID + ")");
	var userName=wazeModel.users.get(wmeUserID);
	console.dir(userName);
	return (getForumUserIdFromName(userName.userName));
}

function getForumUserIdFromName(userName)
{
	consoleLog("call getForumUserIdFromName(" + userName + ")");
	var forumID=-1;
	var forumIDs=new Array();

	if (userName.indexOf('/')!=-1)
	{
		var userNames=userName.split('/');
		for (var i=0; i<userNames.length; i++)
		{
			forumID=getForumUserIdFromName(userNames[i]);
			forumIDs[i]=forumID[0];
		}
		return forumIDs;
	}

	consoleLog("looking for " + userName + " in the forum.");

	var xhr3_object;

	if(window.XMLHttpRequest) // Firefox & Chrome
		xhr3_object = new XMLHttpRequest();
	else if(window.ActiveXObject) // Internet Explorer
		xhr3_object = new ActiveXObject("Microsoft.XMLHTTP");

	xhr3_object.open("GET", "https://www.waze.com/forum/memberlist.php?username=" + userName, false);

	xhr3_object.onreadystatechange = function() {
		if(xhr3_object.readyState == 4)
		{
			var test = xhr3_object.responseText.match(/u=([0-9]+)"/g);
			if (test==null)
			{
				consoleLog('Forum return null');
				return(-1); // no match
			}
			if (test.length>1)
			{
				consoleLog('Forum return multiple match:');
				console.dir(test);
				return(-2); // multiple match
			}
			forumID=test[0].substring(2, test[0].length-1);
		}
	};

	console.dir(xhr3_object);

	try {
		xhr3_object.send(null);
	}
	catch (err) {
		consoleLog("XMLHttpRequest error: " +err.name);
		console.dir(err);
		return(-3);
	}
	forumIDs[0]=forumID;
	return (forumIDs);
}

function click_submitPMForm()
{
	if (typeof Waze.selectionManager === "undefined")
	{
		consoleLog('Waze.selectionManager not found');
		return;
	}

	if (Waze.selectionManager.selectedItems.length == 0)
	{
		alert(wmer_LanguageRU?'Сначала необходимо выделить сегмент':'Please, select one segment before');
		return false;
	}

	//-------------
	var sccObjs=new Array();
	for (var i=0; i < Waze.selectionManager.selectedItems.length; ++i)
	{
		var sccObj = wmer_getCCSD(Waze.selectionManager.selectedItems[i]);
		if (sccObj.userID==-1)
		{
			consoleLog("PM request - Do not PM Admin!");
			alert("Can't PM admin!");
			return false;
		}

		var j;
		for (j=0; j < wmer_UserCache.length; j+=2)
		{
			if (wmer_UserCache[j] === sccObj.userID)
			{
				sccObj.forumuserID=wmer_UserCache[j+1];
				consoleLog("found ["+j+"]"+wmer_UserCache[j+1]);
				break;
			}
		}

		if (sccObj.forumuserID == "")
		{
			consoleLog("not found "+sccObj.userID);
			sccObj.forumuserID=getForumUserIdFromID(sccObj.userID);
			wmer_UserCache.push(sccObj.userID,sccObj.forumuserID);
		}

		sccObjs.push(sccObj);
	}

	var forumIDs=new Array();
	for (var i=0; i < sccObjs.length; ++i)
		forumIDs[i]=sccObjs[i].forumuserID;
	//-------------

	if (forumIDs.length==1 && forumIDs[0]==-1)
	{
		consoleLog("PM request - User never logged to the forum...");
		alert(wmer_LanguageRU?'Автор сегмента не найден на форуме':'Sorry: unable to find the user in the forum');
		return false;
	}
	if (forumIDs.length==1 && forumIDs[0]==-2)
	{
		consoleLog("PM request - Several users match name. Should never happen :s");
		alert(wmer_LanguageRU?'Найдено более одного пользователя\nОтправьте сообщение самостоятельно.':'Sorry: more than one user found in the forum.\nYou should look for him/her by yourself.');
		return false;
	}
	if (forumIDs.length==1 && forumIDs[0]==-3)
	{
		consoleLog("A network error occurred.");
		alert(wmer_LanguageRU?'Сетевые проблемы\nОтправьте сообщение самостоятельно.':'Sorry: a network error occurred.\nYou should look for him/her by yourself.');
		return false;
	}

	consoleLog("PM request - all OK. go to PM!");

	var formID="WMER-PM-FORM";

	var nodePM;

	if (getId("WMER-PM-Send") == null)
	{
		nodePM= document.createElement('div');
		nodePM.id = 'WMER-PM-Send';
		nodePM.style.display='hidden';
		getId('WME.Request_' + wmer_Version).appendChild(nodePM);
	}
	else
	{
		nodePM=getId("WMER-PM-Send");
	}

	var PMForm;
	PMForm='<form id="' + formID + '" target="_blank" method="post" style="display: inline">';
	PMForm+='<input id="' + formID + '-subject" type="hidden" name="subject" value="" />';
	PMForm+='<input type="hidden" name="addbbcode20" value="100" />';
	PMForm+='<input id="' + formID + '-message" type="hidden" name="message" value="" />';
	PMForm+='<input type="hidden" name="preview" value="Preview" />';
	PMForm+='<input type="hidden" name="attach_sig" value="on" />';
	PMForm+='<input id="' + formID + '-ct" type="hidden" name="creation_time" value="0" />';
	PMForm+='<input id="' + formID + '-lc" type="hidden" name="lastclick" value="0" />';
	for (var i=0; i<forumIDs.length; i++)
	{
		PMForm+='<input type="hidden" name="address_list[u]['+forumIDs[i]+']" value="to" />';
	}
	PMForm+='</form>';
	nodePM.innerHTML=PMForm;

	var permalink=wmer_generate_permalink();
	linkParts=permalink.replace(/#/g, "").split('&');
	for (var j=0; j<linkParts.length; j++)
	{
		if (linkParts[j].indexOf("segments=")==0)
		{
			linkParts.splice (j,1);
			break;
		}
	}
	//console.dir(linkParts);

	var message=wmer_LanguageRU?
		'Есть вопросы по вашим правкам в [url=' + permalink + ']этой области редактирования[/url]:\n\n':
		'Some questions about [url=' + permalink + ']this area[/url]:\n\n';

	permalink=linkParts.join('&');

	for (var i=0; i < sccObjs.length; ++i)
	{
		message += '[b]2' + sccObjs[i].username + '[/b]: '+
			sccObjs[i].type+' ('+
			'[url=' + permalink + '&segments=' + sccObjs[i].objid + ']'+
			(sccObjs[i].country === ''?'':'country: [b]'+sccObjs[i].country+'[/b]/')+
			(sccObjs[i].sity === ''?'':'sity: [b]'+sccObjs[i].sity+'[/b]/')+
			'name: [b]'+(sccObjs[i].street==null?'<<noname>>':sccObjs[i].street)+'[/b]'+
			(sccObjs[i].description === ''?'':'/description: [b]'+sccObjs[i].description+'[/b]') +
			'[/url])\n\n';
	}
	//consoleLog(message);

	getId(formID + '-message').value=message;
	var now=new Date().getTime();
	now /= 1000;
	now = Math.floor(now);
	getId(formID + '-ct').value=now;
	getId(formID + '-lc').value=now;

	getId(formID).action="https://www.waze.com/forum/ucp.php?i=pm&mode=compose&action=post";
	getId(formID + '-subject').value=
		wmer_LanguageRU?
			'[WME Request] Уточнение по вашим правкам.':
			'[WME Request] Question about your map edits';

	//console.dir(getId(formID));

	getId(formID).submit();
	return true; // this forces to open in new tab!
}
// </WME Fancy permalink>


function wmer_WazeBits()
{
	if (typeof Waze === "undefined")
		Waze=unsafeWindow.Waze;

	if (typeof Waze === "undefined")
		Waze=window.Waze;
}

function wmer_FakeLoad()
{
	wmer_WazeBits();

	if (typeof Waze === "undefined")
	{
		consoleLog('Waze not found, retrying in 500ms...');
		setTimeout(wmer_FakeLoad,500);
		return;
	}
	if (typeof Waze.selectionManager === "undefined")
	{
		consoleLog('Waze.selectionManager not found, retrying in 500ms...');
		setTimeout(wmer_FakeLoad,500);
		return;
	}
	if (typeof Waze.model === "undefined")
	{
		consoleLog('Waze.model not found, retrying in 500ms...');
		setTimeout(wmer_FakeLoad,500);
		return;
	}

	wazeModel = Waze.model;

	try {
		Waze.selectionManager.events.register("selectionchanged", null, wmer_insertButton);
		consoleLog('added event handler');
	}
	catch (err) {
		consoleLog("added event handler error: " +err.name);
	}
}

function wmer_Init() {
	consoleLog('init');
	setTimeout(wmer_FakeLoad, 500);
}

wmer_bootstrap();