Browse Source

wxGUI/startup: Create grassdata automatically during the first GUI startup (#705)

New function for a grassdata directory in the default path for user's platform was created.

MS Windows is the special case and follows what the current installer does on Windows,
i.e., use Documents which should exist on all modern versions.
Linux, macOS etc. use home dir directly.

A temporary directory is used as a fallback for extreme, but real, cases when the home directory is not writable because this may happen in try-GRASS-GIS-online cases which is one of the cases when we want grassdata to be created automatically.  

Closes #682.
Linda Kladivova 4 years ago
parent
commit
4b6d5f4f89
2 changed files with 56 additions and 1 deletions
  1. 6 1
      gui/wxpython/gis_set.py
  2. 50 0
      gui/wxpython/startup/utils.py

+ 6 - 1
gui/wxpython/gis_set.py

@@ -38,7 +38,8 @@ import wx.lib.mixins.listctrl as listmix
 from core.gcmd import GMessage, GError, DecodeString, RunCommand
 from core.utils import GetListOfLocations, GetListOfMapsets
 from startup.utils import (
-    get_lockfile_if_present, get_possible_database_path, create_mapset)
+    get_lockfile_if_present, get_possible_database_path,
+    create_database_directory, create_mapset)
 import startup.utils as sutils
 from startup.guiutils import SetSessionMapset, NewMapsetDialog
 import startup.guiutils as sgui
@@ -507,6 +508,10 @@ class GRASSStartup(wx.Frame):
         if self.GetRCValue("LOCATION_NAME") != "<UNKNOWN>":
             return
         path = get_possible_database_path()
+        # If nothing found, try to create GRASS directory
+        if path is None:
+            path = create_database_directory()
+
         if path:
             try:
                 self.tgisdbase.SetValue(path)

+ 50 - 0
gui/wxpython/startup/utils.py

@@ -18,6 +18,9 @@ solve the errors etc. in a general manner).
 
 import os
 import shutil
+import tempfile
+import getpass
+import sys
 
 
 def get_possible_database_path():
@@ -43,6 +46,53 @@ def get_possible_database_path():
     return None
 
 
+def create_database_directory():
+    """Creates the standard GRASS GIS directory.
+
+    Creates database directory named grassdata in the standard location 
+    according to the platform.
+
+    Returns the new path as a string or None if nothing was found or created.
+    """
+    home = os.path.expanduser('~')
+
+    # Determine the standard path according to the platform
+    if sys.platform == 'win32':
+        path = os.path.join(home, "Documents", "grassdata")
+    else:
+        path = os.path.join(home, "grassdata")
+
+    # Create "grassdata" directory
+    try:
+        os.mkdir(path)
+        return path
+    except OSError:
+        pass
+
+    # Create a temporary "grassdata" directory if GRASS is running
+    # in some special environment and the standard directories
+    # cannot be created which might be the case in some "try out GRASS"
+    # use cases.
+    path = os.path.join(
+        tempfile.gettempdir(),
+        "grassdata_{}".format(getpass.getuser())
+    )
+
+    # The created tmp is not cleaned by GRASS, so we are relying on
+    # the system to do it at some point. The positive outcome is that
+    # another GRASS instance will find the data created by the first
+    # one which is desired in the "try out GRASS" use case we are
+    # aiming towards."
+    if os.path.exists(path):
+        return path
+    try:
+        os.mkdir(path)
+        return path
+    except OSError:
+        pass
+
+    return None
+
 def get_lockfile_if_present(database, location, mapset):
     """Return path to lock if present, None otherwise