calibre-server: Expand environment variables and ~ in the userdb path

Also, exit with a nice error if opening the userdb fails instead of
giving HTTP 500 errors on access.
This commit is contained in:
Kovid Goyal 2018-08-30 07:26:17 +05:30
parent 40302f5b83
commit 07876602aa
No known key found for this signature in database
GPG Key ID: 06BC317B515ACE7C
2 changed files with 18 additions and 9 deletions

View File

@ -10,8 +10,8 @@ import sys
from calibre import as_unicode
from calibre.constants import is_running_from_develop, isosx, iswindows, plugins
from calibre.db.legacy import LibraryDatabase
from calibre.db.delete_service import shutdown as shutdown_delete_service
from calibre.db.legacy import LibraryDatabase
from calibre.srv.bonjour import BonJour
from calibre.srv.handler import Handler
from calibre.srv.http_response import create_http_handler
@ -19,6 +19,7 @@ from calibre.srv.library_broker import load_gui_libraries
from calibre.srv.loop import ServerLoop
from calibre.srv.manage_users_cli import manage_users_cli
from calibre.srv.opts import opts_to_parser
from calibre.srv.users import connect
from calibre.srv.utils import RotatingLog
from calibre.utils.config import prefs
from calibre.utils.localization import localize_user_manual_link
@ -172,6 +173,9 @@ def ensure_single_instance():
def main(args=sys.argv):
opts, args = create_option_parser().parse_args(args)
ensure_single_instance()
if opts.userdb:
opts.userdb = os.path.abspath(os.path.expandvars(os.path.expanduser(opts.userdb)))
connect(opts.userdb, exc_class=SystemExit).close()
if opts.manage_users:
try:
manage_users_cli(opts.userdb)

View File

@ -9,6 +9,7 @@ from threading import RLock
import apsw
from calibre import as_unicode
from calibre.constants import config_dir
from calibre.utils.config import to_json, from_json
@ -68,6 +69,17 @@ def create_user_data(pw, readonly=False, restriction=None):
}
def connect(path, exc_class=ValueError):
try:
return apsw.Connection(path)
except apsw.CantOpenError as e:
pdir = os.path.dirname(path)
if os.path.isdir(pdir):
raise exc_class('Failed to open userdb database at {} with error: {}'.format(path, as_unicode(e)))
os.makedirs(pdir)
return apsw.Connection(path)
class UserManager(object):
lock = RLock()
@ -76,14 +88,7 @@ class UserManager(object):
def conn(self):
with self.lock:
if self._conn is None:
try:
self._conn = apsw.Connection(self.path)
except apsw.CantOpenError:
pdir = os.path.dirname(self.path)
if os.path.isdir(pdir):
raise
os.makedirs(pdir)
self._conn = apsw.Connection(self.path)
self._conn = connect(self.path)
with self._conn:
c = self._conn.cursor()
uv = next(c.execute('PRAGMA user_version'))[0]