[GRASS-SVN] r73706 - grass/trunk/lib/python/script

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Nov 24 12:25:27 PST 2018


Author: mmetz
Date: 2018-11-24 12:25:27 -0800 (Sat, 24 Nov 2018)
New Revision: 73706

Modified:
   grass/trunk/lib/python/script/setup.py
Log:
libpython: add functions to finish a GRASS session

Modified: grass/trunk/lib/python/script/setup.py
===================================================================
--- grass/trunk/lib/python/script/setup.py	2018-11-24 14:41:32 UTC (rev 73705)
+++ grass/trunk/lib/python/script/setup.py	2018-11-24 20:25:27 UTC (rev 73706)
@@ -1,7 +1,7 @@
-"""Setup and initialization functions
+"""Setup, initialization, and clean-up functions
 
-Function can be used in Python scripts to setup a GRASS environment
-without starting an actual GRASS session.
+Functions can be used in Python scripts to setup a GRASS environment
+and session without using grassXY.
 
 Usage::
 
@@ -77,8 +77,8 @@
     for vect in gscript.list_strings(type='vector'):
         print vect
 
-    # delete the rcfile
-    os.remove(rcfile)
+    # clean up at the end
+    gsetup.cleanup()
 
 
 (C) 2010-2012 by the GRASS Development Team
@@ -88,6 +88,7 @@
 
 @author Martin Landa <landa.martin gmail.com>
 @author Vaclav Petras <wenzeslaus gmail.com>
+ at author Markus Metz
 """
 
 # TODO: this should share code from lib/init/grass.py
@@ -100,6 +101,9 @@
 import tempfile as tmpfile
 
 
+windows = sys.platform == 'win32'
+
+
 def write_gisrc(dbase, location, mapset):
     """Write the ``gisrc`` file and return its path."""
     gisrc = tmpfile.mktemp()
@@ -117,21 +121,19 @@
         sys.path.insert(0, gui_path)
 
 
-# TODO: there should be a function to do the clean up
-# (unset the GISRC and delete the file)
 def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
     """Initialize system variables to run GRASS modules
 
-    This function is for running GRASS GIS without starting it
-    explicitly. No GRASS modules shall be called before call of this
-    function but any module or user script can be called afterwards
-    as if it would be called in an actual GRASS session. GRASS Python
-    libraries are usable as well in general but the ones using
-    C libraries through ``ctypes`` are not (which is caused by
-    library path not being updated for the current process
-    which is a common operating system limitation).
+    This function is for running GRASS GIS without starting it with the 
+    standard script grassXY. No GRASS modules shall be called before 
+    call of this function but any module or user script can be called 
+    afterwards because a GRASS session has been set up. GRASS Python 
+    libraries are usable as well in general but the ones using C 
+    libraries through ``ctypes`` are not (which is caused by library 
+    path not being updated for the current process which is a common 
+    operating system limitation).
 
-    To create a (fake) GRASS session a ``gisrc`` file is created.
+    To create a GRASS session a ``gisrc`` file is created.
     Caller is responsible for deleting the ``gisrc`` file.
 
     Basic usage::
@@ -142,8 +144,8 @@
                                    "/home/john/grassdata",
                                    "nc_spm_08", "user1")
         # ... use GRASS modules here
-        # remove the session's gisrc file to end the session
-        os.remove(gisrc)
+        # end the session
+        gscript.setup.finish()
 
     :param gisbase: path to GRASS installation
     :param dbase: path to GRASS database (default: '')
@@ -152,7 +154,8 @@
     
     :returns: path to ``gisrc`` file (to be deleted later)
     """
-    # TODO: why we don't set GISBASE?
+    # Set GISBASE
+    os.environ['GISBASE'] = gisbase
     mswin = sys.platform.startswith('win')
     # define PATH
     os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')
@@ -179,6 +182,7 @@
         os.environ['@LD_LIBRARY_PATH_VAR@'] = ''
     os.environ['@LD_LIBRARY_PATH_VAR@'] += os.pathsep + os.path.join(gisbase, 'lib')
 
+    # TODO: lock the mapset?
     os.environ['GIS_LOCK'] = str(os.getpid())
 
     # Set GRASS_PYTHON and PYTHONPATH to find GRASS Python modules
@@ -207,20 +211,64 @@
 
 
 # clean-up functions when terminating a GRASS session
+# these fns can only be called within a valid GRASS session
 def clean_default_db():
     # clean the default db if it is sqlite
     from grass.script import db as gdb
     from grass.script import core as gcore
+
     conn = gdb.db_connection()
     if conn and conn['driver'] == 'sqlite':
-	# check if db exists
-	gisenv = gcore.gisenv()
-	database = conn['database']
-	database = database.replace('$GISDBASE', gisenv['GISDBASE'])
-	database = database.replace('$LOCATION_NAME', gisenv['LOCATION_NAME'])
-	database = database.replace('$MAPSET', gisenv['MAPSET'])
-	if os.path.exists(database):
-	    gcore.message(_("Cleaning up sqlite database ..."))
-	    gcore.start_command('db.execute', sql = 'VACUUM')
+        # check if db exists
+        gisenv = gcore.gisenv()
+        database = conn['database']
+        database = database.replace('$GISDBASE', gisenv['GISDBASE'])
+        database = database.replace('$LOCATION_NAME', gisenv['LOCATION_NAME'])
+        database = database.replace('$MAPSET', gisenv['MAPSET'])
+        if os.path.exists(database):
+            gcore.message(_("Cleaning up default sqlite database ..."))
+            gcore.start_command('db.execute', sql = 'VACUUM')
+	    # give it some time to start
+            import time
+            time.sleep(0.1)
 
 
+def call(cmd, **kwargs):
+    import subprocess
+    """Wrapper for subprocess.call to deal with platform-specific issues"""
+    if windows:
+        kwargs['shell'] = True
+    return subprocess.call(cmd, **kwargs)
+
+
+def clean_temp():
+    from grass.script import core as gcore
+
+    gcore.message(_("Cleaning up temporary files..."))
+    nul = open(os.devnull, 'w')
+    gisbase = os.environ['GISBASE']
+    call([os.path.join(gisbase, "etc", "clean_temp")], stdout=nul)
+    nul.close()
+
+
+def finish():
+    """Terminate the GRASS session and clean up
+
+    GRASS commands can no longer be used after this function has been
+    called
+    
+    Basic usage::
+        import grass.script as gscript
+
+        gscript.setup.cleanup()
+    """
+
+    clean_default_db()
+    clean_temp()
+    # TODO: unlock the mapset?
+    # unset the GISRC and delete the file
+    from grass.script import utils as gutils
+    gutils.try_remove(os.environ['GISRC'])
+    os.environ.pop('GISRC')
+    # remove gislock env var (not the gislock itself
+    os.environ.pop('GIS_LOCK')



More information about the grass-commit mailing list