API to get all field names from the server

This commit is contained in:
Kovid Goyal 2018-03-06 15:08:26 +05:30
parent 229dd92b59
commit f092e5a236
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
3 changed files with 73 additions and 3 deletions

View File

@ -384,3 +384,13 @@ def tag_browser(ctx, rd):
return json(ctx, rd, tag_browser, categories_as_json(ctx, rd, db, opts, vl))
return rd.etagged_dynamic_response(etag, generate)
@endpoint('/interface-data/field-names/{field}', postprocess=json)
def field_names(ctx, rd, field):
'''
Get a list of all names for the specified field
Optional: ?library_id=<default library>
'''
db, library_id = get_library_data(ctx, rd)[:2]
return tuple(db.all_field_names(field))

View File

@ -11,8 +11,8 @@ from book_list.book_details import (
basic_table_rules, fetch_metadata, field_sorter, no_book, report_load_failure
)
from book_list.library_data import (
book_metadata, current_library_id, library_data, load_status, loaded_book_ids,
set_book_metadata
book_metadata, current_library_id, field_names_for, library_data, load_status,
loaded_book_ids, set_book_metadata
)
from book_list.router import back
from book_list.top_bar import create_top_bar, set_title
@ -114,6 +114,23 @@ def simple_line_edit(container_id, book_id, field, fm, div, mi):
return x
def multiple_line_edit(list_to_ui, ui_to_list, container_id, book_id, field, fm, div, mi):
nonlocal value_to_json
name = fm.name or field
le = E.input(type='text', name=name.replace('#', '_c_'), autocomplete=True)
le.value = (resolved_metadata(mi, field) or v'[]').join(list_to_ui)
form = create_form(le, line_edit_get_value, container_id, book_id, field)
div.appendChild(E.div(style='margin: 0.5ex 1rem', _(
'Edit the "{0}" below. Multiple items can be separated by {1}.').format(name, list_to_ui.strip())))
div.appendChild(E.div(style='margin: 0.5ex 1rem', form))
div.appendChild(E.div(style='margin: 0.5ex 1rem'))
le.focus(), le.select()
value_to_json = def(x):
return [a.strip() for a in x.split(ui_to_list) if a.strip()]
div.lastChild.appendChild(E.span(_('Loading all {}...').format(name)))
field_names_for(field, print)
def edit_field(container_id, book_id, field):
nonlocal value_to_json
fm = library_data.field_metadata[field]
@ -125,10 +142,16 @@ def edit_field(container_id, book_id, field):
d.style.display = 'block'
d.previousSibling.style.display = 'none'
clear(d)
simple_line_edit(container_id, book_id, field, fm, d, mi)
if field is 'authors':
multiple_line_edit(' & ', '&', container_id, book_id, field, fm, d, mi)
else:
simple_line_edit(container_id, book_id, field, fm, d, mi)
if field is 'title':
value_to_json = def(x):
return x or _('Untitled')
elif field is 'authors':
value_to_json = def(x):
return [a.strip() for a in x.split('&') if a.strip()] or [_('Unknown')]
def render_metadata(mi, table, container_id, book_id): # {{{

View File

@ -73,6 +73,9 @@ def update_library_data(data):
load_status.ok = True
load_status.error_html = None
library_data.previous_book_ids = v'[]'
if library_data.for_library is not current_library_id():
library_data.field_names = {}
library_data.for_library = current_library_id()
for key in 'search_result sortable_fields field_metadata metadata virtual_libraries book_display_fields'.split(' '):
library_data[key] = data[key]
sr = library_data.search_result
@ -140,6 +143,40 @@ def fetch_init_data():
load_status.current_fetch.send()
def field_names_received(library_id, field, proceed, end_type, xhr, event):
if library_id is not current_library_id():
return
if end_type is not 'load':
if end_type is not 'abort':
proceed(False, field, xhr.error_html)
return
try:
names = JSON.parse(xhr.responseText)
except Exception:
import traceback
traceback.print_exc()
proceed(False, field, 'Invalid JSON from server')
return
library_data.field_names[field] = {
'loading': False,
'loaded': True,
'last_updated_at': Date.now(),
'names': names
}
proceed(True, field, names)
def field_names_for(field, proceed):
if library_data.field_names[field] and library_data.field_names[field].loaded:
proceed(True, field, library_data.field_names[field].names)
if not library_data.field_names[field] or (not library_data.field_names[field].loading and Date.now() - library_data.field_names[field].last_updated_at > 3600 * 1000):
ajax(f'interface-data/field-names/{encodeURIComponent(field)}', field_names_received.bind(None, current_library_id(), field, proceed), query={'library_id': current_library_id()}).send()
if not library_data.field_names[field]:
library_data.field_names[field] = {'last_updated_at': 0, 'loaded': False, 'names': v'[]'}
library_data.field_names[field].loading = True
def thumbnail_url(book_id, width, height):
return absolute_path(
'get/thumb/{}/{}?sz={}x{}'.format(