// ==UserScript==
// @name 今日优读
// @description 主要搭建一个知识平台以及读书辅助工具,提供书籍搜索,中图分类和学科搜索。
// @author 018([email protected])
// @contributor Rhilip
// @connect *
// @grant GM_xmlhttpRequest
// @require https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @require https://greasyfork.org/scripts/32927-md5-hash/code/MD5%20Hash.js?version=225078
// @include http://uread.today/*
// @include http://127.0.0.1:9090/*
// @include http://book.ucdrs.superlib.net/views/specific/*
// @include http://product.dangdang.com/*
// @include https://item.jd.com/*
// @include https://book.douban.com/subject/*
// @include https://kns.cnki.net/*
// @include https://ct.istic.ac.cn/*
// @include https://weread.qq.com/*
// @include https://yabook.org/*
// @include https://yabook.blog/*
// @include https://www.jiumodiary.com/*
// @include http://www.ncpssd.org/*
// @version 0.3.0
// @icon http://uread.today/static/img/favicon.ico
// @run-at document-end
// @namespace http://uread.today
// ==/UserScript==
// This Userscirpt can't run under Greasemonkey 4.x platform
if (typeof GM_xmlhttpRequest === 'undefined') {
alert('不支持Greasemonkey 4.x,请换用暴力猴或Tampermonkey')
return
}
;(function () {
'use strict';
$(document).ready(function () {
if (location.href.includes('http://book.ucdrs.superlib.net/views/specific')) {
addViewOrEmbody('.tubox dl', '.tutilte');
} else if (location.href.includes('http://product.dangdang.com')) {
addViewOrEmbody('#detail_describe', '.name_info h1');
} else if (location.href.includes('https://item.jd.com')) {
addViewOrEmbody('.p-parameter-list', '.sku-name');
} else if (location.href.includes('https://book.douban.com/subject')) {
addViewOrEmbody('#info', '#wrapper > h1 > span');
} else if (location.href.includes('https://kns.cnki.net/kns8/defaultresult/index')) {
handleCNKI();
} else if (location.href.includes('https://ct.istic.ac.cn/site/organize/word')) {
handleIstic();
} else if (location.href.includes('https://weread.qq.com/')) {
handleWeread();
} else if (location.href.includes('https://yabook.')) {
handleYabook();
} else if (location.href.includes('https://www.jiumodiary.com/')) {
handleJiumodiary();
} else if (location.href.includes('http://www.ncpssd.org/index.aspx')) {
handleNcpssd();
} else if (location.href.includes('http://uread.today/')) {
handleuRead();
} else if (location.href.includes('http://127.0.0.1:9090/')) {
handleuRead();
}
})
function addViewOrEmbody(isbnselecter, titleselecter) {
let match = document.querySelector(isbnselecter).innerText.match(/ISBN.*/)
if (match) {
let isbn = match[0].replace(/\D/g, '');
doGet('http://api.uread.today/master/anon/book/get?isbn=' + isbn, {isbn: isbn}, function(ret, responseDetail, meta) {
if (ret && ret.resultcode === 1) {
$(titleselecter).append('<a target="_blank" href="http://uread.today/book?doi=' + ret.data + '" style="margin-left: 20px !important"><img title="查看" width="15px" src="data:image/jpeg;base64,/9j/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//dAAQAAv/uAA5BZG9iZQBkwAAAAAH/wAARCAAPAA8DABEAAREBAhEB/8QAbAABAQEAAAAAAAAAAAAAAAAACAkKAQEBAQAAAAAAAAAAAAAAAAAFBgQQAAEFAAIDAQEAAAAAAAAAAAUCAwQGBwEICRESEyIRAAICAgEDBAIDAAAAAAAAAAECAxEEBSESEzEABiJBFBUyUXH/2gAMAwAAARECEQA/ANNvm77NTOtHUMNO+XBgHS9goVGslyZuJCkSqyOFyZOk8xBhcRHlFeSVuTQli/hpvn3DkSPf9fHHNL7Y1eDtcuSLOyvxQkJZWpWJawvh6U0CSQSOBf1RN2+xzdTrptjrtadxnQxsyYQmXGOSwHEQyHKpEx8qzkKzAISOsEVVza8D9LoFOv4tthiFb66KPNw45oDY0DnSERp6UJcOVYmZrZSUJlqXGedgy5MVTzSvzcWn0rmemjEUrRg9QViLoiwPBo8gHyL59a8WWWbGjmnjMM7opaMlWKMQCUZkLIWU/ElGZSQelmFE/wD/0HB526b3G7jGcspNj69RMko+I2bRTIQ4F7DVXSoGgyTMULHrJktnkuvZy3WjbMYKthmTyRIuQIxaY3wlfClfdp7f/W4/UZJj81Bvtm1K8hf5chjwTxVA0ar0Pu591jYAm0GJDm7LvxL2pZzjp2WcLPL3RFN84YyZEj7dTMvbLx31hU+FU524wzND+JBuklNgZwc0MtoabKz2jrAxusqmZ1Ta48OFZwMzsoJRyesNKWRIOwpQ5qQTMS5rkdT7j7j523jw5ZTO0xElVXQT9k+bHi6FjwB/gXIVXKxnqjs0TwSPokc0SPqzX9n1/9k="></a>');
} else {
$(titleselecter).append('<a target="_blank" href="http://uread.today/embody?isbn=' + meta.isbn + '" style="margin-left: 20px !important"><img title="收录" width="15px" src="data:image/jpeg;base64,/9j/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQECAgICAgICAgICAgMDAwMDAwMDAwMBAQEBAQEBAgEBAgICAQICAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDA//dAAQAAv/uAA5BZG9iZQBkwAAAAAH/wAARCAAPAA8DABEAAREBAhEB/8QAbAABAQEAAAAAAAAAAAAAAAAACAkKAQEBAQAAAAAAAAAAAAAAAAAFBgQQAAEFAAIDAQEAAAAAAAAAAAUCAwQGBwEICRESEyIRAAICAgEDBAIDAAAAAAAAAAECAxEEBSESEzEABiJBFBUyUXH/2gAMAwAAARECEQA/ANNvm77NTOtHUMNO+XBgHS9goVGslyZuJCkSqyOFyZOk8xBhcRHlFeSVuTQli/hpvn3DkSPf9fHHNL7Y1eDtcuSLOyvxQkJZWpWJawvh6U0CSQSOBf1RN2+xzdTrptjrtadxnQxsyYQmXGOSwHEQyHKpEx8qzkKzAISOsEVVza8D9LoFOv4tthiFb66KPNw45oDY0DnSERp6UJcOVYmZrZSUJlqXGedgy5MVTzSvzcWn0rmemjEUrRg9QViLoiwPBo8gHyL59a8WWWbGjmnjMM7opaMlWKMQCUZkLIWU/ElGZSQelmFE/wD/0HB526b3G7jGcspNj69RMko+I2bRTIQ4F7DVXSoGgyTMULHrJktnkuvZy3WjbMYKthmTyRIuQIxaY3wlfClfdp7f/W4/UZJj81Bvtm1K8hf5chjwTxVA0ar0Pu591jYAm0GJDm7LvxL2pZzjp2WcLPL3RFN84YyZEj7dTMvbLx31hU+FU524wzND+JBuklNgZwc0MtoabKz2jrAxusqmZ1Ta48OFZwMzsoJRyesNKWRIOwpQ5qQTMS5rkdT7j7j523jw5ZTO0xElVXQT9k+bHi6FjwB/gXIVXKxnqjs0TwSPokc0SPqzX9n1/9k="></a>');
}
}, function(err, meta) {
console.warn(err)
});
}
}
function similar(s, t) {
if (!s || !t) {
return 0
}
var l = s.length > t.length ? s.length : t.length
var n = s.length
var m = t.length
var d = []
var min = function(a, b, c) {
return a < b ? (a < c ? a : c) : (b < c ? b : c)
}
var i, j, si, tj, cost
if (n === 0) return m
if (m === 0) return n
for (i = 0; i <= n; i++) {
d[i] = []
d[i][0] = i
}
for (j = 0; j <= m; j++) {
d[0][j] = j
}
for (i = 1; i <= n; i++) {
si = s.charAt(i - 1)
for (j = 1; j <= m; j++) {
tj = t.charAt(j - 1)
if (si === tj) {
cost = 0
} else {
cost = 1
}
d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + cost)
}
}
let res = (1 - d[n][m] / l)
return res
}
function handleuRead() {
// 试读
$('#tags').parent().after('<tr><td valign="top" width="60px" class="minor-content">试读:</td> <td class="placeholder-color" id="tryread">...</td></tr>')
var a = $('#superlibnet');
if (a) {
loadSrcDoc (a.attr('href'), {}, function (doc, responseDetail, meta) {
var element = Object.values(doc.scripts).find(element => element.textContent.includes('send_requestajax'))
if (element) {
var pattern = /".*?"/
if (pattern.test(element.textContent)) {
var url = pattern.exec(element.textContent)[0].replaceAll('"', '');
doText ('http://book.ucdrs.superlib.net/' + url, {}, function (responseText, responseDetail, meta) {
var htmlText = unescape(responseText.trim());
var html = (new DOMParser()).parseFromString(htmlText, 'text/html');
var as = '';
for(var a of html.querySelectorAll('.link a')) {
if (as.length > 0) {
as += '<span> | </span>'
}
if (a.textContent === '图书馆文献传递') {
as += '<a href="http://book.ucdrs.superlib.net' + a.href.replace('javascript:subtoRefer(true,', '').replace('\'', '').replace(')', '') + '" target="_blank">' + a.textContent + '</a>'
} else {
as += '<a href="' + a.href.replace(location.origin, 'http://book.ucdrs.superlib.net') + '" target="_blank">' + a.textContent + '</a>'
}
}
$('#tryread').html(as)
}, function (responseDetail, meta) {
$('#tryread').html('<div>无</div>')
})
}
}
}, function (responseDetail, meta) {
$('#tryread').html('<div>发生异常,请刷新重试。</div>')
})
} else {
$('#tryread').html('<div>无</div>')
}
// 电子书
let title = $('#title').text();
let srctitle = $('#title > span:nth-child(1)').text();
let isbn = $('#isbn').text();
$('#ebook').parent().after('<tr><td valign="top" width="60px" class="minor-content">其他:</td> <td class="placeholder-color" id="otherebook"><span id="ZLibrary"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(...)' +
'</span><span> | </span><span id="libgen"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(...)</span>' +
'</span><span> | </span><span id="weread"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(...)</span>' +
'</span><span> | </span><span id="readersteam">互助联盟(...)</span>' +
'</span><span> | </span><span id="LoreFree"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(...)</span>' +
'</span><span> | </span><a id="yabook" target="_blank" href="https://yabook.blog/?q=' + title + '" class="link-item"><img width="12px" src="https://yabook.org/favicon.ico"> 雅书搜索</a>' +
'</td></tr>')
// Z-Library
loadDoc('https://1lib.us/s/' + isbn, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
let found = false;
for (let a of doc.querySelectorAll('table.resItemTable h3[itemprop=name] a')) {
//if (a.textContent.includes(meta.title) || meta.title.includes(a.textContent)) {
if (similar(a.textContent, meta.title) > 0.5) {
let url = a.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
found = true;
loadDoc(url, {}, function(doc, responseDetail, meta) {
let addDownloadedBook = doc.querySelector('.addDownloadedBook');
if (addDownloadedBook) {
let txt = addDownloadedBook.textContent.match(/\(.*\)/g);
url = addDownloadedBook.href.replace(location.host, 'b-ok.global').replace('http:', 'https:');
if ($('#ZLibrary').text().includes('(...)')) {
$('#ZLibrary').html('<a target="_blank" href="' + url + '"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library' + txt + '</a>');
} else {
$('#ZLibrary').append('<a target="_blank" href="' + url + '"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library' + txt + '</a>');
}
} else {
$('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
}
}, function(err, meta) {
$('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
});
}
}
if (!found) {
$('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
}
}, function(err, meta) {
$('#ZLibrary').html('<span style="color:#989B9B"><img width="12px" src="https://1lib.us/favicon.ico"> Z-Library(暂无资源)</span>');
});
// Library Genesis
loadDoc('https://libgen.rs/search.php?req=' + isbn + '&lg_topic=libgen&open=0&view=simple&res=25&phrase=1&column=identifier', {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
let tr = doc.querySelector('body > table.c > tbody > tr:nth-child(2)');
if (tr) {
let size = tr.querySelector('td:nth-child(8)').textContent;
let extension = tr.querySelector('td:nth-child(9)').textContent;
let download = tr.querySelector('td:nth-child(10) a');
$('#libgen').html('<a target="_blank" href="' + download.href + '"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(' + extension + ', ' + size + ')</a>');
} else {
$('#libgen').html('<span style="color:#989B9B"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(暂无资源)</span>');
}
}, function(err, meta) {
$('#libgen').html('<span style="color:#989B9B"><img width="12px" src="https://libgen.rs/favicon.ico"> Library Genesis(暂无资源)</span>');
});
// 微信读书
doGet('https://weread.qq.com/web/search/global?keyword=' + title + '&maxIdx=0&fragmentSize=120&count=40', {title: title, isbn: isbn}, function(json, responseDetail, meta) {
if (json.books && json.books.length > 0) {
let bookId
let paring = function (val) {
return val.replace(/(/g, '')
.replace(/)/g, '')
.replace(/【|﹝|〔/g, '')
.replace(/】|﹞|〕/g, '')
.replace(/ *编|著|译|等|校/g, '')
.replace(/翻译/g, '')
.replace(/\(审校\)/g, '')
.replace(/译校/g, '')
.replace(/编译/g, '')
.replace(/正校/g, '')
.replace(/•|・|▪/g, '')
.replace(/\] +/g, '')
.replace(/ *· */g, '')
.replace(/ /g, '')
.replace(/./g, '')
.replace(/\. */g, '.')
}
let createId = function (bookId) {
let str = MD5(bookId, false)
let strSub = str.substr(0, 3)
let func = function (id) {
if (/^\d*$/.test(id)) {
for (var len = id['length'], c = [], a = 0; a < len; a += 9) {
var b = id['slice'](a, Math.min(a + 9, len))
c['push'](parseInt(b)['toString'](16))
}
return ['3', c]
}
for (var d = '', i = 0; i < id['length']; i++) {
d += id['charCodeAt'](i)['toString'](16)
}
return ['4', [d]]
}
let fa = func(bookId)
strSub += fa[0],
strSub += 2 + str['substr'](str['length'] - 2, 2)
for (var m = fa[1], j = 0; j < m.length; j++) {
var n = m[j].length.toString(16)
1 === n['length'] && (n = '0' + n), strSub += n, strSub += m[j], j < m['length'] - 1 && (strSub += 'g')
}
return strSub.length < 20 && (strSub += str.substr(0, 20 - strSub.length)), strSub += MD5(strSub, false).substr(0, 3)
}
for (let index = 0; index < json.books.length; index++) {
const book = json.books[index]
var creators = document.querySelectorAll('#author a')
if (creators) {
for (const creator of creators) {
let author = paring(book.bookInfo.author)
let lastName = paring(creator.textContent || '')
if (lastName && (lastName.startsWith(author) || lastName.endsWith(author) || author.startsWith(lastName) || author.endsWith(lastName))) {
bookId = book.bookInfo.bookId
break
}
}
}
if (bookId) {
break
}
}
if (bookId) {
let urlid = createId(bookId)
let url = `https://weread.qq.com/web/reader/${urlid}`
$('#weread').html('<a target="_blank" href="' + url + '"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书</a>');
} else {
$('#weread').html('<span style="color:#989B9B"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(暂无资源)</span>');
}
} else {
$('#weread').html('<span style="color:#989B9B"><img width="12px" src="https://weread.qq.com/favicon.ico"> 微信读书(暂无资源)</span>');
}
}, function(err, meta) {
$('#weread').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
});
// 互助联盟
loadDoc('https://www.readersteam.com/vip/?aff=readersteam&q=' + isbn, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
let a = doc.querySelector('dl.result-list > dt:nth-child(1) a');
if (a) {
$('#readersteam').html('<a target="_blank" href="' + a.href.replace(location.origin, 'https://www.readersteam.com/vip') + '">互助联盟(发起互助)</a>');
} else {
$('#readersteam').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
}
}, function(err, meta) {
$('#readersteam').html('<span style="color:#989B9B">互助联盟(暂无资源)</span>');
});
// LoreFree
let lorefreeurl = 'https://ebook2.lorefree.com/site/index?s=' + srctitle
loadDoc(lorefreeurl, {title: title, isbn: isbn}, function(doc, responseDetail, meta) {
let divs = doc.querySelectorAll('div.body-content > div:nth-child(2) div');
if (divs && divs.length > 0) {
$('#LoreFree').html('<a target="_blank" href="' + lorefreeurl + '"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(' + divs.length + '+)</a>');
} else {
$('#LoreFree').html('<span style="color:#989B9B"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(暂无资源)</span>');
}
}, function(err, meta) {
$('#LoreFree').html('<span style="color:#989B9B"><img width="12px" src="https://ebook2.lorefree.com/favicon.ico"> LoreFree(暂无资源)</span>');
});
}
function handleCNKI() {
let q = getQuery(location.search)
if (q) {
$('#txt_search').val(decodeURIComponent(q))
$('.search-btn').click()
}
}
function handleIstic() {
let q = getQuery(location.search)
if (q) {
$('#termname').val(decodeURIComponent(q))
$('#btn-search').click()
}
}
function handleWeread() {
let q = getQuery(location.search)
if (q) {
setTimeout(() => {
$('.search_input_text').val(decodeURIComponent(q))
$('.search_input_right').click()
}, 2000)
}
}
function handleYabook() {
let q = getQuery(location.search)
if (q) {
$('#bdcsMain').val(decodeURIComponent(q))
$('.btn').click()
}
}
function handleJiumodiary() {
let q = getQuery(location.search)
if (q) {
$('#SearchWord').val(decodeURIComponent(q))
$('#SearchButton').click()
}
}
function handleNcpssd() {
let q = getQuery(location.search)
if (q) {
$('#text_search').val(decodeURIComponent(q))
$('#but_search').click()
}
}
function getQuery(url) {
if (!url) return false;
var q = url.match(/[?&]q=([^&#]*)/i);
if (!q || !q[1]) return false;
return q[1];
}
// 判断,空返回空字符串
function opt(val) {
if (!val) return '';
if (val instanceof Array) {
if (val.length > 0) {
return val[0];
}
} else {
return val;
}
}
// 对使用GM_xmlhttpRequest返回的html文本进行处理并返回DOM树
function page_parser(responseText, src) {
// 替换一些信息防止图片和页面脚本的加载,同时可能加快页面解析速度
if (!src) {
responseText = responseText.replace(/s+src=/ig, ' data-src='); // 图片,部分外源脚本
responseText = responseText.replace(/<script[^>]*?>[\S\s]*?<\/script>/ig, ''); //页面脚本
}
return (new DOMParser()).parseFromString(responseText, 'text/html');
}
// 加载网页
function loadDoc (url, meta, callback, fail) {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function (responseDetail) {
if (responseDetail.status === 200) {
let doc = page_parser(responseDetail.responseText, false)
callback(doc, responseDetail, meta)
} else if (fail){
fail(responseDetail, meta);
}
},
onerror: function(err) {
if (fail) {
fail(err, meta);
}
}
})
}
// 加载网页
function loadSrcDoc (url, meta, callback, fail) {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function (responseDetail) {
if (responseDetail.status === 200) {
let doc = page_parser(responseDetail.responseText, true)
callback(doc, responseDetail, meta)
} else if (fail){
fail(responseDetail, meta);
}
},
onerror: function(err) {
if (fail) {
fail(err, meta);
}
}
})
}
// get请求
function doText (url, meta, callback, fail) {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function (responseDetail) {
if (responseDetail.status === 200) {
callback(responseDetail.responseText, responseDetail, meta)
} else if (fail){
fail(responseDetail, meta);
}
},
onerror: function(err) {
if (fail) {
fail(err, meta);
}
}
})
}
// get请求
function doGet (url, meta, callback, fail) {
GM_xmlhttpRequest({
method: 'GET',
url: url,
onload: function (responseDetail) {
if (responseDetail.status === 200) {
callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
} else if (fail){
fail(responseDetail, meta);
}
},
onerror: function(err) {
if (fail) {
fail(err, meta);
}
}
})
}
// post请求
function doPost (url, headers, data, meta, callback, fail) {
GM_xmlhttpRequest({
method: "POST",
url: url,
data: data,
headers: headers,
onload: function(responseDetail){
if (responseDetail.status === 200) {
callback(JSON.parse(responseDetail.responseText), responseDetail, meta)
} else if (fail){
fail(responseDetail, meta);
}
},
onerror: function(err) {
if (fail) {
fail(err, meta);
}
}
})
}
})()