mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-07 18:24:30 -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,
|
||||
print_function)
|
||||
import re, hashlib
|
||||
import re, hashlib, random
|
||||
from functools import partial
|
||||
from threading import Lock
|
||||
from json import load as load_json_file
|
||||
@ -216,17 +216,27 @@ def get_books(ctx, rd):
|
||||
mdata[book_id] = data
|
||||
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):
|
||||
'''
|
||||
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>
|
||||
'''
|
||||
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)
|
||||
if data is None:
|
||||
raise HTTPNotFound('No book with id: %d in library' % book_id)
|
||||
notfound()
|
||||
data['id'] = book_id
|
||||
return data
|
||||
|
||||
@endpoint('/interface-data/tag-browser')
|
||||
|
@ -58,17 +58,15 @@ class BookDetailsPanel:
|
||||
def fetch_metadata(self, book_id):
|
||||
if self.is_fetching:
|
||||
self.is_fetching.abort()
|
||||
def fetched(end_type, xhr, ev):
|
||||
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})
|
||||
self.is_fetching = ajax('interface-data/book-metadata/' + book_id, self.metadata_fetched.bind(self),
|
||||
query={'library_id':self.interface_data.library_id})
|
||||
self.is_fetching.send()
|
||||
self.container.appendChild(E.div(
|
||||
style='margin: 1ex 1em',
|
||||
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:
|
||||
return # Fetching was aborted
|
||||
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())
|
||||
return
|
||||
clear(c)
|
||||
book_id = data['id']
|
||||
self.interface_data.metadata[book_id] = data
|
||||
self.render_book(book_id)
|
||||
elif end_type != 'abort':
|
||||
@ -98,12 +97,13 @@ class BookDetailsPanel:
|
||||
alt = str.format(_('{} by {}'), metadata['title'], metadata['authors'].join(' & '))
|
||||
img = E.img(
|
||||
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)
|
||||
c = self.container
|
||||
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
|
||||
))
|
||||
|
||||
|
@ -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'))
|
||||
return ibs
|
||||
|
||||
def random_book():
|
||||
get_boss().ui.replace_panel('book-details', extra_query_data={'book-id':'0'})
|
||||
|
||||
class UI:
|
||||
|
||||
ROOT_PANEL = 'books'
|
||||
@ -85,6 +88,7 @@ class UI:
|
||||
|
||||
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(_('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=[])
|
||||
@ -132,11 +136,11 @@ class UI:
|
||||
else:
|
||||
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
|
||||
if action_needed:
|
||||
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:
|
||||
self.apply_state()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user