diff --git a/src/calibre/gui2/dialogs/config/__init__.py b/src/calibre/gui2/dialogs/config/__init__.py
index 20c7843aa8..c5b61f146d 100644
--- a/src/calibre/gui2/dialogs/config/__init__.py
+++ b/src/calibre/gui2/dialogs/config/__init__.py
@@ -447,6 +447,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
self.password.setText(opts.password if opts.password else '')
self.opt_max_opds_items.setValue(opts.max_opds_items)
self.opt_max_opds_ungrouped_items.setValue(opts.max_opds_ungrouped_items)
+ self.opt_restriction.setText(self.db.prefs.get('cs_restriction', ''))
self.auto_launch.setChecked(config['autolaunch_server'])
self.systray_icon.setChecked(config['systray_icon'])
self.sync_news.setChecked(config['upload_news_to_device'])
@@ -906,6 +907,7 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
sc.set('max_opds_items', self.opt_max_opds_items.value())
sc.set('max_opds_ungrouped_items',
self.opt_max_opds_ungrouped_items.value())
+ self.db.prefs.set('cs_restriction', unicode(self.opt_restriction.text()))
config['delete_news_from_library_on_upload'] = self.delete_news.isChecked()
config['upload_news_to_device'] = self.sync_news.isChecked()
config['search_as_you_type'] = self.search_as_you_type.isChecked()
diff --git a/src/calibre/gui2/dialogs/config/config.ui b/src/calibre/gui2/dialogs/config/config.ui
index 1359278512..62eb7bb620 100644
--- a/src/calibre/gui2/dialogs/config/config.ui
+++ b/src/calibre/gui2/dialogs/config/config.ui
@@ -1040,6 +1040,26 @@
+ -
+
+
+ Provides a restriction to be used by the content server
+
+
+
+
+
+
+ -
+
+
+ Restriction (saved search) to apply:
+
+
+ opt_restriction
+
+
+
-
diff --git a/src/calibre/library/caches.py b/src/calibre/library/caches.py
index fa07ed8b83..ca66d28ddb 100644
--- a/src/calibre/library/caches.py
+++ b/src/calibre/library/caches.py
@@ -609,26 +609,24 @@ class ResultCache(SearchQueryParser):
self._map.sort(cmp=fcmp, reverse=not ascending)
self._map_filtered = [id for id in self._map if id in self._map_filtered]
- def search(self, query, return_matches=False,
- ignore_search_restriction=False):
- q = ''
- if not query or not query.strip():
- if not ignore_search_restriction:
- q = self.search_restriction
- else:
- q = query
- if not ignore_search_restriction and self.search_restriction:
- q = u'%s (%s)' % (self.search_restriction, query)
- if not q:
- if return_matches:
- return list(self._map) # when return_matches, do not update the maps!
- self._map_filtered = list(self._map)
- return
- matches = sorted(self.parse(q))
- ans = [id for id in self._map if id in matches]
+ def search(self, query, return_matches=False):
+ ans = self.search_getting_ids(query, self.search_restriction)
if return_matches:
return ans
self._map_filtered = ans
+ def search_getting_ids(self, query, search_restriction):
+ q = ''
+ if not query or not query.strip():
+ q = search_restriction
+ else:
+ q = query
+ if search_restriction:
+ q = u'%s (%s)' % (search_restriction, query)
+ if not q:
+ return list(self._map)
+ matches = sorted(self.parse(q))
+ return [id for id in self._map if id in matches]
+
def set_search_restriction(self, s):
self.search_restriction = s
diff --git a/src/calibre/library/database2.py b/src/calibre/library/database2.py
index b8ac065760..6728735eb3 100644
--- a/src/calibre/library/database2.py
+++ b/src/calibre/library/database2.py
@@ -296,6 +296,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
self.book_on_device_func = None
self.data = ResultCache(self.FIELD_MAP, self.field_metadata)
self.search = self.data.search
+ self.search_getting_ids = self.data.search_getting_ids
self.refresh = functools.partial(self.data.refresh, self)
self.sort = self.data.sort
self.index = self.data.index
diff --git a/src/calibre/library/server/base.py b/src/calibre/library/server/base.py
index 57e5e702fa..bdaee1c42d 100644
--- a/src/calibre/library/server/base.py
+++ b/src/calibre/library/server/base.py
@@ -57,15 +57,13 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache):
server_name = __appname__ + '/' + __version__
- def __init__(self, db, opts, embedded=False, show_tracebacks=True,
- ignore_search_restriction=True):
+ def __init__(self, db, opts, embedded=False, show_tracebacks=True):
self.db = db
for item in self.db:
item
break
self.opts = opts
self.embedded = embedded
- self.ignore_search_restriction=ignore_search_restriction
self.state_callback = None
self.max_cover_width, self.max_cover_height = \
map(int, self.opts.max_cover.split('x'))
@@ -97,9 +95,19 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache):
'tools.digest_auth.users' : {opts.username.strip():opts.password.strip()},
}
+ self.set_search_restriction(db.prefs.get('cs_restriction', ''))
+ if opts.restriction is not None:
+ self.set_search_restriction(opts.restriction)
+
self.is_running = False
self.exception = None
+ def set_search_restriction(self, restriction):
+ if restriction:
+ self.search_restriction = 'search:'+restriction
+ else:
+ self.search_restriction = ''
+
def setup_loggers(self):
access_file = log_access_file
error_file = log_error_file
diff --git a/src/calibre/library/server/cache.py b/src/calibre/library/server/cache.py
index 6f6c21e60c..94e4a1c041 100644
--- a/src/calibre/library/server/cache.py
+++ b/src/calibre/library/server/cache.py
@@ -17,8 +17,7 @@ class Cache(object):
def search_cache(self, search):
old = self._search_cache.pop(search, None)
if old is None or old[0] <= self.db.last_modified():
- matches = self.db.data.search(search, return_matches=True,
- ignore_search_restriction=self.ignore_search_restriction)
+ matches = self.db.data.search_getting_ids(search, self.search_restriction)
if not matches:
matches = []
self._search_cache[search] = (utcnow(), frozenset(matches))
diff --git a/src/calibre/library/server/main.py b/src/calibre/library/server/main.py
index 2fad001a86..e87d2d75d7 100644
--- a/src/calibre/library/server/main.py
+++ b/src/calibre/library/server/main.py
@@ -33,7 +33,8 @@ def option_parser():
parser.add_option('--daemonize', default=False, action='store_true',
help='Run process in background as a daemon. No effect on windows.')
parser.add_option('--restriction', default=None,
- help='Specifies a restriction to be used for this invocation.')
+ help=_('Specifies a restriction to be used for this invocation. '
+ 'This option overrides the default set in the GUI'))
return parser
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
@@ -85,9 +86,7 @@ def main(args=sys.argv):
if opts.with_library is None:
opts.with_library = prefs['library_path']
db = LibraryDatabase2(opts.with_library)
- server = LibraryServer(db, opts, ignore_search_restriction=False)
- if opts.restriction:
- db.data.set_search_restriction('search:' + opts.restriction)
+ server = LibraryServer(db, opts)
server.start()
return 0
diff --git a/src/calibre/library/server/mobile.py b/src/calibre/library/server/mobile.py
index 391ad70bfd..8ea9a04515 100644
--- a/src/calibre/library/server/mobile.py
+++ b/src/calibre/library/server/mobile.py
@@ -181,8 +181,7 @@ class MobileServer(object):
num = int(num)
except ValueError:
raise cherrypy.HTTPError(400, 'num: %s is not an integer'%num)
- ids = self.db.search(search, return_matches=True,
- ignore_search_restriction=self.ignore_search_restriction)
+ ids = self.db.search_getting_ids(search, self.search_restriction)
FM = self.db.FIELD_MAP
items = [r for r in iter(self.db) if r[FM['id']] in ids]
if sort is not None:
diff --git a/src/calibre/library/server/xml.py b/src/calibre/library/server/xml.py
index 5649208036..18370ab641 100644
--- a/src/calibre/library/server/xml.py
+++ b/src/calibre/library/server/xml.py
@@ -45,8 +45,7 @@ class XMLServer(object):
order = order.lower().strip() == 'ascending'
- ids = self.db.search(search, return_matches=True,
- ignore_search_restriction=self.ignore_search_restriction)
+ ids = self.db.search_getting_ids(search, self.search_restriction)
FM = self.db.FIELD_MAP
@@ -54,7 +53,6 @@ class XMLServer(object):
if sort is not None:
self.sort(items, sort, order)
-
books = []
def serialize(x):