// ==UserScript== // @name eBooks Assistant // @name:zh-CN 豆瓣读书助手 // @namespace https://github.com/caspartse/eBooksAssistant // @version 0.15.1 // @description eBooks Assistant for douban.com // @description:zh-CN 为豆瓣读书页面添加亚马逊Kindle、微信读书、多看阅读、喜马拉雅等直达链接 // @author Caspar Tse // @license MIT License // @supportURL https://github.com/caspartse/eBooksAssistant // @match https://book.douban.com/subject/* // @require https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.min.js // @connect amazon.cn // @connect duokan.com // @connect 8.210.230.166 // @connect 127.0.0.1 // @grant GM_xmlhttpRequest // @downloadURL none // ==/UserScript== (function() { var version = "0.15.1"; // 如果自己部署服务,这里修改成你的服务器地址 var domain = "http://8.210.230.166:8081"; // for debug // var domain = "http://127.0.0.1:8082"; function adjustMargin() { if ($('[data-ebassistant="read"]').height() > 36) { $('[data-ebassistant="read"]').attr("style", "margin-right:0;"); } } // 客户端本地抓取,如有结果,结果共享给服务器 function queryAmazon_Local(isbn, title, token="") { GM_xmlhttpRequest({ method: "GET", url: `https://www.amazon.cn/s?__mk_zh_CN=亚马逊网站&i=digital-text&k=${isbn}&ref=nb_sb_noss&url=search-alias%3Ddigital-text`, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var doc = responseDetail.responseText; var errorFlag = /("totalResultCount"\:0)/gi.exec(doc); if (!errorFlag) { var regexbookUrl = /href="(\S+keywords=\d+[^"]+)"[^>]*>Kindle电子书<\/a>/gi; var bookUrl = "https://www.amazon.cn" + regexbookUrl.exec(doc)[1]; bookUrl = bookUrl.replace(isbn, title); var partnerTemplate = ""; if ($('.online-type[data-ebassistant="read"]').length) { partnerTemplate = `
Kindle
`; $('.online-type[data-ebassistant="read"]').append(partnerTemplate); } else if ($('.online-type[data-ebassistant="audio"]').length) { partnerTemplate = `
在线试读:
Kindle
`; $('.online-type[data-ebassistant="audio"]').before(partnerTemplate); } else { partnerTemplate = `
在线试读:
`; $("#link-report").after(partnerTemplate); } var regexbookPrice = /[¥¥]([0-9\.]+)<\/span>/gi; var bookPrice = regexbookPrice.exec(doc)[1]; var amazonKu = false; var buyItemTemplate = "" if (bookPrice == 0.00 ) { regexbookPrice = /(免费借阅)|(免费阅读此书)|(涵盖在您的会员资格中)|(或者[¥¥][0-9\.]+购买)/gi; bookPrice = regexbookPrice.exec(doc)[1]; amazonKu = true; buyItemTemplate = `
  • KU可免费借阅
  • `; } else { buyItemTemplate = `
  • `; } $("#buyinfo ul:nth-child(2)").prepend(buyItemTemplate); var amazonShortUrl = /(https:\/\/www\.amazon\.cn\/dp\/[0-9a-zA-Z]+\/)/gi.exec(bookUrl)[1]; title = encodeURIComponent(title); GM_xmlhttpRequest({ method: "POST", url: `${domain}/amazon/update?isbn=${isbn}`, data: `isbn=${isbn}&title=${title}&price=${bookPrice}&url=${amazonShortUrl}&ku=${amazonKu}&token=${token}&version=${version}`, headers: { "Content-Type": "application/x-www-form-urlencoded" } }); } return; } }); adjustMargin(); return; } // 为提升查询速度,服务器预先缓存了一批数据。 // 但目前遇到一个问题是,难以保证数据最新的,因为请求量较大,屡屡触发亚马逊的反爬虫机制。 // 因此,需要借助各位的力量,去中心化地对数据进行校验和更新。下面这个函数,只会更新当前页面书籍的信息(价格、是否KU) function feedBackAmazon(isbn, url, token="") { GM_xmlhttpRequest({ method: "GET", url: url, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var doc = responseDetail.responseText; var regexbookPrice = /]+>\s*[¥|¥]([0-9\.]+)\s*<\/span>/gi; var bookPrice = regexbookPrice.exec(doc)[1]; var regexAmazonKu = /(免费借阅)|(免费阅读此书)|(涵盖在您的会员资格中)|(或者[¥¥][0-9\.]+购买)/gi; var amazonKu = regexAmazonKu.test(doc); GM_xmlhttpRequest({ method: "POST", url: `${domain}/amazon/feekback?isbn=${isbn}`, data: `isbn=${isbn}&price=${bookPrice}&ku=${amazonKu}&token=${token}&version=${version}`, headers: { "Content-Type": "application/x-www-form-urlencoded" } }); } }); return; } // 使用服务器上的资源 function queryAmazon_Remote(isbn, title, subtitle, author, translator, publisher) { GM_xmlhttpRequest({ method: "GET", url: `${domain}/amazon?isbn=${isbn}&title=${title}&subtitle=${subtitle}&author=${author}&translator=${translator}&publisher=${publisher}&version=${version}`, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var result = JSON.parse(responseDetail.responseText); console.log(result); var token = result.token; if (result.errmsg == "") { var bookUrl = result.data.url; var bookPrice = result.data.price; var ku = result.data.ku; var partnerTemplate = ""; if ($('.online-type[data-ebassistant="read"]').length) { partnerTemplate = ``; $('.online-type[data-ebassistant="read"]').append(partnerTemplate); } else if ($('.online-type[data-ebassistant="audio"]').length) { partnerTemplate = `
    在线试读:
    `; $('.online-type[data-ebassistant="audio"]').before(partnerTemplate); } else { partnerTemplate = `
    在线试读:
    `; $("#link-report").after(partnerTemplate); } var buyItemTemplate = `
  • `; if (ku === true) { buyItemTemplate = `
  • KU可免费借阅
  • `; } $("#buyinfo ul:nth-child(2)").prepend(buyItemTemplate); var ext = result.ext; if (ext == "r") { feedBackAmazon(isbn, bookUrl, token); } } else { console.log("call queryAmazon_Local."); queryAmazon_Local(isbn, title, token); } return; } }); adjustMargin(); return; } // 使用服务器上的资源 function queryWeread_Remote(isbn, title, subtitle, author, translator, publisher) { GM_xmlhttpRequest({ method: "GET", url: `${domain}/weread?isbn=${isbn}&title=${title}&subtitle=${subtitle}&author=${author}&translator=${translator}&publisher=${publisher}&version=${version}`, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var result = JSON.parse(responseDetail.responseText); console.log(result); if (result.errmsg == "") { var bookUrl = result.data.url; var bookPrice = result.data.price; var partnerTemplate = ""; if ($('.online-type[data-ebassistant="read"]').length) { partnerTemplate = ``; $('.online-type[data-ebassistant="read"]').append(partnerTemplate); } else if ($('.online-type[data-ebassistant="audio"]').length) { partnerTemplate = `
    在线试读:
    `; $('.online-type[data-ebassistant="audio"]').before(partnerTemplate); } else { partnerTemplate = `
    在线试读:
    `; $("#link-report").after(partnerTemplate); } var buyItemTemplate = `
  • `; $("#buyinfo ul:nth-child(2)").prepend(buyItemTemplate); } return; } }); adjustMargin(); return; } // 使用服务器上的资源 function queryDuokan_Remote(isbn, title, subtitle, author, translator, publisher) { GM_xmlhttpRequest({ method: "GET", url: `${domain}/duokan?isbn=${isbn}&title=${title}&subtitle=${subtitle}&author=${author}&translator=${translator}&publisher=${publisher}&version=${version}`, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var result = JSON.parse(responseDetail.responseText); console.log(result); if (result.errmsg == "") { var bookUrl = result.data.url; var bookPrice = result.data.price; var partnerTemplate = ""; if ($('.online-type[data-ebassistant="read"]').length) { partnerTemplate = ``; $('.online-type[data-ebassistant="read"]').append(partnerTemplate); } else if ($('.online-type[data-ebassistant="audio"]').length) { partnerTemplate = `
    在线试读:
    `; $('.online-type[data-ebassistant="audio"]').before(partnerTemplate); } else { partnerTemplate = `
    在线试读:
    `; $("#link-report").after(partnerTemplate); } var buyItemTemplate = `
  • `; $("#buyinfo ul:nth-child(2)").prepend(buyItemTemplate); } return; } }); adjustMargin(); return; } // 使用服务器上的资源 function queryXimalaya_Remote(isbn, title, subtitle, author, translator, publisher) { GM_xmlhttpRequest({ method: "GET", url: `${domain}/ximalaya?isbn=${isbn}&title=${title}&subtitle=${subtitle}&author=${author}&translator=${translator}&publisher=${publisher}&version=${version}`, headers: { "User-agent": window.navigator.userAgent, }, onload: function(responseDetail) { var result = JSON.parse(responseDetail.responseText); console.log(result); if (result.errmsg == "") { var alubmUrl = result.data.url; var partnerTemplate = ""; if ($(".online-partner .online-type").length == 2) { partnerTemplate = ``; $('.online-type[data-ebassistant="audio"]').append(partnerTemplate); } else if ($(".online-partner .online-type").length == 1) { partnerTemplate = `
    在线试听:
    `; $('.online-type[data-ebassistant="read"]').after(partnerTemplate); } else { partnerTemplate = `
    在线试听:
    `; $("#link-report").after(partnerTemplate); } } return; } }); adjustMargin(); return; } try { $(".online-partner .online-type:nth-child(1)").attr("data-ebassistant", "read"); $(".online-partner .online-type:nth-child(2)").attr("data-ebassistant", "audio"); } catch(e) { console.log(e); } var newStyle = ``; $("#content").append(newStyle); var regexLinkedData = /