Geocaching.com + GeoLeaks

Add link to www.geoleaks.com on geocache pages

As of 2019-01-08. See the latest version.

/* global $: true */
/* global unsafeWindow: true */

// ==UserScript==
// @name        Geocaching.com + GeoLeaks
// @namespace   geoleaks
// @version     1.6
// @author      Toni Cornelissen (github@technetium.be)
// @author      Michel ten Voorde (michel@tenvoorde.org)
// @description Add link to www.geoleaks.com on geocache pages
// @require     https://greasyfork.org/scripts/38445-monkeyconfig/code/MonkeyConfig.js
// @include     http://www.geocaching.com/geocache/*
// @include     https://www.geocaching.com/geocache/*
// @include     https://geoleaks.com/forum/newthread.php?*
// @include     https://geoleaks.com/forum/search.php*
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_registerMenuCommand
// @grant       GM_addStyle
// ==/UserScript==
// @require     https://raw.github.com/odyniec/MonkeyConfig/master/monkeyconfig.js


(function() {
	'use strict';

	var buttonInfo = {
		error: {
			color: '#cc3399',
			text: 'Error!'
		},
		notfound: {
			color: '#90040b',
			text: 'Not Found on GeoLeaks'
		},
		solved: {
			color: '#02874d',
			text: 'Solved on GeoLeaks'
		},
		unknown: {
			color: '#12508c',
			text: 'Found on GeoLeaks'
		},
		unsolved: {
			color: '#e98300',
			text: 'Solving on GeoLeaks'
		},
		wait: {
			color: '#cdcdcd',
			text: 'Searching on GeoLeaks'
		}
		// dnf: '#1c3d4c' ,
		// virtual: '#009bbb',
	};

	var regions = {
		// Netherlands
		'Groningen, Netherlands': { fid : 12 },
		'Friesland, Netherlands': { fid : 13 },
		'Drenthe, Netherlands': { fid : 14 },
		'Overijssel, Netherlands': { fid : 15 },
		'Flevoland, Netherlands': { fid : 16 },
		'Gelderland, Netherlands': { fid : 17 },
		'Utrecht, Netherlands': { fid : 18 },
		'Noord-Holland, Netherlands': { fid : 19 },
		'Zuid-Holland, Netherlands': { fid : 20 },
		'Zeeland, Netherlands': { fid : 21 },
		'Noord-Brabant, Netherlands': { fid : 22 },
		'Limburg, Netherlands': { fid : 23 },

		// Belgium
		'Brussels, Belgium': { fid : 41 },
		'Antwerpen, Belgium': { fid : 42 },
		'Vlaams-Brabant, Belgium': { fid : 43 },
		'Limburg, Belgium': { fid : 44 },
		'West-Vlaanderen, Belgium': { fid : 45 },
		'Oost-Vlaanderen, Belgium': { fid : 46 },
		'Brabant wallon, Belgium': { fid : 47 },
		'Hainaut, Belgium': { fid : 48 },
		'Liège, Belgium': { fid : 49 },
		'Luxembourg, Belgium': { fid : 50 },
		'Namur, Belgium': { fid : 51 },

		// Germany
		'Bremen, Germany': { fid : 98 },
		'Hamburg, Germany': { fid : 99 },
		'Niedersachsen, Germany': { fid : 100 },
		'Nordrhein-Westfalen, Germany': { fid : 101 },
		'Hessen, Germany': { fid : 102 },
		'Rheinland-Pfalz, Germany': { fid : 103 },
		'Saarland, Germany': { fid : 104 },
		'Schleswig-Holstein, Germany': { fid : 105 },
		'Mecklenburg-Vorpommern, Germany': { fid : 106 },
		'Brandenburg, Germany': { fid : 107 },
		'Berlin, Germany': { fid : 108 },
		'Sachsen-Anhalt, Germany': { fid : 109 },
		'Thüringen, Germany': { fid : 110 },
		'Sachsen, Germany': { fid : 111 },
		'Baden-Württemberg, Germany': { fid : 112 },
		'Bayern, Germany': { fid : 113 },

		// Europe
		'Luxembourg': { fid : 66 },
		'France': { fid : 68 },
		'United Kingdom': { fid : 87 },

		'Aland Islands': { fid : 69, cc : 'AX' },
		'Andorra': { fid : 69, cc : 'AD' },
		'Armenia' : { fid : 69, cc : 'AM' },
		'Austria' : { fid : 69, cc : 'AT' },
		'Azerbaijan' : { fid : 69, cc : 'AZ' },
		'Bosnia and Herzegovina' : { fid : 69, cc : 'BA' },
		'Bulgaria' : { fid : 69, cc : 'BG' },
		'Croatia' : { fid : 69, cc : 'HR' },
		'Cyprus' : { fid : 69, cc : 'CY' },
		'Czechia' : { fid : 69, cc : 'CZ' },
		'Denmark' : { fid : 69, cc : 'DK' },
		'Estonia' : { fid : 69, cc : 'EE' },
		'Faroe Islands' : { fid : 69, cc : 'FO' },
		'Finland' : { fid : 69, cc : 'FI' },
		'Greece' : { fid : 69, cc : 'GR' },
		'Hungary' : { fid : 69, cc : 'HU' },
		'Iceland' : { fid : 69, cc : 'IS' },
		'Ireland' : { fid : 69, cc : 'IE' },
		'Italy' : { fid : 69, cc : 'IT' },
		'Jersey' : { fid : 69, cc : 'JE' },
		'Latvia' : { fid : 69, cc : 'LV' },
		'Liechtenstein' : { fid : 69, cc : 'LI' },
		'Lithuania' : { fid : 69, cc : 'LT' },
		'Norway' : { fid : 69, cc : 'NO' },
		'Poland' : { fid : 69, cc : 'PL' },
		'Portugal' : { fid : 69, cc : 'PT' },
		'Romania' : { fid : 69, cc : 'RO' },
		'Russia' : { fid : 69, cc : 'RU' },
		'Slovakia' : { fid : 69, cc : 'SK' },
		'Slovenia' : { fid : 69, cc : 'SI' },
		'Spain' : { fid : 69, cc : 'ES' },
		'Sweden' : { fid : 69, cc : 'SE' },
		'Switzerland' : { fid : 69, cc : 'CH' },
		'Vatican City State' : { fid : 69, cc : 'VA' },

		'United States' : { fid : 88 },
		'default' : { fid : 70 }

	};

	var gctypes = {
		'Traditional Cache' : { fid : 38 },
		'Multi-cache' : { fid : 38 },
		'Virtual Cache' : { fid : 78 },
		'Letterbox Hybrid' : { fid : 38 },
		// 'Event Cache
		// 'Unknown Cache
		// 'Project APE Cache
		// 'Webcam Cache
		// 'Cache In Trash Out Event
		'Earthcache' : { fid : 78 },
		// 'Mega-Event Cache
		// 'GPS Adventures Exhibit
		'Wherigo Cache' : { fid : 38 },
		// 'Lost and Found Event Cache
		// 'Groundspeak HQ
		// 'Groundspeak Lost and Found Celebration
		// 'Groundspeak Block Party
		// 'Giga-Event Cache
	};

	var cfg = new MonkeyConfig({
		title: 'Geocaching + Geoleaks Configuration',
		menuCommand: true,
		params: {
		    open_in_new_window: {
		        type: 'checkbox',
		        default: false
		    },
		    auto_check: {
		        type: 'checkbox',
		        default: false
		    }
		}
	});

	var gccode = '';
	var gcname = '';
	var gctype = '';
	var region = '';
	var wait = 5000;
	var link_id = '#linkToGeoLeaks';
	var form_id = '#formToGeoLeaks';

	function setInputFields() {
		var params = new URLSearchParams(window.location.search);
		for (var param of params) {
			var elems = document.getElementsByName(param[0]);
			for (var elem of elems) {
				switch (elem.nodeName) {
					case 'TEXTAREA' : elem.innerHTML = param[1]; elem.value = param[1]; break; 
					default : elem.value = param[1]; break; 
				}
			}
		}
	}

	function updateButton(type) {
		$(link_id)
			.css('background-color', buttonInfo[type].color)
			.html(buttonInfo[type].text)
		;
	}

	function setHref(href) {
		$(link_id)
			.attr('href', href)
			.attr('target', cfg.get('open_in_new_window') && !href.startsWith('#') ? '_blank' : '_self')
		;
	}

	function newMessageUrl() {
		var forumInfo = regions.default;
		if (gctypes[gctype]) { forumInfo = gctypes[gctype]; }
		else {
			for (var key in regions) {
				if (region.endsWith(key)) {
					forumInfo = regions[key];
					break;
				}
			}
		}
		var subject = gccode + ' - ' + gcname;
		if (forumInfo.cc) { subject += ' (' + forumInfo.cc + ')'; }
		var message =
			'https://coord.info/' + gccode + "\n" +
			"\n" +
			'https://github.com/technetium/greasemonkey/raw/develop/GeoCachingLeaks.user.js ' +
			'geeft aan dat er nog geen topic voor deze cache is, ' +
			'ik kom er niet uit. ' +
			'Wie wil mij helpen? ' +
			'Ik heb het volgende al geprobeerd:' + "\n" + 
			"\n";
		return '' +
			'https://geoleaks.com/forum/newthread.php?fid=' + forumInfo.fid +
			'&subject=' + encodeURIComponent(subject) +
			'&message_new=' + encodeURIComponent(message) +
			'&message=' + encodeURIComponent(message)
		;
	}
	
	function checkGeoleaks() {
		updateButton('wait');
		$.post({
			url: "https://geoleaks.com/forum/search.php",
			data: {
				'action' : 'do_search',
				'keywords' : gccode,
				'postthread' : 2, // Alleen titels doorzoeken
				'sortby' : 'lastpost',
				'sortordr' : 'asc',
			},
			success: function(result){
				var url = result.match(/search.\php\?action=results[^"]*/);
				if (!url) {
					if (-1 !== result.indexOf('<td class="trow1">Er zijn geen resultaten gevonden voor de zoekopdracht die u uitvoerde. Maak een nieuwe zoekopdracht en probeer het opnieuw.</td>')) {
						updateButton('notfound');
						setHref(newMessageUrl());
						return;
					}
					if (-1 !== result.indexOf('<td class="trow1">U kunt slechts &eacute;&eacute;n zoekopdracht per 10 seconden uitvoeren. Wacht')) {
						wait = wait * 2;
						window.setTimeout(checkGeoleaks, wait);
						return;
					}

					console.error('Cannot find results url');
					console.debug(result);
					updateButton('error');
					setHref('#search');
					return;
				}
				url = url[0].replace('&amp;', '&');
				$.get({
					url: 'https://geoleaks.com/forum/' + url,
					success: function(result){
						var post = result.match(/showthread\.php.*?highlight[^"]*/);
						console.log("POST");
						console.log(post);
						if (post) {
							post = post[0].replace('&amp;', '&');
							setHref('https://geoleaks.com/forum/' + post);
							var forum = result
								.match(/forumdisplay.php.*?<\/a>/)[0]
								.match(/[^>]*<\/a>/)[0]	
								.toLowerCase()
							;
							console.log(forum);
							if (forum.startsWith('opgeloste ')) {
								updateButton('solved');
							} else if (forum.startsWith('niet opgeloste ')) {
								updateButton('unsolved');
							} else {
								updateButton('unknown');
							}
						} else {
							updateButton('notfound');
							setHref(newMessageUrl());
						}
					},
					error: function() {
						updateButton('error');
						setHref('https://geoleaks.com/forum/search.php?action=do_search&keywords='+gccode);
					}
				});
			},
			error: function() {
				updateButton('error');
				setHref('https://geoleaks.com/forum/search.php?action=do_search&keywords='+gccode);
			}
		});
	}

	function geocaching() {
		gccode = $('#ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode').html();
		gcname = $('#ctl00_ContentBody_CacheName').html();
		gctype = $('a[href="/about/cache_types.aspx"]').attr('title');
		region = $('#ctl00_ContentBody_Location').html();

		$('#ctl00_ContentBody_GeoNav_logButton').after('<a id="' + link_id.substr(1) + '" class="btn btn-primary" style="margin-top: 14px; background-color: #009bbb; border:none">GeoLeaks</a>');
		if (
			('Mystery Cache' === gctype) &&
			(cfg.get('auto_check')) &&
			(-1 === gcname.toLowerCase().indexOf('bonus')) &&
			(-1 === gcname.toLowerCase().indexOf('challenge'))
		) {
			checkGeoleaks();		
		}		
		$(link_id).click(function() {
			var href = $(link_id).attr('href');
			if (href) {
				if ('#search' === href) {
					var form = $(form_id);
					if (0 === form.length) {
						form = $('<form />', {
							'method': 'post',
							'target': cfg.get('open_in_new_window') ? '_blank' : '_self',
							'action': 'https://geoleaks.com/forum/search.php'
						}).append(
							$('<input />', { 'name' : 'action', 'value' : 'do_search' }),
							$('<input />', { 'name' : 'keywords', 'value' : gccode }),
							$('<input />', { 'name' : 'postthread', 'value' : 2 })
						)
							.css('display', 'none')
							.appendTo($(document.body))
						;
					}
					form.submit();
					return false;
				}
				return true;
			}
			checkGeoleaks();
		});
	}
	if (window.top == window.self) {
		switch (window.location.hostname) {
			case 'www.geocaching.com' : geocaching(); break;
			case 'geoleaks.com' : setInputFields(); break;
			default : console.error('Unknown hostname: ' + window.location.hostname); break;
		}
	}
}());