Greasy Fork

Greasy Fork is available in English.

豆瓣电影C+|MyDoubanMovieHelper|豆瓣|豆瓣电影|douban.movie.com

在豆瓣电影详情界面下添加下载或者网盘链接。数据来自多个站点。点击即复制。

当前为 2016-05-20 提交的版本,查看 最新版本

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

You will need to install an extension such as Tampermonkey to install this script.

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @id           [email protected]
// @name         豆瓣电影C+|MyDoubanMovieHelper|豆瓣|豆瓣电影|douban.movie.com
// @namespace    Chang_way_enjoying
// @version      0.6.3_2016-05-20
// @description  在豆瓣电影详情界面下添加下载或者网盘链接。数据来自多个站点。点击即复制。
// @author       c wt U r
// @match        https://movie.douban.com/subject/*
// @connect      mp4ba.com
// @connect      edmag.net
// @connect      tl95.com
// @connect      kat.cr
// @require      https://cdn.bootcss.com/jquery/2.2.3/jquery.min.js
// @require      https://cdn.bootcss.com/jBox/0.3.2/jBox.min.js
// @grant        GM_xmlhttpRequest
// @grant        GM_setClipboard
// ==/UserScript==

/**
 * Created by c wt U r on 2016/5/18.
 * QQ 3099891314
 *
 * node{detailURL,downloadURL,date,type[0,1,2],title}
 * type[0 , // mag
 *      1 , // ed2k
 *      2 , // thunder
 *      3   // netdisk
 *      ]
 * TODO 加入book.douban.com的支持
 * TODO baidu网盘的链接有效性检测函数
 * TODO baidu网盘加密链接的搜索
 * TODO baidu网盘非加密的链接的搜索
 * TODO baidu网盘已登录用户一键保持
 *
 */

var config = {
	c01: 3,
};
addCSSfile("https://cdn.bootcss.com/jBox/0.3.2/jBox.min.css");

function addCSSfile(url) {
	$("<link>").attr({
		rel: "stylesheet",
		type: "text/css",
		href: url
	}).appendTo("head")
}
function getDoc(url, callback) {
	GM_xmlhttpRequest({
		method: 'GET',
		url: url,
		headers: {
			'User-agent': window.navigator.userAgent,
			'Content-type': null
		},
		onload: function(responseDetail) {
			var doc = '';
			if (responseDetail.status == 200) {
				doc = new DOMParser().parseFromString(responseDetail.responseText, 'text/html');
				if (doc === undefined) {
					doc = document.implementation.createHTMLDocument("");
					doc.querySelector('html').innerHTML = responseText
				}
			}
			callback(doc, responseDetail.finalUrl)
		}
	})
}
function postDoc(url, callback, data) {
	GM_xmlhttpRequest({
		anonymous: true,
		method: 'POST',
		url: url,
		headers: {
			'User-agent': window.navigator.userAgent,
			'Content-type': 'application/x-www-form-urlencoded'
		},
		data: data,
		onload: function(responseDetail) {
			callback(responseDetail.responseText, responseDetail.finalUrl)
		}
	})
}
function timeago(stime) {
	var publishTime = new Date(stime);
	var d_minutes, d_hours, d_days;
	var timeNow = parseInt(new Date().getTime() / 1000);
	var d;
	d = timeNow - publishTime;
	d_days = parseInt(d / 86400);
	d_hours = parseInt(d / 3600);
	d_minutes = parseInt(d / 60);
	if (d_days > 0 && d_days < 4) {
		return d_days + "天前"
	} else if (d_days <= 0 && d_hours > 0) {
		return d_hours + "小时前"
	} else if (d_hours <= 0 && d_minutes > 0) {
		return d_minutes + "分钟前"
	} else {
		var s = new Date(publishTime * 1000);
		return (s.getMonth() + 1) + "月" + s.getDate() + "日"
	}
}
function msg_info(msg) {
	new jBox('Notice', {
		content: msg,
		position: {
			x: 15,
			y: 65
		},
		zIndex: 12000,
		onInit: function() {
			this.options.color = 'blue'
		},
	})
}
function msg_warning(msg) {
	console.log(msg);
	var color = 'yellow';
	new jBox('Notice', {
		attributes: {
			x: 'left',
			y: 'bottom'
		},
		delayClose: 1000 * 30,
		theme: 'NoticeBorder',
		color: color,
		animation: {
			open: 'slide:bottom',
			close: 'slide:left'
		},
		onInit: function() {
			this.options.color = color;
			this.options.title = "提示";
			this.options.content = msg
		},
	})
}
function msg_error(msg) {
	var color = 'red';
	new jBox('Notice', {
		attributes: {
			x: 'left',
			y: 'bottom'
		},
		theme: 'NoticeBorder',
		color: color,
		animation: {
			open: 'slide:bottom',
			close: 'slide:left'
		},
		onInit: function() {
			this.options.color = color;
			this.options.title = "错误警告";
			this.options.content = msg
		},
	});
	console.error(msg)
}
imdb = $("#info").find("a[href^='http://www.imdb.com/title/tt']").text();
title_cn = $("#content").children()[0].firstElementChild.textContent.split(" ")[0];
title_en = undefined;
if (!imdb) {
	msg_error('imdb is null')
} else {
	if (imdb.startsWith('tt')) {
		imdb = imdb.slice(2)
	}
}
msg = ["IMDB:\t" + imdb, "TITLE:\t" + title_cn].join("\n");
msg_info(msg);
var linksTable = {
	table: undefined,
	nodes: [],
	init: function() {
		var div, h2 = undefined;
		div = $("<div>").attr({
			id: "dtable"
		});
		h2 = $("<h2>");
		h2 = h2.html("下载地址");
		div.append(h2);
		$($("div.related-info")[0]).after(div);
		var tr, th = undefined;
		this.table = $("<table>").attr({
			id: "dlinks",
			class: "table table-condensed table-hover table-striped"
		});
		thead = $("<thead>");
		tr = $("<tr>");
		th = $("<th>").attr({
			"data-column-id": "copy",
			style: "width:33px"
		});
		th = th.html("   ");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "detail",
			style: "width:33px"
		});
		th = th.html("   ");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "date",
			style: "width:80px"
		});
		th = th.html("时间");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "type",
			style: "width:55px"
		});
		th = th.html("类型");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "title"
		});
		th = th.html("详细信息");
		tr.append(th);
		thead.append(tr);
		this.table.append(thead);
		this.table.appendTo($("#dtable"))
	},
	clean: function() {
		$("#dtable").remove();
		this.init()
	},
	_add: function(data) {
		thead = $($("#dlinks")[0].firstElementChild);
		types = {
			0: "mag",
			1: "ed2k",
			2: 'thunder'
		};
		var tr, th = undefined;
		tr = $('<tr style="max-height: 19px;">');
		th = $("<th>");
		th = th.html('<a href="' + data.detailURL + '" target="_blank" rel="nofollow">详情</a>');
		tr.append(th);
		th = $("<th>");
		th = th.html('<a onclick="" class="j" data-src="' + data.downloadURL + '" rel="nofollow">复制</a>');
		th.click(function() {
			url = $(this.firstElementChild).attr("data-src");
			GM_setClipboard(url, "{ type: 'text', mimetype: 'text/plain'}");
			msg_info("链接已复制")
		});
		tr.append(th);
		th = $("<th>");
		th = th.html("");
		tr.append(th);
		th = $("<th>");
		th = th.html(types[data.type]);
		tr.append(th);
		if (data.title.length > 45) {
			th = $('<th class="link_title" data="' + data.title + '" style="max-height: 19px;">');
			th = th.html(data.title.slice(0, 40) + "...");
			th.jBox('Tooltip', {
				id: 'jBox_dlinks_tooltip',
				width: 280,
				closeOnMouseleave: true,
				animation: 'zoomIn',
				zIndex: 8000,
				content: th.attr("data")
			});
			tr.append(th)
		} else {
			th = $('<th class="link_title" style="max-height: 19px;">');
			th = th.html(data.title);
			tr.append(th)
		}
		thead.append(tr)
	},
	print: function() {
		this.clean();
		var mag = [];
		var ed2k = [];
		var thunder = [];
		var netdisk = [];
		var all = [netdisk, mag, ed2k, thunder, ];
		for (i = 0; i < this.nodes.length; i++) {
			var node = this.nodes[i];
			if (node.type === 0) {
				mag.push(node)
			} else if (node.type === 1) {
				ed2k.push(node)
			} else if (node.type === 2) {
				thunder.push(node)
			} else if (node.type === 3) {
				netdisk.push(node)
			} else {
				msg_warning("code:1001 msg:不支持当前链接格式.")
			}
		}
		for (var i = 0, n;
		(n = all[i]) != null; i++) {
			if (n.length) {
				function unique(arr) {
					var result = [],
						hash = {};
					for (var i = 0, elem;
					(elem = arr[i]) != null; i++) {
						if (!hash[elem.downloadURL]) {
							result.push(elem);
							hash[elem.downloadURL] = true
						}
					}
					return result
				};
				n = unique(n);
				for (var i2 = 0, node;
				((node = n[i2]) != null) && i2 < config.c01; i2++) {
					if (node) {
						this._add(node)
					}
				}
			}
		}
	},
	refresh: function() {
		this.nodes = [];
		for (i = 0; i < dmovie.sites.length; i++) {
			this.nodes = this.nodes.concat(dmovie.sites[i].nodes)
		}
		this.print()
	},
	act: function() {
		$("#dtable").bootgrid()
	}
};
var baidu_netdisk = {
	id: "netdisk_table",
	nodes: [],
	hashtable: {},
	init: function() {
		var div, h2 = undefined;
		div = $("<div>").attr({
			id: this.id
		});
		h2 = $("<h2>");
		h2 = h2.html("网盘信息");
		div.append(h2);
		$($("div.related-info")[0]).after(div);
		var tr, th = undefined;
		this.table = $("<table>").attr({
			id: "nlinks",
			class: "table table-condensed table-hover table-striped"
		});
		thead = $("<thead>");
		tr = $("<tr>");
		th = $("<th>").attr({
			"data-column-id": "copy",
			style: "width:33px"
		});
		th = th.html("   ");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "detail",
			style: "width:33px"
		});
		th = th.html("   ");
		tr.append(th);
		th = $("<th>").attr({
			"data-column-id": "title"
		});
		th = th.html("详细信息");
		tr.append(th);
		thead.append(tr);
		this.table.append(thead);
		this.table.appendTo($("#netdisk_table"))
	},
	clean: function() {
		$("#" + this.id).remove();
		this.init()
	},
	add: function(sdoc) {
		var re = /(pan.baidu.com\/s\/[a-zA-Z0-9]+)\s*.+\s*.([a-zA-Z0-9]{4})/g;
		var m;
		urls = [];
		while ((m = re.exec(sdoc)) !== null) {
			if (m.index === re.lastIndex) {
				re.lastIndex++
			}
			var u = "http://" + m[1] + "#" + m[2];
			urls.push(u)
		}
		this.verify(urls)
	},
	_add: function(url, detail) {
		thead = $($("#nlinks")[0].firstElementChild);
		var tr, th = undefined;
		tr = $('<tr style="max-height: 19px;">');
		th = $("<th>");
		th = th.html('<a href="' + url + '" target="_blank" rel="nofollow">查看</a>');
		tr.append(th);
		th = $("<th>");
		th = th.html('<a onclick="" class="j" data-src="' + url + '" rel="nofollow">保存</a>');
		th.click(function() {
			msg_info("功能开发中...")
		});
		tr.append(th);
		if (detail.length > 65) {
			th = $('<th class="link_detail" data="' + detail + '" style="max-height: 19px;">');
			th = th.html(detail.slice(0, 60) + "...");
			th.jBox('Tooltip', {
				id: 'jBox_baidu_tooltip',
				width: 280,
				closeOnMouseleave: true,
				animation: 'zoomIn',
				zIndex: 8000,
				content: th.attr("data")
			});
			tr.append(th)
		} else {
			th = $('<th class="link_detail" style="max-height: 19px;">');
			th = th.html(detail);
			tr.append(th)
		}
		thead.append(tr)
	},
	verify: function(data) {
		type = Object.prototype.toString.call(data);
		type = type.slice(1, type.length - 1).split(" ")[1];
		if (type === "String") {
			if (this.hashtable[data] === undefined) {
				this._verify(data)
			}
		} else if (type === "Array") {
			for (var i = 0, n;
			(n = data[i]) != null; i++) {
				if (this.hashtable[n] === undefined) {
					this._verify(n)
				}
			}
		}
	},
	_verify: function(url) {
		this.hashtable[url] = true;
		getDoc(url, function(doc, url) {
			if (doc.title === "百度云 网盘-链接不存在" || doc.title === "百度云升级") {
				baidu_netdisk.hashtable[url] = false;
				console.log("分享失效", url);
				return
			}
			if (doc.title === "百度云 请输入提取密码") {
				baidu_netdisk._add(url, "带密码的分享");
				return
			}
			if (doc.title.endsWith("百度云 网盘-分享无限制")) {
				console.log("分享正常", url);
				baidu_netdisk._add(url, doc.title.split("|")[0]);
				return
			}
			console.log(url, doc.title)
		})
	},
	print: function() {
		this.clean();
		var mag = [];
		var ed2k = [];
		var thunder = [];
		var netdisk = [];
		var all = [netdisk, mag, ed2k, thunder, ];
		for (i = 0; i < this.nodes.length; i++) {
			var node = this.nodes[i];
			if (node.type === 0) {
				mag.push(node)
			} else if (node.type === 1) {
				ed2k.push(node)
			} else if (node.type === 2) {
				thunder.push(node)
			} else if (node.type === 3) {
				netdisk.push(node)
			} else {
				msg_warning("code:1001 msg:不支持当前链接格式.")
			}
		}
		for (var i = 0, n;
		(n = all[i]) != null; i++) {
			if (n.length) {
				function unique(arr) {
					var result = [],
						hash = {};
					for (var i = 0, elem;
					(elem = arr[i]) != null; i++) {
						if (!hash[elem.downloadURL]) {
							result.push(elem);
							hash[elem.downloadURL] = true
						}
					}
					return result
				};
				n = unique(n);
				for (var i2 = 0, node;
				((node = n[i2]) != null) && i2 < config.c01; i2++) {
					if (node) {
						this._add(node)
					}
				}
			}
		}
	},
	refresh: function() {
		this.nodes = [];
		for (i = 0; i < dmovie.sites.length; i++) {
			this.nodes = this.nodes.concat(dmovie.sites[i].nodes)
		}
		this.print()
	},
};
edmag = {
	s: title_cn,
	nodes: [],
	init: function() {
		if (!title_cn) {
			return
		}
		this.url = "http://edmag.net/movie-search-" + this.s + ".html";
		getDoc(this.url, function(doc, url) {
			var trs = $("tr", doc);
			var nodes = [];
			for (i = 1; i < trs.length; i++) {
				var tr = trs[i];
				var title = tr.getElementsByClassName("magTitle")[0].getElementsByTagName("a")[0];
				var dURL = title.getAttribute("href");
				dURL = "http://edmag.net" + dURL.slice(1);
				title = title.getAttribute("title");
				var time = tr.getElementsByClassName("time")[0].textContent;
				var dow = tr.getElementsByClassName("dow")[0];
				var ed2k, mag = undefined;
				try {
					mag = dow.getElementsByClassName("magDown")[0].getAttribute("href")
				} catch (e) {}
				try {
					ed2k = dow.getElementsByClassName("ed2kDown")[0].getAttribute("ed2k")
				} catch (e) {}
				if (mag) {
					var node = {
						detailURL: dURL,
						downloadURL: mag,
						date: time,
						type: 0,
						title: title
					};
					edmag.nodes.push(node)
				}
				if (ed2k) {
					var node = {
						detailURL: dURL,
						downloadURL: ed2k,
						date: time,
						type: 1,
						title: title
					};
					edmag.nodes.push(node)
				}
			}
			edmag.over()
		})
	},
	over: function() {
		var msg = "并入\t" + this.nodes.length + "\tedmag链接";
		msg_info(msg);
		linksTable.refresh()
	}
};
mp4ba = {
	s: title_cn,
	count: 0,
	nodes: [],
	init: function() {
		if (!title_cn) {
			return
		}
		var url = "http://www.mp4ba.com/search.php?keyword=" + this.s;
		getDoc(url, function(doc) {
			var urls = $("a[href^='show.php?hash=']", doc);
			mp4ba.count = urls.length;
			for (i = 0; i < urls.length; i++) {
				var url = "http://www.mp4ba.com/" + urls[i].getAttribute("href");
				getDoc(url, function(doc, url) {
					var mag = $("#magnet", doc)[0].getAttribute("href");
					var title = $("div.location", doc)[0].textContent.split("»").pop();
					title = title.trim();
					var ps = $("p", doc);
					var date = undefined;
					for (i = 0; i < ps.length; i++) {
						if (ps[i].textContent.startsWith("发布时间")) {
							date = ps[i]
						}
					}
					date = date.textContent.slice(5).trim();
					var node = {
						detailURL: url,
						downloadURL: mag,
						date: date,
						type: 0,
						title: title
					};
					mp4ba.nodes.push(node);
					baidu_netdisk.add(doc.body.outerText);
					if (mp4ba.nodes.length >= mp4ba.count) {
						mp4ba.over()
					}
				})
			}
			if (!urls.length) {
				mp4ba.over()
			}
		})
	},
	over: function() {
		var msg = "并入\t" + this.nodes.length + "\t\tmp4ba链接";
		msg_info(msg);
		linksTable.refresh()
	}
};
tl95_com = {
	s: title_cn,
	count: 0,
	nodes: [],
	init: function() {
		if (!title_cn) {
			return
		}
		url = "http://www.tl95.com/?s=" + this.s;
		getDoc(url, function(doc, url) {
			var urls = $($("#main", doc)[0]).find("a[rel='bookmark'][href]");
			tl95_com.count = urls.length;
			for (i = 0; i < urls.length; i++) {
				var title = $(urls[i]).text();
				if (title.indexOf(tl95_com.s) === -1) {
					urls[i] = undefined;
					--tl95_com.count
				}
			}
			for (i = 0; i < urls.length; i++) {
				if (!urls[i]) {
					continue
				}
				url = urls[i].getAttribute("href");
				getDoc(url, function(doc, url) {
					var date = $("div.single-cat", doc)[0].textContent.split("  ")[0].slice(5);
					var ed2k = $("a[href^='ed2k']", doc);
					if (ed2k) {
						for (i = 0; i < ed2k.length; i++) {
							n = ed2k[i];
							n = $(n);
							var node = {
								detailURL: url,
								downloadURL: n.attr("href"),
								date: date,
								type: 1,
								title: n.text()
							};
							tl95_com.nodes.push(node)
						}
					}
					var thunder = $("a[href^='thunder']", doc);
					if (thunder) {
						for (i = 0; i < thunder.length; i++) {
							n = thunder[i];
							n = $(n);
							var node = {
								detailURL: url,
								downloadURL: n.attr("href"),
								date: date,
								type: 2,
								title: n.text()
							};
							tl95_com.nodes.push(node)
						}
					}
					baidu_netdisk.add(doc.body.outerText);
					if (tl95_com.nodes.length >= tl95_com.count) {
						tl95_com.over()
					}
				})
			}
			if (!urls.length) {
				tl95_com.over()
			}
		})
	},
	over: function() {
		var msg = "并入\t" + this.nodes.length + "\t\ttl95_cpm链接";
		msg_info(msg);
		linksTable.refresh()
	}
};
kickass = {
	s: imdb,
	nodes: [],
	init: function() {
		if (!imdb) {
			return
		}
		var url = "https://kat.cr/usearch/imdb:" + this.s;
		getDoc(url, function(doc, url) {
			var s01 = "https://kat.cr";
			var trs = $("tbody > tr.odd,tbody > tr.even", doc);
			for (i = 0; i < trs.length; i++) {
				var tr = trs[i];
				tr = $(tr);
				var cellMainLink = tr.find("a.cellMainLink");
				var node = {
					detailURL: s01 + cellMainLink.attr("href"),
					downloadURL: tr.find("a[href^='magnet']").attr("href"),
					date: $(tr.find("td[title]")[0]).attr("title"),
					type: 0,
					title: cellMainLink.text()
				};
				kickass.nodes.push(node)
			}
			kickass.over()
		})
	},
	over: function() {
		var msg = "并入\t" + this.nodes.length + "\t\tkickass链接";
		msg_info(msg);
		linksTable.refresh()
	}
};
var dmovie = {
	init: function() {
		msg_warning("进入查询逻辑");
		for (i = 0; i < dmovie.sites.length; i++) {
			this.sites[i].init()
		}
	},
	sites: [edmag, kickass, mp4ba, tl95_com, ]
};
linksTable.init();
baidu_netdisk.init();
if (!title_cn) {
	msg_error('title is null')
}
dmovie.init();