Implement picking a random book

This commit is contained in:
Kovid Goyal 2016-02-13 16:12:39 +05:30
parent 585acda8cb
commit c1b41b14fc
3 changed files with 27 additions and 13 deletions

View File

@ -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')

View File

@ -58,9 +58,7 @@ 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,
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(
@ -68,7 +66,7 @@ class BookDetailsPanel:
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
))

View File

@ -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()