// ==UserScript== // @name NeoDB for Douban // @version 1.5.0 // @description Search missing movie/tv/book/music for douban // @author kaiix // @namespace https://github.com/kaiix // @license MIT // @match *://search.douban.com/movie/* // @match *://search.douban.com/book/* // @match *://search.douban.com/music/* // @match *://*.douban.com/search* // @grant GM.xmlHttpRequest // @grant GM.addStyle // @icon https://www.google.com/s2/favicons?sz=64&domain=neodb.social // @updateURL https://raw.githubusercontent.com/kaiix/userscripts/main/douban-neodb.user.js // @downloadURL https://raw.githubusercontent.com/kaiix/userscripts/main/douban-neodb.user.js // @supportURL https://github.com/kaiix/userscripts/issues // ==/UserScript== const userStyle = ` .user-aside { margin-bottom: 25px; background: #F4F4EC; padding: 10px; word-wrap: break-word; } .user-aside .user-loading { color: #999; display: flex; justify-content: center; } .user-aside .user-loading.hidden { display: none; } .user-item-wrapper { margin-bottom: 30px; } .user-item-wrapper:last-child { margin-bottom: 0; } .user-item-wrapper .item-root { display: flex; flex-wrap: wrap; position: relative; justify-content: space-between; } .user-item-wrapper .cover-link { background: none; width: 65px; max-height: 97px; margin-right: 15px; } .user-item-wrapper .cover { width: 65px; max-height: 97px; } .user-item-wrapper .detail { flex: 1; min-width: 0; } .user-item-wrapper .detail .title { font-size: 14px; font-weight: 500; overflow: visible; position: relative; top: -1px; color: #007722; } .user-item-wrapper .detail .label { height: 12px; font-size: 12px; margin-left: 5px; } .user-item-wrapper .detail .meta { margin-top: 7px; color: #999; font-size: 12px; line-height: 1.5; overflow: visible; display: inline-block; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; word-wrap: normal; display: block; } `; function searchNeoDB({ query, categories, callback }) { GM.xmlHttpRequest({ method: "GET", url: `https://neodb.social/api/catalog/search?query=${query}`, onload: function (response) { const data = JSON.parse(response.responseText); let items = data.data; if (categories.length > 0) { items = items.filter((item) => categories.includes(item.category)); } callback(items); }, }); } function createItem(item) { if (item.category === "movie" || item.category === "tv") { return createMovieItem(item); } else if (item.category === "book") { return createBookItem(item); } else if (item.category === "music") { return createMusicItem(item); } } function createMovieItem(item) { const { url, title, category, cover_image_url, year, rating, rating_count, area, genre, other_title, duration, director, playwright, actor, } = item; const fullUrl = `https://neodb.social${url}`; const abstract = [area, genre, other_title, duration] .flat() .filter(Boolean) .join(" / "); const abstract2 = [director, playwright, actor.slice(5)] .flat() .filter(Boolean) .join(" / "); const star_grade = parseInt((parseInt(rating) * 10) / 2) + parseInt((parseInt(rating * 10) % 10) / 5) * 5; const el = document.createElement("div"); el.classList.add("user-item-wrapper"); el.innerHTML = formatItemHtml({ url: fullUrl, cover_image_url, title, year, category, star_grade, rating, rating_count, abstract, abstract2, }); return el; } function createBookItem(item) { const { url, title, category, cover_image_url, rating, rating_count, author, pub_house, pub_year, pub_month, } = item; const fullUrl = `https://neodb.social${url}`; const abstract = [author, pub_house, `${pub_year}-${pub_month}`] .flat() .filter(Boolean) .join(" / "); const abstract2 = ""; const star_grade = parseInt((parseInt(rating) * 10) / 2) + parseInt((parseInt(rating * 10) % 10) / 5) * 5; const year = pub_year; const el = document.createElement("div"); el.classList.add("user-item-wrapper"); el.innerHTML = formatItemHtml({ url: fullUrl, cover_image_url, title, year, category, star_grade, rating, rating_count, abstract, abstract2, }); return el; } function createMusicItem(item) { const { url, title, category, cover_image_url, rating, rating_count, artist, genre, release_date, } = item; const fullUrl = `https://neodb.social${url}`; const abstract = [artist, release_date, genre] .flat() .filter(Boolean) .join(" / "); const abstract2 = ""; const star_grade = parseInt((parseInt(rating) * 10) / 2) + parseInt((parseInt(rating * 10) % 10) / 5) * 5; const el = document.createElement("div"); el.classList.add("user-item-wrapper"); el.innerHTML = formatItemHtml({ url: fullUrl, cover_image_url, title, year: undefined, category, star_grade, rating, rating_count, abstract, abstract2, }); return el; } function formatItemHtml({ url, cover_image_url, title, year, category, star_grade, rating, rating_count, abstract, abstract2, }) { return `