More work on adding books in the server UI

This commit is contained in:
Kovid Goyal 2018-01-23 16:17:42 +05:30
parent 61ab18b81a
commit d48c8e7a2b
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
4 changed files with 124 additions and 12 deletions

View File

@ -113,7 +113,7 @@ def ajax(path, on_complete, on_progress=None, bypass_cache=True, method='GET', q
xhr.timeout = timeout * 1000 # IE requires timeout to be set after open
return xhr
def ajax_send(path, data, on_complete, on_progress=None, query=None, timeout=30*1000, ok_code=200):
def ajax_send(path, data, on_complete, on_progress=None, query=None, timeout=None, ok_code=200):
# Unfortunately, browsers do not allow sending of data with HTTP GET, except
# as query parameters, so we have to use POST
xhr = ajax(path, on_complete, on_progress, False, 'POST', query, timeout, ok_code)
@ -122,6 +122,19 @@ def ajax_send(path, data, on_complete, on_progress=None, query=None, timeout=30*
return xhr
def ajax_send_file(path, file, on_complete, on_progress, query=None, timeout=None, ok_code=200):
xhr = ajax(path, on_complete, on_progress, False, 'POST', query, timeout, ok_code)
if file.name:
xhr.setRequestHeader('Calibre-Filename', file.name)
if file.type:
xhr.overrideMimeType(file.type)
r = FileReader()
r.onload = def(evt):
xhr.send(evt.target.result)
r.readAsBinaryString(file)
return xhr
def console_print(*args):
ρσ_print(*args) # noqa: undef
data = ' '.join(map(str, args)) + '\n'

83
src/pyj/book_list/add.pyj Normal file
View File

@ -0,0 +1,83 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2018, Kovid Goyal <kovid at kovidgoyal.net>
from __python__ import bound_methods, hash_literals
from gettext import gettext as _
from ajax import ajax_send_file
from book_list.router import back
from book_list.top_bar import create_top_bar
from dom import ensure_id
from file_uploads import (
update_status_widget, upload_files_widget, upload_status_widget
)
state = {
'in_progress': False,
'container_id': None,
'counter': 0,
'fake_send': False,
}
def on_close():
back()
def get_job_container(container_id, job_id):
container = document.getElementById(container_id)
if not container:
return
return container.querySelector(f'[data-job="{job_id}"]')
def on_progress(container_id, job_id):
container = get_job_container(container_id, job_id)
if container is None:
return
def on_complete(container_id, job_id):
container = get_job_container(container_id, job_id)
if container is None:
return
def fake_send(container_id, job_id):
container = get_job_container(container_id, job_id)
prev = parseInt(container.dataset.fake or '0')
container.dataset.fake = prev + 10
update_status_widget(container, container.dataset.fake, 100)
if parseInt(container.dataset.fake or '0') < 100:
setTimeout(fake_send.bind(None, container_id, job_id), 1000)
def files_chosen(container_id, files):
container = document.getElementById(container_id)
if not container:
return
for file in files:
state.counter += 1
job_id = state.counter
w = upload_status_widget(file.name, job_id)
container.appendChild(w)
w.style.borderBottom = 'solid 1px currentColor'
if state.fake_send:
setTimeout(fake_send.bind(None, container_id, job_id), 100)
else:
ajax_send_file('/add-book', file, on_complete.bind(None, container_id, job_id), on_progress.bind(None, container_id, job_id), query={'id': '' + job_id})
def add_books_panel(container_id):
container = document.getElementById(container_id)
create_top_bar(container, title=_('Add books'), action=on_close, icon='close')
state.in_progress = True
state.container_id = container_id
state.fake_send = False
return upload_files_widget(container, files_chosen)
def develop(container):
c = add_books_panel(ensure_id(container))
state.fake_send = True
container.removeChild(c)
files_chosen(container.id, [{'name': 'test1.epub', 'type': 'application/epub+zip'}, {'name': 'xxxx.yyy'}])

View File

@ -7,6 +7,7 @@ from elementmaker import E
from gettext import gettext as _
from ajax import ajax_send
from book_list.add import add_books_panel
from book_list.cover_grid import (
DESCRIPTION as COVER_GRID_DESCRIPTION, append_item as cover_grid_append_item,
cover_grid_css, create_item as create_cover_grid_item, init as init_cover_grid
@ -35,7 +36,6 @@ from book_list.search import (
from book_list.top_bar import add_button, create_top_bar
from book_list.ui import query_as_href, set_panel_handler, show_panel
from dom import add_extra_css, build_rule, clear, ensure_id, set_css
from file_uploads import upload_files_widget
from modals import error_dialog
from session import get_interface_data
from utils import conditional_timeout, parse_url_params, safe_set_inner_html
@ -452,8 +452,11 @@ def create_more_actions_panel(container_id):
# }}}
# Adding books {{{
def implement_me():
upload_files_widget()
def add_books(container_id):
if not library_data.sortable_fields:
show_panel('book_list', replace=True)
return
add_books_panel(container_id)
# }}}

View File

@ -5,7 +5,7 @@ from __python__ import bound_methods, hash_literals
from elementmaker import E
from gettext import gettext as _
from utils import safe_set_inner_html
from utils import safe_set_inner_html, human_readable
def upload_files_widget(container, proceed, msg):
@ -15,12 +15,13 @@ def upload_files_widget(container, proceed, msg):
files = this.files
container = document.getElementById(container_id)
container.removeChild(container.lastChild)
if callable(proceed):
proceed(container, files)
if callable(proceed) and files.length:
proceed(container_id, files)
msg = msg or _('Upload books by <a>selecting the book files</a> or drag and drop of the files here')
c = E.div(E.span(), E.input(type='file', multiple=True, style='display:none', onchange=files_selected))
c.style.minHeight = '40vh'
c.style.minHeight = '80vh'
c.style.padding = '1rem'
c.style.borderBottom = 'solid 1px currentColor'
safe_set_inner_html(c.firstChild, msg)
@ -47,9 +48,21 @@ def upload_files_widget(container, proceed, msg):
return c
def update_status_widget(w, sent, total):
if total:
p = w.getElementsByTagName('progress')[0]
p.setAttribute('value', '' + sent)
p.setAttribute('max', '' + total)
w.lastChild.textContent = _(' {percent:.0%} of {total}').format(percent=sent / total, total=human_readable(total))
def upload_status_widget(name, job_id):
ans = E.div(style='padding: 1rem 1ex;', data_job='' + job_id)
ans.appendChild(E.h3(E.b(name)))
ans.appendChild(E.progress())
ans.appendChild(E.span())
return ans
def start_send(container, files):
pass
def develop(container):
upload_files_widget(container)