Sfoglia il codice sorgente

init: Create demolocation in grass.py, not wxGUI gis_set.py (#1208)

* Moves functionality from gis_set.py to grass.py.
* Moves library functions from wxGUI startup to new grass.app package.
* Opens the old startup when the PERMANENT of demolocation is not usable (as before).
Vaclav Petras 4 anni fa
parent
commit
28876fe653

+ 0 - 14
gui/wxpython/gis_set.py

@@ -41,10 +41,6 @@ from grass.grassdb.checks import get_lockfile_if_present
 
 
 from core.gcmd import GError, RunCommand
 from core.gcmd import GError, RunCommand
 from core.utils import GetListOfLocations, GetListOfMapsets
 from core.utils import GetListOfLocations, GetListOfMapsets
-from startup.utils import (
-    get_possible_database_path,
-    create_database_directory,
-    create_startup_location_in_grassdb)
 from startup.guiutils import (SetSessionMapset,
 from startup.guiutils import (SetSessionMapset,
                               create_mapset_interactively,
                               create_mapset_interactively,
                               create_location_interactively,
                               create_location_interactively,
@@ -516,16 +512,6 @@ class GRASSStartup(wx.Frame):
         if self.GetRCValue("LOCATION_NAME") != "<UNKNOWN>":
         if self.GetRCValue("LOCATION_NAME") != "<UNKNOWN>":
             return
             return
         path = get_possible_database_path()
         path = get_possible_database_path()
-
-        # If nothing found, try to create GRASS directory and copy startup loc
-        if path is None:
-            grassdb = create_database_directory()
-            location = "world_latlong_wgs84"
-            if create_startup_location_in_grassdb(grassdb,
-                                                  location):
-                self.SetLocation(grassdb, location, "PERMANENT")
-                self.ExitSuccessfully()
-
         if path:
         if path:
             try:
             try:
                 self.tgisdbase.SetValue(path)
                 self.tgisdbase.SetValue(path)

+ 39 - 18
lib/init/grass.py

@@ -565,6 +565,17 @@ def write_gisrc(kv, filename, append=False):
     f.close()
     f.close()
 
 
 
 
+def set_mapset_to_gisrc(gisrc, grassdb, location, mapset):
+    if os.access(gisrc, os.R_OK):
+        kv = read_gisrc(gisrc)
+    else:
+        kv = {}
+    kv['GISDBASE'] = grassdb
+    kv['LOCATION_NAME'] = location
+    kv['MAPSET'] = mapset
+    write_gisrc(kv, gisrc)
+
+
 def read_gui(gisrc, default_gui):
 def read_gui(gisrc, default_gui):
     grass_gui = None
     grass_gui = None
     # At this point the GRASS user interface variable has been set from the
     # At this point the GRASS user interface variable has been set from the
@@ -1050,16 +1061,7 @@ def set_mapset(gisrc, arg=None, geofile=None, create_new=False,
                     s = readfile(os.path.join(gisdbase, location_name,
                     s = readfile(os.path.join(gisdbase, location_name,
                                               "PERMANENT", "DEFAULT_WIND"))
                                               "PERMANENT", "DEFAULT_WIND"))
                     writefile(os.path.join(path, "WIND"), s)
                     writefile(os.path.join(path, "WIND"), s)
-
-        if os.access(gisrc, os.R_OK):
-            kv = read_gisrc(gisrc)
-        else:
-            kv = {}
-
-        kv['GISDBASE'] = gisdbase
-        kv['LOCATION_NAME'] = location_name
-        kv['MAPSET'] = mapset
-        write_gisrc(kv, gisrc)
+        set_mapset_to_gisrc(gisrc, gisdbase, location_name, mapset)
     else:
     else:
         fatal(_("GRASS GIS database directory, location and mapset"
         fatal(_("GRASS GIS database directory, location and mapset"
                 " not set properly."
                 " not set properly."
@@ -1661,6 +1663,7 @@ def start_gui(grass_gui):
     debug("GRASS GUI should be <%s>" % grass_gui)
     debug("GRASS GUI should be <%s>" % grass_gui)
     # Check for gui interface
     # Check for gui interface
     if grass_gui == "wxpython":
     if grass_gui == "wxpython":
+        # TODO: report failures
         return Popen([os.getenv('GRASS_PYTHON'), wxpath("wxgui.py")])
         return Popen([os.getenv('GRASS_PYTHON'), wxpath("wxgui.py")])
     return None
     return None
 
 
@@ -2368,18 +2371,36 @@ def main():
 
 
     # Parsing argument to get LOCATION
     # Parsing argument to get LOCATION
     if not params.mapset and not params.tmp_location:
     if not params.mapset and not params.tmp_location:
+        # Mapset is not specified in command line arguments.
         last_mapset_usable = can_start_in_gisrc_mapset(
         last_mapset_usable = can_start_in_gisrc_mapset(
             gisrc=gisrc, ignore_lock=params.force_gislock_removal
             gisrc=gisrc, ignore_lock=params.force_gislock_removal
         )
         )
-        # Try interactive startup
-        # User selects LOCATION and MAPSET if not set
-        if not last_mapset_usable and not set_mapset_interactive(grass_gui):
-            # No GUI available, update gisrc file
-            fatal(_("<{0}> requested, but not available. Run GRASS in text "
-                    "mode (--text) or install missing package (usually "
-                    "'grass-gui').").format(grass_gui))
+        debug(f"last_mapset_usable: {last_mapset_usable}")
+        if not last_mapset_usable:
+            import grass.app as ga
+            from grass.grassdb.checks import can_start_in_mapset
+
+            # Try to use demolocation
+            grassdb, location, mapset = ga.ensure_demolocation()
+            demo_mapset_usable = can_start_in_mapset(
+                mapset_path=os.path.join(grassdb, location, mapset),
+                ignore_lock=params.force_gislock_removal
+            )
+            debug(f"demo_mapset_usable: {demo_mapset_usable}")
+            if demo_mapset_usable:
+                set_mapset_to_gisrc(
+                    gisrc=gisrc, grassdb=grassdb, location=location, mapset=mapset
+                )
+            else:
+                # Try interactive startup
+                # User selects LOCATION and MAPSET if not set
+                if not set_mapset_interactive(grass_gui):
+                    # No GUI available, update gisrc file
+                    fatal(_("<{0}> requested, but not available. Run GRASS in text "
+                            "mode (--text) or install missing package (usually "
+                            "'grass-gui').").format(grass_gui))
     else:
     else:
-        # Try non-interactive start up
+        # Mapset was specified in command line parameters.
         if params.tmp_location:
         if params.tmp_location:
             # tmp loc requires other things to be set as well
             # tmp loc requires other things to be set as well
             set_mapset(gisrc=gisrc, geofile=params.geofile,
             set_mapset(gisrc=gisrc, geofile=params.geofile,

+ 1 - 1
lib/python/Makefile

@@ -5,7 +5,7 @@ include $(MODULE_TOPDIR)/include/Make/Python.make
 
 
 PYDIR = $(ETC)/python/grass
 PYDIR = $(ETC)/python/grass
 
 
-SUBDIRS = exceptions script ctypes grassdb temporal pygrass pydispatch imaging gunittest bandref
+SUBDIRS = app exceptions script ctypes grassdb temporal pygrass pydispatch imaging gunittest bandref
 
 
 default: $(PYDIR)/__init__.py
 default: $(PYDIR)/__init__.py
 	$(MAKE) subdirs
 	$(MAKE) subdirs

+ 19 - 0
lib/python/app/Makefile

@@ -0,0 +1,19 @@
+MODULE_TOPDIR = ../../..
+
+include $(MODULE_TOPDIR)/include/Make/Other.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
+
+DSTDIR = $(ETC)/python/grass/app
+
+MODULES = data
+
+PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
+PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
+
+default: $(PYFILES) $(PYCFILES)
+
+$(DSTDIR):
+	$(MKDIR) $@
+
+$(DSTDIR)/%: % | $(DSTDIR)
+	$(INSTALL_DATA) $< $@

+ 1 - 0
lib/python/app/__init__.py

@@ -0,0 +1 @@
+from .data import *

+ 32 - 16
gui/wxpython/startup/utils.py

@@ -1,28 +1,25 @@
-"""
-@package startup.utils
-
-@brief General GUI-independent utilities for GUI startup of GRASS GIS
+"""Provides functions for the main GRASS GIS executable
 
 
-(C) 2017-2018 by Vaclav Petras the GRASS Development Team
+(C) 2020 by Vaclav Petras and the GRASS Development Team
 
 
-This program is free software under the GNU General Public License
-(>=v2). Read the file COPYING that comes with GRASS for details.
+This program is free software under the GNU General Public
+License (>=v2). Read the file COPYING that comes with GRASS
+for details.
 
 
-@author Vaclav Petras <wenzeslaus gmail com>
-@author Linda Kladivova <l.kladivova@seznam.cz>
+.. sectionauthor:: Vaclav Petras <wenzeslaus gmail com>
+.. sectionauthor:: Linda Kladivova <l.kladivova seznam cz>
 
 
-This file should not use (import) anything from GUI code (wx or wxGUI).
-This can potentially be part of the Python library (i.e. it needs to
-solve the errors etc. in a general manner).
+This is not a stable part of the API. Use at your own risk.
 """
 """
 
 
-
 import os
 import os
 import tempfile
 import tempfile
 import getpass
 import getpass
 import sys
 import sys
 from shutil import copytree, ignore_patterns
 from shutil import copytree, ignore_patterns
 
 
+from grass.grassdb.checks import is_location_valid
+
 
 
 def get_possible_database_path():
 def get_possible_database_path():
     """Looks for directory 'grassdata' (case-insensitive) in standard
     """Looks for directory 'grassdata' (case-insensitive) in standard
@@ -113,8 +110,11 @@ def _copy_startup_location(startup_location, location_in_grassdb):
     """
     """
     # Copy source startup location into GRASS database
     # Copy source startup location into GRASS database
     try:
     try:
-        copytree(startup_location, location_in_grassdb,
-                 ignore=ignore_patterns('*.tmpl', 'Makefile*'))
+        copytree(
+            startup_location,
+            location_in_grassdb,
+            ignore=ignore_patterns("*.tmpl", "Makefile*"),
+        )
         return True
         return True
     except (IOError, OSError):
     except (IOError, OSError):
         pass
         pass
@@ -129,7 +129,6 @@ def create_startup_location_in_grassdb(grassdatabase, startup_location_name):
     Returns False if there is no location to copy in the installation
     Returns False if there is no location to copy in the installation
     or copying failed.
     or copying failed.
     """
     """
-
     # Find out if startup location exists
     # Find out if startup location exists
     startup_location = _get_startup_location_in_distribution()
     startup_location = _get_startup_location_in_distribution()
     if not startup_location:
     if not startup_location:
@@ -140,3 +139,20 @@ def create_startup_location_in_grassdb(grassdatabase, startup_location_name):
     if _copy_startup_location(startup_location, location_in_grassdb):
     if _copy_startup_location(startup_location, location_in_grassdb):
         return True
         return True
     return False
     return False
+
+
+def ensure_demolocation():
+    """Ensure that demolocation exists
+
+    Creates both database directory and location if needed.
+
+    Returns the db, location name, and preferred mapset of the demolocation.
+    """
+    grassdb = get_possible_database_path()
+    # If nothing found, try to create GRASS directory and copy startup loc
+    if grassdb is None:
+        grassdb = create_database_directory()
+    location = "world_latlong_wgs84"
+    if not is_location_valid(grassdb, location):
+        create_startup_location_in_grassdb(grassdb, location)
+    return (grassdb, location, "PERMANENT")