Skip to content

Commit

Permalink
Optionally ignore lock file (#458)
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidMStraub authored Nov 19, 2023
1 parent 70a1f48 commit a59cf27
Show file tree
Hide file tree
Showing 7 changed files with 59 additions and 22 deletions.
9 changes: 6 additions & 3 deletions gramps_webapi/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,11 @@
import click
from whoosh.index import LockError


from .api.util import get_db_manager, get_search_indexer, list_trees
from .dbmanager import WebDbManager
from .app import create_app
from .auth import add_user, delete_user, fill_tree, user_db
from .const import ENV_CONFIG_FILE, TREE_MULTI
from .dbmanager import WebDbManager

logging.basicConfig()
LOG = logging.getLogger("gramps_webapi")
Expand Down Expand Up @@ -128,7 +127,11 @@ def search(ctx, tree):
if app.config["TREE"] == TREE_MULTI:
raise ValueError("`tree` is required when multi-tree support is enabled.")
# needed for backwards compatibility!
dbmgr = WebDbManager(name=app.config["TREE"], create_if_missing=False)
dbmgr = WebDbManager(
name=app.config["TREE"],
create_if_missing=False,
ignore_lock=app.config["IGNORE_DB_LOCK"],
)
tree = dbmgr.dirname
with app.app_context():
ctx.obj["db_manager"] = get_db_manager(tree=tree)
Expand Down
14 changes: 11 additions & 3 deletions gramps_webapi/api/resources/trees.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,11 @@
def get_tree_details(tree_id: str) -> Dict[str, str]:
"""Get details about a tree."""
try:
dbmgr = WebDbManager(dirname=tree_id, create_if_missing=False)
dbmgr = WebDbManager(
dirname=tree_id,
create_if_missing=False,
ignore_lock=current_app.config["IGNORE_DB_LOCK"],
)
except ValueError:
abort(404)
usage = get_tree_usage(tree_id) or {}
Expand Down Expand Up @@ -100,7 +104,7 @@ def post(self, args):
require_permissions([PERM_ADD_TREE])
tree_id = str(uuid.uuid4())
backend = current_app.config["NEW_DB_BACKEND"]
dbmgr = WebDbManager(
WebDbManager(
dirname=tree_id,
name=args["name"],
create_if_missing=True,
Expand Down Expand Up @@ -153,7 +157,11 @@ def put(self, args, tree_id: str):
require_permissions([PERM_EDIT_OTHER_TREE])
validate_tree_id(tree_id)
try:
dbmgr = WebDbManager(dirname=tree_id, create_if_missing=False)
dbmgr = WebDbManager(
dirname=tree_id,
create_if_missing=False,
ignore_lock=current_app.config["IGNORE_DB_LOCK"],
)
except ValueError:
abort(404)
rv = {}
Expand Down
19 changes: 12 additions & 7 deletions gramps_webapi/api/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@
from gramps.gen.const import GRAMPS_LOCALE
from gramps.gen.db.base import DbReadBase
from gramps.gen.db.dbconst import (
CITATION_KEY,
DBBACKEND,
KEY_TO_NAME_MAP,
PERSON_KEY,
FAMILY_KEY,
SOURCE_KEY,
EVENT_KEY,
FAMILY_KEY,
KEY_TO_NAME_MAP,
MEDIA_KEY,
NOTE_KEY,
PERSON_KEY,
PLACE_KEY,
REPOSITORY_KEY,
NOTE_KEY,
CITATION_KEY,
SOURCE_KEY,
)
from gramps.gen.dbstate import DbState
from gramps.gen.errors import HandleError
Expand Down Expand Up @@ -254,6 +254,7 @@ def get_db_manager(tree: Optional[str]) -> WebDbManager:
username=current_app.config["POSTGRES_USER"],
password=current_app.config["POSTGRES_PASSWORD"],
create_if_missing=False,
ignore_lock=current_app.config["IGNORE_DB_LOCK"],
)


Expand Down Expand Up @@ -472,7 +473,11 @@ def get_tree_id(guid: str) -> str:
# multi-tree support enabled but user has no tree ID: forbidden!
abort_with_message(403, "Forbidden")
# needed for backwards compatibility: single-tree mode but user without tree ID
dbmgr = WebDbManager(name=current_app.config["TREE"], create_if_missing=False)
dbmgr = WebDbManager(
name=current_app.config["TREE"],
create_if_missing=False,
ignore_lock=current_app.config["IGNORE_DB_LOCK"],
)
tree_id = dbmgr.dirname
return tree_id

Expand Down
6 changes: 5 additions & 1 deletion gramps_webapi/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,11 @@ def create_app(config: Optional[Dict[str, Any]] = None):

if app.config["TREE"] != TREE_MULTI:
# create database if missing (only in single-tree mode)
WebDbManager(name=app.config["TREE"], create_if_missing=True)
WebDbManager(
name=app.config["TREE"],
create_if_missing=True,
ignore_lock=app.config["IGNORE_DB_LOCK"],
)

if app.config["TREE"] == TREE_MULTI and not app.config["MEDIA_PREFIX_TREE"]:
warnings.warn(
Expand Down
1 change: 1 addition & 0 deletions gramps_webapi/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class DefaultConfig(object):
POSTGRES_PASSWORD = None
POSTGRES_HOST = "localhost"
POSTGRES_PORT = "5432"
IGNORE_DB_LOCK = False
CELERY_CONFIG: Dict[str, str] = {}
MEDIA_BASE_DIR = ""
MEDIA_PREFIX_TREE = False
Expand Down
13 changes: 10 additions & 3 deletions gramps_webapi/dbloader.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
from gramps.gen.recentfiles import recent_files
from gramps.gen.utils.config import get_researcher


_ = glocale.translation.gettext

LOG = logging.getLogger(__name__)
Expand Down Expand Up @@ -106,9 +105,17 @@ def read_file(self, filename, mode: str, username: str, password: str):
# set readonly correctly again
self.dbstate.db.readonly = mode == DBMODE_R

def open_activate(self, filename, mode, username=None, password=None):
def open_activate(
self,
filename,
mode,
username=None,
password=None,
ignore_lock: bool = False,
):
"""Open and make a family tree active."""
check_lock(dir_name=filename, mode=mode)
if not ignore_lock:
check_lock(dir_name=filename, mode=mode)
self.read_file(filename, mode, username, password)
# Attempt to figure out the database title
title = get_title(filename)
Expand Down
19 changes: 14 additions & 5 deletions gramps_webapi/dbmanager.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,13 @@

import os
import uuid

from typing import Optional, Tuple

from gramps.cli.clidbman import CLIDbManager, NAME_FILE
from gramps.cli.clidbman import NAME_FILE, CLIDbManager
from gramps.cli.user import User
from gramps.gen.config import config
from gramps.gen.db.dbconst import DBBACKEND, DBLOCKFN, DBMODE_R, DBMODE_W
from gramps.gen.db.utils import make_database, get_dbid_from_path
from gramps.gen.db.utils import get_dbid_from_path, make_database
from gramps.gen.dbstate import DbState

from .dbloader import WebDbSessionManager
Expand All @@ -51,6 +50,7 @@ def __init__(
password: Optional[str] = None,
create_if_missing: bool = True,
create_backend: str = "sqlite",
ignore_lock: bool = False,
) -> None:
"""Initialize given a family tree name or subdirectory name (path)."""
if dirname:
Expand All @@ -67,6 +67,7 @@ def __init__(
self.password = password
self.create_if_missing = create_if_missing
self.create_backend = create_backend
self.ignore_lock = ignore_lock
self.path = self._get_path()
self._check_backend()

Expand Down Expand Up @@ -154,7 +155,11 @@ def break_lock(self) -> None:
if os.path.exists(os.path.join(self.path, DBLOCKFN)):
os.unlink(os.path.join(self.path, DBLOCKFN))

def get_db(self, readonly: bool = True, force_unlock: bool = False) -> DbState:
def get_db(
self,
readonly: bool = True,
force_unlock: bool = False,
) -> DbState:
"""Open the database and return a dbstate instance.
If `readonly` is `True` (default), write operations will fail (note,
Expand All @@ -170,7 +175,11 @@ def get_db(self, readonly: bool = True, force_unlock: bool = False) -> DbState:
self.break_lock()
mode = DBMODE_R if readonly else DBMODE_W
smgr.open_activate(
self.path, mode=mode, username=self.username, password=self.password
self.path,
mode=mode,
username=self.username,
password=self.password,
ignore_lock=self.ignore_lock,
)
return dbstate

Expand Down

0 comments on commit a59cf27

Please sign in to comment.