[GRASS-SVN] r61854 - in grass/trunk: gui/wxpython/animation gui/wxpython/core gui/wxpython/gmodeler gui/wxpython/mapdisp gui/wxpython/mapwin gui/wxpython/rlisetup gui/wxpython/vnet lib/python/script scripts/d.correlate scripts/d.polar scripts/db.out.ogr scripts/db.univar scripts/g.extension scripts/g.manual scripts/i.oif scripts/i.spectral scripts/m.proj scripts/r.pack scripts/r.tileset scripts/r.unpack scripts/v.in.e00 scripts/v.in.gns scripts/v.in.lines scripts/v.in.mapgen scripts/v.in.wfs scripts/v.pack scripts/v.unpack
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Sep 10 22:54:54 PDT 2014
Author: annakrat
Date: 2014-09-10 22:54:54 -0700 (Wed, 10 Sep 2014)
New Revision: 61854
Added:
grass/trunk/lib/python/script/utils.py
Modified:
grass/trunk/gui/wxpython/animation/data.py
grass/trunk/gui/wxpython/core/render.py
grass/trunk/gui/wxpython/core/toolboxes.py
grass/trunk/gui/wxpython/core/ws.py
grass/trunk/gui/wxpython/gmodeler/frame.py
grass/trunk/gui/wxpython/mapdisp/main.py
grass/trunk/gui/wxpython/mapwin/analysis.py
grass/trunk/gui/wxpython/rlisetup/frame.py
grass/trunk/gui/wxpython/vnet/vnet_core.py
grass/trunk/gui/wxpython/vnet/vnet_data.py
grass/trunk/lib/python/script/Makefile
grass/trunk/lib/python/script/__init__.py
grass/trunk/lib/python/script/array.py
grass/trunk/lib/python/script/core.py
grass/trunk/lib/python/script/db.py
grass/trunk/lib/python/script/pythonlib.dox
grass/trunk/lib/python/script/raster.py
grass/trunk/lib/python/script/raster3d.py
grass/trunk/lib/python/script/task.py
grass/trunk/lib/python/script/vector.py
grass/trunk/scripts/d.correlate/d.correlate.py
grass/trunk/scripts/d.polar/d.polar.py
grass/trunk/scripts/db.out.ogr/db.out.ogr.py
grass/trunk/scripts/db.univar/db.univar.py
grass/trunk/scripts/g.extension/g.extension.py
grass/trunk/scripts/g.manual/g.manual.py
grass/trunk/scripts/i.oif/i.oif.py
grass/trunk/scripts/i.spectral/i.spectral.py
grass/trunk/scripts/m.proj/m.proj.py
grass/trunk/scripts/r.pack/r.pack.py
grass/trunk/scripts/r.tileset/r.tileset.py
grass/trunk/scripts/r.unpack/r.unpack.py
grass/trunk/scripts/v.in.e00/v.in.e00.py
grass/trunk/scripts/v.in.gns/v.in.gns.py
grass/trunk/scripts/v.in.lines/v.in.lines.py
grass/trunk/scripts/v.in.mapgen/v.in.mapgen.py
grass/trunk/scripts/v.in.wfs/v.in.wfs.py
grass/trunk/scripts/v.pack/v.pack.py
grass/trunk/scripts/v.unpack/v.unpack.py
Log:
pythonlib: create new file utils not to clutter core with simple functions and move some of them from core and change all affected imports
Modified: grass/trunk/gui/wxpython/animation/data.py
===================================================================
--- grass/trunk/gui/wxpython/animation/data.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/animation/data.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -19,6 +19,7 @@
import os
import copy
+from grass.script.utils import parse_key_val
from grass.script import core as gcore
from core.utils import _
@@ -232,11 +233,11 @@
self._regions = regions
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),
val_type=float)
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),
val_type=float)
for key in ('n', 's', 'e', 'w'):
Modified: grass/trunk/gui/wxpython/core/render.py
===================================================================
--- grass/trunk/gui/wxpython/core/render.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/core/render.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -38,6 +38,7 @@
import wx
from grass.script import core as grass
+from grass.script.utils import try_remove
from grass.pydispatch.signal import Signal
from core import utils
@@ -171,7 +172,7 @@
for f in [self.mapfile, self.maskfile]:
if not f:
continue
- grass.try_remove(f)
+ try_remove(f)
f = None
self.forceRender = False
@@ -1308,9 +1309,9 @@
def _clean(self, llist):
for layer in llist:
if layer.maskfile:
- grass.try_remove(layer.maskfile)
+ try_remove(layer.maskfile)
if layer.mapfile:
- grass.try_remove(layer.mapfile)
+ try_remove(layer.mapfile)
llist.remove(layer)
def Clean(self):
Modified: grass/trunk/gui/wxpython/core/toolboxes.py
===================================================================
--- grass/trunk/gui/wxpython/core/toolboxes.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/core/toolboxes.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -36,6 +36,7 @@
import grass.script.task as gtask
import grass.script.core as gcore
+from grass.script.utils import try_remove
from grass.script.core import ScriptError
from core.debug import Debug
@@ -59,7 +60,7 @@
to let gui regenerate it next time it starts."""
path = os.path.join(GetSettingsPath(), 'toolboxes', 'menudata.xml')
if os.path.exists(path):
- gcore.try_remove(path)
+ try_remove(path)
def getMenudataFile(userRootFile, newFile, fallback):
Modified: grass/trunk/gui/wxpython/core/ws.py
===================================================================
--- grass/trunk/gui/wxpython/core/ws.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/core/ws.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -22,6 +22,7 @@
import wx
from wx.lib.newevent import NewEvent
+from grass.script.utils import try_remove
from grass.script import core as grass
from core import utils
@@ -74,7 +75,7 @@
self.updateProgress = Signal('RenderWMSMgr.updateProgress')
def __del__(self):
- grass.try_remove(self.tempMap)
+ try_remove(self.tempMap)
def Render(self, cmd, env):
"""If it is needed, download missing WMS data.
@@ -117,8 +118,8 @@
self.fetched_data_cmd = None
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.thread.abort()
Modified: grass/trunk/gui/wxpython/gmodeler/frame.py
===================================================================
--- grass/trunk/gui/wxpython/gmodeler/frame.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/gmodeler/frame.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -55,6 +55,7 @@
from gmodeler.model import *
from gmodeler.dialogs import *
+from grass.script.utils import try_remove
from grass.script import core as grass
class ModelFrame(wx.Frame):
@@ -1726,7 +1727,7 @@
def OnDone(self, cmd, returncode):
"""Python script finished"""
- grass.try_remove(self.filename)
+ try_remove(self.filename)
self.filename = None
def SaveAs(self, force = False):
Modified: grass/trunk/gui/wxpython/mapdisp/main.py
===================================================================
--- grass/trunk/gui/wxpython/mapdisp/main.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/mapdisp/main.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -38,10 +38,11 @@
from core.render import Map, MapLayer
from core.utils import _
from mapdisp.frame import MapFrame
-from grass.script import core as grass
from core.debug import Debug
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
# for standalone app
@@ -377,7 +378,7 @@
# self.timer.Stop()
# terminate thread
for f in monFile.itervalues():
- grass.try_remove(f)
+ try_remove(f)
def watcher(self):
"""Redraw, if new layer appears (check's timestamp of
Modified: grass/trunk/gui/wxpython/mapwin/analysis.py
===================================================================
--- grass/trunk/gui/wxpython/mapwin/analysis.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/mapwin/analysis.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -27,7 +27,7 @@
from core.giface import Notification
from grass.pydispatch.signal import Signal
-import grass.script.core as gcore
+from grass.script.utils import parse_key_val
class AnalysisControllerBase:
@@ -354,7 +354,7 @@
coordinates = coords + [coords[0]]
coordinates = ','.join([str(item) for sublist in coordinates for item in sublist])
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:
self._giface.WriteWarning(_("Units not recognized, measurement failed."))
unit = ''
Modified: grass/trunk/gui/wxpython/rlisetup/frame.py
===================================================================
--- grass/trunk/gui/wxpython/rlisetup/frame.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/rlisetup/frame.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -10,7 +10,7 @@
from core import globalvar, gcmd
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.wizard import RLIWizard
import locale
@@ -217,7 +217,7 @@
if dlg.ShowModal() == wx.ID_YES:
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()
dlg.Destroy()
return
Modified: grass/trunk/gui/wxpython/vnet/vnet_core.py
===================================================================
--- grass/trunk/gui/wxpython/vnet/vnet_core.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/vnet/vnet_core.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -20,6 +20,7 @@
"""
import os
+from grass.script.utils import try_remove
from grass.script import core as grass
import wx
@@ -466,7 +467,7 @@
def _vnetPathRunAnDone(self, cmd, returncode):
"""Called when v.net.path analysis is done"""
- grass.try_remove(self.coordsTmpFile)
+ try_remove(self.coordsTmpFile)
self._onDone(cmd, returncode)
@@ -582,7 +583,7 @@
driver = driver,
database = database)
- grass.try_remove(sqlFile)
+ try_remove(sqlFile)
def _runTurnsAnDone(self, cmd, returncode):
"""Called when analysis is done"""
@@ -694,7 +695,7 @@
"""Called when analysis is done"""
self.tmp_maps.DeleteTmpMap(self.tmpInPts) #TODO remove earlier (OnDone lambda?)
self.tmp_maps.DeleteTmpMap(self.tmpInPtsConnected)
- grass.try_remove(self.tmpPtsAsciiFile)
+ try_remove(self.tmpPtsAsciiFile)
if cmd[0] == "v.net.flow":
self.tmp_maps.DeleteTmpMap(self.vnetFlowTmpCut)
Modified: grass/trunk/gui/wxpython/vnet/vnet_data.py
===================================================================
--- grass/trunk/gui/wxpython/vnet/vnet_data.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/gui/wxpython/vnet/vnet_data.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -26,6 +26,7 @@
import types
from copy import deepcopy
+from grass.script.utils import try_remove
from grass.script import core as grass
import wx
@@ -1093,7 +1094,7 @@
self.sep = ';'
def __del__(self):
- grass.try_remove(self.histFile)
+ try_remove(self.histFile)
def GetNext(self):
"""Go one step forward in history"""
@@ -1148,7 +1149,7 @@
oldHist.close()
newHist.close()
- grass.try_remove(self.histFile)
+ try_remove(self.histFile)
self.histFile = newHistFile
self.newHistStepData.clear()
Modified: grass/trunk/lib/python/script/Makefile
===================================================================
--- grass/trunk/lib/python/script/Makefile 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/Makefile 2014-09-11 05:54:54 UTC (rev 61854)
@@ -6,7 +6,7 @@
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__)
PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
Modified: grass/trunk/lib/python/script/__init__.py
===================================================================
--- grass/trunk/lib/python/script/__init__.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/__init__.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -3,3 +3,4 @@
from raster import *
from raster3d import *
from vector import *
+from utils import *
Modified: grass/trunk/lib/python/script/array.py
===================================================================
--- grass/trunk/lib/python/script/array.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/array.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -130,8 +130,10 @@
import os
import numpy
+from utils import try_remove
import core as grass
+
###############################################################################
class array(numpy.memmap):
@@ -161,7 +163,7 @@
def _close(self):
numpy.memmap._close(self)
if isinstance(self, array):
- grass.try_remove(self.filename)
+ try_remove(self.filename)
def read(self, mapname, null=None):
"""!Read raster map into array
@@ -274,7 +276,7 @@
numpy.memmap._close(self)
if isinstance(self, array):
- grass.try_remove(self.filename)
+ try_remove(self.filename)
def read(self, mapname, null=None):
"""!Read 3D raster map into array
Modified: grass/trunk/lib/python/script/core.py
===================================================================
--- grass/trunk/lib/python/script/core.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/core.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -30,9 +30,9 @@
import atexit
import subprocess
import shutil
-import locale
import codecs
+from utils import KeyValue, parse_key_val, basename, encode
from grass.exceptions import ScriptError
# i18N
@@ -82,20 +82,6 @@
"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):
if isinstance(val, types.StringType) or \
isinstance(val, types.UnicodeType):
@@ -670,38 +656,6 @@
return _parse_opts(lines[1:])
-
-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
-
# interface to g.tempfile
@@ -728,81 +682,6 @@
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: `=')
-
- >>> 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 _compare_projection(dic):
"""
!Check if projection has some possibility of duplicate names like
@@ -977,23 +856,6 @@
return False
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
@@ -1456,25 +1318,6 @@
## 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):
"""!Attempt to run a program, with optional arguments.
@@ -1511,49 +1354,6 @@
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.
-
- >>> 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(':')))
-
# interface to g.mapsets
Modified: grass/trunk/lib/python/script/db.py
===================================================================
--- grass/trunk/lib/python/script/db.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/db.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -25,7 +25,9 @@
import tempfile as pytempfile # conflict with core.tempfile
from core import *
+from utils import try_remove
+
def db_describe(table, **args):
"""!Return the list of columns for a database table
(interface to `db.describe -c'). Example:
Modified: grass/trunk/lib/python/script/pythonlib.dox
===================================================================
--- grass/trunk/lib/python/script/pythonlib.dox 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/pythonlib.dox 2014-09-11 05:54:54 UTC (rev 61854)
@@ -13,6 +13,7 @@
- \subpage pythonUsage
- \subpage pythonModules
- \subpage pythonCore
+ - \subpage pythonUtils
- \subpage pythonDb
- \subpage pythonRaster
- \subpage pythonVector
@@ -180,18 +181,30 @@
- 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::try_remove()
+\subsection pythonUtils Utils
+
+ - python::script::utils::float_or_dms()
+
+ - python::script::utils::separator()
- - python::script::core::try_rmdir()
+ - python::script::utils::diff_files()
- - python::script::core::float_or_dms()
+ - python::script::utils::try_remove()
+ - python::script::utils::try_rmdir()
+
+ - python::script::utils::basename()
+
+ - python::script::utils::parse_key_val()
+
+ - python::script::utils::decode()
+
+ - python::script::utils::encode()
+
\subsection pythonDb Database
Interface for <tt>db.*</tt> modules.
Modified: grass/trunk/lib/python/script/raster.py
===================================================================
--- grass/trunk/lib/python/script/raster.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/raster.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -28,6 +28,7 @@
import time
from core import *
+from utils import float_or_dms, parse_key_val
# add raster history
Modified: grass/trunk/lib/python/script/raster3d.py
===================================================================
--- grass/trunk/lib/python/script/raster3d.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/raster3d.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -27,6 +27,7 @@
import string
from core import *
+from utils import float_or_dms, parse_key_val
# add raster history
Modified: grass/trunk/lib/python/script/task.py
===================================================================
--- grass/trunk/lib/python/script/task.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/task.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -30,6 +30,7 @@
except ImportError:
import elementtree.ElementTree as etree # Python <= 2.4
+from utils import decode
from core import *
class grassTask:
Added: grass/trunk/lib/python/script/utils.py
===================================================================
--- grass/trunk/lib/python/script/utils.py (rev 0)
+++ grass/trunk/lib/python/script/utils.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -0,0 +1,220 @@
+"""!@package grass.script.utils
+
+ at brief GRASS Python scripting module (various useful functions)
+
+Useful functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import utils as gutils
+
+...
+ at 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.
+
+ at author Glynn Clements
+ at author Martin Landa <landa.martin gmail.com>
+ at 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
Property changes on: grass/trunk/lib/python/script/utils.py
___________________________________________________________________
Added: svn:mime-type
+ text/x-python
Added: svn:eol-style
+ native
Modified: grass/trunk/lib/python/script/vector.py
===================================================================
--- grass/trunk/lib/python/script/vector.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/lib/python/script/vector.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -27,6 +27,7 @@
import copy
import __builtin__
+from utils import parse_key_val
from core import *
# run "v.db.connect -g ..." and parse output
Modified: grass/trunk/scripts/d.correlate/d.correlate.py
===================================================================
--- grass/trunk/scripts/d.correlate/d.correlate.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/d.correlate/d.correlate.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -28,6 +28,7 @@
import sys
import os
+from grass.script.utils import try_remove
from grass.script import core as grass
def main():
@@ -96,7 +97,7 @@
ofile.close()
p.wait()
- grass.try_remove(tmpfile)
+ try_remove(tmpfile)
if __name__ == "__main__":
options, flags = grass.parser()
Modified: grass/trunk/scripts/d.polar/d.polar.py
===================================================================
--- grass/trunk/scripts/d.polar/d.polar.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/d.polar/d.polar.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -50,12 +50,13 @@
import atexit
import glob
import shutil
+from grass.script.utils import try_remove, basename
from grass.script import core as grass
def cleanup():
- grass.try_remove(tmp)
+ try_remove(tmp)
for f in glob.glob(tmp + '_*'):
- grass.try_remove(f)
+ try_remove(f)
def plot_xgraph():
newline = ['\n']
@@ -480,7 +481,7 @@
# Now output:
if eps:
- psout = grass.basename(eps, 'eps') + '.eps'
+ psout = basename(eps, 'eps') + '.eps'
plot_eps(psout)
elif xgraph:
plot_xgraph()
Modified: grass/trunk/scripts/db.out.ogr/db.out.ogr.py
===================================================================
--- grass/trunk/scripts/db.out.ogr/db.out.ogr.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/db.out.ogr/db.out.ogr.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -54,6 +54,7 @@
import sys
import os
+from grass.script.utils import try_remove, basename
from grass.script import core as grass
def main():
@@ -67,7 +68,7 @@
format = "ESRI_Shapefile"
if format.lower() == 'csv':
- olayer = grass.basename(dsn, 'csv')
+ olayer = basename(dsn, 'csv')
else:
olayer = None
@@ -89,13 +90,13 @@
if format == "ESRI_Shapefile":
exts = ['shp', 'shx', 'prj']
if dsn.endswith('.dbf'):
- outname = grass.basename(dsn, 'dbf')
+ outname = basename(dsn, 'dbf')
for ext in exts:
- grass.try_remove("%s.%s" % (outname, ext))
+ try_remove("%s.%s" % (outname, ext))
outname += '.dbf'
else:
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")
elif format.lower() == 'csv':
outname = dsn + '.csv'
Modified: grass/trunk/scripts/db.univar/db.univar.py
===================================================================
--- grass/trunk/scripts/db.univar/db.univar.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/db.univar/db.univar.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -59,11 +59,12 @@
import os
import atexit
import math
+from grass.script.utils import try_remove
from grass.script import core as grass
def cleanup():
for ext in ['', '.sort']:
- grass.try_remove(tmp + ext)
+ try_remove(tmp + ext)
def sortfile(infile, outfile):
inf = file(infile, 'r')
Modified: grass/trunk/scripts/g.extension/g.extension.py
===================================================================
--- grass/trunk/scripts/g.extension/g.extension.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/g.extension/g.extension.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -131,6 +131,7 @@
except ImportError:
import elementtree.ElementTree as etree # Python <= 2.4
+from grass.script.utils import try_rmdir
from grass.script import core as grass
# temp dir
@@ -391,7 +392,7 @@
def cleanup():
if REMOVE_TMPDIR:
- grass.try_rmdir(TMPDIR)
+ try_rmdir(TMPDIR)
else:
grass.message("\n%s\n" % _("Path to the source code:"))
sys.stderr.write('%s\n' % os.path.join(TMPDIR, options['extension']))
Modified: grass/trunk/scripts/g.manual/g.manual.py
===================================================================
--- grass/trunk/scripts/g.manual/g.manual.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/g.manual/g.manual.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -50,6 +50,7 @@
import os
import urllib
+from grass.script.utils import basename
from grass.script import core as grass
def start_browser(entry):
@@ -120,9 +121,9 @@
browser_name = os.getenv('GRASS_HTML_BROWSER_MACOSX', '..').split('.')[2]
elif sys.platform == 'cygwin':
# hack for Cygwin
- browser_name = grass.basename(browser, 'exe')
+ browser_name = basename(browser, 'exe')
else:
- browser_name = grass.basename(browser)
+ browser_name = basename(browser)
# keep order!
# first test for index...
Modified: grass/trunk/scripts/i.oif/i.oif.py
===================================================================
--- grass/trunk/scripts/i.oif/i.oif.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/i.oif/i.oif.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -42,6 +42,7 @@
import sys
import os
+from grass.script.utils import parse_key_val
from grass.script import core as grass
@@ -86,7 +87,7 @@
for band in bands:
grass.verbose("band %d" % 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'])
else:
# run all bands in parallel
@@ -117,7 +118,7 @@
# parse the results
for band in bands:
- kv = grass.parse_key_val(pout[band])
+ kv = parse_key_val(pout[band])
stddev[band] = float(kv['stddev'])
Modified: grass/trunk/scripts/i.spectral/i.spectral.py
===================================================================
--- grass/trunk/scripts/i.spectral/i.spectral.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/i.spectral/i.spectral.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -72,11 +72,12 @@
import os
import atexit
+from grass.script.utils import try_rmdir
from grass.script import core as grass
def cleanup():
- grass.try_rmdir(tmp_dir)
+ try_rmdir(tmp_dir)
def draw_gnuplot(what, xlabels, output, img_format, coord_legend):
Modified: grass/trunk/scripts/m.proj/m.proj.py
===================================================================
--- grass/trunk/scripts/m.proj/m.proj.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/m.proj/m.proj.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -93,6 +93,7 @@
import sys
import os
import threading
+from grass.script.utils import separator, parse_key_val
from grass.script import core as grass
class TrThread(threading.Thread):
@@ -158,12 +159,12 @@
except ValueError:
ifs = ofs = fs
- ifs = grass.separator(ifs)
- ofs = grass.separator(ofs)
+ ifs = separator(ifs)
+ ofs = separator(ofs)
#### set up projection params
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):
grass.fatal(_("Unable to project to or from a XY location"))
Modified: grass/trunk/scripts/r.pack/r.pack.py
===================================================================
--- grass/trunk/scripts/r.pack/r.pack.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/r.pack/r.pack.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -37,10 +37,11 @@
import atexit
import tarfile
+from grass.script.utils import try_rmdir, try_remove
from grass.script import core as grass
def cleanup():
- grass.try_rmdir(tmp)
+ try_rmdir(tmp)
def main():
infile = options['input']
@@ -69,7 +70,7 @@
if os.path.exists(outfile):
if os.getenv('GRASS_OVERWRITE'):
grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
- grass.try_remove(outfile)
+ try_remove(outfile)
else:
grass.fatal(_("option <output>: <%s> exists.") % outfile)
Modified: grass/trunk/scripts/r.tileset/r.tileset.py
===================================================================
--- grass/trunk/scripts/r.tileset/r.tileset.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/r.tileset/r.tileset.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -112,6 +112,7 @@
import tempfile
import math
+from grass.script.utils import separator
from grass.script import core as grass
def bboxToPoints(bbox):
@@ -266,7 +267,7 @@
grass.debug('Getting destination region')
# output field separator
- fs = grass.separator(options['separator'])
+ fs = separator(options['separator'])
# project the destination region into the source:
grass.verbose('Projecting destination region into source...')
Modified: grass/trunk/scripts/r.unpack/r.unpack.py
===================================================================
--- grass/trunk/scripts/r.unpack/r.unpack.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/r.unpack/r.unpack.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -41,11 +41,12 @@
import tarfile
import atexit
+from grass.script.utils import diff_files, try_rmdir
from grass.script import core as grass
def cleanup():
- grass.try_rmdir(tmp_dir)
+ try_rmdir(tmp_dir)
def main():
@@ -94,14 +95,14 @@
if not grass.compare_key_value_text_files(filename_a=proj_info_file_1,
filename_b=proj_info_file_2,
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_2 = os.path.join(mset_dir, '..', 'PERMANENT', 'PROJ_UNITS')
if not grass.compare_key_value_text_files(filename_a=proj_units_file_1,
filename_b=proj_units_file_2,
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 flags['o']:
Modified: grass/trunk/scripts/v.in.e00/v.in.e00.py
===================================================================
--- grass/trunk/scripts/v.in.e00/v.in.e00.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.in.e00/v.in.e00.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -41,6 +41,7 @@
import os
import shutil
import glob
+from grass.script.utils import try_rmdir, try_remove, basename
from grass.script import core as grass
def main():
@@ -66,7 +67,7 @@
if type not in ['point','line','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:
e00shortname = e00name[:13]
@@ -85,7 +86,7 @@
#make a temporary directory
tmpdir = grass.tempfile()
- grass.try_remove(tmpdir)
+ try_remove(tmpdir)
os.mkdir(tmpdir)
files = glob.glob(e00name + '.e[0-9][0-9]') + glob.glob(e00name + '.E[0-9][0-9]')
@@ -115,8 +116,8 @@
grass.message(_("E00 ASCII found and converted to Arc Coverage in current directory"))
else:
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.message(_("...converted to Arc Coverage in current directory"))
grass.call(['avcimport', e00tmp + '.e00', e00shortname], stderr = nuldev)
@@ -141,10 +142,10 @@
for root, dirs, files in os.walk('.', False):
for f in files:
path = os.path.join(root, f)
- grass.try_remove(path)
+ try_remove(path)
for d in dirs:
path = os.path.join(root, d)
- grass.try_rmdir(path)
+ try_rmdir(path)
os.chdir('..')
os.rmdir(tmpdir)
Modified: grass/trunk/scripts/v.in.gns/v.in.gns.py
===================================================================
--- grass/trunk/scripts/v.in.gns/v.in.gns.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.in.gns/v.in.gns.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -39,6 +39,7 @@
import sys
import os
+from grass.script.utils import try_remove, basename, parse_key_val
from grass.script import core as grass
from grass.script import vector as vgrass
@@ -47,11 +48,11 @@
filevect = options['output']
if not filevect:
- filevect = grass.basename(fileorig, 'txt')
+ filevect = basename(fileorig, 'txt')
#are we in LatLong location?
s = grass.read_command("g.proj", flags='j')
- kv = grass.parse_key_val(s)
+ kv = parse_key_val(s)
if kv['+proj'] != 'longlat':
grass.fatal(_("This module only operates in LatLong/WGS84 locations"))
@@ -139,7 +140,7 @@
input = tmpfile, output = filevect,
columns = columns)
- grass.try_remove(tmpfile)
+ try_remove(tmpfile)
# write cmd history:
vgrass.vector_history(filevect)
Modified: grass/trunk/scripts/v.in.lines/v.in.lines.py
===================================================================
--- grass/trunk/scripts/v.in.lines/v.in.lines.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.in.lines/v.in.lines.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -36,15 +36,16 @@
import os
import atexit
import string
+from grass.script.utils import separator, try_remove
from grass.script import core as grass
def cleanup():
- grass.try_remove(tmp)
+ try_remove(tmp)
def main():
global tmp
- fs = grass.separator(options['separator'])
+ fs = separator(options['separator'])
threeD = flags['z']
prog = 'v.in.lines'
Modified: grass/trunk/scripts/v.in.mapgen/v.in.mapgen.py
===================================================================
--- grass/trunk/scripts/v.in.mapgen/v.in.mapgen.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.in.mapgen/v.in.mapgen.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -50,11 +50,12 @@
import string
import time
import shutil
+from grass.script.utils import try_remove
from grass.script import core as grass
def cleanup():
- grass.try_remove(tmp)
- grass.try_remove(tmp + '.dig')
+ try_remove(tmp)
+ try_remove(tmp + '.dig')
def main():
global tmp
Modified: grass/trunk/scripts/v.in.wfs/v.in.wfs.py
===================================================================
--- grass/trunk/scripts/v.in.wfs/v.in.wfs.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.in.wfs/v.in.wfs.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -76,6 +76,7 @@
import os
import sys
+from grass.script.utils import try_remove
from grass.script import core as grass
import urllib
@@ -131,13 +132,13 @@
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
shutil.copy(tmpxml, 'wms_capabilities.xml')
- grass.try_remove(tmpxml)
+ try_remove(tmpxml)
sys.exit(0)
grass.message(_("Importing data..."))
ret = grass.run_command('v.in.ogr', flags = 'o', dsn = tmpxml, out = out)
- grass.try_remove(tmpxml)
+ try_remove(tmpxml)
if ret == 0:
grass.message(_("Vector points map <%s> imported from WFS.") % out)
Modified: grass/trunk/scripts/v.pack/v.pack.py
===================================================================
--- grass/trunk/scripts/v.pack/v.pack.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.pack/v.pack.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -37,11 +37,12 @@
import tarfile
import atexit
+from grass.script.utils import try_rmdir, try_remove
from grass.script import core as grass
from grass.script import vector as vector
def cleanup():
- grass.try_rmdir(basedir)
+ try_rmdir(basedir)
def main():
infile = options['input']
@@ -74,7 +75,7 @@
if os.path.exists(outfile):
if os.getenv('GRASS_OVERWRITE'):
grass.warning(_("Pack file <%s> already exists and will be overwritten") % outfile)
- grass.try_remove(outfile)
+ try_remove(outfile)
else:
grass.fatal(_("option <%s>: <%s> exists.") % ("output", outfile))
Modified: grass/trunk/scripts/v.unpack/v.unpack.py
===================================================================
--- grass/trunk/scripts/v.unpack/v.unpack.py 2014-09-10 21:55:33 UTC (rev 61853)
+++ grass/trunk/scripts/v.unpack/v.unpack.py 2014-09-11 05:54:54 UTC (rev 61854)
@@ -39,12 +39,13 @@
import tarfile
import atexit
+from grass.script.utils import diff_files, try_rmdir
from grass.script import core as grass
from grass.script import db as grassdb
def cleanup():
- grass.try_rmdir(tmp_dir)
+ try_rmdir(tmp_dir)
def main():
@@ -102,13 +103,13 @@
diff_result_1 = diff_result_2 = None
if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_INFO'),
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)
if not grass.compare_key_value_text_files(filename_a=os.path.join(tmp_dir,'PROJ_UNITS'),
filename_b=loc_proj_units,
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)
if diff_result_1 or diff_result_2:
More information about the grass-commit
mailing list