mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add entry to Connect/share menu to conveniently stop.start the Content Server
This commit is contained in:
parent
898b61a55e
commit
1834ae8a10
@ -329,6 +329,7 @@ class ShareConnMenu(QMenu): # {{{
|
||||
connect_to_folder = pyqtSignal()
|
||||
connect_to_itunes = pyqtSignal()
|
||||
config_email = pyqtSignal()
|
||||
toggle_server = pyqtSignal()
|
||||
|
||||
def __init__(self, parent=None):
|
||||
QMenu.__init__(self, parent)
|
||||
@ -336,15 +337,27 @@ class ShareConnMenu(QMenu): # {{{
|
||||
mitem.setEnabled(True)
|
||||
mitem.triggered.connect(lambda x : self.connect_to_folder.emit())
|
||||
self.connect_to_folder_action = mitem
|
||||
|
||||
mitem = self.addAction(QIcon(I('devices/itunes.png')),
|
||||
_('Connect to iTunes'))
|
||||
mitem.setEnabled(True)
|
||||
mitem.triggered.connect(lambda x : self.connect_to_itunes.emit())
|
||||
self.connect_to_itunes_action = mitem
|
||||
self.addSeparator()
|
||||
self.toggle_server_action = \
|
||||
self.addAction(QIcon(I('network-server.svg')),
|
||||
_('Start Content Server'))
|
||||
self.toggle_server_action.triggered.connect(lambda x:
|
||||
self.toggle_server.emit())
|
||||
self.addSeparator()
|
||||
|
||||
self.email_actions = []
|
||||
|
||||
def server_state_changed(self, running):
|
||||
text = _('Start Content Server')
|
||||
if running:
|
||||
text = _('Stop Content Server')
|
||||
self.toggle_server_action.setText(text)
|
||||
|
||||
def build_email_entries(self, sync_menu):
|
||||
from calibre.gui2.device import DeviceAction
|
||||
for ac in self.email_actions:
|
||||
@ -478,6 +491,7 @@ class MainWindowMixin(object):
|
||||
self.action_news.triggered.connect(
|
||||
self.scheduler.show_dialog)
|
||||
self.share_conn_menu = ShareConnMenu(self)
|
||||
self.share_conn_menu.toggle_server.connect(self.toggle_content_server)
|
||||
self.share_conn_menu.config_email.connect(partial(self.do_config,
|
||||
initial_category='email'))
|
||||
self.action_conn_share.setMenu(self.share_conn_menu)
|
||||
@ -614,4 +628,12 @@ class MainWindowMixin(object):
|
||||
def show_help(self, *args):
|
||||
open_url(QUrl('http://calibre-ebook.com/user_manual'))
|
||||
|
||||
def content_server_state_changed(self, running):
|
||||
self.share_conn_menu.server_state_changed(running)
|
||||
|
||||
def toggle_content_server(self):
|
||||
if self.content_server is None:
|
||||
self.start_content_server()
|
||||
else:
|
||||
self.content_server.exit()
|
||||
self.content_server = None
|
||||
|
@ -24,7 +24,7 @@ from calibre.ptempfile import PersistentTemporaryFile
|
||||
from calibre.utils.config import prefs, dynamic
|
||||
from calibre.utils.ipc.server import Server
|
||||
from calibre.gui2 import error_dialog, GetMetadata, open_local_file, \
|
||||
gprefs, max_available_height, config, info_dialog
|
||||
gprefs, max_available_height, config, info_dialog, Dispatcher
|
||||
from calibre.gui2.cover_flow import CoverFlowMixin
|
||||
from calibre.gui2.widgets import ProgressIndicator
|
||||
from calibre.gui2.update import UpdateMixin
|
||||
@ -106,6 +106,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
opts = self.opts
|
||||
self.preferences_action, self.quit_action = actions
|
||||
self.library_path = library_path
|
||||
self.content_server = None
|
||||
self.spare_servers = []
|
||||
self.must_restart_before_config = False
|
||||
# Initialize fontconfig in a separate thread as this can be a lengthy
|
||||
@ -146,7 +147,6 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
self.default_thumbnail = None
|
||||
self.tb_wrapper = textwrap.TextWrapper(width=40)
|
||||
self.viewers = collections.deque()
|
||||
self.content_server = None
|
||||
self.system_tray_icon = SystemTrayIcon(QIcon(I('library.png')), self)
|
||||
self.system_tray_icon.setToolTip('calibre')
|
||||
self.system_tray_icon.tooltip_requested.connect(
|
||||
@ -246,11 +246,7 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
|
||||
|
||||
if config['autolaunch_server']:
|
||||
from calibre.library.server.main import start_threaded_server
|
||||
from calibre.library.server import server_config
|
||||
self.content_server = start_threaded_server(
|
||||
db, server_config().parse())
|
||||
self.test_server_timer = QTimer.singleShot(10000, self.test_server)
|
||||
self.start_content_server()
|
||||
|
||||
self.keyboard_interrupt.connect(self.quit, type=Qt.QueuedConnection)
|
||||
AddAction.__init__(self)
|
||||
@ -263,6 +259,15 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
self.library_view.model().delete_books_by_id,
|
||||
type=Qt.QueuedConnection)
|
||||
|
||||
def start_content_server(self):
|
||||
from calibre.library.server.main import start_threaded_server
|
||||
from calibre.library.server import server_config
|
||||
self.content_server = start_threaded_server(
|
||||
self.library_view.model().db, server_config().parse())
|
||||
self.content_server.state_callback = Dispatcher(self.content_server_state_changed)
|
||||
self.content_server.state_callback(True)
|
||||
self.test_server_timer = QTimer.singleShot(10000, self.test_server)
|
||||
|
||||
|
||||
def resizeEvent(self, ev):
|
||||
MainWindow.resizeEvent(self, ev)
|
||||
@ -308,7 +313,8 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
setattr(window, '__systray_minimized', False)
|
||||
|
||||
def test_server(self, *args):
|
||||
if self.content_server.exception is not None:
|
||||
if self.content_server is not None and \
|
||||
self.content_server.exception is not None:
|
||||
error_dialog(self, _('Failed to start content server'),
|
||||
unicode(self.content_server.exception)).exec_()
|
||||
|
||||
@ -367,6 +373,10 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
|
||||
d.exec_()
|
||||
self.content_server = d.server
|
||||
self.content_server.state_callback = \
|
||||
Dispatcher(self.content_server_state_changed)
|
||||
self.content_server.state_callback(self.content_server.is_running)
|
||||
|
||||
if d.result() == d.Accepted:
|
||||
self.read_toolbar_settings()
|
||||
self.search.search_as_you_type(config['search_as_you_type'])
|
||||
@ -583,7 +593,9 @@ class Main(MainWindow, MainWindowMixin, DeviceMixin, # {{{
|
||||
try:
|
||||
try:
|
||||
if self.content_server is not None:
|
||||
self.content_server.exit()
|
||||
s = self.content_server
|
||||
self.content_server = None
|
||||
s.exit()
|
||||
except:
|
||||
pass
|
||||
time.sleep(2)
|
||||
|
@ -64,6 +64,7 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache):
|
||||
break
|
||||
self.opts = opts
|
||||
self.embedded = embedded
|
||||
self.state_callback = None
|
||||
self.max_cover_width, self.max_cover_height = \
|
||||
map(int, self.opts.max_cover.split('x'))
|
||||
path = P('content_server')
|
||||
@ -159,11 +160,22 @@ class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache):
|
||||
import traceback
|
||||
cherrypy.log.error('Failed to stop BonJour:')
|
||||
cherrypy.log.error(traceback.format_exc())
|
||||
try:
|
||||
if callable(self.state_callback):
|
||||
self.state_callback(self.is_running)
|
||||
except:
|
||||
pass
|
||||
|
||||
def exit(self):
|
||||
try:
|
||||
cherrypy.engine.exit()
|
||||
finally:
|
||||
cherrypy.server.httpserver = None
|
||||
self.is_running = False
|
||||
try:
|
||||
if callable(self.state_callback):
|
||||
self.state_callback(self.is_running)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user