mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Prevent any of calibre, calibre-server, calibredb from running simultaneously
This commit is contained in:
parent
3e70294279
commit
9965600b3b
@ -90,7 +90,32 @@ def generate_calibredb_help(preamble, app):
|
|||||||
preamble += textwrap.dedent('''
|
preamble += textwrap.dedent('''
|
||||||
|
|
||||||
:command:`calibredb` is the command line interface to the calibre database. It has
|
:command:`calibredb` is the command line interface to the calibre database. It has
|
||||||
several sub-commands, documented below:
|
several sub-commands, documented below.
|
||||||
|
|
||||||
|
:command:`calibredb` can be used to manipulate either a calibre database
|
||||||
|
specified by path or a calibre :guilabel:`Content server` running either on
|
||||||
|
the local machine or over the internet. You can start a calibre
|
||||||
|
:guilabel:`Content server` using either the :command:`calibre-server`
|
||||||
|
program or in the main calibre program click :guilabel:`Connect/share ->
|
||||||
|
Start Content server`. Since :command:`calibredb` can make changes to your
|
||||||
|
calibre libraries, you must setup authentication on the server first. There
|
||||||
|
are two ways to do that:
|
||||||
|
|
||||||
|
* If you plan to connect only to a server running on the same computer,
|
||||||
|
you can simply use the ``--enable-local-write`` option of the
|
||||||
|
content server, to allow any program, including calibredb, running on
|
||||||
|
the local computer to make changes to your calibre data. When running
|
||||||
|
the server from the main calibre program, this option is in
|
||||||
|
:guilabel:`Preferences->Sharing over the net->Advanced`.
|
||||||
|
|
||||||
|
* If you want to enable access over the internet, then you should setup
|
||||||
|
user accounts on the server and use the :option:`--username` and :option:`--password`
|
||||||
|
options to :command:`calibredb` to give it access. You can setup
|
||||||
|
user authentication for :command:`calibre-server` by using the ``--enable-auth``
|
||||||
|
option and using ``--manage-users`` to create the user accounts.
|
||||||
|
If you are running the server from the main calibre program, use
|
||||||
|
:guilabel:`Preferences->Sharing over the net->Require username/password`.
|
||||||
|
|
||||||
|
|
||||||
''')
|
''')
|
||||||
|
|
||||||
|
@ -12,10 +12,12 @@ from urllib import urlencode
|
|||||||
from urlparse import urlparse, urlunparse
|
from urlparse import urlparse, urlunparse
|
||||||
|
|
||||||
from calibre import browser, prints
|
from calibre import browser, prints
|
||||||
from calibre.constants import __appname__, __version__
|
from calibre.constants import __appname__, __version__, iswindows
|
||||||
from calibre.db.cli import module_for_cmd
|
from calibre.db.cli import module_for_cmd
|
||||||
from calibre.db.legacy import LibraryDatabase
|
from calibre.db.legacy import LibraryDatabase
|
||||||
from calibre.utils.config import OptionParser, prefs
|
from calibre.utils.config import OptionParser, prefs
|
||||||
|
from calibre.utils.localization import localize_user_manual_link
|
||||||
|
from calibre.utils.lock import singleinstance
|
||||||
from calibre.utils.serialize import MSGPACK_MIME
|
from calibre.utils.serialize import MSGPACK_MIME
|
||||||
|
|
||||||
COMMANDS = (
|
COMMANDS = (
|
||||||
@ -51,8 +53,8 @@ def run_cmd(cmd, opts, args, dbctx):
|
|||||||
if dbctx.is_remote and getattr(m, 'no_remote', False):
|
if dbctx.is_remote and getattr(m, 'no_remote', False):
|
||||||
raise SystemExit(_('The {} command is not supported with remote (server based) libraries').format(cmd))
|
raise SystemExit(_('The {} command is not supported with remote (server based) libraries').format(cmd))
|
||||||
ret = m.main(opts, args, dbctx)
|
ret = m.main(opts, args, dbctx)
|
||||||
if not dbctx.is_remote and not opts.dont_notify_gui and not getattr(m, 'readonly', False):
|
# if not dbctx.is_remote and not opts.dont_notify_gui and not getattr(m, 'readonly', False):
|
||||||
send_message()
|
# send_message()
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
@ -71,17 +73,11 @@ def get_parser(usage):
|
|||||||
' for example, http://localhost:8080/#mylibrary. library_id is the library id'
|
' for example, http://localhost:8080/#mylibrary. library_id is the library id'
|
||||||
' of the library you want to connect to on the Content server. You can use'
|
' of the library you want to connect to on the Content server. You can use'
|
||||||
' the special library_id value of - to get a list of library ids available'
|
' the special library_id value of - to get a list of library ids available'
|
||||||
' on the server.'
|
' on the server. For details on how to setup access via a Content server, see'
|
||||||
)
|
' {}.'
|
||||||
)
|
).format(localize_user_manual_link(
|
||||||
go.add_option(
|
'https://manual.calibre-ebook.com/generated/en/calibredb.html'
|
||||||
'--dont-notify-gui',
|
))
|
||||||
default=False,
|
|
||||||
action='store_true',
|
|
||||||
help=_(
|
|
||||||
'Do not notify the running calibre GUI (if any) that the database has'
|
|
||||||
' changed. Use with care, as it can lead to database corruption!'
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
go.add_option(
|
go.add_option(
|
||||||
'-h', '--help', help=_('show this help message and exit'), action='help'
|
'-h', '--help', help=_('show this help message and exit'), action='help'
|
||||||
@ -107,7 +103,7 @@ def get_parser(usage):
|
|||||||
|
|
||||||
|
|
||||||
def option_parser():
|
def option_parser():
|
||||||
parser = OptionParser(
|
return get_parser(
|
||||||
_(
|
_(
|
||||||
'''\
|
'''\
|
||||||
%%prog command [options] [arguments]
|
%%prog command [options] [arguments]
|
||||||
@ -121,7 +117,6 @@ For help on an individual command: %%prog command --help
|
|||||||
'''
|
'''
|
||||||
) % '\n '.join(COMMANDS)
|
) % '\n '.join(COMMANDS)
|
||||||
)
|
)
|
||||||
return parser
|
|
||||||
|
|
||||||
|
|
||||||
def read_credetials(opts):
|
def read_credetials(opts):
|
||||||
@ -163,6 +158,16 @@ class DBCtx(object):
|
|||||||
raise SystemExit()
|
raise SystemExit()
|
||||||
else:
|
else:
|
||||||
self.library_path = os.path.expanduser(self.library_path)
|
self.library_path = os.path.expanduser(self.library_path)
|
||||||
|
if not singleinstance('db'):
|
||||||
|
ext = '.exe' if iswindows else ''
|
||||||
|
raise SystemExit(_(
|
||||||
|
'Another calibre program such as {} or the main calibre program is running.'
|
||||||
|
' Having multiple programs that can make changes to a calibre library'
|
||||||
|
' running at the same time is a bad idea. calibredb can connect directly'
|
||||||
|
' to a running calibre content server, to make changes through it, instead.'
|
||||||
|
' See the documentation of the {} option for details.'
|
||||||
|
).format('calibre-server' + ext, '--with-library')
|
||||||
|
)
|
||||||
self._db = None
|
self._db = None
|
||||||
self.is_remote = False
|
self.is_remote = False
|
||||||
|
|
||||||
|
@ -26,6 +26,7 @@ from calibre.gui2.main_window import option_parser as _option_parser
|
|||||||
from calibre.gui2.splash_screen import SplashScreen
|
from calibre.gui2.splash_screen import SplashScreen
|
||||||
from calibre.utils.config import dynamic, prefs
|
from calibre.utils.config import dynamic, prefs
|
||||||
from calibre.utils.ipc import RC, gui_socket_address
|
from calibre.utils.ipc import RC, gui_socket_address
|
||||||
|
from calibre.utils.lock import singleinstance
|
||||||
|
|
||||||
if iswindows:
|
if iswindows:
|
||||||
winutil = plugins['winutil'][0]
|
winutil = plugins['winutil'][0]
|
||||||
@ -364,6 +365,16 @@ def shellquote(s):
|
|||||||
|
|
||||||
|
|
||||||
def run_gui(opts, args, listener, app, gui_debug=None):
|
def run_gui(opts, args, listener, app, gui_debug=None):
|
||||||
|
si = singleinstance('db')
|
||||||
|
if not si:
|
||||||
|
ext = '.exe' if iswindows else ''
|
||||||
|
error_dialog(None, _('Cannot start calibre'), _(
|
||||||
|
'Another calibre program that can modify calibre libraries, such as,'
|
||||||
|
' {} or {} is already running. You must first shut it down, before'
|
||||||
|
' starting the main calibre program. If you are sure no such'
|
||||||
|
' program is running, try restarting your computer.').format(
|
||||||
|
'calibre-server' + ext, 'calibredb' + ext), show=True)
|
||||||
|
return 1
|
||||||
initialize_file_icon_provider()
|
initialize_file_icon_provider()
|
||||||
app.load_builtin_fonts(scan_for_fonts=True)
|
app.load_builtin_fonts(scan_for_fonts=True)
|
||||||
if not dynamic.get('welcome_wizard_was_run', False):
|
if not dynamic.get('welcome_wizard_was_run', False):
|
||||||
@ -462,7 +473,6 @@ def shutdown_other(rc=None):
|
|||||||
if rc.conn is None:
|
if rc.conn is None:
|
||||||
prints(_('No running calibre found'))
|
prints(_('No running calibre found'))
|
||||||
return # No running instance found
|
return # No running instance found
|
||||||
from calibre.utils.lock import singleinstance
|
|
||||||
rc.conn.send('shutdown:')
|
rc.conn.send('shutdown:')
|
||||||
prints(_('Shutdown command sent, waiting for shutdown...'))
|
prints(_('Shutdown command sent, waiting for shutdown...'))
|
||||||
for i in xrange(50):
|
for i in xrange(50):
|
||||||
@ -518,7 +528,6 @@ def main(args=sys.argv):
|
|||||||
except AbortInit:
|
except AbortInit:
|
||||||
return 1
|
return 1
|
||||||
try:
|
try:
|
||||||
from calibre.utils.lock import singleinstance
|
|
||||||
si = singleinstance(singleinstance_name)
|
si = singleinstance(singleinstance_name)
|
||||||
except Exception:
|
except Exception:
|
||||||
error_dialog(None, _('Cannot start calibre'), _(
|
error_dialog(None, _('Cannot start calibre'), _(
|
||||||
|
@ -1,6 +1,3 @@
|
|||||||
Prevent standalone and embedded servers from running simultaneously
|
|
||||||
Prevent more than a single instance of the standalone server from running
|
|
||||||
|
|
||||||
Fix search completion popups
|
Fix search completion popups
|
||||||
Read progress
|
Read progress
|
||||||
Bookmarks/annotations
|
Bookmarks/annotations
|
||||||
|
@ -18,6 +18,7 @@ from calibre.srv.http_response import create_http_handler
|
|||||||
from calibre.srv.handler import Handler
|
from calibre.srv.handler import Handler
|
||||||
from calibre.srv.utils import RotatingLog
|
from calibre.srv.utils import RotatingLog
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
|
from calibre.utils.lock import singleinstance
|
||||||
from calibre.db.legacy import LibraryDatabase
|
from calibre.db.legacy import LibraryDatabase
|
||||||
|
|
||||||
|
|
||||||
@ -297,6 +298,15 @@ def main(args=sys.argv):
|
|||||||
raise SystemExit(_('You must specify at least one calibre library'))
|
raise SystemExit(_('You must specify at least one calibre library'))
|
||||||
libraries=[prefs['library_path']]
|
libraries=[prefs['library_path']]
|
||||||
|
|
||||||
|
if not singleinstance('db'):
|
||||||
|
ext = '.exe' if iswindows else ''
|
||||||
|
raise SystemExit(_(
|
||||||
|
'Another calibre program such as another instance of {} or the main'
|
||||||
|
' calibre program is running. Having multiple programs that can make'
|
||||||
|
' changes to a calibre library running at the same time is not supported.'
|
||||||
|
).format('calibre-server' + ext)
|
||||||
|
)
|
||||||
|
|
||||||
if opts.auto_reload:
|
if opts.auto_reload:
|
||||||
if opts.daemonize:
|
if opts.daemonize:
|
||||||
raise SystemExit('Cannot specify --auto-reload and --daemonize at the same time')
|
raise SystemExit('Cannot specify --auto-reload and --daemonize at the same time')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user