/* This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) * Copyright (C) 2018 idalin * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ /* * Get Metadata from Douban Books api and Google Books api and ComicVine * Google Books api document: https://developers.google.com/books/docs/v1/using * Douban Books api document: https://developers.douban.com/wiki/?title=book_v2 (Chinese Only) * ComicVine api document: https://comicvine.gamespot.com/api/documentation */ /* global _, i18nMsg, tinymce */ var dbResults = []; var ggResults = []; var cvResults = []; var gsResults = []; $(function () { var msg = i18nMsg; var douban = "https://api.douban.com"; var dbSearch = "/v2/book/search"; var dbDone = 0; var google = "https://www.googleapis.com"; var ggSearch = "/books/v1/volumes"; var ggDone = 0; var comicvine = "https://comicvine.gamespot.com"; var cvSearch = "/api/search/"; var cvDone = 0; var googlescholar = window.location.href.split('/admin/book')[0]; var gsSearch = "/scholarsearch/" var gsDone = 0; var showFlag = 0; var templates = { bookResult: _.template( $("#template-book-result").html() ) }; function populateForm (book) { tinymce.get("description").setContent(book.description); var uniqueTags = []; $.each(book.tags, function(i, el) { if ($.inArray(el, uniqueTags) === -1) uniqueTags.push(el); }); var ampSeparatedAuthors = (book.authors || []).join(" & "); $("#bookAuthor").val(ampSeparatedAuthors); $("#book_title").val(book.title); $("#tags").val(uniqueTags.join(",")); $("#rating").data("rating").setValue(Math.round(book.rating)); if(book.cover !== null){ $(".cover img").attr("src", book.cover); $("#cover_url").val(book.cover); } $("#pubdate").val(book.publishedDate); $("#publisher").val(book.publisher); if (typeof book.series !== "undefined") { $("#series").val(book.series); } } function showResult () { showFlag++; if (showFlag === 1) { $("#meta-info").html(""); } if ((ggDone === 3 || (ggDone === 1 && ggResults.length === 0)) && (dbDone === 3 || (dbDone === 1 && dbResults.length === 0)) && (cvDone === 3 || (cvDone === 1 && cvResults.length === 0)) && (gsDone === 3 || (gsDone === 1 && gsResults.length === 0))) { $("#meta-info").html("

" + msg.no_result + "

"); return; } function formatDate (date) { var d = new Date(date), month = "" + (d.getMonth() + 1), day = "" + d.getDate(), year = d.getFullYear(); if (month.length < 2) { month = "0" + month; } if (day.length < 2) { day = "0" + day; } return [year, month, day].join("-"); } function generateID (title) { return title.split("").reduce(function(a,b){a=((a<<5)-a)+b.charCodeAt(0);return a&a},0).toString().substr(0,12); } if (ggResults.length > 0) { if (ggDone < 2) { ggResults.forEach(function(result) { var book = { id: result.id, title: result.volumeInfo.title, authors: result.volumeInfo.authors || [], description: result.volumeInfo.description || "", publisher: result.volumeInfo.publisher || "", publishedDate: result.volumeInfo.publishedDate || "", tags: result.volumeInfo.categories || [], rating: result.volumeInfo.averageRating || 0, cover: result.volumeInfo.imageLinks ? result.volumeInfo.imageLinks.thumbnail : location + "/../../../static/generic_cover.jpg", url: "https://books.google.com/books?id=" + result.id, source: { id: "google", description: "Google Books", url: "https://books.google.com/" } }; var $book = $(templates.bookResult(book)); $book.find("img").on("click", function () { populateForm(book); }); $("#book-list").append($book); }); ggDone = 2; } else { ggDone = 3; } } if (gsResults.length > 0) { if (gsDone < 2) { gsResults.forEach(function(result) { var book = { id: generateID(result.bib.title), title: result.bib.title, authors: result.bib.author || [], description: result.bib.abstract || "", publisher: result.bib.venue || "", publishedDate: result.bib.pub_year ? result.bib.pub_year+"-01-01" : "", tags: [], rating: 0, series: "", cover: null, url: result.pub_url || result.eprint_url || "", source: { id: "googlescholar", description: "Google Scholar", link: "https://scholar.google.com/" } } var $book = $(templates.bookResult(book)); $book.find("img").on("click", function () { populateForm(book); }); $("#book-list").append($book); }); gsDone = 2; } else { gsDone = 3; } } if (dbResults.length > 0) { if (dbDone < 2) { dbResults.forEach(function(result) { var seriesTitle = ""; if (result.series) { seriesTitle = result.series.title; } var dateFomers = result.pubdate.split("-"); var publishedYear = parseInt(dateFomers[0], 10); var publishedMonth = parseInt(dateFomers[1], 10); var publishedDate = new Date(publishedYear, publishedMonth - 1, 1); publishedDate = formatDate(publishedDate); var book = { id: result.id, title: result.title, authors: result.author || [], description: result.summary, publisher: result.publisher || "", publishedDate: publishedDate || "", tags: result.tags.map(function(tag) { return tag.title.toLowerCase().replace(/,/g, "_"); }), rating: result.rating.average || 0, series: seriesTitle || "", cover: result.image, url: "https://book.douban.com/subject/" + result.id, source: { id: "douban", description: "Douban Books", url: "https://book.douban.com/" } }; if (book.rating > 0) { book.rating /= 2; } var $book = $(templates.bookResult(book)); $book.find("img").on("click", function () { populateForm(book); }); $("#book-list").append($book); }); dbDone = 2; } else { dbDone = 3; } } if (cvResults.length > 0) { if (cvDone < 2) { cvResults.forEach(function(result) { var seriesTitle = ""; if (result.volume.name) { seriesTitle = result.volume.name; } var dateFomers = ""; if (result.store_date) { dateFomers = result.store_date.split("-"); } else { dateFomers = result.date_added.split("-"); } var publishedYear = parseInt(dateFomers[0], 10); var publishedMonth = parseInt(dateFomers[1], 10); var publishedDate = new Date(publishedYear, publishedMonth - 1, 1); publishedDate = formatDate(publishedDate); var book = { id: result.id, title: seriesTitle + " #" + ("00" + result.issue_number).slice(-3) + " - " + result.name, authors: result.author || [], description: result.description, publisher: "", publishedDate: publishedDate || "", tags: ["Comics", seriesTitle], rating: 0, series: seriesTitle || "", cover: result.image.original_url, url: result.site_detail_url, source: { id: "comicvine", description: "ComicVine Books", url: "https://comicvine.gamespot.com/" } }; var $book = $(templates.bookResult(book)); $book.find("img").on("click", function () { populateForm(book); }); $("#book-list").append($book); }); cvDone = 2; } else { cvDone = 3; } } } function ggSearchBook (title) { $.ajax({ url: google + ggSearch + "?q=" + title.replace(/\s+/gm, "+"), type: "GET", dataType: "jsonp", jsonp: "callback", success: function success(data) { if ("items" in data) { ggResults = data.items; } }, complete: function complete() { ggDone = 1; showResult(); $("#show-google").trigger("change"); } }); } function dbSearchBook (title) { var apikey = "054022eaeae0b00e0fc068c0c0a2102a"; $.ajax({ url: douban + dbSearch + "?apikey=" + apikey + "&q=" + title + "&fields=all&count=10", type: "GET", dataType: "jsonp", jsonp: "callback", success: function success(data) { dbResults = data.books; }, error: function error() { $("#meta-info").html("

" + msg.search_error + "!

" + $("#meta-info")[0].innerHTML); }, complete: function complete() { dbDone = 1; showResult(); $("#show-douban").trigger("change"); } }); } function cvSearchBook (title) { var apikey = "57558043c53943d5d1e96a9ad425b0eb85532ee6"; title = encodeURIComponent(title); $.ajax({ url: comicvine + cvSearch + "?api_key=" + apikey + "&resources=issue&query=" + title + "&sort=name:desc&format=jsonp", type: "GET", dataType: "jsonp", jsonp: "json_callback", success: function success(data) { cvResults = data.results; }, error: function error() { $("#meta-info").html("

" + msg.search_error + "!

" + $("#meta-info")[0].innerHTML); }, complete: function complete() { cvDone = 1; showResult(); $("#show-comics").trigger("change"); } }); } function gsSearchBook (title) { $.ajax({ url: googlescholar + gsSearch + title.replace(/\s+/gm,'+'), type: "GET", dataType: "json", success: function success(data) { gsResults = data; }, complete: function complete() { gsDone = 1; showResult(); $("#show-googlescholar").trigger("change"); } }) } function doSearch (keyword) { showFlag = 0; dbDone = ggDone = cvDone = 0; dbResults = []; ggResults = []; cvResults = []; gsResults = []; $("#meta-info").text(msg.loading); if (keyword) { dbSearchBook(keyword); ggSearchBook(keyword); cvSearchBook(keyword); gsSearchBook(keyword); } } $("#meta-search").on("submit", function (e) { e.preventDefault(); var keyword = $("#keyword").val(); if (keyword) { doSearch(keyword); } }); $("#get_meta").click(function () { var bookTitle = $("#book_title").val(); if (bookTitle) { $("#keyword").val(bookTitle); doSearch(bookTitle); } }); });