Browse Source

libpython: add functions to finish a GRASS session

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@73706 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 6 năm trước cách đây
mục cha
commit
0dc9fac7fe
1 tập tin đã thay đổi với 76 bổ sung28 xóa
  1. 76 28
      lib/python/script/setup.py

+ 76 - 28
lib/python/script/setup.py

@@ -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::
 Usage::
 
 
@@ -77,8 +77,8 @@ Usage::
     for vect in gscript.list_strings(type='vector'):
     for vect in gscript.list_strings(type='vector'):
         print vect
         print vect
 
 
-    # delete the rcfile
-    os.remove(rcfile)
+    # clean up at the end
+    gsetup.cleanup()
 
 
 
 
 (C) 2010-2012 by the GRASS Development Team
 (C) 2010-2012 by the GRASS Development Team
@@ -88,6 +88,7 @@ for details.
 
 
 @author Martin Landa <landa.martin gmail.com>
 @author Martin Landa <landa.martin gmail.com>
 @author Vaclav Petras <wenzeslaus gmail.com>
 @author Vaclav Petras <wenzeslaus gmail.com>
+@author Markus Metz
 """
 """
 
 
 # TODO: this should share code from lib/init/grass.py
 # TODO: this should share code from lib/init/grass.py
@@ -100,6 +101,9 @@ import sys
 import tempfile as tmpfile
 import tempfile as tmpfile
 
 
 
 
+windows = sys.platform == 'win32'
+
+
 def write_gisrc(dbase, location, mapset):
 def write_gisrc(dbase, location, mapset):
     """Write the ``gisrc`` file and return its path."""
     """Write the ``gisrc`` file and return its path."""
     gisrc = tmpfile.mktemp()
     gisrc = tmpfile.mktemp()
@@ -117,21 +121,19 @@ def set_gui_path():
         sys.path.insert(0, gui_path)
         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'):
 def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
     """Initialize system variables to run GRASS modules
     """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.
     Caller is responsible for deleting the ``gisrc`` file.
 
 
     Basic usage::
     Basic usage::
@@ -142,8 +144,8 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
                                    "/home/john/grassdata",
                                    "/home/john/grassdata",
                                    "nc_spm_08", "user1")
                                    "nc_spm_08", "user1")
         # ... use GRASS modules here
         # ... 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 gisbase: path to GRASS installation
     :param dbase: path to GRASS database (default: '')
     :param dbase: path to GRASS database (default: '')
@@ -152,7 +154,8 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
     
     
     :returns: path to ``gisrc`` file (to be deleted later)
     :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')
     mswin = sys.platform.startswith('win')
     # define PATH
     # define PATH
     os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')
     os.environ['PATH'] += os.pathsep + os.path.join(gisbase, 'bin')
@@ -179,6 +182,7 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
         os.environ['@LD_LIBRARY_PATH_VAR@'] = ''
         os.environ['@LD_LIBRARY_PATH_VAR@'] = ''
     os.environ['@LD_LIBRARY_PATH_VAR@'] += os.pathsep + os.path.join(gisbase, 'lib')
     os.environ['@LD_LIBRARY_PATH_VAR@'] += os.pathsep + os.path.join(gisbase, 'lib')
 
 
+    # TODO: lock the mapset?
     os.environ['GIS_LOCK'] = str(os.getpid())
     os.environ['GIS_LOCK'] = str(os.getpid())
 
 
     # Set GRASS_PYTHON and PYTHONPATH to find GRASS Python modules
     # Set GRASS_PYTHON and PYTHONPATH to find GRASS Python modules
@@ -207,20 +211,64 @@ def init(gisbase, dbase='', location='demolocation', mapset='PERMANENT'):
 
 
 
 
 # clean-up functions when terminating a GRASS session
 # clean-up functions when terminating a GRASS session
+# these fns can only be called within a valid GRASS session
 def clean_default_db():
 def clean_default_db():
     # clean the default db if it is sqlite
     # clean the default db if it is sqlite
     from grass.script import db as gdb
     from grass.script import db as gdb
     from grass.script import core as gcore
     from grass.script import core as gcore
+
     conn = gdb.db_connection()
     conn = gdb.db_connection()
     if conn and conn['driver'] == 'sqlite':
     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')