1
0
mirror of https://github.com/janeczku/calibre-web synced 2024-11-28 12:30:00 +00:00

Update python search Metadata

This commit is contained in:
Ozzie Isaacs 2021-07-07 21:24:29 +02:00
parent d5e9cdc5b7
commit aa2d3d2b36
6 changed files with 38 additions and 377 deletions

View File

@ -127,7 +127,6 @@ def create_app():
def get_locale(): def get_locale():
# if a user is logged in, use the locale from the user settings # if a user is logged in, use the locale from the user settings
user = getattr(g, 'user', None) user = getattr(g, 'user', None)
# user = None
if user is not None and hasattr(user, "locale"): if user is not None and hasattr(user, "locale"):
if user.name != 'Guest': # if the account is the guest account bypass the config lang settings if user.name != 'Guest': # if the account is the guest account bypass the config lang settings
return user.locale return user.locale
@ -148,7 +147,6 @@ def get_timezone():
user = getattr(g, 'user', None) user = getattr(g, 'user', None)
return user.timezone if user else None return user.timezone if user else None
from . import search_metadata
from .updater import Updater from .updater import Updater
updater_thread = Updater() updater_thread = Updater()

View File

@ -16,6 +16,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# ComicVine api document: https://comicvine.gamespot.com/api/documentation
import requests import requests
from cps.services.Metadata import Metadata from cps.services.Metadata import Metadata

View File

@ -16,6 +16,8 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
# Google Books api document: https://developers.google.com/books/docs/v1/using
import requests import requests
from cps.services.Metadata import Metadata from cps.services.Metadata import Metadata

View File

@ -17,17 +17,17 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import division, print_function, unicode_literals from __future__ import division, print_function, unicode_literals
from cps.services.Metadata import Metadata
import os import os
import json import json
import importlib
import sys
import inspect
from flask import Blueprint, request, Response from flask import Blueprint, request, Response
from flask_login import login_required from flask_login import login_required
from . import constants, logger from . import constants, logger
from os.path import basename, isfile from cps.services.Metadata import Metadata
import importlib
import sys, inspect
meta = Blueprint('metadata', __name__) meta = Blueprint('metadata', __name__)
@ -37,8 +37,8 @@ new_list = list()
meta_dir = os.path.join(constants.BASE_DIR, "cps", "metadata_provider") meta_dir = os.path.join(constants.BASE_DIR, "cps", "metadata_provider")
modules = os.listdir(os.path.join(constants.BASE_DIR, "cps", "metadata_provider")) #glob.glob(join(dirname(__file__), "*.py")) modules = os.listdir(os.path.join(constants.BASE_DIR, "cps", "metadata_provider")) #glob.glob(join(dirname(__file__), "*.py"))
for f in modules: for f in modules:
if isfile(os.path.join(meta_dir, f)) and not f.endswith('__init__.py'): if os.path.isfile(os.path.join(meta_dir, f)) and not f.endswith('__init__.py'):
a = basename(f)[:-3] a = os.path.basename(f)[:-3]
try: try:
importlib.import_module("cps.metadata_provider." + a) importlib.import_module("cps.metadata_provider." + a)
new_list.append(a) new_list.append(a)
@ -55,8 +55,6 @@ def list_classes(provider_list):
return classes return classes
cl = list_classes(new_list) cl = list_classes(new_list)
#for c in cl:
# print(c.search("Walking"))
@meta.route("/metadata/provider") @meta.route("/metadata/provider")
@login_required @login_required
@ -72,8 +70,3 @@ def metadata_search():
for c in cl: for c in cl:
data.extend(c.search(query)) data.extend(c.search(query))
return Response(json.dumps(data), mimetype='application/json') return Response(json.dumps(data), mimetype='application/json')
@meta.route("/metadata/replace/<id>")
@login_required
def metadata_replace(id):
return ""

View File

@ -14,349 +14,38 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* /* global _, i18nMsg, tinymce, getPath */
* 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, getPatch */
var dbResults = [];
var ggResults = [];
var cvResults = [];
var gsResults = [];
$(function () { $(function () {
var msg = i18nMsg; var msg = i18nMsg;
var douban = "https://api.douban.com";
var dbSearch = "/v2/book/search";
var dbDone = 0;
var google = "https://www.googleapis.com"; var templates = {
var ggSearch = "/books/v1/volumes"; bookResult: _.template(
var ggDone = 0; $("#template-book-result").html()
)
};
var comicvine = "https://comicvine.gamespot.com"; function populateForm (book) {
var cvSearch = "/api/search/"; tinymce.get("description").setContent(book.description);
var cvDone = 0; var uniqueTags = [];
$.each(book.tags, function(i, el) {
var googlescholar = window.location.href.split('/admin/book')[0]; if ($.inArray(el, uniqueTags) === -1) uniqueTags.push(el);
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("<ul id=\"book-list\" class=\"media-list\"></ul>");
}
/*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("<p class=\"text-danger\">" + msg.no_result + "</p>");
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; var ampSeparatedAuthors = (book.authors || []).join(" & ");
} else { $("#bookAuthor").val(ampSeparatedAuthors);
ggDone = 3; $("#book_title").val(book.title);
} $("#tags").val(uniqueTags.join(","));
} $("#rating").data("rating").setValue(Math.round(book.rating));
if(book.cover !== null){
if (gsResults.length > 0) { $(".cover img").attr("src", book.cover);
if (gsDone < 2) { $("#cover_url").val(book.cover);
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;
} }
}, $("#pubdate").val(book.publishedDate);
complete: function complete() { $("#publisher").val(book.publisher);
ggDone = 1; if (typeof book.series !== "undefined") {
showResult(); $("#series").val(book.series);
$("#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("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#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("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#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) { function doSearch (keyword) {
if (keyword) { if (keyword) {
@ -367,7 +56,8 @@ $(function () {
data: {"query": keyword}, data: {"query": keyword},
dataType: "json", dataType: "json",
success: function success(data) { success: function success(data) {
console.log(data); // console.log(data);
$("#meta-info").html("<ul id=\"book-list\" class=\"media-list\"></ul>");
data.forEach(function(book) { data.forEach(function(book) {
var $book = $(templates.bookResult(book)); var $book = $(templates.bookResult(book));
$book.find("img").on("click", function () { $book.find("img").on("click", function () {
@ -379,27 +69,9 @@ $(function () {
error: function error() { error: function error() {
$("#meta-info").html("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#meta-info")[0].innerHTML); $("#meta-info").html("<p class=\"text-danger\">" + msg.search_error + "!</p>" + $("#meta-info")[0].innerHTML);
}, },
complete: function complete() {
showResult();
// $("#show-douban").trigger("change");
}
}); });
} }
} }
/*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) { $("#meta-search").on("submit", function (e) {
e.preventDefault(); e.preventDefault();
@ -414,5 +86,4 @@ $(function () {
doSearch(bookTitle); doSearch(bookTitle);
} }
}); });
}); });

View File

@ -242,9 +242,6 @@
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="text-center padded-bottom"> <div class="text-center padded-bottom">
<input type="checkbox" id="show-douban" class="pill" data-control="douban" checked>
<label for="show-douban">Douban <span class="glyphicon glyphicon-ok"></span></label>
<input type="checkbox" id="show-google" class="pill" data-control="google" checked> <input type="checkbox" id="show-google" class="pill" data-control="google" checked>
<label for="show-google">Google <span class="glyphicon glyphicon-ok"></span></label> <label for="show-google">Google <span class="glyphicon glyphicon-ok"></span></label>
@ -253,13 +250,12 @@
<input type="checkbox" id="show-googlescholar" class="pill" data-control="googlescholar" checked> <input type="checkbox" id="show-googlescholar" class="pill" data-control="googlescholar" checked>
<label for="show-googlescholar">Google Scholar <span class="glyphicon glyphicon-ok"></span></label> <label for="show-googlescholar">Google Scholar <span class="glyphicon glyphicon-ok"></span></label>
</div> </div>
<div id="meta-info"> <div id="meta-info">
{{_("Loading...")}} {{_("Loading...")}}
</div> </div>
<ul id="book-list" class="media-list"></ul> <!--ul id="book-list" class="media-list"></ul-->
</div> </div>
<div class="modal-footer"> <div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">{{_('Close')}}</button> <button type="button" class="btn btn-default" data-dismiss="modal">{{_('Close')}}</button>