mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add a tweak to automatically connect to a folder on startup (#6237). Add settings to apply a search restriction on startup and to the content server. Fixes #5513 (Allow/Disallow books from being shown/served by the content server)
This commit is contained in:
commit
36fe291ceb
@ -81,3 +81,11 @@ title_series_sorting = 'library_order'
|
|||||||
# strictly_alphabetic, it would remain "The Client".
|
# strictly_alphabetic, it would remain "The Client".
|
||||||
save_template_title_series_sorting = 'library_order'
|
save_template_title_series_sorting = 'library_order'
|
||||||
|
|
||||||
|
# Specify a folder that calibre should connect to at startup using
|
||||||
|
# connect_to_folder. This must be a full path to the folder. If the folder does
|
||||||
|
# not exist when calibre starts, it is ignored. If there are '\' characters in
|
||||||
|
# the path (such as in Windows paths), you must double them.
|
||||||
|
# Examples:
|
||||||
|
# auto_connect_to_folder = 'C:\\Users\\someone\\Desktop\\testlib'
|
||||||
|
# auto_connect_to_folder = '/home/dropbox/My Dropbox/someone/library'
|
||||||
|
auto_connect_to_folder = ''
|
@ -33,7 +33,7 @@ from calibre.devices.apple.driver import ITUNES_ASYNC
|
|||||||
from calibre.devices.folder_device.driver import FOLDER_DEVICE
|
from calibre.devices.folder_device.driver import FOLDER_DEVICE
|
||||||
from calibre.ebooks.metadata.meta import set_metadata
|
from calibre.ebooks.metadata.meta import set_metadata
|
||||||
from calibre.constants import DEBUG
|
from calibre.constants import DEBUG
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs, tweaks
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
@ -613,6 +613,8 @@ class DeviceMixin(object): # {{{
|
|||||||
self.device_manager = DeviceManager(Dispatcher(self.device_detected),
|
self.device_manager = DeviceManager(Dispatcher(self.device_detected),
|
||||||
self.job_manager, Dispatcher(self.status_bar.show_message))
|
self.job_manager, Dispatcher(self.status_bar.show_message))
|
||||||
self.device_manager.start()
|
self.device_manager.start()
|
||||||
|
if tweaks['auto_connect_to_folder']:
|
||||||
|
self.connect_to_folder_named(tweaks['auto_connect_to_folder'])
|
||||||
|
|
||||||
def set_default_thumbnail(self, height):
|
def set_default_thumbnail(self, height):
|
||||||
r = QSvgRenderer(I('book.svg'))
|
r = QSvgRenderer(I('book.svg'))
|
||||||
@ -624,6 +626,11 @@ class DeviceMixin(object): # {{{
|
|||||||
self.default_thumbnail = (pixmap.width(), pixmap.height(),
|
self.default_thumbnail = (pixmap.width(), pixmap.height(),
|
||||||
pixmap_to_data(pixmap))
|
pixmap_to_data(pixmap))
|
||||||
|
|
||||||
|
def connect_to_folder_named(self, folder):
|
||||||
|
if os.path.exists(folder) and os.path.isdir(folder):
|
||||||
|
self.device_manager.mount_device(kls=FOLDER_DEVICE, kind='folder',
|
||||||
|
path=folder)
|
||||||
|
|
||||||
def connect_to_folder(self):
|
def connect_to_folder(self):
|
||||||
dir = choose_dir(self, 'Select Device Folder',
|
dir = choose_dir(self, 'Select Device Folder',
|
||||||
_('Select folder to open as device'))
|
_('Select folder to open as device'))
|
||||||
|
@ -36,6 +36,7 @@ from calibre.gui2.convert.structure_detection import StructureDetectionWidget
|
|||||||
from calibre.ebooks.conversion.plumber import Plumber
|
from calibre.ebooks.conversion.plumber import Plumber
|
||||||
from calibre.utils.logging import Log
|
from calibre.utils.logging import Log
|
||||||
from calibre.gui2.convert.toc import TOCWidget
|
from calibre.gui2.convert.toc import TOCWidget
|
||||||
|
from calibre.utils.search_query_parser import saved_searches
|
||||||
|
|
||||||
|
|
||||||
class ConfigTabs(QTabWidget):
|
class ConfigTabs(QTabWidget):
|
||||||
@ -493,6 +494,14 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
if x == config['gui_layout']:
|
if x == config['gui_layout']:
|
||||||
li = i
|
li = i
|
||||||
self.opt_gui_layout.setCurrentIndex(li)
|
self.opt_gui_layout.setCurrentIndex(li)
|
||||||
|
restrictions = sorted(saved_searches().names(),
|
||||||
|
cmp=lambda x,y: cmp(x.lower(), y.lower()))
|
||||||
|
restrictions.insert(0, '')
|
||||||
|
for x in ('gui', 'cs'):
|
||||||
|
w = getattr(self, 'opt_%s_restriction'%x)
|
||||||
|
w.addItems(restrictions)
|
||||||
|
idx = w.findText(self.db.prefs.get(x+'_restriction', ''))
|
||||||
|
w.setCurrentIndex(0 if idx < 0 else idx)
|
||||||
self.opt_disable_animations.setChecked(config['disable_animations'])
|
self.opt_disable_animations.setChecked(config['disable_animations'])
|
||||||
self.opt_show_donate_button.setChecked(config['show_donate_button'])
|
self.opt_show_donate_button.setChecked(config['show_donate_button'])
|
||||||
idx = 0
|
idx = 0
|
||||||
@ -927,6 +936,9 @@ class ConfigDialog(ResizableDialog, Ui_Dialog):
|
|||||||
config['internally_viewed_formats'] = fmts
|
config['internally_viewed_formats'] = fmts
|
||||||
val = self.opt_gui_layout.itemData(self.opt_gui_layout.currentIndex()).toString()
|
val = self.opt_gui_layout.itemData(self.opt_gui_layout.currentIndex()).toString()
|
||||||
config['gui_layout'] = unicode(val)
|
config['gui_layout'] = unicode(val)
|
||||||
|
for x in ('gui', 'cs'):
|
||||||
|
w = getattr(self, 'opt_%s_restriction'%x)
|
||||||
|
self.db.prefs.set(x+'_restriction', unicode(w.currentText()))
|
||||||
|
|
||||||
if must_restart:
|
if must_restart:
|
||||||
warning_dialog(self, _('Must restart'),
|
warning_dialog(self, _('Must restart'),
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1000</width>
|
<width>1001</width>
|
||||||
<height>730</height>
|
<height>730</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
@ -89,8 +89,8 @@
|
|||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>720</width>
|
<width>725</width>
|
||||||
<height>679</height>
|
<height>683</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_7">
|
<layout class="QGridLayout" name="gridLayout_7">
|
||||||
@ -295,7 +295,7 @@
|
|||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page">
|
<widget class="QWidget" name="page">
|
||||||
<layout class="QGridLayout" name="gridLayout_8">
|
<layout class="QGridLayout" name="gridLayout_8">
|
||||||
<item row="1" column="0">
|
<item row="2" column="0">
|
||||||
<widget class="QCheckBox" name="roman_numerals">
|
<widget class="QCheckBox" name="roman_numerals">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Use &Roman numerals for series number</string>
|
<string>Use &Roman numerals for series number</string>
|
||||||
@ -305,35 +305,35 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0">
|
<item row="3" column="0">
|
||||||
<widget class="QCheckBox" name="systray_icon">
|
<widget class="QCheckBox" name="systray_icon">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Enable system &tray icon (needs restart)</string>
|
<string>Enable system &tray icon (needs restart)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="3" column="1">
|
||||||
<widget class="QCheckBox" name="systray_notifications">
|
<widget class="QCheckBox" name="systray_notifications">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show &notifications in system tray</string>
|
<string>Show &notifications in system tray</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="4" column="0">
|
||||||
<widget class="QCheckBox" name="show_splash_screen">
|
<widget class="QCheckBox" name="show_splash_screen">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show &splash screen at startup</string>
|
<string>Show &splash screen at startup</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="0" colspan="2">
|
<item row="5" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="separate_cover_flow">
|
<widget class="QCheckBox" name="separate_cover_flow">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show cover &browser in a separate window (needs restart)</string>
|
<string>Show cover &browser in a separate window (needs restart)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="0" colspan="2">
|
<item row="6" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="show_avg_rating">
|
<widget class="QCheckBox" name="show_avg_rating">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show &average ratings in the tags browser</string>
|
<string>Show &average ratings in the tags browser</string>
|
||||||
@ -343,7 +343,7 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="7" column="0">
|
||||||
<widget class="QCheckBox" name="search_as_you_type">
|
<widget class="QCheckBox" name="search_as_you_type">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Search as you type</string>
|
<string>Search as you type</string>
|
||||||
@ -353,21 +353,21 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="8" column="0" colspan="2">
|
<item row="9" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="sync_news">
|
<widget class="QCheckBox" name="sync_news">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Automatically send downloaded &news to ebook reader</string>
|
<string>Automatically send downloaded &news to ebook reader</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="9" column="0" colspan="2">
|
<item row="10" column="0" colspan="2">
|
||||||
<widget class="QCheckBox" name="delete_news">
|
<widget class="QCheckBox" name="delete_news">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>&Delete news from library when it is automatically sent to reader</string>
|
<string>&Delete news from library when it is automatically sent to reader</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="10" column="0" colspan="2">
|
<item row="11" column="0" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QLabel" name="label_6">
|
<widget class="QLabel" name="label_6">
|
||||||
@ -384,7 +384,7 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0" colspan="2">
|
<item row="12" column="0" colspan="2">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QGroupBox" name="groupBox">
|
<widget class="QGroupBox" name="groupBox">
|
||||||
@ -570,7 +570,36 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_170">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restriction to apply when the current library is opened:</string>
|
||||||
|
</property>
|
||||||
|
<property name="buddy">
|
||||||
|
<cstring>opt_gui_restriction</cstring>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="1" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_gui_restriction">
|
||||||
|
<property name="maximumSize">
|
||||||
|
<size>
|
||||||
|
<width>250</width>
|
||||||
|
<height>16777215</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>Apply this restriction on calibre startup if the current library is being used. Also applied when switching to this library. Note that this setting is per library. </string>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
<widget class="QCheckBox" name="opt_disable_animations">
|
<widget class="QCheckBox" name="opt_disable_animations">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>Disable all animations. Useful if you have a slow/old computer.</string>
|
<string>Disable all animations. Useful if you have a slow/old computer.</string>
|
||||||
@ -580,14 +609,14 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="4" column="1">
|
||||||
<widget class="QCheckBox" name="opt_show_donate_button">
|
<widget class="QCheckBox" name="opt_show_donate_button">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Show &donate button (restart)</string>
|
<string>Show &donate button (restart)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="0" colspan="2">
|
<item row="8" column="0" colspan="2">
|
||||||
<widget class="QGroupBox" name="groupBox_2">
|
<widget class="QGroupBox" name="groupBox_2">
|
||||||
<property name="title">
|
<property name="title">
|
||||||
<string>&Toolbar</string>
|
<string>&Toolbar</string>
|
||||||
@ -1040,6 +1069,26 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="7" column="0">
|
||||||
|
<widget class="QLabel" name="label_164">
|
||||||
|
<property name="text">
|
||||||
|
<string>Restriction (saved search) to apply:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QComboBox" name="opt_cs_restriction">
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>This restriction (based on a saved search) will restrict the books the content server makes available to those matching the search. This setting is per library (i.e. you can have a different restriction per library).</string>
|
||||||
|
</property>
|
||||||
|
<property name="sizeAdjustPolicy">
|
||||||
|
<enum>QComboBox::AdjustToMinimumContentsLengthWithIcon</enum>
|
||||||
|
</property>
|
||||||
|
<property name="minimumContentsLength">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
|
@ -402,8 +402,7 @@ class SavedSearchBoxMixin(object):
|
|||||||
b.setStatusTip(b.toolTip())
|
b.setStatusTip(b.toolTip())
|
||||||
|
|
||||||
def saved_searches_changed(self):
|
def saved_searches_changed(self):
|
||||||
p = saved_searches().names()
|
p = sorted(saved_searches().names(), cmp=lambda x,y: cmp(x.lower(), y.lower()))
|
||||||
p.sort()
|
|
||||||
t = unicode(self.search_restriction.currentText())
|
t = unicode(self.search_restriction.currentText())
|
||||||
self.search_restriction.clear() # rebuild the restrictions combobox using current saved searches
|
self.search_restriction.clear() # rebuild the restrictions combobox using current saved searches
|
||||||
self.search_restriction.addItem('')
|
self.search_restriction.addItem('')
|
||||||
|
@ -230,6 +230,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
|||||||
|
|
||||||
######################### Search Restriction ##########################
|
######################### Search Restriction ##########################
|
||||||
SearchRestrictionMixin.__init__(self)
|
SearchRestrictionMixin.__init__(self)
|
||||||
|
self.apply_named_search_restriction(db.prefs.get('gui_restriction', ''))
|
||||||
|
|
||||||
########################### Cover Flow ################################
|
########################### Cover Flow ################################
|
||||||
|
|
||||||
@ -373,6 +374,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
|||||||
self.set_window_title()
|
self.set_window_title()
|
||||||
self.apply_named_search_restriction('') # reset restriction to null
|
self.apply_named_search_restriction('') # reset restriction to null
|
||||||
self.saved_searches_changed() # reload the search restrictions combo box
|
self.saved_searches_changed() # reload the search restrictions combo box
|
||||||
|
self.apply_named_search_restriction(db.prefs.get('gui_restriction', ''))
|
||||||
|
|
||||||
def set_window_title(self):
|
def set_window_title(self):
|
||||||
self.setWindowTitle(__appname__ + u' - ||%s||'%self.iactions['Choose Library'].library_name())
|
self.setWindowTitle(__appname__ + u' - ||%s||'%self.iactions['Choose Library'].library_name())
|
||||||
|
@ -609,26 +609,24 @@ class ResultCache(SearchQueryParser):
|
|||||||
self._map.sort(cmp=fcmp, reverse=not ascending)
|
self._map.sort(cmp=fcmp, reverse=not ascending)
|
||||||
self._map_filtered = [id for id in self._map if id in self._map_filtered]
|
self._map_filtered = [id for id in self._map if id in self._map_filtered]
|
||||||
|
|
||||||
def search(self, query, return_matches=False,
|
def search(self, query, return_matches=False):
|
||||||
ignore_search_restriction=False):
|
ans = self.search_getting_ids(query, self.search_restriction)
|
||||||
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]
|
|
||||||
if return_matches:
|
if return_matches:
|
||||||
return ans
|
return ans
|
||||||
self._map_filtered = 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):
|
def set_search_restriction(self, s):
|
||||||
self.search_restriction = s
|
self.search_restriction = s
|
||||||
|
@ -296,6 +296,7 @@ class LibraryDatabase2(LibraryDatabase, SchemaUpgrade, CustomColumns):
|
|||||||
self.book_on_device_func = None
|
self.book_on_device_func = None
|
||||||
self.data = ResultCache(self.FIELD_MAP, self.field_metadata)
|
self.data = ResultCache(self.FIELD_MAP, self.field_metadata)
|
||||||
self.search = self.data.search
|
self.search = self.data.search
|
||||||
|
self.search_getting_ids = self.data.search_getting_ids
|
||||||
self.refresh = functools.partial(self.data.refresh, self)
|
self.refresh = functools.partial(self.data.refresh, self)
|
||||||
self.sort = self.data.sort
|
self.sort = self.data.sort
|
||||||
self.index = self.data.index
|
self.index = self.data.index
|
||||||
|
@ -95,9 +95,19 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache):
|
|||||||
'tools.digest_auth.users' : {opts.username.strip():opts.password.strip()},
|
'tools.digest_auth.users' : {opts.username.strip():opts.password.strip()},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sr = db.prefs.get('cs_restriction', '') if opts.restriction is None \
|
||||||
|
else opts.restriction
|
||||||
|
self.set_search_restriction(sr)
|
||||||
|
|
||||||
self.is_running = False
|
self.is_running = False
|
||||||
self.exception = None
|
self.exception = None
|
||||||
|
|
||||||
|
def set_search_restriction(self, restriction):
|
||||||
|
if restriction:
|
||||||
|
self.search_restriction = 'search:"%s"'%restriction
|
||||||
|
else:
|
||||||
|
self.search_restriction = ''
|
||||||
|
|
||||||
def setup_loggers(self):
|
def setup_loggers(self):
|
||||||
access_file = log_access_file
|
access_file = log_access_file
|
||||||
error_file = log_error_file
|
error_file = log_error_file
|
||||||
|
@ -17,8 +17,7 @@ class Cache(object):
|
|||||||
def search_cache(self, search):
|
def search_cache(self, search):
|
||||||
old = self._search_cache.pop(search, None)
|
old = self._search_cache.pop(search, None)
|
||||||
if old is None or old[0] <= self.db.last_modified():
|
if old is None or old[0] <= self.db.last_modified():
|
||||||
matches = self.db.data.search(search, return_matches=True,
|
matches = self.db.data.search_getting_ids(search, self.search_restriction)
|
||||||
ignore_search_restriction=True)
|
|
||||||
if not matches:
|
if not matches:
|
||||||
matches = []
|
matches = []
|
||||||
self._search_cache[search] = (utcnow(), frozenset(matches))
|
self._search_cache[search] = (utcnow(), frozenset(matches))
|
||||||
|
@ -32,6 +32,10 @@ def option_parser():
|
|||||||
help=_('Write process PID to the specified file'))
|
help=_('Write process PID to the specified file'))
|
||||||
parser.add_option('--daemonize', default=False, action='store_true',
|
parser.add_option('--daemonize', default=False, action='store_true',
|
||||||
help='Run process in background as a daemon. No effect on windows.')
|
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. '
|
||||||
|
'This option overrides any per-library settings specified'
|
||||||
|
' in the GUI'))
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||||
|
@ -181,7 +181,9 @@ class MobileServer(object):
|
|||||||
num = int(num)
|
num = int(num)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
raise cherrypy.HTTPError(400, 'num: %s is not an integer'%num)
|
raise cherrypy.HTTPError(400, 'num: %s is not an integer'%num)
|
||||||
ids = self.db.data.parse(search) if search and search.strip() else self.db.data.universal_set()
|
if not search:
|
||||||
|
search = ''
|
||||||
|
ids = self.db.search_getting_ids(search.strip(), self.search_restriction)
|
||||||
FM = self.db.FIELD_MAP
|
FM = self.db.FIELD_MAP
|
||||||
items = [r for r in iter(self.db) if r[FM['id']] in ids]
|
items = [r for r in iter(self.db) if r[FM['id']] in ids]
|
||||||
if sort is not None:
|
if sort is not None:
|
||||||
|
@ -45,7 +45,10 @@ class XMLServer(object):
|
|||||||
|
|
||||||
order = order.lower().strip() == 'ascending'
|
order = order.lower().strip() == 'ascending'
|
||||||
|
|
||||||
ids = self.db.data.parse(search) if search and search.strip() else self.db.data.universal_set()
|
if not search:
|
||||||
|
search = ''
|
||||||
|
|
||||||
|
ids = self.db.search_getting_ids(search.strip(), self.search_restriction)
|
||||||
|
|
||||||
FM = self.db.FIELD_MAP
|
FM = self.db.FIELD_MAP
|
||||||
|
|
||||||
@ -53,7 +56,6 @@ class XMLServer(object):
|
|||||||
if sort is not None:
|
if sort is not None:
|
||||||
self.sort(items, sort, order)
|
self.sort(items, sort, order)
|
||||||
|
|
||||||
|
|
||||||
books = []
|
books = []
|
||||||
|
|
||||||
def serialize(x):
|
def serialize(x):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user