mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Content server home page: Show the three most recently added books in the default library
This commit is contained in:
parent
896df3daf9
commit
81708d3614
@ -1404,6 +1404,12 @@ class Cache:
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@read_api
|
||||||
|
def newly_added_book_ids(self, count=5) -> list[int]:
|
||||||
|
ids_to_sort = self._all_book_ids(list)
|
||||||
|
ids_to_sort.sort(reverse=True)
|
||||||
|
return ids_to_sort[:count]
|
||||||
|
|
||||||
@read_api
|
@read_api
|
||||||
def multisort(self, fields, ids_to_sort=None, virtual_fields=None):
|
def multisort(self, fields, ids_to_sort=None, virtual_fields=None):
|
||||||
'''
|
'''
|
||||||
|
@ -300,6 +300,22 @@ def interface_data(ctx, rd):
|
|||||||
return ans
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
@endpoint('/interface-data/newly-added', postprocess=json)
|
||||||
|
def newly_added(ctx, rd):
|
||||||
|
'''
|
||||||
|
Get newly added books.
|
||||||
|
|
||||||
|
Optional: ?num=3&library_id=<default library>
|
||||||
|
'''
|
||||||
|
db, library_id = get_library_data(ctx, rd)[:2]
|
||||||
|
count = int(rd.query.get('num', 3))
|
||||||
|
with db.safe_read_lock:
|
||||||
|
nbids = db._newly_added_book_ids(count)
|
||||||
|
titles = db._all_field_for('title', nbids)
|
||||||
|
authors = db._all_field_for('authors', nbids)
|
||||||
|
return {'library_id': library_id, 'books': nbids, 'titles': titles, 'authors': authors}
|
||||||
|
|
||||||
|
|
||||||
@endpoint('/interface-data/more-books', postprocess=json, methods=POSTABLE)
|
@endpoint('/interface-data/more-books', postprocess=json, methods=POSTABLE)
|
||||||
def more_books(ctx, rd):
|
def more_books(ctx, rd):
|
||||||
'''
|
'''
|
||||||
|
@ -4,7 +4,7 @@ from __python__ import bound_methods, hash_literals
|
|||||||
|
|
||||||
from elementmaker import E
|
from elementmaker import E
|
||||||
|
|
||||||
from ajax import absolute_path, ajax_send
|
from ajax import absolute_path, ajax_send, ajax
|
||||||
from book_list.cover_grid import BORDER_RADIUS
|
from book_list.cover_grid import BORDER_RADIUS
|
||||||
from book_list.globals import get_db
|
from book_list.globals import get_db
|
||||||
from book_list.library_data import (
|
from book_list.library_data import (
|
||||||
@ -27,7 +27,7 @@ add_extra_css(def():
|
|||||||
sel = f'.{CLASS_NAME} '
|
sel = f'.{CLASS_NAME} '
|
||||||
ans += build_rule(f'{sel} h2', padding='1rem', font_size='1.5em')
|
ans += build_rule(f'{sel} h2', padding='1rem', font_size='1.5em')
|
||||||
sel += '.recently-read img'
|
sel += '.recently-read img'
|
||||||
ans += build_rule(sel, max_width='25vw', max_height='40vh', height='auto', border_radius=f'{BORDER_RADIUS}px')
|
ans += build_rule(sel, max_width='25vw', max_height='30vh', height='auto', border_radius=f'{BORDER_RADIUS}px')
|
||||||
ans += build_rule(f'{sel}:hover', transform='scale(1.2)')
|
ans += build_rule(f'{sel}:hover', transform='scale(1.2)')
|
||||||
ans += build_rule(f'{sel}:active', transform='scale(2)')
|
ans += build_rule(f'{sel}:active', transform='scale(2)')
|
||||||
return ans
|
return ans
|
||||||
@ -61,6 +61,10 @@ def read_book(library_id, book_id, fmt, extra_query):
|
|||||||
open_book(book_id, fmt, library_id, extra_query=extra_query)
|
open_book(book_id, fmt, library_id, extra_query=extra_query)
|
||||||
|
|
||||||
|
|
||||||
|
def view_book_page(library_id, book_id):
|
||||||
|
show_panel('book_details', {'library_id': library_id, 'book_id': book_id + ''}, replace=False)
|
||||||
|
|
||||||
|
|
||||||
def get_last_read_position(last_read_positions, prev_last_read):
|
def get_last_read_position(last_read_positions, prev_last_read):
|
||||||
prev_epoch = prev_last_read.getTime()
|
prev_epoch = prev_last_read.getTime()
|
||||||
dev = get_device_uuid()
|
dev = get_device_uuid()
|
||||||
@ -196,6 +200,29 @@ def show_recent():
|
|||||||
else:
|
else:
|
||||||
print(db.initialize_error_msg)
|
print(db.initialize_error_msg)
|
||||||
|
|
||||||
|
|
||||||
|
def newly_added_received(newly_container_id, end_type, xhr, ev):
|
||||||
|
container = document.getElementById(newly_container_id)
|
||||||
|
if not container or end_type is not 'load':
|
||||||
|
return
|
||||||
|
data = JSON.parse(xhr.responseText)
|
||||||
|
if not data.books or not data.books.length:
|
||||||
|
return
|
||||||
|
container.style.display = 'block'
|
||||||
|
container.appendChild(E.div(style='display:flex'))
|
||||||
|
images = container.lastChild
|
||||||
|
|
||||||
|
for book_id in data.books:
|
||||||
|
authors = data.authors[book_id].join(' & ')
|
||||||
|
alt=_('{} by {}').format(data.titles[book_id], authors)
|
||||||
|
img = E.img(alt=alt, src=absolute_path(f'get/cover/{book_id}/{data.library_id}'))
|
||||||
|
images.appendChild(E.div(style='margin: 0 1em',
|
||||||
|
E.a(img, href='javascript: void(0)', title=img.alt,
|
||||||
|
onclick=view_book_page.bind(None, data.library_id, book_id)
|
||||||
|
),
|
||||||
|
))
|
||||||
|
|
||||||
|
|
||||||
# User account {{{
|
# User account {{{
|
||||||
|
|
||||||
def change_password():
|
def change_password():
|
||||||
@ -314,4 +341,11 @@ def init(container_id):
|
|||||||
cl.lastChild.style.margin = '1ex 1rem'
|
cl.lastChild.style.margin = '1ex 1rem'
|
||||||
cl.lastChild.dataset.lid = library_id
|
cl.lastChild.dataset.lid = library_id
|
||||||
|
|
||||||
|
# Newly added
|
||||||
|
newly = E.div(style='border-top: solid 1px currentColor; padding-top: 1em; display: none', class_='recently-read')
|
||||||
|
newly.appendChild(E.h2(_('Newly added…')))
|
||||||
|
newly_container_id = ensure_id(newly)
|
||||||
|
container.appendChild(newly)
|
||||||
|
ajax('interface-data/newly-added', newly_added_received.bind(None, newly_container_id)).send()
|
||||||
|
|
||||||
set_default_panel_handler(init)
|
set_default_panel_handler(init)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user