[GRASS-SVN] r73736 - in grass/branches/releasebranch_7_6/lib: init python/script

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Nov 30 05:04:16 PST 2018


Author: neteler
Date: 2018-11-30 05:04:15 -0800 (Fri, 30 Nov 2018)
New Revision: 73736

Modified:
   grass/branches/releasebranch_7_6/lib/init/grass.py
   grass/branches/releasebranch_7_6/lib/python/script/setup.py
Log:
sqlite db: automatically enable vacuum, trac #3697 (bundle backport: trunk r73692, r73703, r73704, r73706, r73707, r73708)

 * lib/init: clean up sqlite db if existing, see #3697
 * libpython: move clean_default_db() to setup
 * libinit: use clean_default_db() from script.setup
 * libpython: add functions to finish a GRASS session
 * libinit: start rewriting to use functions in lib/python/scripts
 * libinit: fix r73707, clean_all() takes no arguments


Modified: grass/branches/releasebranch_7_6/lib/init/grass.py
===================================================================
--- grass/branches/releasebranch_7_6/lib/init/grass.py	2018-11-30 12:35:19 UTC (rev 73735)
+++ grass/branches/releasebranch_7_6/lib/init/grass.py	2018-11-30 13:04:15 UTC (rev 73736)
@@ -607,7 +607,12 @@
 
     # Set PYTHONPATH to find GRASS Python modules
     if os.path.exists(gpath('etc', 'python')):
-        path_prepend(gpath('etc', 'python'), 'PYTHONPATH')
+        pythonpath = gpath('etc', 'python')
+        path_prepend(pythonpath, 'PYTHONPATH')
+        # the env var PYTHONPATH is only evaluated when python is started,
+        # thus:
+        sys.path.append(pythonpath)
+        # now we can import stuff from GRASS lib/python 
 
     # set path for the GRASS man pages
     grass_man_path = gpath('docs', 'man')
@@ -1779,6 +1784,17 @@
     nul.close()
 
 
+def clean_all():
+    from grass.script import setup as gsetup
+    # clean default sqlite db
+    gsetup.clean_default_db()
+    # remove leftover temp files
+    clean_temp()
+    # save 'last used' GISRC after removing variables which shouldn't
+    # be saved, e.g. d.mon related
+    clean_env(os.environ['GISRC'])
+
+
 def grep(pattern, lines):
     """Search lines (list of strings) and return them when beginning matches.
 
@@ -2128,10 +2144,12 @@
     # only non-error, interactive version continues from here
     if batch_job:
         returncode = run_batch_job(batch_job)
-        clean_temp()
+        clean_all()
         sys.exit(returncode)
     elif params.exit_grass:
-        clean_temp()
+        # clean always at exit, cleans whatever is current mapset based on
+        # the GISRC env variable
+        clean_all()
         sys.exit(0)
     else:
         clear_screen()
@@ -2166,17 +2184,15 @@
 
         # close GUI if running
         close_gui()
+
         # here we are at the end of grass session
         clear_screen()
-        # TODO: can we just register this atexit?
-        # TODO: and what is difference to deleting .tmp which we do?
-        clean_temp()
-        # save 'last used' GISRC after removing variables which shouldn't
-        # be saved, e.g. d.mon related
-        clean_env(gisrc)
+        clean_all()
         if not params.tmp_location:
             writefile(gisrcrc, readfile(gisrc))
         # After this point no more grass modules may be called
+        # done message at last: no atexit.register()
+        # or register done_message() 
         done_message()
 
 if __name__ == '__main__':

Modified: grass/branches/releasebranch_7_6/lib/python/script/setup.py
===================================================================
--- grass/branches/releasebranch_7_6/lib/python/script/setup.py	2018-11-30 12:35:19 UTC (rev 73735)
+++ grass/branches/releasebranch_7_6/lib/python/script/setup.py	2018-11-30 13:04:15 UTC (rev 73736)
@@ -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
@@ -204,3 +208,67 @@
 
     os.environ['GISRC'] = write_gisrc(dbase, location, mapset)
     return os.environ['GISRC']
+
+
+# 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 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