Просмотр исходного кода

init: Start in a world (demo) location for first-time user with GUI (#868)

The first-time user, when GUI is used, will be brought into a newly created location with a empty dedicated mapset.
PERMANENT contains map of the world (countries). This should demonstrate correctly the mapset concept.
Consequently, the startup window is skipped for the first-time user and the main GUI with data tab is the first thing user sees.

When something goes wrong (e.g., installation does not include demolocation), the fallback is the startup window.
Limitations include missing only config dir or only grassdata (neither must be present) and empty grassdata.

The primary naming in the code is startup location because it is used primarily for startup
and at the same time it is more serious than demo. User sees a name based on the intended area of use and CRS.

Closes #862 and #897.
Linda Kladivova 4 лет назад
Родитель
Сommit
8e8a14a0aa
2 измененных файлов с 84 добавлено и 4 удалено
  1. 11 4
      gui/wxpython/gis_set.py
  2. 73 0
      gui/wxpython/startup/utils.py

+ 11 - 4
gui/wxpython/gis_set.py

@@ -43,7 +43,8 @@ from core.gcmd import GError, RunCommand
 from core.utils import GetListOfLocations, GetListOfMapsets
 from startup.utils import (
     get_possible_database_path,
-    create_database_directory)
+    create_database_directory,
+    create_startup_location_in_grassdb)
 from startup.guiutils import (SetSessionMapset,
                               create_mapset_interactively,
                               create_location_interactively,
@@ -515,9 +516,16 @@ 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 nothing found, try to create GRASS directory and copy startup loc
         if path is None:
-            path = create_database_directory()
+            grassdb = create_database_directory()
+            location = "world_latlong_wgs84"
+            mapset_name = create_startup_location_in_grassdb(grassdb,
+                                                             location)
+            if mapset_name:
+                self.SetLocation(grassdb, location, mapset_name)
+                self.ExitSuccessfully()
 
         if path:
             try:
@@ -559,7 +567,6 @@ class GRASSStartup(wx.Frame):
             self.lbmapsets.SetSelection(0)
             self.SetLocation(grassdatabase, location, mapset)
 
-
     # the event can be refactored out by using lambda in bind
     def OnRenameMapset(self, event):
         """Rename selected mapset

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

@@ -9,6 +9,7 @@ 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>
 
 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
@@ -20,6 +21,8 @@ import os
 import tempfile
 import getpass
 import sys
+from shutil import copytree, ignore_patterns
+from grass.grassdb.create import create_mapset, get_default_mapset_name
 
 
 def get_possible_database_path():
@@ -87,3 +90,73 @@ def create_database_directory():
         pass
 
     return None
+
+
+def _get_startup_location_in_distribution():
+    """Check for startup location directory in distribution.
+
+    Returns startup location if found or None if nothing was found.
+    """
+    gisbase = os.getenv("GISBASE")
+    startup_location = os.path.join(gisbase, "demolocation")
+
+    # Find out if startup location exists
+    if os.path.exists(startup_location):
+        return startup_location
+    return None
+
+
+def _copy_startup_location(startup_location, location_in_grassdb):
+    """Copy the simple startup_location with some data to GRASS database.
+
+    Returns True if successfully copied or False
+    when an error was encountered.
+    """
+    # Copy source startup location into GRASS database
+    try:
+        copytree(startup_location, location_in_grassdb,
+                 ignore=ignore_patterns('*.tmpl', 'Makefile*'))
+        return True
+    except (IOError, OSError):
+        pass
+    return False
+
+
+def _create_startup_mapset(location_path):
+    """Create the new empty startup mapset named after user.
+
+    Returns new mapset name if successfully created or None when
+    an error was encountered.
+    """
+    mapset_name = default_name = get_default_mapset_name()
+    mapset_path = os.path.join(location_path, mapset_name)
+
+    # Create new startup mapset
+    try:
+        grassdatabase, location = os.path.split(location_path)
+        create_mapset(grassdatabase, location, mapset_name)
+        return mapset_name
+    except (IOError, OSError):
+        pass
+    return None
+
+
+def create_startup_location_in_grassdb(grassdatabase, startup_location_name):
+    """Create a new startup location in the given GRASS database.
+
+    Returns the newly created mapset name on success. Returns None if there is
+    no location to copy in the installation or copying failed.
+    """
+
+    # Find out if startup location exists
+    startup_location = _get_startup_location_in_distribution()
+    if not startup_location:
+        return None
+
+    # Copy the simple startup_location with some data to GRASS database.
+    mapset = None
+    location_in_grassdb = os.path.join(grassdatabase, startup_location_name)
+    if _copy_startup_location(startup_location, location_in_grassdb):
+        mapset = _create_startup_mapset(location_in_grassdb)
+        return mapset
+    return None