浏览代码

pythonlib: create new file utils not to clutter core with simple functions and move some of them from core and change all affected imports (merge from trunk, https://trac.osgeo.org/grass/changeset/61854)

git-svn-id: https://svn.osgeo.org/grass/grass/branches/releasebranch_7_0@61924 15284696-431f-4ddb-bdfa-cd5b030d7da7
Anna Petrášová 10 年之前
父节点
当前提交
bdde045836
共有 40 个文件被更改,包括 356 次插入260 次删除
  1. 3 2
      gui/wxpython/animation/data.py
  2. 4 3
      gui/wxpython/core/render.py
  3. 2 1
      gui/wxpython/core/toolboxes.py
  4. 4 3
      gui/wxpython/core/ws.py
  5. 2 1
      gui/wxpython/gmodeler/frame.py
  6. 3 2
      gui/wxpython/mapdisp/main.py
  7. 2 2
      gui/wxpython/mapwin/analysis.py
  8. 2 2
      gui/wxpython/rlisetup/frame.py
  9. 4 3
      gui/wxpython/vnet/vnet_core.py
  10. 3 2
      gui/wxpython/vnet/vnet_data.py
  11. 1 1
      lib/python/script/Makefile
  12. 1 0
      lib/python/script/__init__.py
  13. 4 2
      lib/python/script/array.py
  14. 13 186
      lib/python/script/core.py
  15. 2 0
      lib/python/script/db.py
  16. 19 6
      lib/python/script/pythonlib.dox
  17. 1 0
      lib/python/script/raster.py
  18. 1 0
      lib/python/script/raster3d.py
  19. 1 0
      lib/python/script/task.py
  20. 220 0
      lib/python/script/utils.py
  21. 1 0
      lib/python/script/vector.py
  22. 2 1
      scripts/d.correlate/d.correlate.py
  23. 4 3
      scripts/d.polar/d.polar.py
  24. 5 4
      scripts/db.out.ogr/db.out.ogr.py
  25. 2 1
      scripts/db.univar/db.univar.py
  26. 2 1
      scripts/g.extension/g.extension.py
  27. 3 2
      scripts/g.manual/g.manual.py
  28. 3 2
      scripts/i.oif/i.oif.py
  29. 2 1
      scripts/i.spectral/i.spectral.py
  30. 4 3
      scripts/m.proj/m.proj.py
  31. 3 2
      scripts/r.pack/r.pack.py
  32. 2 1
      scripts/r.tileset/r.tileset.py
  33. 4 3
      scripts/r.unpack/r.unpack.py
  34. 7 6
      scripts/v.in.e00/v.in.e00.py
  35. 4 3
      scripts/v.in.gns/v.in.gns.py
  36. 3 2
      scripts/v.in.lines/v.in.lines.py
  37. 3 2
      scripts/v.in.mapgen/v.in.mapgen.py
  38. 3 2
      scripts/v.in.wfs/v.in.wfs.py
  39. 3 2
      scripts/v.pack/v.pack.py
  40. 4 3
      scripts/v.unpack/v.unpack.py

+ 3 - 2
gui/wxpython/animation/data.py

@@ -19,6 +19,7 @@ This program is free software under the GNU General Public License
 import os
 import os
 import copy
 import copy
 
 
+from grass.script.utils import parse_key_val
 from grass.script import core as gcore
 from grass.script import core as gcore
 
 
 from core.utils import _
 from core.utils import _
@@ -232,11 +233,11 @@ class AnimationData(object):
             self._regions = regions
             self._regions = regions
             return
             return
 
 
-        startRegionDict = gcore.parse_key_val(gcore.read_command('g.region', flags='gu',
+        startRegionDict = parse_key_val(gcore.read_command('g.region', flags='gu',
                                                                  region=startRegion),
                                                                  region=startRegion),
                                               val_type=float)
                                               val_type=float)
         if endRegion:
         if endRegion:
-            endRegionDict = gcore.parse_key_val(gcore.read_command('g.region', flags='gu',
+            endRegionDict = parse_key_val(gcore.read_command('g.region', flags='gu',
                                                                    region=endRegion),
                                                                    region=endRegion),
                                                 val_type=float)
                                                 val_type=float)
             for key in ('n', 's', 'e', 'w'):
             for key in ('n', 's', 'e', 'w'):

+ 4 - 3
gui/wxpython/core/render.py

@@ -35,6 +35,7 @@ import types
 import wx
 import wx
 
 
 from grass.script import core as grass
 from grass.script import core as grass
+from grass.script.utils import try_remove
 from grass.pydispatch.signal import Signal
 from grass.pydispatch.signal import Signal
 
 
 from core          import utils
 from core          import utils
@@ -167,7 +168,7 @@ class Layer(object):
             for f in [self.mapfile, self.maskfile]:
             for f in [self.mapfile, self.maskfile]:
                 if not f:
                 if not f:
                     continue
                     continue
-                grass.try_remove(f)
+                try_remove(f)
                 f = None
                 f = None
 
 
         self.forceRender = False
         self.forceRender = False
@@ -1298,9 +1299,9 @@ class Map(object):
     def _clean(self, llist):
     def _clean(self, llist):
         for layer in llist:
         for layer in llist:
             if layer.maskfile:
             if layer.maskfile:
-                grass.try_remove(layer.maskfile)
+                try_remove(layer.maskfile)
             if layer.mapfile:
             if layer.mapfile:
-                grass.try_remove(layer.mapfile)
+                try_remove(layer.mapfile)
             llist.remove(layer)
             llist.remove(layer)
         
         
     def Clean(self):
     def Clean(self):

+ 2 - 1
gui/wxpython/core/toolboxes.py

@@ -36,6 +36,7 @@ from core.gcmd import GError, RunCommand
 
 
 import grass.script.task as gtask
 import grass.script.task as gtask
 import grass.script.core as gcore
 import grass.script.core as gcore
+from grass.script.utils import try_remove
 from grass.script.core import ScriptError
 from grass.script.core import ScriptError
 from core.debug import Debug
 from core.debug import Debug
 
 
@@ -59,7 +60,7 @@ def toolboxesOutdated():
     to let gui regenerate it next time it starts."""
     to let gui regenerate it next time it starts."""
     path = os.path.join(GetSettingsPath(), 'toolboxes', 'menudata.xml')
     path = os.path.join(GetSettingsPath(), 'toolboxes', 'menudata.xml')
     if os.path.exists(path):
     if os.path.exists(path):
-        gcore.try_remove(path)
+        try_remove(path)
 
 
 
 
 def getMenudataFile(userRootFile, newFile, fallback):
 def getMenudataFile(userRootFile, newFile, fallback):

+ 4 - 3
gui/wxpython/core/ws.py

@@ -22,6 +22,7 @@ import copy
 import wx
 import wx
 from wx.lib.newevent import NewEvent
 from wx.lib.newevent import NewEvent
 
 
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 from core          import utils
 from core          import utils
@@ -74,7 +75,7 @@ class RenderWMSMgr(wx.EvtHandler):
         self.updateProgress = Signal('RenderWMSMgr.updateProgress')
         self.updateProgress = Signal('RenderWMSMgr.updateProgress')
 
 
     def __del__(self):
     def __del__(self):
-        grass.try_remove(self.tempMap)
+        try_remove(self.tempMap)
 
 
     def Render(self, cmd, env):
     def Render(self, cmd, env):
         """!If it is needed, download missing WMS data.
         """!If it is needed, download missing WMS data.
@@ -116,8 +117,8 @@ class RenderWMSMgr(wx.EvtHandler):
             self.fetched_data_cmd = None
             self.fetched_data_cmd = None
             self.renderedRegion = region
             self.renderedRegion = region
 
 
-            grass.try_remove(self.mapfile)
-            grass.try_remove(self.tempMap)
+            try_remove(self.mapfile)
+            try_remove(self.tempMap)
 
 
             self.currentPid = self.thread.GetId()
             self.currentPid = self.thread.GetId()
             self.thread.abort()
             self.thread.abort()

+ 2 - 1
gui/wxpython/gmodeler/frame.py

@@ -55,6 +55,7 @@ from gmodeler.giface import GraphicalModelerGrassInterface
 from gmodeler.model       import *
 from gmodeler.model       import *
 from gmodeler.dialogs     import *
 from gmodeler.dialogs     import *
 
 
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 class ModelFrame(wx.Frame):
 class ModelFrame(wx.Frame):
@@ -1723,7 +1724,7 @@ class PythonPanel(wx.Panel):
 
 
     def OnDone(self, cmd, returncode):
     def OnDone(self, cmd, returncode):
         """!Python script finished"""
         """!Python script finished"""
-        grass.try_remove(self.filename)
+        try_remove(self.filename)
         self.filename = None
         self.filename = None
         
         
     def SaveAs(self, force = False):
     def SaveAs(self, force = False):

+ 3 - 2
gui/wxpython/mapdisp/main.py

@@ -38,10 +38,11 @@ from core.gcmd     import RunCommand
 from core.render   import Map, MapLayer
 from core.render   import Map, MapLayer
 from core.utils import _
 from core.utils import _
 from mapdisp.frame import MapFrame
 from mapdisp.frame import MapFrame
-from grass.script  import core as grass
 from core.debug    import Debug
 from core.debug    import Debug
 from core.settings import UserSettings
 from core.settings import UserSettings
 
 
+from grass.script.utils import try_remove
+from grass.script import core as grass
 from grass.pydispatch.signal import Signal
 from grass.pydispatch.signal import Signal
 
 
 # for standalone app
 # for standalone app
@@ -377,7 +378,7 @@ class MapApp(wx.App):
             # self.timer.Stop()
             # self.timer.Stop()
             # terminate thread
             # terminate thread
             for f in monFile.itervalues():
             for f in monFile.itervalues():
-                grass.try_remove(f)
+                try_remove(f)
             
             
     def watcher(self):
     def watcher(self):
         """!Redraw, if new layer appears (check's timestamp of
         """!Redraw, if new layer appears (check's timestamp of

+ 2 - 2
gui/wxpython/mapwin/analysis.py

@@ -27,7 +27,7 @@ from core.gcmd import RunCommand
 from core.giface import Notification
 from core.giface import Notification
 
 
 from grass.pydispatch.signal import Signal
 from grass.pydispatch.signal import Signal
-import grass.script.core as gcore
+from grass.script.utils import parse_key_val
 
 
 
 
 class AnalysisControllerBase:
 class AnalysisControllerBase:
@@ -354,7 +354,7 @@ class MeasureAreaController(AnalysisControllerBase):
         coordinates = coords + [coords[0]]
         coordinates = coords + [coords[0]]
         coordinates = ','.join([str(item) for sublist in coordinates for item in sublist])
         coordinates = ','.join([str(item) for sublist in coordinates for item in sublist])
         result = RunCommand('m.measure', flags='g', coordinates=coordinates, read=True).strip()
         result = RunCommand('m.measure', flags='g', coordinates=coordinates, read=True).strip()
-        result = gcore.parse_key_val(result)
+        result = parse_key_val(result)
         if 'units' not in result:
         if 'units' not in result:
             self._giface.WriteWarning(_("Units not recognized, measurement failed."))
             self._giface.WriteWarning(_("Units not recognized, measurement failed."))
             unit = ''
             unit = ''

+ 2 - 2
gui/wxpython/rlisetup/frame.py

@@ -10,7 +10,7 @@ import os
 
 
 from core import globalvar, gcmd
 from core import globalvar, gcmd
 from core.utils import _
 from core.utils import _
-from grass.script import core as grass
+from grass.script.utils import try_remove
 from rlisetup.functions import retRLiPath
 from rlisetup.functions import retRLiPath
 from rlisetup.wizard import RLIWizard
 from rlisetup.wizard import RLIWizard
 import locale
 import locale
@@ -217,7 +217,7 @@ class RLiSetupFrame(wx.Frame):
 
 
         if dlg.ShowModal() == wx.ID_YES:
         if dlg.ShowModal() == wx.ID_YES:
             self.listfileBox.Delete(self.listfileBox.GetSelections()[0])
             self.listfileBox.Delete(self.listfileBox.GetSelections()[0])
-            grass.try_remove(os.path.join(self.rlipath, confile))
+            try_remove(os.path.join(self.rlipath, confile))
             self.listfiles = self.ListFiles()
             self.listfiles = self.ListFiles()
         dlg.Destroy()
         dlg.Destroy()
         return
         return

+ 4 - 3
gui/wxpython/vnet/vnet_core.py

@@ -20,6 +20,7 @@ This program is free software under the GNU General Public License
 """
 """
 
 
 import os
 import os
+from grass.script.utils import try_remove
 from grass.script     import core as grass
 from grass.script     import core as grass
 
 
 import wx
 import wx
@@ -466,7 +467,7 @@ class VNETAnalyses:
 
 
     def _vnetPathRunAnDone(self, cmd, returncode):
     def _vnetPathRunAnDone(self, cmd, returncode):
         """!Called when v.net.path analysis is done"""
         """!Called when v.net.path analysis is done"""
-        grass.try_remove(self.coordsTmpFile)
+        try_remove(self.coordsTmpFile)
 
 
         self._onDone(cmd, returncode)
         self._onDone(cmd, returncode)
 
 
@@ -582,7 +583,7 @@ class VNETAnalyses:
                                driver = driver,
                                driver = driver,
                                database = database)
                                database = database)
 
 
-        grass.try_remove(sqlFile)
+        try_remove(sqlFile)
 
 
     def _runTurnsAnDone(self, cmd, returncode):
     def _runTurnsAnDone(self, cmd, returncode):
         """!Called when analysis is done"""
         """!Called when analysis is done"""
@@ -694,7 +695,7 @@ class VNETAnalyses:
         """!Called when analysis is done"""
         """!Called when analysis is done"""
         self.tmp_maps.DeleteTmpMap(self.tmpInPts) #TODO remove earlier (OnDone lambda?)
         self.tmp_maps.DeleteTmpMap(self.tmpInPts) #TODO remove earlier (OnDone lambda?)
         self.tmp_maps.DeleteTmpMap(self.tmpInPtsConnected)
         self.tmp_maps.DeleteTmpMap(self.tmpInPtsConnected)
-        grass.try_remove(self.tmpPtsAsciiFile)
+        try_remove(self.tmpPtsAsciiFile)
 
 
         if cmd[0] == "v.net.flow":
         if cmd[0] == "v.net.flow":
             self.tmp_maps.DeleteTmpMap(self.vnetFlowTmpCut)
             self.tmp_maps.DeleteTmpMap(self.vnetFlowTmpCut)

+ 3 - 2
gui/wxpython/vnet/vnet_data.py

@@ -26,6 +26,7 @@ import os
 import types
 import types
 from copy import deepcopy
 from copy import deepcopy
 
 
+from grass.script.utils import try_remove
 from grass.script     import core as grass
 from grass.script     import core as grass
 
 
 import wx
 import wx
@@ -1092,7 +1093,7 @@ class History:
         self.sep = ';'
         self.sep = ';'
 
 
     def __del__(self):
     def __del__(self):
-        grass.try_remove(self.histFile)
+        try_remove(self.histFile)
 
 
     def GetNext(self):
     def GetNext(self):
         """!Go one step forward in history"""
         """!Go one step forward in history"""
@@ -1147,7 +1148,7 @@ class History:
 
 
         oldHist.close()
         oldHist.close()
         newHist.close()
         newHist.close()
-        grass.try_remove(self.histFile)
+        try_remove(self.histFile)
         self.histFile = newHistFile
         self.histFile = newHistFile
 
 
         self.newHistStepData.clear() 
         self.newHistStepData.clear() 

+ 1 - 1
lib/python/script/Makefile

@@ -6,7 +6,7 @@ include $(MODULE_TOPDIR)/include/Make/Doxygen.make
 
 
 DSTDIR = $(ETC)/python/grass/script
 DSTDIR = $(ETC)/python/grass/script
 
 
-MODULES = core db raster raster3d vector array setup task 
+MODULES = core db raster raster3d vector array setup task utils
 
 
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
 PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)

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

@@ -3,3 +3,4 @@ from db     import *
 from raster import *
 from raster import *
 from raster3d import *
 from raster3d import *
 from vector import *
 from vector import *
+from utils import *

+ 4 - 2
lib/python/script/array.py

@@ -130,8 +130,10 @@ for details.
 import os
 import os
 import numpy
 import numpy
 
 
+from utils import try_remove
 import core as grass
 import core as grass
 
 
+
 ###############################################################################
 ###############################################################################
 
 
 class array(numpy.memmap):
 class array(numpy.memmap):
@@ -161,7 +163,7 @@ class array(numpy.memmap):
     def _close(self):
     def _close(self):
         numpy.memmap._close(self)
         numpy.memmap._close(self)
         if isinstance(self, array):
         if isinstance(self, array):
-            grass.try_remove(self.filename)
+            try_remove(self.filename)
 
 
     def read(self, mapname, null=None):
     def read(self, mapname, null=None):
         """!Read raster map into array
         """!Read raster map into array
@@ -274,7 +276,7 @@ class array3d(numpy.memmap):
 
 
         numpy.memmap._close(self)
         numpy.memmap._close(self)
         if isinstance(self, array):
         if isinstance(self, array):
-            grass.try_remove(self.filename)
+            try_remove(self.filename)
 
 
     def read(self, mapname, null=None):
     def read(self, mapname, null=None):
         """!Read 3D raster map into array
         """!Read 3D raster map into array

+ 13 - 186
lib/python/script/core.py

@@ -30,15 +30,17 @@ import re
 import atexit
 import atexit
 import subprocess
 import subprocess
 import shutil
 import shutil
-import locale
 import codecs
 import codecs
 
 
+from utils import KeyValue, parse_key_val, basename, encode
+
 # i18N
 # i18N
 import gettext
 import gettext
 gettext.install('grasslibs', os.path.join(os.getenv("GISBASE"), 'locale'))
 gettext.install('grasslibs', os.path.join(os.getenv("GISBASE"), 'locale'))
 
 
 # subprocess wrapper that uses shell on Windows
 # subprocess wrapper that uses shell on Windows
 
 
+
 class Popen(subprocess.Popen):
 class Popen(subprocess.Popen):
     _builtin_exts = set(['.com', '.exe', '.bat', '.cmd'])
     _builtin_exts = set(['.com', '.exe', '.bat', '.cmd'])
 
 
@@ -86,20 +88,6 @@ _popen_args = ["bufsize", "executable", "stdin", "stdout", "stderr",
                "universal_newlines", "startupinfo", "creationflags"]
                "universal_newlines", "startupinfo", "creationflags"]
 
 
 
 
-def decode(string):
-    enc = locale.getdefaultlocale()[1]
-    if enc:
-        return string.decode(enc)
-
-    return string
-
-def encode(string):
-    enc = locale.getdefaultlocale()[1]
-    if enc:
-        return string.encode(enc)
-
-    return string
-
 def _make_val(val):
 def _make_val(val):
     if isinstance(val, types.StringType) or \
     if isinstance(val, types.StringType) or \
             isinstance(val, types.UnicodeType):
             isinstance(val, types.UnicodeType):
@@ -518,7 +506,7 @@ def debug(msg, debug=1):
     if debug_level() >= debug:
     if debug_level() >= debug:
         if sys.platform == "win32":
         if sys.platform == "win32":
             msg = msg.replace('&', '^&')
             msg = msg.replace('&', '^&')
-            
+
         run_command("g.message", flags='d', message=msg, debug=debug)
         run_command("g.message", flags='d', message=msg, debug=debug)
 
 
 def verbose(msg):
 def verbose(msg):
@@ -673,28 +661,6 @@ def parser():
 
 
     return _parse_opts(lines[1:])
     return _parse_opts(lines[1:])
 
 
-
-def separator(sep):
-    """!Returns separator from G_OPT_F_SEP appropriately converted
-    to character.
-
-    @param separator character or separator keyword
-
-    @return separator character
-    """
-    if sep == "pipe":
-        return "|"
-    elif sep == "comma":
-        return ","
-    elif sep == "space":
-        return " "
-    elif sep == "tab" or sep == "\\t":
-        return "\t"
-    elif sep == "newline" or sep == "\\n":
-        return "\n"
-    return sep
-    
-
 # interface to g.tempfile
 # interface to g.tempfile
 
 
 
 
@@ -721,75 +687,6 @@ def tempdir():
     return tmp
     return tmp
 
 
 
 
-class KeyValue(dict):
-    """A general-purpose key-value store.
-
-    KeyValue is a subclass of dict, but also allows entries to be read and
-    written using attribute syntax. Example:
-
-    \code
-    >>> reg = KeyValue()
-    >>> reg['north'] = 489
-    >>> reg.north
-    489
-    >>> reg.south = 205
-    >>> reg['south']
-    205
-
-    \endcode
-    """
-
-    def __getattr__(self, key):
-        return self[key]
-
-    def __setattr__(self, key, value):
-        self[key] = value
-
-# key-value parsers
-
-
-def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
-    """!Parse a string into a dictionary, where entries are separated
-    by newlines and the key and value are separated by `sep' (default: `=')
-
-    @param s string to be parsed
-    @param sep key/value separator
-    @param dflt default value to be used
-    @param val_type value type (None for no cast)
-    @param vsep vertical separator (default os.linesep)
-
-    @return parsed input (dictionary of keys/values)
-    """
-    result = KeyValue()
-
-    if not s:
-        return result
-
-    if vsep:
-        lines = s.split(vsep)
-        try:
-            lines.remove('\n')
-        except ValueError:
-            pass
-    else:
-        lines = s.splitlines()
-
-    for line in lines:
-        kv = line.split(sep, 1)
-        k = kv[0].strip()
-        if len(kv) > 1:
-            v = kv[1].strip()
-        else:
-            v = dflt
-
-        if val_type:
-            result[k] = val_type(v)
-        else:
-            result[k] = v
-
-    return result
-
-
 def _compare_projection(dic):
 def _compare_projection(dic):
     """
     """
         !Check if projection has some possibility of duplicate names like
         !Check if projection has some possibility of duplicate names like
@@ -848,7 +745,7 @@ def _text_to_key_value_dict(filename, sep=":", val_sep=",", checkproj=False,
         @param val_sep The character that separates the values of a single key, default is ","
         @param val_sep The character that separates the values of a single key, default is ","
         @param checkproj True if it has to check some information about projection system
         @param checkproj True if it has to check some information about projection system
         @param checkproj True if it has to check some information about units
         @param checkproj True if it has to check some information about units
-        
+
         @return The dictionary
         @return The dictionary
 
 
         A text file with this content:
         A text file with this content:
@@ -964,23 +861,6 @@ def compare_key_value_text_files(filename_a, filename_b, sep=":",
                 return False
                 return False
     return True
     return True
 
 
-def diff_files(filename_a, filename_b):
-    """!Diffs two text files and returns difference.
-
-    @param filename_a first file path    
-    @param filename_b second file path
-    
-    @return list of strings
-    """
-    import difflib
-    differ = difflib.Differ()
-    fh_a = open(filename_a, 'r')
-    fh_b = open(filename_b, 'r')
-    result = list(differ.compare(fh_a.readlines(),
-                                 fh_b.readlines()))
-    return result
-
-
 # interface to g.gisenv
 # interface to g.gisenv
 
 
 
 
@@ -1437,38 +1317,22 @@ def verbosity():
 
 
 ## various utilities, not specific to GRASS
 ## various utilities, not specific to GRASS
 
 
-# basename inc. extension stripping
-
-
-def basename(path, ext=None):
-    """!Remove leading directory components and an optional extension
-    from the specified path
-
-    @param path path
-    @param ext extension
-    """
-    name = os.path.basename(path)
-    if not ext:
-        return name
-    fs = name.rsplit('.', 1)
-    if len(fs) > 1 and fs[1].lower() == ext:
-        name = fs[0]
-    return name
-
 def find_program(pgm, *args):
 def find_program(pgm, *args):
     """!Attempt to run a program, with optional arguments.
     """!Attempt to run a program, with optional arguments.
+
     You must call the program in a way that will return a successful
     You must call the program in a way that will return a successful
     exit code. For GRASS modules this means you need to pass it some
     exit code. For GRASS modules this means you need to pass it some
     valid CLI option, like "--help". For other programs a common
     valid CLI option, like "--help". For other programs a common
-    valid do-little option is "--version".
-    
+    valid do-little option is usually "--version".
+
     Example:
     Example:
 
 
     @code
     @code
-    >>> grass.find_program('r.sun', 'help')
+    >>> find_program('r.sun', '--help')
     True
     True
-    >>> grass.find_program('gdalwarp', '--version')
+    >>> find_program('ls', '--version')
     True
     True
+
     @endcode
     @endcode
 
 
     @param pgm program name
     @param pgm program name
@@ -1480,6 +1344,7 @@ def find_program(pgm, *args):
     """
     """
     nuldev = file(os.devnull, 'w+')
     nuldev = file(os.devnull, 'w+')
     try:
     try:
+        # TODO: the doc or impl is not correct, any return code is accepted
         call([pgm] + list(args), stdin = nuldev, stdout = nuldev, stderr = nuldev)
         call([pgm] + list(args), stdin = nuldev, stdout = nuldev, stderr = nuldev)
         found = True
         found = True
     except:
     except:
@@ -1488,44 +1353,6 @@ def find_program(pgm, *args):
 
 
     return found
     return found
 
 
-# try to remove a file, without complaints
-
-
-def try_remove(path):
-    """!Attempt to remove a file; no exception is generated if the
-    attempt fails.
-
-    @param path path to file to remove
-    """
-    try:
-        os.remove(path)
-    except:
-        pass
-
-# try to remove a directory, without complaints
-
-
-def try_rmdir(path):
-    """!Attempt to remove a directory; no exception is generated if the
-    attempt fails.
-
-    @param path path to directory to remove
-    """
-    try:
-        os.rmdir(path)
-    except:
-        shutil.rmtree(path, ignore_errors=True)
-
-
-def float_or_dms(s):
-    """!Convert DMS to float.
-
-    @param s DMS value
-
-    @return float value
-    """
-    return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
-
 # interface to g.mapsets
 # interface to g.mapsets
 
 
 
 
@@ -1586,7 +1413,7 @@ def create_location(dbase, location, epsg=None, proj4=None, filename=None,
         else:
         else:
             warning(_("Location <%s> already exists and will be overwritten") % location)
             warning(_("Location <%s> already exists and will be overwritten") % location)
             shutil.rmtree(os.path.join(dbase, location))
             shutil.rmtree(os.path.join(dbase, location))
-    
+
     kwargs = dict()
     kwargs = dict()
     if datum:
     if datum:
         kwargs['datum'] = datum
         kwargs['datum'] = datum

+ 2 - 0
lib/python/script/db.py

@@ -25,6 +25,8 @@ for details.
 import tempfile as pytempfile # conflict with core.tempfile
 import tempfile as pytempfile # conflict with core.tempfile
 
 
 from core import *
 from core import *
+from utils import try_remove
+
 
 
 def db_describe(table, **args):
 def db_describe(table, **args):
     """!Return the list of columns for a database table
     """!Return the list of columns for a database table

+ 19 - 6
lib/python/script/pythonlib.dox

@@ -13,6 +13,7 @@ the end users.
 - \subpage pythonUsage
 - \subpage pythonUsage
 - \subpage pythonModules
 - \subpage pythonModules
  - \subpage pythonCore
  - \subpage pythonCore
+ - \subpage pythonUtils
  - \subpage pythonDb
  - \subpage pythonDb
  - \subpage pythonRaster
  - \subpage pythonRaster
  - \subpage pythonVector
  - \subpage pythonVector
@@ -180,17 +181,29 @@ Returns the name of a temporary file, created with \gmod{g.tempfile}.
 
 
  - python::script::core::create_location()
  - python::script::core::create_location()
 
 
-<b>Various utilities, not specific to GRASS</b>
- 
- - python::script::core::basename()
+<b>Others</b>
 
 
  - python::script::core::find_program()
  - python::script::core::find_program()
 
 
- - python::script::core::try_remove()
+\subsection pythonUtils Utils
+ 
+ - python::script::utils::float_or_dms()
+ 
+ - python::script::utils::separator()
+
+ - python::script::utils::diff_files()
+
+ - python::script::utils::try_remove()
+
+ - python::script::utils::try_rmdir()
+
+ - python::script::utils::basename()
+
+ - python::script::utils::parse_key_val()
 
 
- - python::script::core::try_rmdir()
+ - python::script::utils::decode()
 
 
- - python::script::core::float_or_dms()
+ - python::script::utils::encode()
 
 
 \subsection pythonDb Database
 \subsection pythonDb Database
 
 

+ 1 - 0
lib/python/script/raster.py

@@ -28,6 +28,7 @@ import types
 import time
 import time
 
 
 from core import *
 from core import *
+from utils import float_or_dms, parse_key_val
 
 
 # add raster history
 # add raster history
 
 

+ 1 - 0
lib/python/script/raster3d.py

@@ -27,6 +27,7 @@ import os
 import string
 import string
 
 
 from core import *
 from core import *
+from utils import float_or_dms, parse_key_val
 
 
 # add raster history
 # add raster history
 
 

+ 1 - 0
lib/python/script/task.py

@@ -30,6 +30,7 @@ try:
 except ImportError:
 except ImportError:
     import elementtree.ElementTree as etree # Python <= 2.4
     import elementtree.ElementTree as etree # Python <= 2.4
 
 
+from utils import decode
 from core import *
 from core import *
 
 
 class grassTask:
 class grassTask:

+ 220 - 0
lib/python/script/utils.py

@@ -0,0 +1,220 @@
+"""!@package grass.script.utils
+
+@brief GRASS Python scripting module (various useful functions)
+
+Useful functions to be used in Python scripts.
+
+Usage:
+
+@code
+from grass.script import utils as gutils
+
+...
+@endcode
+
+(C) 2014 by 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.
+
+@author Glynn Clements
+@author Martin Landa <landa.martin gmail.com>
+@author Anna Petrasova <kratochanna gmail.com>
+"""
+
+import os
+import shutil
+import locale
+
+
+def float_or_dms(s):
+    """!Convert DMS to float.
+
+    >>> round(float_or_dms('26:45:30'), 5)
+    26.75833
+    >>> round(float_or_dms('26:0:0.1'), 5)
+    26.00003
+
+    @param s DMS value
+
+    @return float value
+    """
+    return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
+
+
+def separator(sep):
+    """!Returns separator from G_OPT_F_SEP appropriately converted
+    to character.
+
+    >>> separator('pipe')
+    '|'
+    >>> separator('comma')
+    ','
+
+    If the string does not match any of the spearator keywords,
+    it is returned as is:
+
+    >>> separator(', ')
+    ', '
+
+    @param separator character or separator keyword
+
+    @return separator character
+    """
+    if sep == "pipe":
+        return "|"
+    elif sep == "comma":
+        return ","
+    elif sep == "space":
+        return " "
+    elif sep == "tab" or sep == "\\t":
+        return "\t"
+    elif sep == "newline" or sep == "\\n":
+        return "\n"
+    return sep
+
+
+def diff_files(filename_a, filename_b):
+    """!Diffs two text files and returns difference.
+
+    @param filename_a first file path
+    @param filename_b second file path
+
+    @return list of strings
+    """
+    import difflib
+    differ = difflib.Differ()
+    fh_a = open(filename_a, 'r')
+    fh_b = open(filename_b, 'r')
+    result = list(differ.compare(fh_a.readlines(),
+                                 fh_b.readlines()))
+    return result
+
+
+def try_remove(path):
+    """!Attempt to remove a file; no exception is generated if the
+    attempt fails.
+
+    @param path path to file to remove
+    """
+    try:
+        os.remove(path)
+    except:
+        pass
+
+
+def try_rmdir(path):
+    """!Attempt to remove a directory; no exception is generated if the
+    attempt fails.
+
+    @param path path to directory to remove
+    """
+    try:
+        os.rmdir(path)
+    except:
+        shutil.rmtree(path, ignore_errors=True)
+
+
+def basename(path, ext=None):
+    """!Remove leading directory components and an optional extension
+    from the specified path
+
+    @param path path
+    @param ext extension
+    """
+    name = os.path.basename(path)
+    if not ext:
+        return name
+    fs = name.rsplit('.', 1)
+    if len(fs) > 1 and fs[1].lower() == ext:
+        name = fs[0]
+    return name
+
+
+class KeyValue(dict):
+    """A general-purpose key-value store.
+
+    KeyValue is a subclass of dict, but also allows entries to be read and
+    written using attribute syntax. Example:
+
+    \code
+    >>> reg = KeyValue()
+    >>> reg['north'] = 489
+    >>> reg.north
+    489
+    >>> reg.south = 205
+    >>> reg['south']
+    205
+
+    \endcode
+    """
+
+    def __getattr__(self, key):
+        return self[key]
+
+    def __setattr__(self, key, value):
+        self[key] = value
+
+
+def parse_key_val(s, sep='=', dflt=None, val_type=None, vsep=None):
+    """!Parse a string into a dictionary, where entries are separated
+    by newlines and the key and value are separated by `sep' (default: `=')
+
+    >>> parse_key_val('min=20\\nmax=50') == {'min': '20', 'max': '50'}
+    True
+    >>> parse_key_val('min=20\\nmax=50',
+    ...     val_type=float) == {'min': 20, 'max': 50}
+    True
+
+    @param s string to be parsed
+    @param sep key/value separator
+    @param dflt default value to be used
+    @param val_type value type (None for no cast)
+    @param vsep vertical separator (default is Python 'universal newlines' approach)
+
+    @return parsed input (dictionary of keys/values)
+    """
+    result = KeyValue()
+
+    if not s:
+        return result
+
+    if vsep:
+        lines = s.split(vsep)
+        try:
+            lines.remove('\n')
+        except ValueError:
+            pass
+    else:
+        lines = s.splitlines()
+
+    for line in lines:
+        kv = line.split(sep, 1)
+        k = kv[0].strip()
+        if len(kv) > 1:
+            v = kv[1].strip()
+        else:
+            v = dflt
+
+        if val_type:
+            result[k] = val_type(v)
+        else:
+            result[k] = v
+
+    return result
+
+
+def decode(string):
+    enc = locale.getdefaultlocale()[1]
+    if enc:
+        return string.decode(enc)
+
+    return string
+
+
+def encode(string):
+    enc = locale.getdefaultlocale()[1]
+    if enc:
+        return string.encode(enc)
+
+    return string

+ 1 - 0
lib/python/script/vector.py

@@ -27,6 +27,7 @@ import types
 import copy
 import copy
 import __builtin__
 import __builtin__
 
 
+from utils import parse_key_val
 from core import *
 from core import *
 
 
 # run "v.db.connect -g ..." and parse output
 # run "v.db.connect -g ..." and parse output

+ 2 - 1
scripts/d.correlate/d.correlate.py

@@ -28,6 +28,7 @@
 
 
 import sys
 import sys
 import os
 import os
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def main():
 def main():
@@ -96,7 +97,7 @@ def main():
 		ofile.close()
 		ofile.close()
 		p.wait()
 		p.wait()
 
 
-    grass.try_remove(tmpfile)
+    try_remove(tmpfile)
 
 
 if __name__ == "__main__":
 if __name__ == "__main__":
     options, flags = grass.parser()
     options, flags = grass.parser()

+ 4 - 3
scripts/d.polar/d.polar.py

@@ -50,12 +50,13 @@ import math
 import atexit
 import atexit
 import glob
 import glob
 import shutil
 import shutil
+from grass.script.utils import try_remove, basename
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def cleanup():
 def cleanup():
-    grass.try_remove(tmp)
+    try_remove(tmp)
     for f in glob.glob(tmp + '_*'):
     for f in glob.glob(tmp + '_*'):
-	grass.try_remove(f)
+	try_remove(f)
 
 
 def plot_xgraph():
 def plot_xgraph():
     newline = ['\n']
     newline = ['\n']
@@ -480,7 +481,7 @@ def main():
     # Now output:
     # Now output:
 
 
     if eps:
     if eps:
-	psout = grass.basename(eps, 'eps') + '.eps'
+	psout = basename(eps, 'eps') + '.eps'
 	plot_eps(psout)
 	plot_eps(psout)
     elif xgraph:
     elif xgraph:
 	plot_xgraph()
 	plot_xgraph()

+ 5 - 4
scripts/db.out.ogr/db.out.ogr.py

@@ -54,6 +54,7 @@
 
 
 import sys
 import sys
 import os
 import os
+from grass.script.utils import try_remove, basename
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def main():
 def main():
@@ -67,7 +68,7 @@ def main():
 	format = "ESRI_Shapefile"
 	format = "ESRI_Shapefile"
 
 
     if format.lower() == 'csv':
     if format.lower() == 'csv':
-	olayer = grass.basename(dsn, 'csv')
+	olayer = basename(dsn, 'csv')
     else:
     else:
 	olayer = None
 	olayer = None
 
 
@@ -89,13 +90,13 @@ def main():
     if format == "ESRI_Shapefile":
     if format == "ESRI_Shapefile":
 	exts = ['shp', 'shx', 'prj']
 	exts = ['shp', 'shx', 'prj']
 	if dsn.endswith('.dbf'):
 	if dsn.endswith('.dbf'):
-	    outname = grass.basename(dsn, 'dbf')
+	    outname = basename(dsn, 'dbf')
 	    for ext in exts:
 	    for ext in exts:
-		grass.try_remove("%s.%s" % (outname, ext))
+		try_remove("%s.%s" % (outname, ext))
 	    outname += '.dbf'
 	    outname += '.dbf'
 	else:
 	else:
 	    for ext in exts:
 	    for ext in exts:
-		grass.try_remove(os.path.join(dsn, "%s.%s" % (input, ext)))
+		try_remove(os.path.join(dsn, "%s.%s" % (input, ext)))
 	    outname = os.path.join(dsn, input + ".dbf")
 	    outname = os.path.join(dsn, input + ".dbf")
     elif format.lower() == 'csv':
     elif format.lower() == 'csv':
 	outname = dsn + '.csv'
 	outname = dsn + '.csv'

+ 2 - 1
scripts/db.univar/db.univar.py

@@ -59,11 +59,12 @@ import sys
 import os
 import os
 import atexit
 import atexit
 import math
 import math
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def cleanup():
 def cleanup():
     for ext in ['', '.sort']:
     for ext in ['', '.sort']:
-        grass.try_remove(tmp + ext)
+        try_remove(tmp + ext)
 
 
 def sortfile(infile, outfile):
 def sortfile(infile, outfile):
     inf = file(infile, 'r')
     inf = file(infile, 'r')

+ 2 - 1
scripts/g.extension/g.extension.py

@@ -131,6 +131,7 @@ try:
 except ImportError:
 except ImportError:
     import elementtree.ElementTree as etree # Python <= 2.4
     import elementtree.ElementTree as etree # Python <= 2.4
 
 
+from grass.script.utils import try_rmdir
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 # temp dir
 # temp dir
@@ -391,7 +392,7 @@ def get_wxgui_extensions():
 
 
 def cleanup():
 def cleanup():
     if REMOVE_TMPDIR:
     if REMOVE_TMPDIR:
-        grass.try_rmdir(TMPDIR)
+        try_rmdir(TMPDIR)
     else:
     else:
         grass.message("\n%s\n" % _("Path to the source code:"))
         grass.message("\n%s\n" % _("Path to the source code:"))
         sys.stderr.write('%s\n' % os.path.join(TMPDIR, options['extension']))
         sys.stderr.write('%s\n' % os.path.join(TMPDIR, options['extension']))

+ 3 - 2
scripts/g.manual/g.manual.py

@@ -50,6 +50,7 @@ import sys
 import os
 import os
 import urllib
 import urllib
 
 
+from grass.script.utils import basename
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def start_browser(entry):
 def start_browser(entry):
@@ -120,9 +121,9 @@ def main():
         browser_name = os.getenv('GRASS_HTML_BROWSER_MACOSX', '..').split('.')[2]
         browser_name = os.getenv('GRASS_HTML_BROWSER_MACOSX', '..').split('.')[2]
     elif sys.platform == 'cygwin':
     elif sys.platform == 'cygwin':
         # hack for Cygwin
         # hack for Cygwin
-        browser_name = grass.basename(browser, 'exe')
+        browser_name = basename(browser, 'exe')
     else:
     else:
-        browser_name = grass.basename(browser)
+        browser_name = basename(browser)
     
     
     # keep order!
     # keep order!
     # first test for index...
     # first test for index...

+ 3 - 2
scripts/i.oif/i.oif.py

@@ -42,6 +42,7 @@
 
 
 import sys
 import sys
 import os
 import os
+from grass.script.utils import parse_key_val
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 
 
@@ -86,7 +87,7 @@ def main():
         for band in bands:
         for band in bands:
             grass.verbose("band %d" % band)
             grass.verbose("band %d" % band)
             s = grass.read_command('r.univar', flags='g', map=band)
             s = grass.read_command('r.univar', flags='g', map=band)
-            kv = grass.parse_key_val(s)
+            kv = parse_key_val(s)
             stddev[band] = float(kv['stddev'])
             stddev[band] = float(kv['stddev'])
     else:
     else:
         # run all bands in parallel
         # run all bands in parallel
@@ -117,7 +118,7 @@ def main():
 
 
     # parse the results
     # parse the results
         for band in bands:
         for band in bands:
-            kv = grass.parse_key_val(pout[band])
+            kv = parse_key_val(pout[band])
             stddev[band] = float(kv['stddev'])
             stddev[band] = float(kv['stddev'])
 
 
 
 

+ 2 - 1
scripts/i.spectral/i.spectral.py

@@ -72,11 +72,12 @@
 
 
 import os
 import os
 import atexit
 import atexit
+from grass.script.utils import try_rmdir
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 
 
 def cleanup():
 def cleanup():
-    grass.try_rmdir(tmp_dir)
+    try_rmdir(tmp_dir)
 
 
 
 
 def draw_gnuplot(what, xlabels, output, img_format, coord_legend):
 def draw_gnuplot(what, xlabels, output, img_format, coord_legend):

+ 4 - 3
scripts/m.proj/m.proj.py

@@ -93,6 +93,7 @@
 import sys
 import sys
 import os
 import os
 import threading
 import threading
+from grass.script.utils import separator, parse_key_val
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 class TrThread(threading.Thread):
 class TrThread(threading.Thread):
@@ -158,12 +159,12 @@ def main():
 	except ValueError:
 	except ValueError:
 	    ifs = ofs = fs
 	    ifs = ofs = fs
 
 
-    ifs = grass.separator(ifs)
-    ofs = grass.separator(ofs)
+    ifs = separator(ifs)
+    ofs = separator(ofs)
 
 
     #### set up projection params
     #### set up projection params
     s = grass.read_command("g.proj", flags='j')
     s = grass.read_command("g.proj", flags='j')
-    kv = grass.parse_key_val(s)
+    kv = parse_key_val(s)
     if "XY location" in kv['+proj'] and (ll_in or ll_out):
     if "XY location" in kv['+proj'] and (ll_in or ll_out):
 	grass.fatal(_("Unable to project to or from a XY location")) 
 	grass.fatal(_("Unable to project to or from a XY location")) 
 
 

+ 3 - 2
scripts/r.pack/r.pack.py

@@ -37,10 +37,11 @@ import shutil
 import atexit
 import atexit
 import tarfile
 import tarfile
 
 
+from grass.script.utils import try_rmdir, try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def cleanup():
 def cleanup():
-    grass.try_rmdir(tmp)
+    try_rmdir(tmp)
 
 
 def main():
 def main():
     infile = options['input']
     infile = options['input']
@@ -69,7 +70,7 @@ def main():
     if os.path.exists(outfile):
     if os.path.exists(outfile):
         if os.getenv('GRASS_OVERWRITE'):
         if os.getenv('GRASS_OVERWRITE'):
             grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
             grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
-            grass.try_remove(outfile)
+            try_remove(outfile)
         else:
         else:
             grass.fatal(_("option <output>: <%s> exists.") % outfile)
             grass.fatal(_("option <output>: <%s> exists.") % outfile)
     
     

+ 2 - 1
scripts/r.tileset/r.tileset.py

@@ -112,6 +112,7 @@ import subprocess
 import tempfile
 import tempfile
 import math
 import math
 
 
+from grass.script.utils import separator
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def bboxToPoints(bbox):
 def bboxToPoints(bbox):
@@ -266,7 +267,7 @@ def main():
     grass.debug('Getting destination region')
     grass.debug('Getting destination region')
 
 
     # output field separator
     # output field separator
-    fs = grass.separator(options['separator'])
+    fs = separator(options['separator'])
 
 
     # project the destination region into the source:
     # project the destination region into the source:
     grass.verbose('Projecting destination region into source...')
     grass.verbose('Projecting destination region into source...')

+ 4 - 3
scripts/r.unpack/r.unpack.py

@@ -41,11 +41,12 @@ import shutil
 import tarfile
 import tarfile
 import atexit
 import atexit
 
 
+from grass.script.utils import diff_files, try_rmdir
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 
 
 def cleanup():
 def cleanup():
-    grass.try_rmdir(tmp_dir)
+    try_rmdir(tmp_dir)
 
 
 
 
 def main():
 def main():
@@ -94,14 +95,14 @@ def main():
     if not grass.compare_key_value_text_files(filename_a=proj_info_file_1,
     if not grass.compare_key_value_text_files(filename_a=proj_info_file_1,
                                               filename_b=proj_info_file_2,
                                               filename_b=proj_info_file_2,
                                               proj=True):
                                               proj=True):
-        diff_result_1 = grass.diff_files(proj_info_file_1, proj_info_file_2)
+        diff_result_1 = diff_files(proj_info_file_1, proj_info_file_2)
 
 
     proj_units_file_1 = 'PROJ_UNITS'
     proj_units_file_1 = 'PROJ_UNITS'
     proj_units_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
     proj_units_file_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
     if not grass.compare_key_value_text_files(filename_a=proj_units_file_1,
     if not grass.compare_key_value_text_files(filename_a=proj_units_file_1,
                                               filename_b=proj_units_file_2,
                                               filename_b=proj_units_file_2,
                                               units=True):
                                               units=True):
-        diff_result_2 = grass.diff_files(proj_units_file_1, proj_units_file_2)
+        diff_result_2 = diff_files(proj_units_file_1, proj_units_file_2)
 
 
     if diff_result_1 or diff_result_2:
     if diff_result_1 or diff_result_2:
         if flags['o']:
         if flags['o']:

+ 7 - 6
scripts/v.in.e00/v.in.e00.py

@@ -41,6 +41,7 @@ import sys
 import os
 import os
 import shutil
 import shutil
 import glob
 import glob
+from grass.script.utils import try_rmdir, try_remove, basename
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def main():
 def main():
@@ -66,7 +67,7 @@ def main():
     if type not in ['point','line','area']:
     if type not in ['point','line','area']:
 	grass.fatal(_('Must specify one of "point", "line", or "area".'))
 	grass.fatal(_('Must specify one of "point", "line", or "area".'))
 
 
-    e00name = grass.basename(filename, 'e00')
+    e00name = basename(filename, 'e00')
     # avcimport only accepts 13 chars:
     # avcimport only accepts 13 chars:
     e00shortname = e00name[:13]
     e00shortname = e00name[:13]
 
 
@@ -85,7 +86,7 @@ def main():
 
 
     #make a temporary directory
     #make a temporary directory
     tmpdir = grass.tempfile()
     tmpdir = grass.tempfile()
-    grass.try_remove(tmpdir)
+    try_remove(tmpdir)
     os.mkdir(tmpdir)
     os.mkdir(tmpdir)
 
 
     files = glob.glob(e00name + '.e[0-9][0-9]') + glob.glob(e00name + '.E[0-9][0-9]')
     files = glob.glob(e00name + '.e[0-9][0-9]') + glob.glob(e00name + '.E[0-9][0-9]')
@@ -115,8 +116,8 @@ def main():
 	grass.message(_("E00 ASCII found and converted to Arc Coverage in current directory"))
 	grass.message(_("E00 ASCII found and converted to Arc Coverage in current directory"))
     else:
     else:
 	grass.message(_("E00 Compressed ASCII found. Will uncompress first..."))
 	grass.message(_("E00 Compressed ASCII found. Will uncompress first..."))
-	grass.try_remove(e00shortname)
-	grass.try_remove(info)
+	try_remove(e00shortname)
+	try_remove(info)
 	grass.call(['e00conv', filename, e00tmp + '.e00'])
 	grass.call(['e00conv', filename, e00tmp + '.e00'])
 	grass.message(_("...converted to Arc Coverage in current directory"))
 	grass.message(_("...converted to Arc Coverage in current directory"))
 	grass.call(['avcimport', e00tmp + '.e00', e00shortname], stderr = nuldev)
 	grass.call(['avcimport', e00tmp + '.e00', e00shortname], stderr = nuldev)
@@ -141,10 +142,10 @@ def main():
     for root, dirs, files in os.walk('.', False):
     for root, dirs, files in os.walk('.', False):
 	for f in files:
 	for f in files:
 	    path = os.path.join(root, f)
 	    path = os.path.join(root, f)
-	    grass.try_remove(path)
+	    try_remove(path)
 	for d in dirs:
 	for d in dirs:
 	    path = os.path.join(root, d)
 	    path = os.path.join(root, d)
-	    grass.try_rmdir(path)
+	    try_rmdir(path)
 
 
     os.chdir('..')
     os.chdir('..')
     os.rmdir(tmpdir)
     os.rmdir(tmpdir)

+ 4 - 3
scripts/v.in.gns/v.in.gns.py

@@ -39,6 +39,7 @@
 
 
 import sys
 import sys
 import os
 import os
+from grass.script.utils import try_remove, basename, parse_key_val
 from grass.script import core as grass
 from grass.script import core as grass
 from grass.script import vector as vgrass
 from grass.script import vector as vgrass
 
 
@@ -47,11 +48,11 @@ def main():
     filevect = options['output']
     filevect = options['output']
     
     
     if not filevect:
     if not filevect:
-	filevect = grass.basename(fileorig, 'txt')
+	filevect = basename(fileorig, 'txt')
 
 
     #are we in LatLong location?
     #are we in LatLong location?
     s = grass.read_command("g.proj", flags='j')
     s = grass.read_command("g.proj", flags='j')
-    kv = grass.parse_key_val(s)
+    kv = parse_key_val(s)
     if kv['+proj'] != 'longlat':
     if kv['+proj'] != 'longlat':
 	grass.fatal(_("This module only operates in LatLong/WGS84 locations"))
 	grass.fatal(_("This module only operates in LatLong/WGS84 locations"))
 
 
@@ -139,7 +140,7 @@ def main():
 		      input = tmpfile, output = filevect,
 		      input = tmpfile, output = filevect,
 		      columns = columns)
 		      columns = columns)
 
 
-    grass.try_remove(tmpfile)
+    try_remove(tmpfile)
 
 
     # write cmd history:
     # write cmd history:
     vgrass.vector_history(filevect)
     vgrass.vector_history(filevect)

+ 3 - 2
scripts/v.in.lines/v.in.lines.py

@@ -36,15 +36,16 @@ import sys
 import os
 import os
 import atexit
 import atexit
 import string
 import string
+from grass.script.utils import separator, try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def cleanup():
 def cleanup():
-    grass.try_remove(tmp)
+    try_remove(tmp)
 
 
 def main():
 def main():
     global tmp
     global tmp
 
 
-    fs = options['separator']
+    fs = separator(options['separator'])
     threeD = flags['z']
     threeD = flags['z']
 
 
     prog = 'v.in.lines'
     prog = 'v.in.lines'

+ 3 - 2
scripts/v.in.mapgen/v.in.mapgen.py

@@ -50,11 +50,12 @@ import atexit
 import string
 import string
 import time
 import time
 import shutil
 import shutil
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 
 
 def cleanup():
 def cleanup():
-    grass.try_remove(tmp)
-    grass.try_remove(tmp + '.dig')
+    try_remove(tmp)
+    try_remove(tmp + '.dig')
 
 
 def main():
 def main():
     global tmp
     global tmp

+ 3 - 2
scripts/v.in.wfs/v.in.wfs.py

@@ -76,6 +76,7 @@
 
 
 import os
 import os
 import sys
 import sys
+from grass.script.utils import try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 import urllib
 import urllib
 
 
@@ -131,13 +132,13 @@ def main():
             grass.fatal('A file called "wms_capabilities.xml" already exists here')
             grass.fatal('A file called "wms_capabilities.xml" already exists here')
         # os.move() might fail if the temp file is on another volume, so we copy instead
         # os.move() might fail if the temp file is on another volume, so we copy instead
         shutil.copy(tmpxml, 'wms_capabilities.xml')
         shutil.copy(tmpxml, 'wms_capabilities.xml')
-        grass.try_remove(tmpxml)
+        try_remove(tmpxml)
         sys.exit(0)
         sys.exit(0)
 
 
 
 
     grass.message(_("Importing data..."))
     grass.message(_("Importing data..."))
     ret = grass.run_command('v.in.ogr', flags = 'o', dsn = tmpxml, out = out)
     ret = grass.run_command('v.in.ogr', flags = 'o', dsn = tmpxml, out = out)
-    grass.try_remove(tmpxml)
+    try_remove(tmpxml)
     
     
     if ret == 0:
     if ret == 0:
         grass.message(_("Vector points map <%s> imported from WFS.") % out)
         grass.message(_("Vector points map <%s> imported from WFS.") % out)

+ 3 - 2
scripts/v.pack/v.pack.py

@@ -37,11 +37,12 @@ import shutil
 import tarfile
 import tarfile
 import atexit
 import atexit
 
 
+from grass.script.utils import try_rmdir, try_remove
 from grass.script import core as grass
 from grass.script import core as grass
 from grass.script import vector as vector
 from grass.script import vector as vector
 
 
 def cleanup():
 def cleanup():
-    grass.try_rmdir(basedir)
+    try_rmdir(basedir)
 
 
 def main():
 def main():
     infile = options['input']
     infile = options['input']
@@ -74,7 +75,7 @@ def main():
     if os.path.exists(outfile):
     if os.path.exists(outfile):
         if os.getenv('GRASS_OVERWRITE'):
         if os.getenv('GRASS_OVERWRITE'):
             grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
             grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
-            grass.try_remove(outfile)
+            try_remove(outfile)
         else:
         else:
             grass.fatal(_("option <%s>: <%s> exists.") % ("output", outfile))
             grass.fatal(_("option <%s>: <%s> exists.") % ("output", outfile))
     
     

+ 4 - 3
scripts/v.unpack/v.unpack.py

@@ -39,12 +39,13 @@ import shutil
 import tarfile
 import tarfile
 import atexit
 import atexit
 
 
+from grass.script.utils import diff_files, try_rmdir
 from grass.script import core as grass
 from grass.script import core as grass
 from grass.script import db as grassdb
 from grass.script import db as grassdb
 
 
 
 
 def cleanup():
 def cleanup():
-    grass.try_rmdir(tmp_dir)
+    try_rmdir(tmp_dir)
 
 
 
 
 def main():
 def main():
@@ -102,13 +103,13 @@ def main():
     diff_result_1 = diff_result_2 = None
     diff_result_1 = diff_result_2 = None
     if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_INFO'),
     if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_INFO'),
                                               filename_b=loc_proj, proj=True):
                                               filename_b=loc_proj, proj=True):
-        diff_result_1 = grass.diff_files(os.path.join(tmp_dir, 'PROJ_INFO'),
+        diff_result_1 = diff_files(os.path.join(tmp_dir, 'PROJ_INFO'),
                                          loc_proj)
                                          loc_proj)
 
 
     if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_UNITS'),
     if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_UNITS'),
                                               filename_b=loc_proj_units,
                                               filename_b=loc_proj_units,
                                               units=True):
                                               units=True):
-        diff_result_2 = grass.diff_files(os.path.join(tmp_dir, 'PROJ_UNITS'),
+        diff_result_2 = diff_files(os.path.join(tmp_dir, 'PROJ_UNITS'),
                                          loc_proj_units)
                                          loc_proj_units)
 
 
     if diff_result_1 or diff_result_2:
     if diff_result_1 or diff_result_2: