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):