Airdates.tv show past weeks

Control how many past weeks you want to see and many other enhancements

当前为 2017-06-15 提交的版本,查看 最新版本

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        Airdates.tv show past weeks
// @namespace   V@no
// @description Control how many past weeks you want to see and many other enhancements
// @include     http://www.airdates.tv/*
// @include     https://www.airdates.tv/*
// @icon        data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsSAAALEgHS3X78AAAEiElEQVRYw+2VW4hVVRjHf+uyz97nnLkcHWfGuWYzDlKUhUrUgynkQxREFJFEDwbzFkXQg0I9hIRF9BDRk1AyigkhouJDBuEEPlcQNdqo1cnRzozpzDnOuezL+no4czVnqIfBl/m/7L2+tde3/vv7/uu/YBWruMdQCweXRkff2Ltv36elUun3MAzFswnabiCq5qiGIX1NIT3uD8TzEJXDmo2kMbAOLvddoTg5RXNDI1YPEIce63vuo1fyrPcm0RmfX0cr97/wylvv9PX3HJjd0y4kkP8zv+nMmTPs379/wyObN3PzVhbPOwDuCF0JHPd38YF7n6zVoL7G6PeYXgebLz7MwTcPEmoIbUwUDpIOrjCQUbyrPuQrPUhLWKWv6xAvvjzauXDPRQQ8L0U6SLPrqV1s2bplJrphbv43OoEnmAbg5lx8ujVkW+nxBZkEShEAEWsp0kYRaG3dSENjsqgF+s6OCI4oDgGo1cA5mZuNFndsPkl89zhAgpn/QZP8e+3ioSBOEGFFIFLPvyQBESGKImSFGLjE4RK3XAUgTpKVI+ASXLKMBhQgzq0YgThOcLJcC2YrwMoQiFxM7OKlCcyqT5z7z0n/D1yckMTLtGD2v1fqFERxjHPLiHC29yulgcQlJHeIcJETzm5sbf3p+4sTqKW0oZYjPD8XhjFRsowG7l6B+Xe1hBMqdWd8fo1esKZSrRLFiwksqoCZcc3duzWtbVCtQHNTlkwWrgjsKWeRqfo3xwPDS00Q3IDCQxkeKIPT4BzktgXYXyAPfPSZZeh1iBLY97ZiZMQtTSAM6xfI2NgPjI3lAB+4ARgwlhGmILmEQ0BfpjloobdsqepmLiQ/gWhIhFxvO6nSbcbLFcKWv4ECnlEYc51ytW9pAr6fVu1tnQTpvWSzoJQQR60kbhOec5w332L0lyilyakcvXQhHjRGf/FYzw6sZ/FTPrq7B2+gn3QqxeFPjnLo4yGMMdRqNZ57/lX/rgREZODw0NBgc64B319DHIVESUzKC3BRREiCHwd0JB2AQitNiSLaGCpGoVvWzOnRK04ixVukrYfVlkqlgmiFiHDhwsigiBxVSg3PERCR7PC5c+dPnT6dEhHa2zsoThVRClK+T6VSwRiDUgqjTf1WAxJxWAXKOZwDqzVaa5qbmylXyigB63mEYUhDJsP18QInTp4kt3btKRF5UCk1pkRkIJ/Pf372m7PbNYrJyUmqtSrWWJwTtNaghFq1hvU80kGKWhSThDFWK0ARR1VwjiCVwg8CfC/AGEu2sZHYJXjaooW6B/iWQqHAkzt3/vzo1i171HfDw18cO3bstfGJCYLAB6kfq7ppODzPm7mmQ5I4RmlDd1cHjQ0NlCshTamA2AiV8m0mCuOgFJ71SZwj5XmEtRqJc2htUAqM1oS1Globnn72mUN2YmLiyLVr1/J9/f391tpGpVUkru4FSlG3TgFtNL6f4urVcX788Xs6OteTL0zT5sXcLJUJgR3bt+OcULpd8tpza4rdPd3XnYjVWiMzfqGVIpPJpC5dvOiM0SdYxSruNf4Bbv4W546hynoAAAAASUVORK5CYII=
// @version     1.7.2
// @run-at document-start
// @noframes
// @grant       none
// ==/UserScript==

//tab = 2 spaces

document.addEventListener("DOMContentLoaded", function(e)
{
let log = console.log,
		_today;

/*
fixing browser history inflating after each page refresh and prev/next history jump don't work
*/
var prevPath;
function loadArchiveFromPathname(originalPath,highlightSelector){
	path = originalPath||document.location.pathname;
	var match = path.match(/^\/archive\/([0-9]+)-([0-9]+)$/);
	var ym = match && match.length == 3? (~~match[1]*12+~~match[2]-1) : ymToday;
//start fix - browser history inflating after each page refresh
	if (originalPath && prevPath != originalPath)
	{
		prevPath = originalPath;
		history.pushState({originalPath:originalPath,highlightSelector:highlightSelector}, "", originalPath);
	}

//end fix
	$("#archive-prev").attr("href", "/archive/" + ym2str(ym-1));
	$("#archive-next").attr("href", "/archive/" + ym2str(ym+1));
	$("body").toggleClass("archive", !!match&&match.length==3);
	$("#leaveArchive").text(ym>ymToday?"Leave future":"Leave archive");

	var whenDone = function(){
		// set title
		$("#archive-current").text((!!match&&match.length==3)?ym2str(ym):"Go waste your time");
		// highlight today with a happy yellow background
		$( "div.day[data-date='" + today.getFullYear() + pad2( today.getMonth() + 1 ) + pad2( today.getDate() ) + "']" ).addClass( "today" ).attr( "id", "today" );
		markSearchResults();

		var $hl = $(highlightSelector||".does-not-exist-and-never-will");
		if($hl.get().length>0){
			// blink
			for( var i = 0; i < 8; i++ ) $hl.animate( {"opacity":i%2}, 1 ).delay( 100 );

			// scroll to
			var val = function(){return $hl.offset().top-Math.max(document.documentElement.clientHeight, window.innerHeight || 0)/2};
			$('html, body').animate({
        		scrollTop: val()
    		},{duration:500, step:function(top,info){
    			info.end = val();
    		}});
		}
//injecting userscript function execution
showPast();
	};

	if(ymCurrent != ym){
		$(".days").load("/_archive/" + ~~(ym/12) + "-" + ~~((ym%12)+1), function(){
			ymCurrent = ym;
			whenDone();
		});
	}
	else{
		whenDone();
	}
}

//fixing prev/next history jump does nothing
$(window).on("popstate", function(e)
{
		let state = e.originalEvent.state;
		prevPath = (state ? state.originalPath : undefined) || e.target.location.pathname;

	loadArchiveFromPathname(prevPath, state ? state.highlightSelector : undefined);
});
/*
end fixing browser history inflating after each page refresh and prev/next history jump don't work
*/

window.loadArchiveFromPathname = loadArchiveFromPathname;
function showPast()
{
// hide all past days
	var	d = new Date();

	_today = $("div.day[data-date='" + d.getFullYear() + pad2((new Date()).getMonth() + 1) + pad2((new Date()).getDate()) + "']");

	if (!_today || $(".archive").length)
		return;

	let	firstDay = $(".days").children().first(),
			firstDate = firstDay.attr("data-date"),
			div = [document.createElement("div")],
			y = firstDate.slice(0, 4),
			m = firstDate.slice(4, 6);

	if (parseInt(firstDate.slice(6, 8)) < 15)
		div.push(document.createElement("div"));

	let c = div.length;
	for (let n = 0; n < div.length; n++)
	{
		let d = new Date(y, m - n - 1);
		$(div[n]).load("/_archive/" + d.getFullYear() + "-" + pad2(d.getMonth() + 1), pastLoadDone);
	}
	function pastLoadDone()
	{
		if (--c > 0)
			return;

		let found = false,
				func = function (i, o)
				{
					if ($(this).attr("data-date") == firstDate)
						found = true;

					if (found)
						$(this).remove();
				};
		for (let n = 0; n < div.length; n++)
		{
			found = false;
		//remove any duplicate dates that already exist;
			$(div[n]).children().each(func);
			$(div[n]).children().prependTo($("div.days"));
		}
		pastLoaded();
	}
}//showPast()

function pastLoaded()
{
	let	hasLoaded = $("#pastWeeks").length,
			stop = false;

	$("div.days").children().each(function(i, o)
	{
		if ($(this).is(_today))
		{
			$(this).attr("today", "true");
			stop = true;
		}
		if (stop)
		{
			$(this).removeClass("past");
		}
		else
		{
			$(this).addClass("past");
		}
	});

	let week = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"],
			match = $(_today).find(".date").text().toLowerCase().match(/([^,]{3})/),
			daysNum = match ? week.indexOf(match[1]) : -1;

	//there is no identication of which week a day belong to, so we must make sure that previous days of current week don't count as previous week.
	if (daysNum > 0)
	{
		let prev = _today.prev();
		for(let i = 0; i < daysNum  && prev; i++)
		{
			prev.removeClass("past");
			prev = prev.prev();
		}
		//remove more then 4 weeks worth of days.
		for(let i = 0; i < 27 && prev; i++)
		{
			prev = prev.prev();
		}
		if (prev)
		{
			let found = false,
					func = function(i, o)
					{
						if (found)
							return;

						if ($(this).is(prev))
							found = true;
						else
							$(this).remove();
					};
			$("div.days").children().each(func);
		}
	}
	let	daysPast = $('div.past'),
			weeks = parseInt(readCookieRaw("w")),
			weeksMax = Math.round((daysPast.length) / 7);//how many past weeks do we have available?

	if (isNaN(weeks))
		weeks = readCookieRaw("p") == "1" ? weeksMax : 0;

	if (weeks > weeksMax)
		weeks = weeksMax;

	//main function that shows/hides past days
	function showWeeks()
	{

		//get week numbers from dropdown
		let weeks = parseInt($("#pastWeeks").val());

		//just some sanity check
		if (weeks * 7 > daysPast.length)
			weeks = weeksMax;

		if (weeks < 1)
			weeks = 0;

		for(var i = weeksMax; i > 0; i--)
			$( "div.calendar" ).toggleClass("showPast" + i, (weeks >= i));

		createCookie("w", weeks);
	}
	//add new class pastNN to each past day, where NN is a week number.
	let func = function(i)
	{
		$(this).addClass("past" +  (Math.ceil((daysPast.length - i) / 7 % (weeksMax + 1))));
	};
	daysPast.each(func);

	if (!hasLoaded)
	{
		//create dropdown menu with number of available past weeks
		var dropdown = document.createElement("select");
		dropdown.id = "pastWeeks";

		for(var i = 0; i <= weeksMax; i++)
		{
			var option = document.createElement("option");
			option.value = i;
			option.text = i;
			option.selected = (weeks == i);
			dropdown.appendChild(option);
		}

		//add event listener to dropdown
		$(dropdown).change(showWeeks);

		var span = document.createElement("span");
		span.id = "past-weeks";
		span.appendChild(document.createTextNode("Show past weeks:"));
		span.appendChild(dropdown);
		//insert our dropdown and new text into document
		$(".calendar").prepend(span);

		//hide "Show/Hide past month" links
		$("#past-showing").toggle(true);
		//togglePast();//make sure we disable "Show past month"
		$("#past-showing").toggle(false);
		$("#past-hidden").toggle(false);
	}
	showWeeks();
}//pastLoaded()

var prevOpened = null;
//adding attribute "opened" to the entry allows us show/hide things from CSS based on entry state
$("div.days").on("click", "div.entry div.title", function()
{
	if (prevOpened)
	{
		prevOpened.attr("opened", "");
		let po = prevOpened;
		setTimeout(function()
		{
			po.removeAttr("opened");
		}, 200);
		prevOpened = null;
	}

	let $entry = $( this ).parent();
	if ($entry.attr("opened") === undefined)
	{
		$entry.attr("opened", "");
//idealy this should've been done via "on complete" function submitted for slideUp/slideDown
		setTimeout(function()
		{
			$entry.attr("opened", "1");
		}, 300);
		prevOpened = $entry;
	}
});

//create stylesheet. A little trick to have multi-line text in javascript
var	style = document.createElement("style"),
		css = function(){/*
.past
{
	display: none;
}

div.showPast1 div.past1,
div.showPast2 div.past2,
div.showPast3 div.past3,
div.showPast4 div.past4,
div.showPast5 div.past5,
div.showPast6 div.past6,
div.showPast7 div.past7,
div.showPast8 div.past8,
div.showPast9 div.past9
{
	display: block;
}

div.calendar.searching > span
{
	text-decoration: line-through;
}

#past-weeks
{
	margin-left: 0.2%;
}

#pastWeeks
{
	margin-left: 0.5em;
}

.archive #past-weeks
{
	text-decoration: line-through;
}


/* today column border *//*
div.today
{
	border-color: #FFC800;
}

/* higlighted title under cursor *//*
div.title:hover
{
	background-color: #ffffd5;
}

div[white] div.title:hover
{
	color: black;
}

/* highlight opened entry *//*
.entry[opened]
{
	border: 1px solid black;
}

.entry[opened][white]
{
	border-color: grey;
}

div[opened] + div
{
	border-top: 0;
}

*/};

style.innerHTML = css.toString().slice(14, -3).replace(/\*\/\/\*/g, "*/");
$("head").append(style);


//fix incorrect initial color in colorpicker
//fix clicking outside of colorpicker saves selected color instead of discarding
//fix close colorpicker by pressing escape button

var editingSeriesId = -1;
var clone = $("#colorPickerHolder").clone();
$("#colorPickerHolder").remove();
var picker = clone.colorPicker(
{
	animationSpeed: 0,
	opacity: false,
	buildCallback: function($elm)
	{
		let cp = this;
		$elm
			.append('<div class="cp-disp"><input type="button" value="save"> <input type="button" value="cancel"></div>')
			.on( "click", 'input', function()
			{
				if (this.value == 'save')
					assignColor( editingSeriesId, "#" + cp.color.colors.HEX, true );

				editingSeriesId = -1;
				cp.toggle();
			});
		$("body").on("keydown", function(e)
		{
//ESC(27) = cancel
			if (e.which == 27 && $elm.is(":visible"))
				cp.toggle();
		});
	},
	cssAddon: ".cp-disp{ padding-bottom: 2px; clear:both; }",
	renderCallback: function($elm, toggled) {
		var colors = this.color.colors;
		// on show
		if( toggled === true ){
		}
		// on change
		else if( toggled === undefined ){
//preview new color
			assignColor( editingSeriesId, "#" + colors.HEX, false );
		}
		// on hide
		else if( toggled === false ){
//restore entry color
			if( editingSeriesId > 0 )
				loadColor( editingSeriesId );

			editingSeriesId = -1;
			picker.detach().appendTo("body");
		}

	}
}).attr("id", "colorPickerHolderNew"); //replace ID so it won't initialize in main.js

$("body").off("click", ".picker");

// now hook up the picker to the picker icons
$("body").on("click", ".picker", function(e){
	if( !$(e.target).hasClass("picker") ) return;

	editingSeriesId = $(this).parents("[data-series-id]").data("series-id");
//set initial color in colorpicker based on current entry or default to white
	picker.val(coalesce(DB.savedColors[editingSeriesId], "#ffffff"));
	picker.detach().appendTo(this).click();
});

let engines = [
	{ name: "Wikipedia", host: "en.wikipedia.org", href: "http://en.wikipedia.org/wiki/{WIKI_TITLE}" } ,
	{ name: "Google", host: "www.google.com", href: "https://www.google.com/?#q=MONKEY" } ,
	{ name: "rarbg", host: "rarbg.to", href: "https://rarbg.to/torrents.php?search=MONKEY" } ,
	{ name: "Torrentz2.eu", host: "torrentz2.eu", href: "https://torrentz2.eu/search?f=MONKEY" } ,
	{ name: "Piratebay", host: "thepiratebay.se", href: "https://thepiratebay.se/search/MONKEY/0/7/0" } ,
	{ name: "Idope", host: "www.idope.se", href: "https://www.idope.se/torrent/MONKEY/" } ,
	{ name: "Alluc", host: "www.alluc.com", href: "http://www.alluc.com/stream/MONKEY" } ,
	{ name: "Subtitleseeker", host: "www.subtitleseeker.com", href: "http://www.subtitleseeker.com/search/TITLES/MONKEY" } ,
	{ name: "Subscene", host: "subscene.com", href: "http://subscene.com/subtitles/release?q=MONKEY" } ,
	{ name: "IMDB", host: "www.imdb.com", href: "http://www.imdb.com/search/title?title=MONKEY_N&title_type=tv_series,tv_episode,tv_special,mini_series" }

];


//middle click on day's title opens selected engines for user's shows
let _engines = [],
		list = ["Piratebay"];
for(let i = 0; i < engines.length; i++)
{
	let n = list.indexOf(engines[i].name);
	if (n != -1)
		_engines.push(engines[i]);
}

$("div.date").on("mousedown", function(e)
{
	if (e.button != 1)
		return;

	e.stopPropagation();
	e.preventDefault();
	let func = function()
	{
		let el = $(this),
				MONKEY_ID = encodeURIComponent( el.data("series-id") );
		if (!DB.getColor(MONKEY_ID))
			return;

		let title = el.children("div.title").text().replace("?", ""),
				MONKEY = encodeURIComponent( title ),
				MONKEY_N = encodeURIComponent( title.replace( /S[0-9]+E[0-9]+$/g, '' ) ),
				WIKI_TITLE = encodeURIComponent( el.data("series-source") );

		$.each( _engines, function( i, engine ){
			let href = engine.href
				.replace( "MONKEY_ID", MONKEY_ID )
				.replace( "MONKEY_N", MONKEY_N )
				.replace( "MONKEY", MONKEY )
				.replace( "{WIKI_TITLE}", WIKI_TITLE );
			window.open(href, MONKEY);
		} );
	};
	$(this).parent().find("div.entry").each(func);
});

$( "body").on("click", "div.entry div.title", function(e)
{
	let obj = this;
	setTimeout(function()
	{
		$(obj).parent().find(".engines").children().each(function(i, o)
		{
			if (o.href)
				o.href = o.href.replace("%3F", "");
		});
	});
});

},true);