mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
pep8
This commit is contained in:
parent
775a946ac3
commit
d983025899
@ -1,7 +1,6 @@
|
|||||||
#!/usr/bin/env python2
|
#!/usr/bin/env python2
|
||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
from __future__ import (unicode_literals, division, absolute_import,
|
from __future__ import (unicode_literals, division, absolute_import, print_function)
|
||||||
print_function)
|
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
__copyright__ = '2015, Kovid Goyal <kovid at kovidgoyal.net>'
|
||||||
@ -49,6 +48,8 @@ def daemonize(): # {{{
|
|||||||
|
|
||||||
# Redirect standard file descriptors.
|
# Redirect standard file descriptors.
|
||||||
plugins['speedup'][0].detach(os.devnull)
|
plugins['speedup'][0].detach(os.devnull)
|
||||||
|
|
||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
@ -65,7 +66,12 @@ class Server(object):
|
|||||||
plugins = []
|
plugins = []
|
||||||
if opts.use_bonjour:
|
if opts.use_bonjour:
|
||||||
plugins.append(BonJour())
|
plugins.append(BonJour())
|
||||||
self.loop = ServerLoop(create_http_handler(self.handler.dispatch), opts=opts, log=log, access_log=access_log, plugins=plugins)
|
self.loop = ServerLoop(
|
||||||
|
create_http_handler(self.handler.dispatch),
|
||||||
|
opts=opts,
|
||||||
|
log=log,
|
||||||
|
access_log=access_log,
|
||||||
|
plugins=plugins)
|
||||||
self.handler.set_log(self.loop.log)
|
self.handler.set_log(self.loop.log)
|
||||||
self.handler.set_jobs_manager(self.loop.jobs_manager)
|
self.handler.set_jobs_manager(self.loop.jobs_manager)
|
||||||
self.serve_forever = self.loop.serve_forever
|
self.serve_forever = self.loop.serve_forever
|
||||||
@ -74,6 +80,7 @@ class Server(object):
|
|||||||
from calibre.utils.rapydscript import compile_srv
|
from calibre.utils.rapydscript import compile_srv
|
||||||
compile_srv()
|
compile_srv()
|
||||||
|
|
||||||
|
|
||||||
# Manage users CLI {{{
|
# Manage users CLI {{{
|
||||||
|
|
||||||
|
|
||||||
@ -86,7 +93,8 @@ def manage_users(path=None):
|
|||||||
prints(prompt, end=' ')
|
prints(prompt, end=' ')
|
||||||
return raw_input().decode(enc)
|
return raw_input().decode(enc)
|
||||||
|
|
||||||
def choice(question=_('What do you want to do?'), choices=(), default=None, banner=''):
|
def choice(
|
||||||
|
question=_('What do you want to do?'), choices=(), default=None, banner=''):
|
||||||
prints(banner)
|
prints(banner)
|
||||||
for i, choice in enumerate(choices):
|
for i, choice in enumerate(choices):
|
||||||
prints('%d)' % (i + 1), choice)
|
prints('%d)' % (i + 1), choice)
|
||||||
@ -94,7 +102,8 @@ def manage_users(path=None):
|
|||||||
while True:
|
while True:
|
||||||
prompt = question + ' [1-%d]:' % len(choices)
|
prompt = question + ' [1-%d]:' % len(choices)
|
||||||
if default is not None:
|
if default is not None:
|
||||||
prompt = question + ' [1-%d %s: %d]' % (len(choices), _('default'), default+1)
|
prompt = question + ' [1-%d %s: %d]' % (
|
||||||
|
len(choices), _('default'), default + 1)
|
||||||
reply = get_input(prompt)
|
reply = get_input(prompt)
|
||||||
if not reply and default is not None:
|
if not reply and default is not None:
|
||||||
reply = str(default + 1)
|
reply = str(default + 1)
|
||||||
@ -128,16 +137,20 @@ def manage_users(path=None):
|
|||||||
def validate(username):
|
def validate(username):
|
||||||
if not m.has_user(username):
|
if not m.has_user(username):
|
||||||
return _('The username %s does not exist') % username
|
return _('The username %s does not exist') % username
|
||||||
|
|
||||||
return get_valid(_('Enter the username'), validate)
|
return get_valid(_('Enter the username'), validate)
|
||||||
|
|
||||||
def get_pass(username):
|
def get_pass(username):
|
||||||
while True:
|
while True:
|
||||||
from getpass import getpass
|
from getpass import getpass
|
||||||
one = getpass(_('Enter the new password for %s: ') % username).decode(enc)
|
one = getpass(
|
||||||
|
_('Enter the new password for %s: ') % username).decode(enc)
|
||||||
if not one:
|
if not one:
|
||||||
prints(_('Empty passwords are not allowed'))
|
prints(_('Empty passwords are not allowed'))
|
||||||
continue
|
continue
|
||||||
two = getpass(_('Re-enter the new password for %s, to verify: ') % username).decode(enc)
|
two = getpass(
|
||||||
|
_('Re-enter the new password for %s, to verify: ') % username
|
||||||
|
).decode(enc)
|
||||||
if one != two:
|
if one != two:
|
||||||
prints(_('Passwords do not match'))
|
prints(_('Passwords do not match'))
|
||||||
continue
|
continue
|
||||||
@ -154,7 +167,8 @@ def manage_users(path=None):
|
|||||||
|
|
||||||
def remove_user():
|
def remove_user():
|
||||||
un = get_valid_user()
|
un = get_valid_user()
|
||||||
if get_input((_('Are you sure you want to remove the user %s?') % un) + ' [y/n]:') != 'y':
|
if get_input((_('Are you sure you want to remove the user %s?') % un) +
|
||||||
|
' [y/n]:') != 'y':
|
||||||
raise SystemExit(0)
|
raise SystemExit(0)
|
||||||
m.remove_user(un)
|
m.remove_user(un)
|
||||||
prints(_('User %s successfully removed!') % un)
|
prints(_('User %s successfully removed!') % un)
|
||||||
@ -182,20 +196,27 @@ def manage_users(path=None):
|
|||||||
if r is None:
|
if r is None:
|
||||||
raise SystemExit('The user {} does not exist'.format(username))
|
raise SystemExit('The user {} does not exist'.format(username))
|
||||||
if r['allowed_library_names']:
|
if r['allowed_library_names']:
|
||||||
prints(_('{} is currently only allowed to access the libraries named: {}').format(
|
prints(
|
||||||
username, ', '.join(r['allowed_library_names'])))
|
_('{} is currently only allowed to access the libraries named: {}')
|
||||||
|
.format(username, ', '.join(r['allowed_library_names'])))
|
||||||
if r['blocked_library_names']:
|
if r['blocked_library_names']:
|
||||||
prints(_('{} is currently not allowed to access the libraries named: {}').format(
|
prints(
|
||||||
username, ', '.join(r['blocked_library_names'])))
|
_('{} is currently not allowed to access the libraries named: {}')
|
||||||
|
.format(username, ', '.join(r['blocked_library_names'])))
|
||||||
if r['library_restrictions']:
|
if r['library_restrictions']:
|
||||||
prints(_('{} has the following additional per-library restrictions:').format(username))
|
prints(
|
||||||
|
_('{} has the following additional per-library restrictions:')
|
||||||
|
.format(username))
|
||||||
for k, v in r['library_restrictions'].iteritems():
|
for k, v in r['library_restrictions'].iteritems():
|
||||||
prints(k + ':', v)
|
prints(k + ':', v)
|
||||||
else:
|
else:
|
||||||
prints(_('{} has the no additional per-library restrictions'))
|
prints(_('{} has the no additional per-library restrictions'))
|
||||||
c = choice(choices=[
|
c = choice(
|
||||||
_('Allow access to all libraries'), _('Allow access to only specified libraries'),
|
choices=[
|
||||||
_('Allow access to all, except specified libraries'), _('Change per-library restrictions'),
|
_('Allow access to all libraries'),
|
||||||
|
_('Allow access to only specified libraries'),
|
||||||
|
_('Allow access to all, except specified libraries'),
|
||||||
|
_('Change per-library restrictions'),
|
||||||
_('Cancel')])
|
_('Cancel')])
|
||||||
if c == 0:
|
if c == 0:
|
||||||
m.update_user_restrictions(username, {})
|
m.update_user_restrictions(username, {})
|
||||||
@ -204,7 +225,9 @@ def manage_users(path=None):
|
|||||||
library = get_input(_('Enter the name of the library:'))
|
library = get_input(_('Enter the name of the library:'))
|
||||||
if not library:
|
if not library:
|
||||||
break
|
break
|
||||||
prints(_('Enter a search expression, access will be granted only to books matching this expression.'
|
prints(
|
||||||
|
_(
|
||||||
|
'Enter a search expression, access will be granted only to books matching this expression.'
|
||||||
' An empty expression will grant access to all books.'))
|
' An empty expression will grant access to all books.'))
|
||||||
plr = get_input(_('Search expression:'))
|
plr = get_input(_('Search expression:'))
|
||||||
if plr:
|
if plr:
|
||||||
@ -227,25 +250,37 @@ def manage_users(path=None):
|
|||||||
|
|
||||||
def edit_user(username=None):
|
def edit_user(username=None):
|
||||||
username = username or get_valid_user()
|
username = username or get_valid_user()
|
||||||
c = choice(choices=[
|
c = choice(
|
||||||
|
choices=[
|
||||||
_('Show password for {}').format(username),
|
_('Show password for {}').format(username),
|
||||||
_('Change password for {}').format(username),
|
_('Change password for {}').format(username),
|
||||||
_('Change read/write permission for {}').format(username),
|
_('Change read/write permission for {}').format(username),
|
||||||
_('Change the libraries {} is allowed to access').format(username),
|
_('Change the libraries {} is allowed to access').format(username),
|
||||||
_('Cancel'),
|
_('Cancel'), ],
|
||||||
], banner='\n' + _('{} has {} access').format(
|
banner='\n' + _('{} has {} access').format(
|
||||||
username, _('readonly') if m.is_readonly(username) else _('read-write'))
|
username,
|
||||||
)
|
_('readonly') if m.is_readonly(username) else _('read-write')))
|
||||||
print()
|
print()
|
||||||
if c > 3:
|
if c > 3:
|
||||||
actions.append(toplevel)
|
actions.append(toplevel)
|
||||||
return
|
return
|
||||||
{0: show_password, 1: change_password, 2: change_readonly, 3: change_restriction}[c](username)
|
{
|
||||||
|
0: show_password,
|
||||||
|
1: change_password,
|
||||||
|
2: change_readonly,
|
||||||
|
3: change_restriction}[c](username)
|
||||||
actions.append(partial(edit_user, username=username))
|
actions.append(partial(edit_user, username=username))
|
||||||
|
|
||||||
def toplevel():
|
def toplevel():
|
||||||
{0:add_user, 1:edit_user, 2:remove_user, 3:lambda: None}[choice(choices=[
|
{
|
||||||
_('Add a new user'), _('Edit an existing user'), _('Remove a user'),
|
0: add_user,
|
||||||
|
1: edit_user,
|
||||||
|
2: remove_user,
|
||||||
|
3: lambda: None}[choice(
|
||||||
|
choices=[
|
||||||
|
_('Add a new user'),
|
||||||
|
_('Edit an existing user'),
|
||||||
|
_('Remove a user'),
|
||||||
_('Cancel')])]()
|
_('Cancel')])]()
|
||||||
|
|
||||||
actions = [toplevel]
|
actions = [toplevel]
|
||||||
@ -256,46 +291,63 @@ def manage_users(path=None):
|
|||||||
|
|
||||||
# }}}
|
# }}}
|
||||||
|
|
||||||
|
|
||||||
def create_option_parser():
|
def create_option_parser():
|
||||||
parser=opts_to_parser('%prog '+ _(
|
parser = opts_to_parser(
|
||||||
|
'%prog ' + _(
|
||||||
'''[options] [path to library folder...]
|
'''[options] [path to library folder...]
|
||||||
|
|
||||||
Start the calibre Content server. The calibre Content server exposes your
|
Start the calibre Content server. The calibre Content server exposes your
|
||||||
calibre libraries over the internet. You can specify the path to the library
|
calibre libraries over the internet. You can specify the path to the library
|
||||||
folders as arguments to %prog. If you do not specify any paths, all the
|
folders as arguments to %prog. If you do not specify any paths, all the
|
||||||
libraries that the main calibre program knows about will be used.
|
libraries that the main calibre program knows about will be used.
|
||||||
'''
|
'''))
|
||||||
|
parser.add_option(
|
||||||
|
'--log',
|
||||||
|
default=None,
|
||||||
|
help=_(
|
||||||
|
'Path to log file for server log. This log contains server information and errors, not access logs. By default it is written to stdout.'
|
||||||
))
|
))
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'--log', default=None,
|
'--access-log',
|
||||||
help=_('Path to log file for server log. This log contains server information and errors, not access logs. By default it is written to stdout.'))
|
default=None,
|
||||||
parser.add_option(
|
help=_(
|
||||||
'--access-log', default=None,
|
'Path to the access log file. This log contains information'
|
||||||
help=_('Path to the access log file. This log contains information'
|
|
||||||
' about clients connecting to the server and making requests. By'
|
' about clients connecting to the server and making requests. By'
|
||||||
' default no access logging is done.'))
|
' default no access logging is done.'))
|
||||||
if not iswindows and not isosx:
|
if not iswindows and not isosx:
|
||||||
# Does not work on macOS because if we fork() we cannot connect to Core
|
# Does not work on macOS because if we fork() we cannot connect to Core
|
||||||
# Serives which is needed by the QApplication() constructor, which in
|
# Serives which is needed by the QApplication() constructor, which in
|
||||||
# turn is needed by ensure_app()
|
# turn is needed by ensure_app()
|
||||||
parser.add_option('--daemonize', default=False, action='store_true',
|
|
||||||
help=_('Run process in background as a daemon.'))
|
|
||||||
parser.add_option('--pidfile', default=None,
|
|
||||||
help=_('Write process PID to the specified file'))
|
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'--auto-reload', default=False, action='store_true',
|
'--daemonize',
|
||||||
help=_('Automatically reload server when source code changes. Useful'
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help=_('Run process in background as a daemon.'))
|
||||||
|
parser.add_option(
|
||||||
|
'--pidfile', default=None, help=_('Write process PID to the specified file'))
|
||||||
|
parser.add_option(
|
||||||
|
'--auto-reload',
|
||||||
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help=_(
|
||||||
|
'Automatically reload server when source code changes. Useful'
|
||||||
' for development. You should also specify a small value for the'
|
' for development. You should also specify a small value for the'
|
||||||
' shutdown timeout.'))
|
' shutdown timeout.'))
|
||||||
parser.add_option(
|
parser.add_option(
|
||||||
'--manage-users', default=False, action='store_true',
|
'--manage-users',
|
||||||
help=_('Manage the database of users allowed to connect to this server.'
|
default=False,
|
||||||
|
action='store_true',
|
||||||
|
help=_(
|
||||||
|
'Manage the database of users allowed to connect to this server.'
|
||||||
' See also the %s option.') % '--userdb')
|
' See also the %s option.') % '--userdb')
|
||||||
parser.get_option('--userdb').help = _(
|
parser.get_option('--userdb').help = _(
|
||||||
'Path to the user database to use for authentication. The database'
|
'Path to the user database to use for authentication. The database'
|
||||||
' is a SQLite file. To create it use {0}. You can read more'
|
' is a SQLite file. To create it use {0}. You can read more'
|
||||||
' about managing users at: {1}').format(
|
' about managing users at: {1}'
|
||||||
'--manage-users', localize_user_manual_link(
|
).format(
|
||||||
|
'--manage-users',
|
||||||
|
localize_user_manual_link(
|
||||||
'https://manual.calibre-ebook.com/server.html#managing-user-accounts-from-the-command-line-only'
|
'https://manual.calibre-ebook.com/server.html#managing-user-accounts-from-the-command-line-only'
|
||||||
))
|
))
|
||||||
|
|
||||||
@ -308,12 +360,12 @@ option_parser = create_option_parser
|
|||||||
def ensure_single_instance():
|
def ensure_single_instance():
|
||||||
if b'CALIBRE_NO_SI_DANGER_DANGER' not in os.environ and not singleinstance('db'):
|
if b'CALIBRE_NO_SI_DANGER_DANGER' not in os.environ and not singleinstance('db'):
|
||||||
ext = '.exe' if iswindows else ''
|
ext = '.exe' if iswindows else ''
|
||||||
raise SystemExit(_(
|
raise SystemExit(
|
||||||
|
_(
|
||||||
'Another calibre program such as another instance of {} or the main'
|
'Another calibre program such as another instance of {} or the main'
|
||||||
' calibre program is running. Having multiple programs that can make'
|
' calibre program is running. Having multiple programs that can make'
|
||||||
' changes to a calibre library running at the same time is not supported.'
|
' changes to a calibre library running at the same time is not supported.'
|
||||||
).format('calibre-server' + ext)
|
).format('calibre-server' + ext))
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
@ -338,7 +390,8 @@ def main(args=sys.argv):
|
|||||||
|
|
||||||
if opts.auto_reload:
|
if opts.auto_reload:
|
||||||
if getattr(opts, 'daemonize', False):
|
if getattr(opts, 'daemonize', False):
|
||||||
raise SystemExit('Cannot specify --auto-reload and --daemonize at the same time')
|
raise SystemExit(
|
||||||
|
'Cannot specify --auto-reload and --daemonize at the same time')
|
||||||
from calibre.srv.auto_reload import auto_reload, NoAutoReload
|
from calibre.srv.auto_reload import auto_reload, NoAutoReload
|
||||||
try:
|
try:
|
||||||
from calibre.utils.logging import default_log
|
from calibre.utils.logging import default_log
|
||||||
@ -350,7 +403,9 @@ def main(args=sys.argv):
|
|||||||
server = Server(libraries, opts)
|
server = Server(libraries, opts)
|
||||||
if getattr(opts, 'daemonize', False):
|
if getattr(opts, 'daemonize', False):
|
||||||
if not opts.log and not iswindows:
|
if not opts.log and not iswindows:
|
||||||
raise SystemExit('In order to daemonize you must specify a log file, you can use /dev/stdout to log to screen even as a daemon')
|
raise SystemExit(
|
||||||
|
'In order to daemonize you must specify a log file, you can use /dev/stdout to log to screen even as a daemon'
|
||||||
|
)
|
||||||
daemonize()
|
daemonize()
|
||||||
if opts.pidfile:
|
if opts.pidfile:
|
||||||
with lopen(opts.pidfile, 'wb') as f:
|
with lopen(opts.pidfile, 'wb') as f:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user