// ==UserScript== // @id heawercher@gmail.com // @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 // @downloadURL none // ==/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) { $("").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 = $("
").attr({ id: "dtable" }); h2 = $("

"); h2 = h2.html("下载地址"); div.append(h2); $($("div.related-info")[0]).after(div); var tr, th = undefined; this.table = $("").attr({ id: "dlinks", class: "table table-condensed table-hover table-striped" }); thead = $(""); tr = $(""); th = $("'); th = $("
").attr({ "data-column-id": "copy", style: "width:33px" }); th = th.html(" "); tr.append(th); th = $("").attr({ "data-column-id": "detail", style: "width:33px" }); th = th.html(" "); tr.append(th); th = $("").attr({ "data-column-id": "date", style: "width:80px" }); th = th.html("时间"); tr.append(th); th = $("").attr({ "data-column-id": "type", style: "width:55px" }); th = th.html("类型"); tr.append(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 = $('
"); th = th.html('详情'); tr.append(th); th = $(""); th = th.html('复制'); 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.html(""); tr.append(th); th = $(""); th = th.html(types[data.type]); tr.append(th); if (data.title.length > 45) { th = $(''); 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 = 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 = $("
").attr({ id: this.id }); h2 = $("

"); h2 = h2.html("网盘信息"); div.append(h2); $($("div.related-info")[0]).after(div); var tr, th = undefined; this.table = $("").attr({ id: "nlinks", class: "table table-condensed table-hover table-striped" }); thead = $(""); tr = $(""); th = $("'); th = $("
").attr({ "data-column-id": "copy", style: "width:33px" }); th = th.html(" "); tr.append(th); th = $("").attr({ "data-column-id": "detail", style: "width:33px" }); th = th.html(" "); tr.append(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 = $('
"); th = th.html('查看'); tr.append(th); th = $(""); th = th.html('保存'); th.click(function() { msg_info("功能开发中...") }); tr.append(th); if (detail.length > 65) { th = $(''); 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 = 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();