mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More work on the preferences UI for the new server
This commit is contained in:
parent
7c1b3ce702
commit
968cfcbcc5
@ -1,24 +1,19 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
|
# License: GPLv3 Copyright: 2010, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
__license__ = 'GPL v3'
|
|
||||||
__copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
|
|
||||||
__docformat__ = 'restructuredtext en'
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from PyQt5.Qt import (
|
from PyQt5.Qt import (
|
||||||
QCheckBox, QDialog, QDialogButtonBox, QLabel, QPlainTextEdit, QSize, Qt,
|
QCheckBox, QDialog, QDialogButtonBox, QFormLayout, QHBoxLayout, QLabel,
|
||||||
QTabWidget, QTimer, QUrl, QVBoxLayout, QWidget, pyqtSignal, QHBoxLayout,
|
QPlainTextEdit, QPushButton, QSize, QSpinBox, Qt, QTabWidget, QTimer, QUrl,
|
||||||
QPushButton
|
QVBoxLayout, QWidget, pyqtSignal
|
||||||
)
|
)
|
||||||
|
|
||||||
from calibre import as_unicode
|
from calibre import as_unicode
|
||||||
from calibre.gui2 import (
|
from calibre.gui2 import config, error_dialog, info_dialog, open_url, warning_dialog
|
||||||
Dispatcher, config, error_dialog, info_dialog, open_url, warning_dialog
|
|
||||||
)
|
|
||||||
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
from calibre.gui2.preferences import ConfigWidgetBase, test_widget
|
||||||
from calibre.srv.opts import server_config, options
|
from calibre.srv.opts import change_settings, options, server_config
|
||||||
|
|
||||||
|
|
||||||
class MainTab(QWidget):
|
class MainTab(QWidget):
|
||||||
@ -40,14 +35,25 @@ class MainTab(QWidget):
|
|||||||
la.setWordWrap(True)
|
la.setWordWrap(True)
|
||||||
l.addWidget(la)
|
l.addWidget(la)
|
||||||
l.addSpacing(10)
|
l.addSpacing(10)
|
||||||
|
self.fl = fl = QFormLayout()
|
||||||
|
l.addLayout(fl)
|
||||||
|
self.opt_port = sb = QSpinBox(self)
|
||||||
|
if options['port'].longdoc:
|
||||||
|
sb.setToolTip(options['port'].longdoc)
|
||||||
|
sb.setRange(1, 65535)
|
||||||
|
sb.valueChanged.connect(self.changed_signal.emit)
|
||||||
|
fl.addRow(options['port'].shortdoc + ':', sb)
|
||||||
|
l.addSpacing(25)
|
||||||
self.opt_auth = cb = QCheckBox(_('Require username/password to access the content server'))
|
self.opt_auth = cb = QCheckBox(_('Require username/password to access the content server'))
|
||||||
l.addWidget(cb)
|
l.addWidget(cb)
|
||||||
self.auth_desc = la = QLabel(self)
|
self.auth_desc = la = QLabel(self)
|
||||||
la.setStyleSheet('QLabel { font-size: smaller }')
|
la.setStyleSheet('QLabel { font-size: small; font-style: italic }')
|
||||||
la.setWordWrap(True)
|
la.setWordWrap(True)
|
||||||
|
l.addWidget(la)
|
||||||
l.addSpacing(25)
|
l.addSpacing(25)
|
||||||
self.opt_autolaunch_server = al = QCheckBox(_('Run server &automatically when calibre starts'))
|
self.opt_autolaunch_server = al = QCheckBox(_('Run server &automatically when calibre starts'))
|
||||||
l.addWidget(al)
|
l.addWidget(al)
|
||||||
|
l.addSpacing(25)
|
||||||
self.h = h = QHBoxLayout()
|
self.h = h = QHBoxLayout()
|
||||||
l.addLayout(h)
|
l.addLayout(h)
|
||||||
for text, name in [(_('&Start server'), 'start_server'), (_('St&op server'), 'stop_server'),
|
for text, name in [(_('&Start server'), 'start_server'), (_('St&op server'), 'stop_server'),
|
||||||
@ -58,11 +64,13 @@ class MainTab(QWidget):
|
|||||||
if name == 'show_logs':
|
if name == 'show_logs':
|
||||||
h.addStretch(10)
|
h.addStretch(10)
|
||||||
h.addWidget(b)
|
h.addWidget(b)
|
||||||
|
l.addStretch(10)
|
||||||
|
|
||||||
def genesis(self):
|
def genesis(self):
|
||||||
opts = server_config()
|
opts = server_config()
|
||||||
self.opt_auth.setChecked(opts.auth)
|
self.opt_auth.setChecked(opts.auth)
|
||||||
self.opt_auth.stateChanged.connect(self.auth_changed)
|
self.opt_auth.stateChanged.connect(self.auth_changed)
|
||||||
|
self.opt_port.setValue(opts.port)
|
||||||
self.change_auth_desc()
|
self.change_auth_desc()
|
||||||
self.update_button_state()
|
self.update_button_state()
|
||||||
|
|
||||||
@ -71,8 +79,8 @@ class MainTab(QWidget):
|
|||||||
_('Remember to create some user accounts in the "Users" tab') if self.opt_auth.isChecked() else
|
_('Remember to create some user accounts in the "Users" tab') if self.opt_auth.isChecked() else
|
||||||
_('Requiring a username/password prevents unauthorized people from'
|
_('Requiring a username/password prevents unauthorized people from'
|
||||||
' accessing your calibre library. It is also needed for some features'
|
' accessing your calibre library. It is also needed for some features'
|
||||||
' such as last read position/annotation syncing and making'
|
' such as making any changes to the library as well as'
|
||||||
' changes to the library.')
|
' last read position/annotation syncing.')
|
||||||
)
|
)
|
||||||
|
|
||||||
def auth_changed(self):
|
def auth_changed(self):
|
||||||
@ -80,15 +88,21 @@ class MainTab(QWidget):
|
|||||||
self.change_auth_desc()
|
self.change_auth_desc()
|
||||||
|
|
||||||
def restore_defaults(self):
|
def restore_defaults(self):
|
||||||
self.auth_changed.setChecked(options['auth'].default)
|
self.opt_auth.setChecked(options['auth'].default)
|
||||||
|
self.opt_port.setValue(options['port'].default)
|
||||||
|
|
||||||
def update_button_state(self):
|
def update_button_state(self):
|
||||||
gui = self.parent().gui
|
from calibre.gui2.ui import get_gui
|
||||||
|
gui = get_gui()
|
||||||
is_running = gui.content_server is not None and gui.content_server.is_running
|
is_running = gui.content_server is not None and gui.content_server.is_running
|
||||||
self.start_server_button.setEnabled(not is_running)
|
self.start_server_button.setEnabled(not is_running)
|
||||||
self.stop_server_button.setEnabled(is_running)
|
self.stop_server_button.setEnabled(is_running)
|
||||||
self.test_server_button.setEnabled(is_running)
|
self.test_server_button.setEnabled(is_running)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def settings(self):
|
||||||
|
return {'auth': self.opt_auth.isChecked(), 'port': self.opt_port.value()}
|
||||||
|
|
||||||
|
|
||||||
class ConfigWidget(ConfigWidgetBase):
|
class ConfigWidget(ConfigWidgetBase):
|
||||||
|
|
||||||
@ -97,6 +111,7 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
self.l = l = QVBoxLayout(self)
|
self.l = l = QVBoxLayout(self)
|
||||||
l.setContentsMargins(0, 0, 0, 0)
|
l.setContentsMargins(0, 0, 0, 0)
|
||||||
self.tabs_widget = t = QTabWidget(self)
|
self.tabs_widget = t = QTabWidget(self)
|
||||||
|
l.addWidget(t)
|
||||||
self.main_tab = m = MainTab(self)
|
self.main_tab = m = MainTab(self)
|
||||||
t.addTab(m, _('Main'))
|
t.addTab(m, _('Main'))
|
||||||
m.start_server.connect(self.start_server)
|
m.start_server.connect(self.start_server)
|
||||||
@ -114,7 +129,7 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def server(self):
|
def server(self):
|
||||||
return self.gui.server
|
return self.gui.content_server
|
||||||
|
|
||||||
def restore_defaults(self):
|
def restore_defaults(self):
|
||||||
ConfigWidgetBase.restore_defaults(self)
|
ConfigWidgetBase.restore_defaults(self)
|
||||||
@ -131,14 +146,14 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
r('autolaunch_server', config)
|
r('autolaunch_server', config)
|
||||||
|
|
||||||
def start_server(self):
|
def start_server(self):
|
||||||
ConfigWidgetBase.commit(self)
|
self.save_changes()
|
||||||
self.setCursor(Qt.BusyCursor)
|
self.setCursor(Qt.BusyCursor)
|
||||||
try:
|
try:
|
||||||
self.gui.start_content_server(check_started=False)
|
self.gui.start_content_server(check_started=False)
|
||||||
while (not self.gui.content_server.is_running and
|
while (not self.server.is_running and
|
||||||
self.gui.content_server.exception is None):
|
self.server.exception is None):
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
if self.gui.content_server.exception is not None:
|
if self.server.exception is not None:
|
||||||
error_dialog(self, _('Failed to start content server'),
|
error_dialog(self, _('Failed to start content server'),
|
||||||
as_unicode(self.gui.content_server.exception)).exec_()
|
as_unicode(self.gui.content_server.exception)).exec_()
|
||||||
return
|
return
|
||||||
@ -147,7 +162,7 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
self.unsetCursor()
|
self.unsetCursor()
|
||||||
|
|
||||||
def stop_server(self):
|
def stop_server(self):
|
||||||
self.gui.content_server.threaded_exit()
|
self.server.stop()
|
||||||
self.stopping_msg = info_dialog(self, _('Stopping'),
|
self.stopping_msg = info_dialog(self, _('Stopping'),
|
||||||
_('Stopping server, this could take up to a minute, please wait...'),
|
_('Stopping server, this could take up to a minute, please wait...'),
|
||||||
show_copy_button=False)
|
show_copy_button=False)
|
||||||
@ -155,7 +170,7 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
self.stopping_msg.exec_()
|
self.stopping_msg.exec_()
|
||||||
|
|
||||||
def check_exited(self):
|
def check_exited(self):
|
||||||
if getattr(self.gui.content_server, 'is_running', False):
|
if getattr(self.server, 'is_running', False):
|
||||||
QTimer.singleShot(20, self.check_exited)
|
QTimer.singleShot(20, self.check_exited)
|
||||||
return
|
return
|
||||||
|
|
||||||
@ -164,7 +179,7 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
self.stopping_msg.accept()
|
self.stopping_msg.accept()
|
||||||
|
|
||||||
def test_server(self):
|
def test_server(self):
|
||||||
prefix = unicode(self.opt_url_prefix.text()).strip()
|
prefix = unicode(opt_url_prefix.text()).strip()
|
||||||
open_url(QUrl('http://127.0.0.1:'+str(self.opt_port.value())+prefix))
|
open_url(QUrl('http://127.0.0.1:'+str(self.opt_port.value())+prefix))
|
||||||
|
|
||||||
def view_server_logs(self):
|
def view_server_logs(self):
|
||||||
@ -193,22 +208,26 @@ class ConfigWidget(ConfigWidgetBase):
|
|||||||
bx.accepted.connect(d.accept)
|
bx.accepted.connect(d.accept)
|
||||||
d.show()
|
d.show()
|
||||||
|
|
||||||
def commit(self):
|
def save_changes(self):
|
||||||
ConfigWidgetBase.commit(self)
|
ConfigWidgetBase.commit(self)
|
||||||
|
settings = {}
|
||||||
|
for tab in self.tabs:
|
||||||
|
settings.update(getattr(tab, 'settings', {}))
|
||||||
|
change_settings(**settings)
|
||||||
|
# TODO: validate settings
|
||||||
|
|
||||||
|
def commit(self):
|
||||||
|
self.save_changes()
|
||||||
warning_dialog(self, _('Restart needed'),
|
warning_dialog(self, _('Restart needed'),
|
||||||
_('You need to restart the server for changes to'
|
_('You need to restart the server for changes to'
|
||||||
' take effect'), show=True)
|
' take effect'), show=True)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def refresh_gui(self, gui):
|
def refresh_gui(self, gui):
|
||||||
gui.content_server = self.server
|
pass
|
||||||
if gui.content_server is not None:
|
|
||||||
gui.content_server.state_callback = \
|
|
||||||
Dispatcher(gui.iactions['Connect Share'].content_server_state_changed)
|
|
||||||
gui.content_server.state_callback(gui.content_server.is_running)
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
from PyQt5.Qt import QApplication
|
from calibre.gui2 import Application
|
||||||
app = QApplication([])
|
app = Application([])
|
||||||
test_widget('Sharing', 'Server')
|
test_widget('Sharing', 'Server')
|
||||||
|
@ -266,6 +266,7 @@ def write_config_file(opts, path=DEFAULT_CONFIG):
|
|||||||
lines.append('%s %s' % (name, changed[name]))
|
lines.append('%s %s' % (name, changed[name]))
|
||||||
raw = '\n'.join(lines).encode('utf-8')
|
raw = '\n'.join(lines).encode('utf-8')
|
||||||
with ExclusiveFile(path) as f:
|
with ExclusiveFile(path) as f:
|
||||||
|
f.truncate()
|
||||||
f.write(raw)
|
f.write(raw)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user