Benutzer Diskussion:Frog23/Dead Link Finder (Greasemonkey Script)

aus Wikipedia, der freien Enzyklopädie
Letzter Kommentar: vor 14 Jahren von Federstrich in Abschnitt Neue Version von Federstrich
Zur Navigation springen Zur Suche springen

Neue Version von Federstrich

[Quelltext bearbeiten]
// ==UserScript==
// @name           Wikipedia - Dead-Link-Finder
// @description    finds external links in Wikipedia-pages, which do not return the HTTP status code 200 and marks them.
// @namespace      http://userscripts.org/users/frog23
// @include        http://*.wikipedia.org/*
// @include        http://*.wikinews.org/*
// @include        http://meta.wikimedia.org/*
// @include        http://*.wiktionary.org/*
// @include        http://*.wikibooks.org/*
// @include        http://*.wikiquote.org/*
// @include        http://*.wikiversity.org/*
// @include        http://*.wikisource.org/*
// @version        1.2.2
// @author         frog23
// @date           2009-11-21
// @license        GPL 2 or later, see <http://www.gnu.org/licenses/>
// ==/UserScript==

var fadeOutDelay = 1500;
var timeToFade = 500;


var enabled = GM_getValue("enabled",true);
if(enabled){
	var links = document.evaluate('id("bodyContent")//a[starts-with(@class, "external")]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	var counter = 0;
	var doneCounter = 0;
	var deadLinkCount = 0;

	var method = GM_getValue("RequestMethod","HEAD");
	var showOk = GM_getValue("showOk",false);
	var showRunning = GM_getValue("showRunning",false);
	var fadeOk = GM_getValue("fadeOk",true);
	var verbose = GM_getValue("verbose",false);

	var countDiv;
	var okDiv;

	if(verbose){GM_log('starting with '+links.snapshotLength+' links to check.');}

	if(document.URL.indexOf("browsemode=on")>-1){
		GM_log("browse mode initialized");
		GM_setValue("browsemode",true)
	}else if(document.URL.indexOf("browsemode=off")>-1){
		GM_log("browse mode stopped by user");
		GM_setValue("browsemode",false)
	}

	function next(){
		if(!GM_getValue("enabled",true)){
			GM_log('script stopped by user');
			return;
		}
		if(counter < links.snapshotLength) {
			var link = links.snapshotItem(counter);

			var linkText = link.href
			if( linkText.substring(29,0)=='http://stable.toolserver.org/' ||
				linkText.substring(7,0)=='mailto:' ||
				linkText.substring(23,0)=='http://de.wikipedia.org'
				){
				counter++;
				if(verbose){GM_log('skipping '+linkText+'('+(links.snapshotLength-counter)+' to go)');}
				doneCounter++;
				next();
			}else{
				if(verbose){GM_log('going to check: '+linkText);}
				GM_xmlhttpRequest({
					method: method,
					url: linkText,
					headers: {
						'User-agent': 'Mozilla/4.0 (compatible) Greasemonkey',
						'Accept': 'application/atom+xml,application/xml,text/xml',
					},
					onload: function(responseDetails) {
						doneCounter++;
						if (responseDetails.readyState == 4) {
							//if the status is not ok, set marker, except if the status is 405 or 406 and the method is HEAD (some servers can not handle head-requests properly and most of them return either one of those two codes)
							if (responseDetails.status != 200 && ((method == "HEAD" && !(responseDetails.status == 405 | responseDetails.status == 406))|method=="GET")) { 
								showError(responseDetails.statusText,responseDetails.status,link);
							}else{
								if(verbose){GM_log('... returned: '+responseDetails.status+' ('+(links.snapshotLength-counter)+' to go)');}
							}
							next();
						}else{
							GM_log('!!! Something went wrong. Being inside onload function with redyState != 4 was not expected. Please inform the author!!!\nlink='+link);
							next();
						}
					},
					onerror: function(responseDetails){
						doneCounter++;
						showError('server not found','x',link);
						next();
					}

				});
								
				counter++;
			}
		}else{
			if(showRunning){
				runningDiv.parentNode.removeChild(runningDiv);
			}
			if(verbose){GM_log('done.');}
			if(deadLinkCount==0 && showOk){
				okDiv = document.createElement("div");
				okDiv.innerHTML = "<a style=\"cursor:pointer\" onclick=\"this.parentNode.style.visibility='hidden';\"><img src=\"http://commons.wikimedia.org/w/thumb.php?f=Gnome-emblem-default.svg&width=40px\" style=\"float:left;\" alt=\"Icon: no dead links found\"></a>";
				okDiv.id = "okDiv";
				okDiv.style.position = "fixed"; 
				okDiv.style.bottom = "0px"; 
				okDiv.style.right = "0px";
				okDiv.style.opacity = "1";
				document.getElementById("bodyContent").appendChild(okDiv);
				if(fadeOk){
					setTimeout(function(){fade();}, fadeOutDelay);
				}
			}

			if(deadLinkCount==0 && GM_getValue("browsemode",false)){
				var link = document.evaluate("id('n-randompage')/a", document, null, 9, null).singleNodeValue;
				if(link){
					window.location = link.href;
				}else{
					GM_setValue("browsemode",false);
					GM_log("browsemode not possible");
				}
			}
		}

	}

	if(method == "HEAD"){
		GM_registerMenuCommand("WP Dead Link Finder: GET", function(){GM_setValue("RequestMethod","GET");location.reload();});
	}else{
		GM_registerMenuCommand("WP Dead Link Finder: HEAD", function(){GM_setValue("RequestMethod","HEAD");location.reload();});
	}
	if(showOk){
		GM_registerMenuCommand("WP Dead Link Finder: hide OK", function(){GM_setValue("showOk",false);location.reload();});
		if(!fadeOk){
			GM_registerMenuCommand("WP Dead Link Finder: fade out OK", function(){GM_setValue("fadeOk",true);location.reload();});
		}else{
			GM_registerMenuCommand("WP Dead Link Finder: don\'t fade OK", function(){GM_setValue("fadeOk",false);location.reload();});
		}
	}else{
		GM_registerMenuCommand("WP Dead Link Finder: show OK", function(){GM_setValue("showOk",true);location.reload();});
	}
	if(showRunning){
		GM_registerMenuCommand("WP Dead Link Finder: hide running", function(){GM_setValue("showRunning",false);location.reload();});
		runningDiv = document.createElement("div");
		runningDiv.innerHTML = "<a style=\"cursor:pointer\" onclick=\"this.parentNode.style.visibility='hidden';\"><img src=\"http://commons.wikimedia.org/w/thumb.php?f=Spur_Gear_12mm,_18t.svg&width=70px\" style=\"float:left;\" alt=\"Icon: skript is running\"></a>";
		runningDiv.id = "runningDiv";
		runningDiv.style.position = "fixed"; 
		runningDiv.style.bottom = "0px"; 
		runningDiv.style.right = "0px";
		runningDiv.style.opacity = "1";
		runningDiv.style.zIndex = "999999";
		document.getElementById("bodyContent").appendChild(runningDiv);
	}else{
		GM_registerMenuCommand("WP Dead Link Finder: show running", function(){GM_setValue("showRunning",true);location.reload();});
	}
	if(verbose){
		GM_registerMenuCommand("WP Dead Link Finder: no verbose", function(){GM_setValue("verbose",false);location.reload();});
	}else{
		GM_registerMenuCommand("WP Dead Link Finder: verbose", function(){GM_setValue("verbose",true);location.reload();});
	}
	//GM_registerMenuCommand("WP Dead Link Finder: disable", function(){GM_setValue("enabled",false);location.reload();});
	GM_registerMenuCommand("WP Dead Link Finder: disable", function(){GM_registerMenuCommand("WP Dead Link Finder: ENABLE AGAIN", function(){GM_setValue("enabled",true);location.reload();});if(verbose){GM_log('==> trying to DISABLE NOW <==')};GM_setValue("enabled",false);});
	next();
}else{
	GM_registerMenuCommand("WP Dead Link Finder: enable", function(){GM_setValue("enabled",true);location.reload();});
}

function showError(errTxt,errStatus,link){
	var txt="page is NOT ok:" + errStatus + " - " + errTxt + " - " + link;
	if(verbose){txt=txt+' ('+(links.snapshotLength-counter)+' to go)';}
	GM_log(txt);
	var alertLabel = document.createElement("span");
	alertLabel.innerHTML = "["+errStatus+"]";
	alertLabel.style.color="#ff0000";
	alertLabel.title=errTxt;
	link.parentNode.insertBefore(alertLabel,link);

	var alertImg = document.createElement("img");
	alertImg.src = "http://commons.wikimedia.org/w/thumb.php?f=Nuvola%20apps%20important.svg&width=16px";
	alertImg.alt="Alert Icon: dead link";
	alertImg.title=errTxt;


	link.parentNode.insertBefore(alertImg,alertLabel);
	link.parentNode.insertBefore(link,alertImg);

	if(deadLinkCount==0){
		alertLabel.id="first-dead-link-ref";

		//insert Icon with count and hide-Option
		var alertDiv = document.createElement("div");
		alertDiv.innerHTML = "<a href=\"#first-dead-link-ref\"><img src=\"http://commons.wikimedia.org/w/thumb.php?f=Nuvola%20apps%20important.svg&width=50px\" style=\"float:left;\" alt=\"Alert Icon: dead link\"></a><small>&nbsp;&nbsp;<a style=\"cursor:pointer\" onclick=\"this.parentNode.parentNode.style.visibility='hidden';\">[x]</a></small><br/><div id=\"dead-link-count\" style=\"float:right; padding-top:4px;\"></div>";
		alertDiv.style.background = "rgb(255, 255, 255) none repeat scroll 0% 0%"; 			
		alertDiv.style.position = "fixed"; 
		alertDiv.style.bottom = "0px"; 
		alertDiv.style.right = "0px";

		document.getElementById("bodyContent").appendChild(alertDiv);
		countDiv = document.getElementById("dead-link-count");
		if(GM_getValue("browsemode",false)){
			GM_setValue("browsemode",false);
			GM_log("browsemode finished");
		}
	}

	deadLinkCount++;
	countDiv.innerHTML = "<small>"+deadLinkCount+"&nbsp;</small>"; 
}

function fade()
{
	okDiv.style.opacity = okDiv.style.opacity-0.05;
	if(okDiv.style.opacity <= 0){
		okDiv.parentNode.removeChild(okDiv);
		return;
	}else{
		setTimeout(function(){fade();}, timeToFade/10);
	}
}

--Federstrich Diskussion 21:59, 10. Aug. 2010 (CEST)Beantworten