Add entry to Connect/share menu to conveniently stop.start the Content Server

This commit is contained in:
Kovid Goyal 2010-07-30 13:49:55 -06:00
parent 898b61a55e
commit 1834ae8a10
3 changed files with 56 additions and 10 deletions

View File

@ -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

View File

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

View File

@ -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