mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add restriction to content server
This commit is contained in:
parent
5fb2c7190b
commit
61dd7b9e9a
@ -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()
|
||||
|
@ -1040,6 +1040,26 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="opt_restriction">
|
||||
<property name="toolTip">
|
||||
<string>Provides a restriction to be used by the content server</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_164">
|
||||
<property name="text">
|
||||
<string>Restriction (saved search) to apply:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>opt_restriction</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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):
|
||||
|
Loading…
x
Reference in New Issue
Block a user