diff --git a/resources/content-server/index.html b/resources/content-server/index.html
index 5460c8cc33..b4e56a6b49 100644
--- a/resources/content-server/index.html
+++ b/resources/content-server/index.html
@@ -6,7 +6,7 @@
-
+
diff --git a/src/calibre/srv/code.py b/src/calibre/srv/code.py
index 61934cb6b0..fd026f0cd1 100644
--- a/src/calibre/srv/code.py
+++ b/src/calibre/srv/code.py
@@ -7,7 +7,7 @@ from __future__ import (unicode_literals, division, absolute_import,
import re, hashlib, random, os
from functools import partial
from threading import Lock
-from json import load as load_json_file
+from json import load as load_json_file, dumps as json_dumps
from calibre import prepare_string_for_xml, as_unicode
from calibre.constants import config_dir
@@ -53,9 +53,13 @@ def get_html(name, auto_reload_port, **replacements):
@endpoint('', auth_required=False)
def index(ctx, rd):
+ default_library = ctx.library_map[1]
return rd.generate_static_output('/', partial(
get_html, 'content-server/index.html', getattr(rd.opts, 'auto_reload_port', 0),
- ENTRY_POINT='book list', LOADING_MSG=prepare_string_for_xml(_('Loading library, please wait'))))
+ ENTRY_POINT='book list',
+ LOADING_MSG=prepare_string_for_xml(_('Loading library, please wait')),
+ DEFAULT_LIBRARY=json_dumps(default_library)
+ ))
def get_library_data(ctx, query):
library_id = query.get('library_id')
diff --git a/src/pyj/book_list/boss.pyj b/src/pyj/book_list/boss.pyj
index fc06a7ec3d..7ebdc7acf3 100644
--- a/src/pyj/book_list/boss.pyj
+++ b/src/pyj/book_list/boss.pyj
@@ -77,7 +77,7 @@ class Boss:
sval = ''
for field, order in zip(str.split(data.search_result.sort, ','), str.split(data.search_result.sort_order, ',')):
sval += field + '.' + order + ','
- get_session_data().set('sort', str.rstrip(sval, ','))
+ get_session_data().set_library_option(self.interface_data.library_id, 'sort', str.rstrip(sval, ','))
self.interface_data.metadata = data.metadata
self.interface_data.search_result = data.search_result
self.ui.refresh_books_view()
diff --git a/src/pyj/book_list/ui.pyj b/src/pyj/book_list/ui.pyj
index 35731ba76c..8d106f3019 100644
--- a/src/pyj/book_list/ui.pyj
+++ b/src/pyj/book_list/ui.pyj
@@ -1,7 +1,7 @@
# vim:fileencoding=utf-8
# License: GPL v3 Copyright: 2015, Kovid Goyal
-from book_list.globals import get_boss
+from book_list.globals import get_boss, get_session_data
from book_list.search import SearchPanel
from book_list.top_bar import TopBar
from book_list.views import BooksView
@@ -10,6 +10,7 @@ from book_list.prefs import PrefsPanel
from book_list.book_details import BookDetailsPanel
from gettext import gettext as _
from utils import debounce
+from modals import error_dialog, ajax_progress_dialog
class BarState:
@@ -70,6 +71,17 @@ def create_book_view_top_bar_state(books_view):
def random_book():
get_boss().ui.replace_panel('book-details', extra_query_data={'book-id':'0'})
+def change_library_actions():
+ boss = get_boss()
+ interface_data = boss.interface_data
+ ans = []
+ ans.subtitle = _('Currently showing the library: ') + interface_data.library_map[interface_data.library_id]
+ for lid in sorted(interface_data.library_map):
+ if lid != interface_data.library_id:
+ library_name = interface_data.library_map[lid]
+ ans.append({'title':library_name, 'action':boss.ui.change_library.bind(boss.ui, lid)})
+ return ans
+
class UI:
ROOT_PANEL = 'books'
@@ -86,10 +98,18 @@ class UI:
self.current_panel = self.ROOT_PANEL
window.addEventListener('resize', debounce(self.on_resize.bind(self), 250))
- self.panel_map['more-actions-menu'] = UIState(ClosePanelBar(_('More actions')), panel_data=[
+ num_of_libraries = len(interface_data.library_map)
+ actions = [
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')),
- ])
+ ]
+ if num_of_libraries > 1:
+ actions.push(
+ create_item(_('Change Library'), replace_panel_action('booklist-change-library'), _('Choose a different library to display'))
+ )
+ self.panel_map['booklist-change-library'] = UIState(ClosePanelBar(_('Change Library')), panel_data=change_library_actions)
+
+ self.panel_map['more-actions-menu'] = UIState(ClosePanelBar(_('More actions')), panel_data=actions)
self.panel_map['booklist-mode-menu'] = UIState(ClosePanelBar(_('Book List Mode')), panel_data=[])
@@ -164,3 +184,25 @@ class UI:
self.books_view.refresh()
if self.current_panel == self.ROOT_PANEL:
self.top_bar.refresh_left()
+
+ def change_library(self, library_id):
+ data = {'search':'', 'sort':get_session_data().get_library_option(library_id, 'sort'), 'library_id':library_id}
+ ajax_progress_dialog('interface-data/get-books', self.library_changed.bind(self), _(
+ 'Fetching data from server, please wait') + '…', query=data, extra_data_for_callback={'library_id':library_id})
+
+ def library_changed(self, end_type, xhr, ev):
+ if end_type == 'load':
+ boss = get_boss()
+ boss.interface_data.library_id = xhr.extra_data_for_callback.library_id
+ try:
+ data = JSON.parse(xhr.responseText)
+ boss.change_books(data)
+ except Exception as err:
+ return error_dialog(_('Could not change library'), err + '', details=err.stack)
+ self.show_panel(self.ROOT_PANEL)
+ window.scrollTo(0, 0)
+ elif end_type != 'abort':
+ msg = xhr.error_html
+ error_dialog(_('Could not change library'), msg)
+
+
diff --git a/src/pyj/book_list/views.pyj b/src/pyj/book_list/views.pyj
index e42a3e00e3..d6c39ccade 100644
--- a/src/pyj/book_list/views.pyj
+++ b/src/pyj/book_list/views.pyj
@@ -240,7 +240,7 @@ class BooksView:
self.abort_get_more_books()
query = query or ''
sd = get_session_data()
- data = {'search':query, 'sort':sd.get('sort'), 'library_id':self.interface_data.library_id}
+ data = {'search':query, 'sort':sd.get_library_option(self.interface_data.library_id, 'sort'), 'library_id':self.interface_data.library_id}
ajax_progress_dialog('interface-data/get-books', self.search_change_completed.bind(self), _(
'Fetching data from server, please wait') + '…', query=data, extra_data_for_callback={'push_state':push_state, 'panel_to_show': panel_to_show})
diff --git a/src/pyj/session.pyj b/src/pyj/session.pyj
index 0a48bf8f4c..5bb280baeb 100644
--- a/src/pyj/session.pyj
+++ b/src/pyj/session.pyj
@@ -128,6 +128,14 @@ class UserSessionData(SessionData):
defval = defaults[key]
return SessionData.get(self, (self.prefix + key), defval)
+ def get_library_option(self, library_id, key, defval):
+ if not library_id:
+ return self.get(key, defval)
+ lkey = key + '-||-' + library_id
+ if defval is undefined:
+ defval = defaults[key]
+ return self.get(lkey, defval)
+
def set(self, key, value):
if self.echo_changes and self.has_user:
self.changes[key] = value
@@ -137,6 +145,11 @@ class UserSessionData(SessionData):
self.push_timer_id = setTimeout(self.push_to_server.bind(self), 1000)
return SessionData.set(self, (self.prefix + key), value)
+ def set_library_option(self, library_id, key, value):
+ if library_id:
+ key = key + '-||-' + library_id
+ return self.set(key, value)
+
def push_to_server(self):
if self.has_changes:
ajax_send('interface-data/set-session-data', self.changes, def(end_type, xhr, ev):
diff --git a/src/pyj/srv.pyj b/src/pyj/srv.pyj
index 6c038631c3..6bc549ca08 100644
--- a/src/pyj/srv.pyj
+++ b/src/pyj/srv.pyj
@@ -33,14 +33,22 @@ def on_library_load_progress(loaded, total):
def load_book_list():
temp = UserSessionData(None, {}) # So that settings for anonymous users are preserved
- query = {k:temp.get(k) for k in str.split('library_id sort')}
+ query = {}
+ default_lib = window.calibre_default_library
+ v'delete window.calibre_default_library'
+ query.sort = temp.get_library_option(default_lib, 'sort')
+ library_id = temp.get('library_id')
+ if library_id:
+ query.library_id = library_id
url_query = parse_url_params()
for key in url_query:
query[key] = url_query[key]
ajax('interface-data/init', on_library_loaded, on_library_load_progress, query=query).send()
def on_load():
- if window.calibre_entry_point == 'book list':
+ ep = window.calibre_entry_point
+ v'delete window.calibre_entry_point'
+ if ep == 'book list':
print('calibre loaded at:', Date().toString())
load_book_list()