mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Content server: When clicking on author names in the book details page perform the same action as clicking it in the calibre program's book details panel
This commit is contained in:
parent
ae15a85e73
commit
0efd8c7b6d
@ -15,10 +15,11 @@ from calibre import as_unicode
|
|||||||
from calibre.constants import in_develop_mode
|
from calibre.constants import in_develop_mode
|
||||||
from calibre.customize.ui import available_input_formats
|
from calibre.customize.ui import available_input_formats
|
||||||
from calibre.db.view import sanitize_sort_field_name
|
from calibre.db.view import sanitize_sort_field_name
|
||||||
|
from calibre.ebooks.metadata.book.render import resolve_default_author_link
|
||||||
from calibre.srv.ajax import search_result
|
from calibre.srv.ajax import search_result
|
||||||
from calibre.srv.errors import BookNotFound, HTTPBadRequest, HTTPForbidden, HTTPNotFound, HTTPRedirect
|
from calibre.srv.errors import BookNotFound, HTTPBadRequest, HTTPForbidden, HTTPNotFound, HTTPRedirect, HTTPTempRedirect
|
||||||
from calibre.srv.last_read import last_read_cache
|
from calibre.srv.last_read import last_read_cache
|
||||||
from calibre.srv.metadata import book_as_json, categories_as_json, categories_settings, icon_map
|
from calibre.srv.metadata import book_as_json, categories_as_json, categories_settings, get_gpref, icon_map, web_search_link
|
||||||
from calibre.srv.routes import endpoint, json
|
from calibre.srv.routes import endpoint, json
|
||||||
from calibre.srv.utils import get_library_data, get_use_roman
|
from calibre.srv.utils import get_library_data, get_use_roman
|
||||||
from calibre.utils.config import prefs, tweaks
|
from calibre.utils.config import prefs, tweaks
|
||||||
@ -172,6 +173,7 @@ def basic_interface_data(ctx, rd):
|
|||||||
'default_book_list_mode': rd.opts.book_list_mode,
|
'default_book_list_mode': rd.opts.book_list_mode,
|
||||||
'donate_link': localize_website_link('https://calibre-ebook.com/donate'),
|
'donate_link': localize_website_link('https://calibre-ebook.com/donate'),
|
||||||
'lang_code_for_user_manual': lang_code_for_user_manual(),
|
'lang_code_for_user_manual': lang_code_for_user_manual(),
|
||||||
|
'default_author_link': resolve_default_author_link(get_gpref('default_author_link')),
|
||||||
}
|
}
|
||||||
ans['library_map'], ans['default_library_id'] = ctx.library_info(rd)
|
ans['library_map'], ans['default_library_id'] = ctx.library_info(rd)
|
||||||
if ans['username']:
|
if ans['username']:
|
||||||
@ -419,6 +421,29 @@ def book_metadata(ctx, rd, book_id):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
|
@endpoint('/web-search/{book_id}/{field}/{item_val}', postprocess=json)
|
||||||
|
def web_search(ctx, rd, book_id, field, item_val):
|
||||||
|
'''
|
||||||
|
Redirect to a web search URL for the specified item.
|
||||||
|
Optional: ?library_id=<default library>
|
||||||
|
'''
|
||||||
|
db, library_id = get_library_data(ctx, rd)[:2]
|
||||||
|
try:
|
||||||
|
book_id = int(book_id)
|
||||||
|
except Exception:
|
||||||
|
raise HTTPNotFound(f'Book with id {book_id!r} does not exist')
|
||||||
|
if db is None:
|
||||||
|
raise HTTPNotFound(f'Library {library_id!r} not found')
|
||||||
|
with db.safe_read_lock:
|
||||||
|
if not ctx.has_id(rd, db, book_id):
|
||||||
|
raise BookNotFound(book_id, db)
|
||||||
|
mi = db.get_metadata(book_id, get_cover=False)
|
||||||
|
url, tooltip = web_search_link(db, book_id, field, item_val)
|
||||||
|
if url:
|
||||||
|
raise HTTPTempRedirect(url)
|
||||||
|
raise HTTPNotFound(f'No web search URL for {field} {item_val}')
|
||||||
|
|
||||||
|
|
||||||
@endpoint('/interface-data/tag-browser')
|
@endpoint('/interface-data/tag-browser')
|
||||||
def tag_browser(ctx, rd):
|
def tag_browser(ctx, rd):
|
||||||
'''
|
'''
|
||||||
|
@ -32,6 +32,12 @@ class HTTPRedirect(HTTPSimpleResponse):
|
|||||||
HTTPSimpleResponse.__init__(self, http_code, http_message, close_connection, location)
|
HTTPSimpleResponse.__init__(self, http_code, http_message, close_connection, location)
|
||||||
|
|
||||||
|
|
||||||
|
class HTTPTempRedirect(HTTPSimpleResponse):
|
||||||
|
|
||||||
|
def __init__(self, location, http_code=http_client.TEMPORARY_REDIRECT, http_message='', close_connection=False):
|
||||||
|
HTTPSimpleResponse.__init__(self, http_code, http_message, close_connection, location)
|
||||||
|
|
||||||
|
|
||||||
class HTTPNotFound(HTTPSimpleResponse):
|
class HTTPNotFound(HTTPSimpleResponse):
|
||||||
|
|
||||||
def __init__(self, http_message='', close_connection=False):
|
def __init__(self, http_message='', close_connection=False):
|
||||||
|
@ -12,7 +12,7 @@ from book_list.item_list import create_item, create_item_list, create_side_actio
|
|||||||
from book_list.library_data import (
|
from book_list.library_data import (
|
||||||
all_libraries, book_after, book_metadata, cover_url, current_library_id,
|
all_libraries, book_after, book_metadata, cover_url, current_library_id,
|
||||||
current_virtual_library, download_url, library_data, load_status,
|
current_virtual_library, download_url, library_data, load_status,
|
||||||
set_book_metadata, download_data_file_url
|
set_book_metadata, download_data_file_url, web_search_url
|
||||||
)
|
)
|
||||||
from book_list.router import back, home, open_book, report_a_load_failure, show_note, open_book_url_in_library, search_url_in_library
|
from book_list.router import back, home, open_book, report_a_load_failure, show_note, open_book_url_in_library, search_url_in_library
|
||||||
from book_list.theme import (
|
from book_list.theme import (
|
||||||
@ -286,18 +286,33 @@ def render_metadata(mi, table, book_id, iframe_css): # {{{
|
|||||||
v += ''
|
v += ''
|
||||||
parent = table.lastChild.lastChild
|
parent = table.lastChild.lastChild
|
||||||
if is_searchable:
|
if is_searchable:
|
||||||
|
websearch_link = False
|
||||||
|
if field is 'authors':
|
||||||
|
websearch_link = bool(interface_data.default_author_link) and interface_data.default_author_link is not 'search-calibre'
|
||||||
text_rep = search_text or v
|
text_rep = search_text or v
|
||||||
parent.appendChild(E.a(
|
target = '_self'
|
||||||
v,
|
if websearch_link and jstype(v) is not 'string':
|
||||||
title=_('Click to see books with {0}: {1}').format(name, text_rep), class_='blue-link',
|
websearch_link = False
|
||||||
href=href_for_search(is_searchable, text_rep, use_quotes=use_quotes)
|
calibre_search_url = href_for_search(is_searchable, text_rep, use_quotes=use_quotes)
|
||||||
))
|
calibre_search_tooltip = _('Click to see books with {0}: {1}').format(name, text_rep)
|
||||||
|
if websearch_link:
|
||||||
|
url = web_search_url(book_id, field, v)
|
||||||
|
target = '_blank'
|
||||||
|
tooltip = _('Click to browse for {} on the web').format(text_rep)
|
||||||
|
else:
|
||||||
|
url = calibre_search_url
|
||||||
|
tooltip = calibre_search_tooltip
|
||||||
|
parent.appendChild(E.a(v, target=target, title=tooltip, class_='blue-link', href=url))
|
||||||
if link_maps[field] and link_maps[field][text_rep]:
|
if link_maps[field] and link_maps[field][text_rep]:
|
||||||
url = link_maps[field][text_rep]
|
url = link_maps[field][text_rep]
|
||||||
if url.startswith('https://') or url.startswith('http://'):
|
if url.startswith('https://') or url.startswith('http://'):
|
||||||
parent.appendChild(document.createTextNode(' '))
|
parent.appendChild(document.createTextNode(' '))
|
||||||
parent.appendChild(E.a(
|
parent.appendChild(E.a(
|
||||||
svgicon('external-link'), title=_('Click to open') + ': ' + url, href=url, target='_new', class_='blue-link'))
|
svgicon('external-link'), title=_('Click to open') + ': ' + url, href=url, target='_blank', class_='blue-link'))
|
||||||
|
if websearch_link:
|
||||||
|
parent.appendChild(document.createTextNode(' '))
|
||||||
|
parent.appendChild(E.a(
|
||||||
|
svgicon('search'), title=calibre_search_tooltip, href=calibre_search_url, class_='blue-link'))
|
||||||
else:
|
else:
|
||||||
if v.appendChild:
|
if v.appendChild:
|
||||||
parent.appendChild(v)
|
parent.appendChild(v)
|
||||||
|
@ -233,6 +233,10 @@ def download_data_file_url(book_id, relpath, content_disposition):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def web_search_url(book_id, field, item_val):
|
||||||
|
return absolute_path(f'web-search/{book_id}/{encodeURIComponent(field)}/{encodeURIComponent(item_val)}?library_id={encodeURIComponent(current_library_id())}')
|
||||||
|
|
||||||
|
|
||||||
def book_metadata(book_id):
|
def book_metadata(book_id):
|
||||||
return library_data.metadata[book_id]
|
return library_data.metadata[book_id]
|
||||||
|
|
||||||
|
@ -313,6 +313,7 @@ default_interface_data = {
|
|||||||
'library_map': None,
|
'library_map': None,
|
||||||
'search_the_net_urls': [],
|
'search_the_net_urls': [],
|
||||||
'donate_link': 'https://calibre-ebook.com/donate',
|
'donate_link': 'https://calibre-ebook.com/donate',
|
||||||
|
'default_author_link': '',
|
||||||
'icon_map': {},
|
'icon_map': {},
|
||||||
'icon_path': '',
|
'icon_path': '',
|
||||||
'custom_list_template': None,
|
'custom_list_template': None,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user