From 8d92b5d63442ea4f3b200d3ee1d362d5f66664b4 Mon Sep 17 00:00:00 2001
From: Doug Blank <dblank@cs.brynmawr.edu>
Date: Thu, 21 May 2015 10:51:36 -0400
Subject: [PATCH] Added DbState.open_database() for opening without DbManager

---
 gramps/gen/dbstate.py | 56 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 53 insertions(+), 3 deletions(-)

diff --git a/gramps/gen/dbstate.py b/gramps/gen/dbstate.py
index 9d1ce8071..b232d612e 100644
--- a/gramps/gen/dbstate.py
+++ b/gramps/gen/dbstate.py
@@ -23,6 +23,8 @@
 Provide the database state class
 """
 import sys
+import os
+import io
 
 from .db import DbReadBase
 from .proxy.proxybase import ProxyDbBase
@@ -62,9 +64,10 @@ class DbState(Callback):
         Closes the existing db, and opens a new one.
         Retained for backward compatibility.
         """
-        self.emit('no-database', ())
-        self.db.close()
-        self.change_database_noclose(database)
+        if database:
+            self.emit('no-database', ())
+            self.db.close()
+            self.change_database_noclose(database)
 
     def change_database_noclose(self, database):
         """
@@ -158,6 +161,53 @@ class DbState(Callback):
             database = getattr(mod, pdata.databaseclass)
             return database()
 
+    def open_database(self, dbname, force_unlock=False, callback=None):
+        """
+        Open a database by name and return the database.
+        """
+        data = self.lookup_family_tree(dbname)
+        database = None
+        if data:
+            dbpath, locked, locked_by, backend = data
+            if (not locked) or (locked and force_unlock):
+                database = self.make_database(backend)
+                database.load(dbpath, callback=callback)
+        return database
+
+    def lookup_family_tree(self, dbname):
+        """
+        Find a Family Tree given its name, and return properties.
+        """
+        dbdir = os.path.expanduser(config.get('behavior.database-path'))
+        for dpath in os.listdir(dbdir):
+            dirpath = os.path.join(dbdir, dpath)
+            path_name = os.path.join(dirpath, "name.txt")
+            if os.path.isfile(path_name):
+                file = io.open(path_name, 'r', encoding='utf8')
+                name = file.readline().strip()
+                file.close()
+                if dbname == name:
+                    locked = False
+                    locked_by = None
+                    backend = None
+                    fname = os.path.join(dirpath, "database.txt")
+                    if os.path.isfile(fname):
+                        ifile = io.open(fname, 'r', encoding='utf8')
+                        backend = ifile.read().strip()
+                        ifile.close()
+                    else:
+                        backend = "bsddb"
+                    try:
+                        fname = os.path.join(dirpath, "lock")
+                        ifile = io.open(fname, 'r', encoding='utf8')
+                        locked_by = ifile.read().strip()
+                        locked = True
+                        ifile.close()
+                    except (OSError, IOError):
+                        pass
+                    return (dirpath, locked, locked_by, backend)
+        return None
+
     ## Work-around for databases that need sys refresh (django):
     def modules_is_set(self):
         LOG.info("modules_is_set?")