cloudswave / blog

在issue写个人博客,自动发布到csdn和github pages
2 stars 1 forks source link

油猴脚本-goodreads #28

Open cloudswave opened 1 year ago

cloudswave commented 1 year ago
// ==UserScript==
// @name         豆瓣读书goodreads
// @namespace    https://github.com/cloudswave/
// @version      0.1.0
// @description  从goodreads摘取评分显示在豆瓣读书条目页面
// @author       ethanzhu
// @match        https://book.douban.com/subject/*
// @connect      www.goodreads.com
// @grant        GM_xmlhttpRequest
// @license      MIT
// ==/UserScript==

function buildCommentItem(props) {
    return `
<li class="comment-item" data-cid="549875751">
    <div class="comment">
        <h3>
            <span class="comment-info">
                <a href=${props.url}>${props.author}</a>
                <span class="user-stars allstar${props.rating}0 rating" title="推荐"></span>
                <span>${props.date}</span>
            </span>
        </h3>
        <p class="comment-content">
            <span class="short">${props.content}</span>
        </p>
    </div>
</li>
`
}

function buildRatingInfo(props, bookId) {
    const starValue = Math.round(props.rating) * 5
    const url = `https://www.goodreads.com/book/show/${bookId}`
    return `
    <div class="rating_wrap clearbox" rel="v:rating">
        <div class="rating_logo">goodreads评分</div>
        <div class="rating_self clearfix" typeof="v:Rating">
            <strong class="ll rating_num " property="v:average"> ${props.rating} </strong>
            <span property="v:best" content="10.0"></span>
            <div class="rating_right ">
                <div class="ll bigstar${starValue}"></div>
                <div class="rating_sum">
                    <span class="">
                        <a href="${url}" class="rating_people"><span property="v:votes">${props.count}</span>人评价</a>
                    </span>
                </div>
            </div>
        </div>
    </div>
    `
}

function getISBN() {
    const metaInfo = document.querySelector('head > script[type="application/ld+json"]')
    if (metaInfo) {
        return JSON.parse(metaInfo.textContent)['isbn']
    }
}

function isEnglishBook(isbn) {
    return (typeof isbn === 'string' && isbn[3] === '0')
}

function Request(url, method, opt = {}) {
    Object.assign(opt, {
        url,
        timeout: 5000,
        method: method
    })

    return new Promise((resolve, reject) => {
        opt.onerror = opt.ontimeout = reject
        opt.onload = resolve
        GM_xmlhttpRequest(opt)
    })
}

function parseBooklogRating(doc) {
    const ratingDiv = doc.querySelector('div[class="rating-value"]')
    const rating = ((+ratingDiv.innerText.split('\n')[0])*2).toFixed(1)
    const count = +doc.querySelector('span[itemprop="reviewCount"]').innerText
    return {
        rating,
        count
    }
}

function ISBN13ToISBN10(isbn13) {
    const commonChars = isbn13.slice(3, -1)
    let sum = 0
    for (const [idx, char] of Array.from(commonChars).entries()) {
        sum += (10 - idx) * parseInt(char)
    }
    let checkDigest = (11 - (sum % 11)) % 11
    checkDigest = checkDigest !== 10 ? checkDigest.toString() : 'X'
    return commonChars + checkDigest
}

(function () {
    'use strict'
    const isbn = getISBN()
    if (!(isbn && isEnglishBook(isbn))) {
        // return
    }
    console.log(isbn);
    const navTab = document.querySelector('div[class="nav-tab"]')
    navTab.firstElementChild.insertAdjacentHTML('beforeend', `<span>/<span><a class="short-comment-tabs" href="booklog" data-tab="booklog">ブクログ</a>`)
    const commentListWrapper = document.getElementById('comment-list-wrapper')
    commentListWrapper.insertAdjacentHTML('beforeend', `<div id="comments" class="comment-list booklog noshow"><ul id="booklog-review-list"></ul></div>`)
    const booklogReviewList = document.getElementById('booklog-review-list')
    const RatingInfoList = document.getElementById('interest_sectl')
    const isbn10 = ISBN13ToISBN10(isbn)

    Request(`https://www.goodreads.com/book/auto_complete?format=json&q=${isbn}`, 'GET').then(res => {
        // console.log(res);
        const response = JSON.parse(res.response);
        if(response.length === 0) {
            console.log(`goodreads ${isbn} not found!!!`);
            RatingInfoList.insertAdjacentHTML('beforeend', '<span class="">goodreads暂无记录</span>')
            return Promise.reject(0);
        }
        const bookId = response[0].bookId;
        console.log(`goodreads found bookId ${bookId}`);
        RatingInfoList.insertAdjacentHTML('beforeend', buildRatingInfo({rating: response[0].avgRating*2, count: response[0].ratingsCount}, bookId))
        return bookId;
    }).then(bookId => {
/*         return Request(`https://www.goodreads.com/book/show/${bookId}`, 'GET').then(res => {
            console.log(res);
             const responseText = res.responseText;
             return new DOMParser().parseFromString(responseText, "text/html")
        }); */
    }).then(doc => {
        // console.log(doc);
        // RatingInfoList.insertAdjacentHTML('beforeend', buildRatingInfo(parseBooklogRating(doc)))
    })
})();

image