mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
Implement picking a random book
This commit is contained in:
parent
585acda8cb
commit
c1b41b14fc
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
from __future__ import (unicode_literals, division, absolute_import,
|
from __future__ import (unicode_literals, division, absolute_import,
|
||||||
print_function)
|
print_function)
|
||||||
import re, hashlib
|
import re, hashlib, random
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from threading import Lock
|
from threading import Lock
|
||||||
from json import load as load_json_file
|
from json import load as load_json_file
|
||||||
@ -216,17 +216,27 @@ def get_books(ctx, rd):
|
|||||||
mdata[book_id] = data
|
mdata[book_id] = data
|
||||||
return ans
|
return ans
|
||||||
|
|
||||||
@endpoint('/interface-data/book-metadata/{book_id}', postprocess=json, types={'book_id': int})
|
@endpoint('/interface-data/book-metadata/{book_id=0}', postprocess=json)
|
||||||
def book_metadata(ctx, rd, book_id):
|
def book_metadata(ctx, rd, book_id):
|
||||||
'''
|
'''
|
||||||
Get metadata for the specified book
|
Get metadata for the specified book. If no book_id is specified, return metadata for a random book.
|
||||||
|
|
||||||
Optional: ?library_id=<default library>
|
Optional: ?library_id=<default library>
|
||||||
'''
|
'''
|
||||||
library_id, db = get_basic_query_data(ctx, rd.query)[:2]
|
library_id, db = get_basic_query_data(ctx, rd.query)[:2]
|
||||||
|
book_ids = ctx.allowed_book_ids(rd, db)
|
||||||
|
def notfound():
|
||||||
|
raise HTTPNotFound(_('No book with id: %d in library') % book_id)
|
||||||
|
if not book_ids:
|
||||||
|
notfound()
|
||||||
|
if not book_id:
|
||||||
|
book_id = random.choice(tuple(book_ids))
|
||||||
|
elif book_id not in book_ids:
|
||||||
|
notfound()
|
||||||
data = book_as_json(db, book_id)
|
data = book_as_json(db, book_id)
|
||||||
if data is None:
|
if data is None:
|
||||||
raise HTTPNotFound('No book with id: %d in library' % book_id)
|
notfound()
|
||||||
|
data['id'] = book_id
|
||||||
return data
|
return data
|
||||||
|
|
||||||
@endpoint('/interface-data/tag-browser')
|
@endpoint('/interface-data/tag-browser')
|
||||||
|
@ -58,9 +58,7 @@ class BookDetailsPanel:
|
|||||||
def fetch_metadata(self, book_id):
|
def fetch_metadata(self, book_id):
|
||||||
if self.is_fetching:
|
if self.is_fetching:
|
||||||
self.is_fetching.abort()
|
self.is_fetching.abort()
|
||||||
def fetched(end_type, xhr, ev):
|
self.is_fetching = ajax('interface-data/book-metadata/' + book_id, self.metadata_fetched.bind(self),
|
||||||
self.metadata_fetched(book_id, end_type, xhr, ev)
|
|
||||||
self.is_fetching = ajax('interface-data/book-metadata/' + book_id, fetched,
|
|
||||||
query={'library_id':self.interface_data.library_id})
|
query={'library_id':self.interface_data.library_id})
|
||||||
self.is_fetching.send()
|
self.is_fetching.send()
|
||||||
self.container.appendChild(E.div(
|
self.container.appendChild(E.div(
|
||||||
@ -68,7 +66,7 @@ class BookDetailsPanel:
|
|||||||
create_spinner(), '\xa0' + _('Fetching metadata for the book, please wait') + '…',
|
create_spinner(), '\xa0' + _('Fetching metadata for the book, please wait') + '…',
|
||||||
))
|
))
|
||||||
|
|
||||||
def metadata_fetched(self, book_id, end_type, xhr, event):
|
def metadata_fetched(self, end_type, xhr, event):
|
||||||
if self.is_fetching is None or self.is_fetching is not xhr:
|
if self.is_fetching is None or self.is_fetching is not xhr:
|
||||||
return # Fetching was aborted
|
return # Fetching was aborted
|
||||||
self.is_fetching = None
|
self.is_fetching = None
|
||||||
@ -80,6 +78,7 @@ class BookDetailsPanel:
|
|||||||
error_dialog(_('Could not fetch metadata for book'), _('Server returned an invalid response'), err.stack or err.toString())
|
error_dialog(_('Could not fetch metadata for book'), _('Server returned an invalid response'), err.stack or err.toString())
|
||||||
return
|
return
|
||||||
clear(c)
|
clear(c)
|
||||||
|
book_id = data['id']
|
||||||
self.interface_data.metadata[book_id] = data
|
self.interface_data.metadata[book_id] = data
|
||||||
self.render_book(book_id)
|
self.render_book(book_id)
|
||||||
elif end_type != 'abort':
|
elif end_type != 'abort':
|
||||||
@ -98,12 +97,13 @@ class BookDetailsPanel:
|
|||||||
alt = str.format(_('{} by {}'), metadata['title'], metadata['authors'].join(' & '))
|
alt = str.format(_('{} by {}'), metadata['title'], metadata['authors'].join(' & '))
|
||||||
img = E.img(
|
img = E.img(
|
||||||
src=cover_url, alt=alt, title=alt, data_title=metadata['title'], data_authors=metadata['authors'].join(' & '),
|
src=cover_url, alt=alt, title=alt, data_title=metadata['title'], data_authors=metadata['authors'].join(' & '),
|
||||||
style='margin-left: 1em; max-width: 45vw; max-height: 95vh; display: block; width:auto; height:auto'
|
style='max-width: 45vw; max-height: 93vh; display: block; width:auto; height:auto'
|
||||||
)
|
)
|
||||||
img.onerror = self.on_img_err.bind(self)
|
img.onerror = self.on_img_err.bind(self)
|
||||||
c = self.container
|
c = self.container
|
||||||
c.appendChild(E.div(
|
c.appendChild(E.div(
|
||||||
E.div(),
|
style='display:flex; flex-wrap: wrap; align-items:flex-start; padding: 1ex 1em',
|
||||||
|
E.div(style='margin-right: 1em'),
|
||||||
img
|
img
|
||||||
))
|
))
|
||||||
|
|
||||||
|
@ -67,6 +67,9 @@ def create_book_view_top_bar_state(books_view):
|
|||||||
ibs.add_button(icon_name='ellipsis-v', tooltip=_('More actions'), action=show_panel_action('more-actions-menu'))
|
ibs.add_button(icon_name='ellipsis-v', tooltip=_('More actions'), action=show_panel_action('more-actions-menu'))
|
||||||
return ibs
|
return ibs
|
||||||
|
|
||||||
|
def random_book():
|
||||||
|
get_boss().ui.replace_panel('book-details', extra_query_data={'book-id':'0'})
|
||||||
|
|
||||||
class UI:
|
class UI:
|
||||||
|
|
||||||
ROOT_PANEL = 'books'
|
ROOT_PANEL = 'books'
|
||||||
@ -85,6 +88,7 @@ class UI:
|
|||||||
|
|
||||||
self.panel_map['more-actions-menu'] = UIState(ClosePanelBar(_('More actions')), panel_data=[
|
self.panel_map['more-actions-menu'] = UIState(ClosePanelBar(_('More actions')), panel_data=[
|
||||||
create_item(_('Book List Mode'), replace_panel_action('booklist-mode-menu'), _('Change how the list of books is displayed')),
|
create_item(_('Book List Mode'), replace_panel_action('booklist-mode-menu'), _('Change how the list of books is displayed')),
|
||||||
|
create_item(_('A Random Book'), random_book, _('Choose a random book from your library')),
|
||||||
])
|
])
|
||||||
|
|
||||||
self.panel_map['booklist-mode-menu'] = UIState(ClosePanelBar(_('Book List Mode')), panel_data=[])
|
self.panel_map['booklist-mode-menu'] = UIState(ClosePanelBar(_('Book List Mode')), panel_data=[])
|
||||||
@ -132,11 +136,11 @@ class UI:
|
|||||||
else:
|
else:
|
||||||
self.show_panel(self.ROOT_PANEL)
|
self.show_panel(self.ROOT_PANEL)
|
||||||
|
|
||||||
def replace_panel(self, panel_name, force=False):
|
def replace_panel(self, panel_name, force=False, extra_query_data=None):
|
||||||
action_needed = force or panel_name != self.current_panel
|
action_needed = force or panel_name != self.current_panel
|
||||||
if action_needed:
|
if action_needed:
|
||||||
self.current_panel = panel_name or self.ROOT_PANEL
|
self.current_panel = panel_name or self.ROOT_PANEL
|
||||||
get_boss().push_state(replace=True)
|
get_boss().push_state(replace=True, extra_query_data=extra_query_data)
|
||||||
if action_needed:
|
if action_needed:
|
||||||
self.apply_state()
|
self.apply_state()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user