[GRASS-SVN] r37345 - in grass/trunk: lib/python swig/python
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu May 21 17:16:29 EDT 2009
Author: martinl
Date: 2009-05-21 17:16:28 -0400 (Thu, 21 May 2009)
New Revision: 37345
Added:
grass/trunk/lib/python/__init__.py
grass/trunk/lib/python/core.py
grass/trunk/lib/python/db.py
grass/trunk/lib/python/raster.py
grass/trunk/lib/python/vector.py
Removed:
grass/trunk/lib/python/grass.py
Modified:
grass/trunk/lib/python/Makefile
grass/trunk/swig/python/Makefile
Log:
Python swig and script modules reorganized
grass
grass.lib
grass.lib.*
grass.script
grass.script.core
grass.script.db
grass.script.raster
grass.script.vector
Modified: grass/trunk/lib/python/Makefile
===================================================================
--- grass/trunk/lib/python/Makefile 2009-05-21 20:53:52 UTC (rev 37344)
+++ grass/trunk/lib/python/Makefile 2009-05-21 21:16:28 UTC (rev 37345)
@@ -3,13 +3,29 @@
include $(MODULE_TOPDIR)/include/Make/Other.make
include $(MODULE_TOPDIR)/include/Make/Doxygen.make
-default: $(ETC)/python
- $(MAKE) $(ETC)/python/grass.py $(ETC)/python/README.txt
+PYDIR = $(ETC)/python
+GDIR = $(PYDIR)/grass
+DSTDIR = $(GDIR)/script
-$(ETC)/python:
- -if [ ! -d $@ ]; then $(MKDIR) $@; fi
+MODULES = grass core db raster vector
-$(ETC)/python/%: %
+PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
+
+default: $(DSTDIR)
+ $(MAKE) $(PYFILES) $(DSTDIR)/README.txt
+
+$(PYDIR):
+ test -d $@ || $(MKDIR) -p $@
+
+$(GDIR): $(PYDIR)
+ test -d $@ || $(MKDIR) -p $@
+
+$(DSTDIR): $(GDIR)
+ test -d $@ || $(MKDIR) -p $@
+ test -f __init__.py || touch $(GDIR)/__init__.py
+ @echo "import script" >> $(GDIR)/__init__.py
+
+$(DSTDIR)/%: %
$(INSTALL_DATA) $< $@
#doxygen:
Added: grass/trunk/lib/python/__init__.py
===================================================================
--- grass/trunk/lib/python/__init__.py (rev 0)
+++ grass/trunk/lib/python/__init__.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -0,0 +1,4 @@
+import core
+import db
+import raster
+import vector
Property changes on: grass/trunk/lib/python/__init__.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:keywords
+ Author Date Id
Name: svn:eol-style
+ native
Added: grass/trunk/lib/python/core.py
===================================================================
--- grass/trunk/lib/python/core.py (rev 0)
+++ grass/trunk/lib/python/core.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -0,0 +1,512 @@
+"""
+ at package grass.script.core
+
+ at brief GRASS Python scripting module
+
+Core functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import core as grass
+
+grass.parser()
+...
+ at endcode
+
+(C) 2008-2009 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>
+"""
+
+import os
+import sys
+import types
+import re
+import atexit
+import subprocess
+
+# subprocess wrapper that uses shell on Windows
+
+class Popen(subprocess.Popen):
+ def __init__(self, args, bufsize=0, executable=None,
+ stdin=None, stdout=None, stderr=None,
+ preexec_fn=None, close_fds=False, shell=None,
+ cwd=None, env=None, universal_newlines=False,
+ startupinfo=None, creationflags=0):
+
+ if shell == None:
+ shell = (sys.platform == "win32")
+
+ subprocess.Popen.__init__(self, args, bufsize, executable,
+ stdin, stdout, stderr,
+ preexec_fn, close_fds, shell,
+ cwd, env, universal_newlines,
+ startupinfo, creationflags)
+
+PIPE = subprocess.PIPE
+STDOUT = subprocess.STDOUT
+
+def call(*args, **kwargs):
+ return Popen(*args, **kwargs).wait()
+
+# GRASS-oriented interface to subprocess module
+
+_popen_args = ["bufsize", "executable", "stdin", "stdout", "stderr",
+ "preexec_fn", "close_fds", "cwd", "env",
+ "universal_newlines", "startupinfo", "creationflags"]
+
+def _make_val(val):
+ if isinstance(val, types.StringType):
+ return val
+ if isinstance(val, types.ListType):
+ return ",".join(map(_make_val, val))
+ if isinstance(val, types.TupleType):
+ return _make_val(list(val))
+ return str(val)
+
+def make_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **options):
+ """Return a list of strings suitable for use as the args parameter to
+ Popen() or call(). Example:
+
+ >>> grass.make_command("g.message", flags = 'w', message = 'this is a warning')
+ ['g.message', '-w', 'message=this is a warning']
+ """
+ args = [prog]
+ if overwrite:
+ args.append("--o")
+ if quiet:
+ args.append("--q")
+ if verbose:
+ args.append("--v")
+ if flags:
+ args.append("-%s" % flags)
+ for opt, val in options.iteritems():
+ if val != None:
+ if opt[0] == '_':
+ opt = opt[1:]
+ args.append("%s=%s" % (opt, _make_val(val)))
+ return args
+
+def start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs):
+ """Returns a Popen object with the command created by make_command.
+ Accepts any of the arguments which Popen() accepts apart from "args"
+ and "shell".
+ """
+ options = {}
+ popts = {}
+ for opt, val in kwargs.iteritems():
+ if opt in _popen_args:
+ popts[opt] = val
+ else:
+ options[opt] = val
+ args = make_command(prog, flags, overwrite, quiet, verbose, **options)
+ return Popen(args, **popts)
+
+def run_command(*args, **kwargs):
+ """Passes all arguments to start_command, then waits for the process to
+ complete, returning its exit code. Similar to subprocess.call(), but
+ with the make_command() interface.
+ """
+ ps = start_command(*args, **kwargs)
+ return ps.wait()
+
+def pipe_command(*args, **kwargs):
+ """Passes all arguments to start_command, but also adds
+ "stdout = PIPE". Returns the Popen object.
+ """
+ kwargs['stdout'] = PIPE
+ return start_command(*args, **kwargs)
+
+def feed_command(*args, **kwargs):
+ """Passes all arguments to start_command, but also adds
+ "stdin = PIPE". Returns the Popen object.
+ """
+ kwargs['stdin'] = PIPE
+ return start_command(*args, **kwargs)
+
+def read_command(*args, **kwargs):
+ """Passes all arguments to pipe_command, then waits for the process to
+ complete, returning its stdout (i.e. similar to shell `backticks`).
+ """
+ ps = pipe_command(*args, **kwargs)
+ return ps.communicate()[0]
+
+def parse_command(*args, **kwargs):
+ """Passes all arguments to read_command, then parses the output by
+ parse_key_val().
+
+ Parsing function can be optionally given by <b>parse</b> parameter
+ including its arguments, e.g.
+
+ @code
+ parse_command(..., parse = (grass.parse_key_val, { 'sep' : ':' }))
+ @endcode
+ """
+ parse = None
+ if kwargs.has_key('parse'):
+ if type(kwargs['parse']) is types.TupleType:
+ parse = kwargs['parse'][0]
+ parse_args = kwargs['parse'][1]
+ del kwargs['parse']
+
+ if not parse:
+ parse = parse_key_val # use default fn
+ parse_args = {}
+
+ res = read_command(*args, **kwargs)
+
+ return parse(res, **parse_args)
+
+def write_command(*args, **kwargs):
+ """Passes all arguments to feed_command, with the string specified
+ by the 'stdin' argument fed to the process' stdin.
+ """
+ stdin = kwargs['stdin']
+ p = feed_command(*args, **kwargs)
+ p.stdin.write(stdin)
+ p.stdin.close()
+ return p.wait()
+
+def exec_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, env = None, **kwargs):
+ """Interface to os.execvpe(), but with the make_command() interface."""
+ args = make_command(prog, flags, overwrite, quiet, verbose, **kwargs)
+ if env == None:
+ env = os.environ
+ os.execvpe(prog, args, env)
+
+# interface to g.message
+
+def message(msg, flag = None):
+ """Display a message using g.message"""
+ run_command("g.message", flags = flag, message = msg)
+
+def debug(msg, debug = 1):
+ """Display a debugging message using g.message -d"""
+ run_command("g.message", flags = 'd', message = msg, debug = debug)
+
+def verbose(msg):
+ """Display a verbose message using g.message -v"""
+ message(msg, flag = 'v')
+
+def info(msg):
+ """Display an informational message using g.message -i"""
+ message(msg, flag = 'i')
+
+def warning(msg):
+ """Display a warning message using g.message -w"""
+ message(msg, flag = 'w')
+
+def error(msg):
+ """Display an error message using g.message -e"""
+ message(msg, flag = 'e')
+
+def fatal(msg):
+ """Display an error message using g.message -e, then abort"""
+ error(msg)
+ sys.exit(1)
+
+# interface to g.parser
+
+def _parse_env():
+ options = {}
+ flags = {}
+ for var, val in os.environ.iteritems():
+ if var.startswith("GIS_OPT_"):
+ opt = var.replace("GIS_OPT_", "", 1).lower()
+ options[opt] = val;
+ if var.startswith("GIS_FLAG_"):
+ flg = var.replace("GIS_FLAG_", "", 1).lower()
+ flags[flg] = bool(int(val));
+ return (options, flags)
+
+def parser():
+ """Interface to g.parser, intended to be run from the top-level, e.g.:
+
+ if __name__ == "__main__":
+ options, flags = grass.parser()
+ main()
+
+ Thereafter, the global variables "options" and "flags" will be
+ dictionaries containing option/flag values, keyed by lower-case
+ option/flag names. The values in "options" are strings, those in
+ "flags" are Python booleans.
+ """
+ if not os.getenv("GISBASE"):
+ print >> sys.stderr, "You must be in GRASS GIS to run this program."
+ sys.exit(1)
+
+ if len(sys.argv) > 1 and sys.argv[1] == "@ARGS_PARSED@":
+ return _parse_env()
+
+ cmdline = [basename(sys.argv[0])]
+ cmdline += ['"' + arg + '"' for arg in sys.argv[1:]]
+ os.environ['CMDLINE'] = ' '.join(cmdline)
+
+ argv = sys.argv[:]
+ name = argv[0]
+ if not os.path.isabs(name):
+ if os.sep in name or (os.altsep and os.altsep in name):
+ argv[0] = os.path.abspath(name)
+ else:
+ argv[0] = os.path.join(sys.path[0], name)
+
+ if sys.platform == "win32":
+ os.execvp("g.parser.exe", [name] + argv)
+ else:
+ os.execvp("g.parser", [name] + argv)
+ raise OSError("error executing g.parser")
+
+# interface to g.tempfile
+
+def tempfile():
+ """Returns the name of a temporary file, created with g.tempfile."""
+ return read_command("g.tempfile", pid = os.getpid()).strip()
+
+# 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: `=')
+ """
+ result = {}
+
+ 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]
+ else:
+ v = dflt
+ if val_type:
+ result[k] = val_type(v)
+ else:
+ result[k] = v
+ return result
+
+# interface to g.gisenv
+
+def gisenv():
+ """Returns the output from running g.gisenv (with no arguments), as a
+ dictionary.
+ """
+ s = read_command("g.gisenv", flags='n')
+ return parse_key_val(s)
+
+# interface to g.region
+
+def region():
+ """Returns the output from running "g.region -g", as a dictionary."""
+ s = read_command("g.region", flags='g')
+ return parse_key_val(s, val_type = float)
+
+def use_temp_region():
+ """Copies the current region to a temporary region with "g.region save=",
+ then sets WIND_OVERRIDE to refer to that region. Installs an atexit
+ handler to delete the temporary region upon termination.
+ """
+ name = "tmp.%s.%d" % (os.path.basename(sys.argv[0]), os.getpid())
+ run_command("g.region", save = name)
+ os.environ['WIND_OVERRIDE'] = name
+ atexit.register(del_temp_region)
+
+def del_temp_region():
+ """Unsets WIND_OVERRIDE and removes any region named by it."""
+ try:
+ name = os.environ.pop('WIND_OVERRIDE')
+ run_command("g.remove", quiet = True, region = name)
+ except:
+ pass
+
+# interface to g.findfile
+
+def find_file(name, element = 'cell', mapset = None):
+ """Returns the output from running g.findfile as a dictionary."""
+ s = read_command("g.findfile", flags='n', element = element, file = name, mapset = mapset)
+ return parse_key_val(s)
+
+# interface to g.list
+
+def list_grouped(type):
+ """Returns the output from running g.list, as a dictionary where the keys
+ are mapset names and the values are lists of maps in that mapset.
+ """
+ dashes_re = re.compile("^----+$")
+ mapset_re = re.compile("<(.*)>")
+ result = {}
+ mapset = None
+ for line in read_command("g.list", type = type).splitlines():
+ if line == "":
+ continue
+ if dashes_re.match(line):
+ continue
+ m = mapset_re.search(line)
+ if m:
+ mapset = m.group(1)
+ result[mapset] = []
+ continue
+ if mapset:
+ result[mapset].extend(line.split())
+ return result
+
+def mlist_grouped(type, mapset = None, pattern = None):
+ """Returns the output from running g.mlist, as a dictionary where the keys
+ are mapset names and the values are lists of maps in that mapset.
+ """
+ result = {}
+ mapset_element = None
+ for line in read_command("g.mlist", flags="m",
+ type = type, mapset = mapset, pattern = pattern).splitlines():
+ try:
+ map, mapset_element = line.split('@')
+ except ValueError:
+ print >> sys.stderr, "Invalid element '%s'" % line
+ continue
+
+ if result.has_key(mapset_element):
+ result[mapset_element].append(map)
+ else:
+ result[mapset_element] = [map, ]
+
+ return result
+
+def _concat(xs):
+ result = []
+ for x in xs:
+ result.extend(x)
+ return result
+
+def list_pairs(type):
+ """Returns the output from running g.list, as a list of (map, mapset)
+ pairs.
+ """
+ return _concat([[(map, mapset) for map in maps]
+ for mapset, maps in list_grouped(type).iteritems()])
+
+def list_strings(type):
+ """Returns the output from running g.list, as a list of qualified names."""
+ return ["%s@%s" % pair for pair in list_pairs(type)]
+
+# color parsing
+
+named_colors = {
+ "white": (1.00, 1.00, 1.00),
+ "black": (0.00, 0.00, 0.00),
+ "red": (1.00, 0.00, 0.00),
+ "green": (0.00, 1.00, 0.00),
+ "blue": (0.00, 0.00, 1.00),
+ "yellow": (1.00, 1.00, 0.00),
+ "magenta": (1.00, 0.00, 1.00),
+ "cyan": (0.00, 1.00, 1.00),
+ "aqua": (0.00, 0.75, 0.75),
+ "grey": (0.75, 0.75, 0.75),
+ "gray": (0.75, 0.75, 0.75),
+ "orange": (1.00, 0.50, 0.00),
+ "brown": (0.75, 0.50, 0.25),
+ "purple": (0.50, 0.00, 1.00),
+ "violet": (0.50, 0.00, 1.00),
+ "indigo": (0.00, 0.50, 1.00)}
+
+def parse_color(val, dflt = None):
+ """Parses the string "val" as a GRASS colour, which can be either one of
+ the named colours or an R:G:B tuple e.g. 255:255:255. Returns an
+ (r,g,b) triple whose components are floating point values between 0
+ and 1.
+ """
+ if val in named_colors:
+ return named_colors[val]
+
+ vals = val.split(':')
+ if len(vals) == 3:
+ return tuple(float(v) / 255 for v in vals)
+
+ return dflt
+
+# check GRASS_OVERWRITE
+
+def overwrite():
+ """Return True if existing files may be overwritten"""
+ owstr = 'GRASS_OVERWRITE'
+ return owstr in os.environ and os.environ[owstr] != '0'
+
+# check GRASS_VERBOSE
+
+def verbosity():
+ """Return the verbosity level selected by GRASS_VERBOSE"""
+ vbstr = os.getenv('GRASS_VERBOSE')
+ if vbstr:
+ return int(vbstr)
+ else:
+ return 0
+
+## 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
+ """
+ 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
+
+# find a program (replacement for "which")
+
+def find_program(pgm, args = []):
+ """Attempt to run a program, with optional arguments. Return False
+ if the attempt failed due to a missing executable, True otherwise
+ """
+ nuldev = file(os.devnull, 'w+')
+ try:
+ call([pgm] + args, stdin = nuldev, stdout = nuldev, stderr = nuldev)
+ found = True
+ except:
+ found = False
+ nuldev.close()
+ 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.
+ """
+ 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.
+ """
+ try:
+ os.rmdir(path)
+ except:
+ pass
+
+def float_or_dms(s):
+ return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
Property changes on: grass/trunk/lib/python/core.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:keywords
+ Author Date Id
Name: svn:eol-style
+ native
Added: grass/trunk/lib/python/db.py
===================================================================
--- grass/trunk/lib/python/db.py (rev 0)
+++ grass/trunk/lib/python/db.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -0,0 +1,62 @@
+"""
+ at package grass.script.db
+
+ at brief GRASS Python scripting module
+
+Database related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import core, db as grass
+
+grass.parser()
+grass.db_describe(table)
+...
+ at endcode
+
+(C) 2008-2009 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>
+"""
+
+from core import *
+
+# run "db.describe -c ..." and parse output
+
+def db_describe(table, **args):
+ """Return the list of columns for a database table
+ (interface to `db.describe -c').
+ """
+ s = read_command('db.describe', flags = 'c', table = table, **args)
+ if not s:
+ return None
+ cols = []
+ result = {}
+ for l in s.splitlines():
+ f = l.split(':')
+ key = f[0]
+ f[1] = f[1].lstrip(' ')
+ if key.startswith('Column '):
+ n = int(key.split(' ')[1])
+ cols.insert(n, f[1:])
+ elif key in ['ncols', 'nrows']:
+ result[key] = int(f[1])
+ else:
+ result[key] = f[1:]
+ result['cols'] = cols
+ return result
+
+# run "db.connect -p" and parse output
+
+def db_connection():
+ """Return the current database connection parameters
+ (interface to `db.connect -p').
+ """
+ s = read_command('db.connect', flags = 'p')
+ return parse_key_val(s, sep = ':')
+
Property changes on: grass/trunk/lib/python/db.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:keywords
+ Author Date Id
Name: svn:eol-style
+ native
Deleted: grass/trunk/lib/python/grass.py
===================================================================
--- grass/trunk/lib/python/grass.py 2009-05-21 20:53:52 UTC (rev 37344)
+++ grass/trunk/lib/python/grass.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -1,636 +0,0 @@
-import os
-import sys
-import types
-import subprocess
-import re
-import atexit
-import string
-import types
-
-# subprocess wrapper that uses shell on Windows
-
-class Popen(subprocess.Popen):
- def __init__(self, args, bufsize=0, executable=None,
- stdin=None, stdout=None, stderr=None,
- preexec_fn=None, close_fds=False, shell=None,
- cwd=None, env=None, universal_newlines=False,
- startupinfo=None, creationflags=0):
-
- if shell == None:
- shell = (sys.platform == "win32")
-
- subprocess.Popen.__init__(self, args, bufsize, executable,
- stdin, stdout, stderr,
- preexec_fn, close_fds, shell,
- cwd, env, universal_newlines,
- startupinfo, creationflags)
-
-PIPE = subprocess.PIPE
-STDOUT = subprocess.STDOUT
-
-def call(*args, **kwargs):
- return Popen(*args, **kwargs).wait()
-
-# GRASS-oriented interface to subprocess module
-
-_popen_args = ["bufsize", "executable", "stdin", "stdout", "stderr",
- "preexec_fn", "close_fds", "cwd", "env",
- "universal_newlines", "startupinfo", "creationflags"]
-
-def _make_val(val):
- if isinstance(val, types.StringType):
- return val
- if isinstance(val, types.ListType):
- return ",".join(map(_make_val, val))
- if isinstance(val, types.TupleType):
- return _make_val(list(val))
- return str(val)
-
-def make_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **options):
- """Return a list of strings suitable for use as the args parameter to
- Popen() or call(). Example:
-
- >>> grass.make_command("g.message", flags = 'w', message = 'this is a warning')
- ['g.message', '-w', 'message=this is a warning']
- """
- args = [prog]
- if overwrite:
- args.append("--o")
- if quiet:
- args.append("--q")
- if verbose:
- args.append("--v")
- if flags:
- args.append("-%s" % flags)
- for opt, val in options.iteritems():
- if val != None:
- if opt[0] == '_':
- opt = opt[1:]
- args.append("%s=%s" % (opt, _make_val(val)))
- return args
-
-def start_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, **kwargs):
- """Returns a Popen object with the command created by make_command.
- Accepts any of the arguments which Popen() accepts apart from "args"
- and "shell".
- """
- options = {}
- popts = {}
- for opt, val in kwargs.iteritems():
- if opt in _popen_args:
- popts[opt] = val
- else:
- options[opt] = val
- args = make_command(prog, flags, overwrite, quiet, verbose, **options)
- return Popen(args, **popts)
-
-def run_command(*args, **kwargs):
- """Passes all arguments to start_command, then waits for the process to
- complete, returning its exit code. Similar to subprocess.call(), but
- with the make_command() interface.
- """
- ps = start_command(*args, **kwargs)
- return ps.wait()
-
-def pipe_command(*args, **kwargs):
- """Passes all arguments to start_command, but also adds
- "stdout = PIPE". Returns the Popen object.
- """
- kwargs['stdout'] = PIPE
- return start_command(*args, **kwargs)
-
-def feed_command(*args, **kwargs):
- """Passes all arguments to start_command, but also adds
- "stdin = PIPE". Returns the Popen object.
- """
- kwargs['stdin'] = PIPE
- return start_command(*args, **kwargs)
-
-def read_command(*args, **kwargs):
- """Passes all arguments to pipe_command, then waits for the process to
- complete, returning its stdout (i.e. similar to shell `backticks`).
- """
- ps = pipe_command(*args, **kwargs)
- return ps.communicate()[0]
-
-def parse_command(*args, **kwargs):
- """Passes all arguments to read_command, then parses the output by
- parse_key_val().
-
- Parsing function can be optionally given by <b>parse</b> parameter
- including its arguments, e.g.
-
- @code
- parse_command(..., parse = (grass.parse_key_val, { 'sep' : ':' }))
- @endcode
- """
- parse = None
- if kwargs.has_key('parse'):
- if type(kwargs['parse']) is types.TupleType:
- parse = kwargs['parse'][0]
- parse_args = kwargs['parse'][1]
- del kwargs['parse']
-
- if not parse:
- parse = parse_key_val # use default fn
- parse_args = {}
-
- res = read_command(*args, **kwargs)
-
- return parse(res, **parse_args)
-
-def write_command(*args, **kwargs):
- """Passes all arguments to feed_command, with the string specified
- by the 'stdin' argument fed to the process' stdin.
- """
- stdin = kwargs['stdin']
- p = feed_command(*args, **kwargs)
- p.stdin.write(stdin)
- p.stdin.close()
- return p.wait()
-
-def exec_command(prog, flags = "", overwrite = False, quiet = False, verbose = False, env = None, **kwargs):
- """Interface to os.execvpe(), but with the make_command() interface."""
- args = make_command(prog, flags, overwrite, quiet, verbose, **kwargs)
- if env == None:
- env = os.environ
- os.execvpe(prog, args, env)
-
-# interface to g.message
-
-def message(msg, flag = None):
- """Display a message using g.message"""
- run_command("g.message", flags = flag, message = msg)
-
-def debug(msg, debug = 1):
- """Display a debugging message using g.message -d"""
- run_command("g.message", flags = 'd', message = msg, debug = debug)
-
-def verbose(msg):
- """Display a verbose message using g.message -v"""
- message(msg, flag = 'v')
-
-def info(msg):
- """Display an informational message using g.message -i"""
- message(msg, flag = 'i')
-
-def warning(msg):
- """Display a warning message using g.message -w"""
- message(msg, flag = 'w')
-
-def error(msg):
- """Display an error message using g.message -e"""
- message(msg, flag = 'e')
-
-def fatal(msg):
- """Display an error message using g.message -e, then abort"""
- error(msg)
- sys.exit(1)
-
-# interface to g.parser
-
-def _parse_env():
- options = {}
- flags = {}
- for var, val in os.environ.iteritems():
- if var.startswith("GIS_OPT_"):
- opt = var.replace("GIS_OPT_", "", 1).lower()
- options[opt] = val;
- if var.startswith("GIS_FLAG_"):
- flg = var.replace("GIS_FLAG_", "", 1).lower()
- flags[flg] = bool(int(val));
- return (options, flags)
-
-def parser():
- """Interface to g.parser, intended to be run from the top-level, e.g.:
-
- if __name__ == "__main__":
- options, flags = grass.parser()
- main()
-
- Thereafter, the global variables "options" and "flags" will be
- dictionaries containing option/flag values, keyed by lower-case
- option/flag names. The values in "options" are strings, those in
- "flags" are Python booleans.
- """
- if not os.getenv("GISBASE"):
- print >> sys.stderr, "You must be in GRASS GIS to run this program."
- sys.exit(1)
-
- if len(sys.argv) > 1 and sys.argv[1] == "@ARGS_PARSED@":
- return _parse_env()
-
- cmdline = [basename(sys.argv[0])]
- cmdline += ['"' + arg + '"' for arg in sys.argv[1:]]
- os.environ['CMDLINE'] = ' '.join(cmdline)
-
- argv = sys.argv[:]
- name = argv[0]
- if not os.path.isabs(name):
- if os.sep in name or (os.altsep and os.altsep in name):
- argv[0] = os.path.abspath(name)
- else:
- argv[0] = os.path.join(sys.path[0], name)
-
- if sys.platform == "win32":
- os.execvp("g.parser.exe", [name] + argv)
- else:
- os.execvp("g.parser", [name] + argv)
- raise OSError("error executing g.parser")
-
-# interface to g.tempfile
-
-def tempfile():
- """Returns the name of a temporary file, created with g.tempfile."""
- return read_command("g.tempfile", pid = os.getpid()).strip()
-
-# 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: `=')
- """
- result = {}
-
- 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]
- else:
- v = dflt
- if val_type:
- result[k] = val_type(v)
- else:
- result[k] = v
- return result
-
-# interface to g.gisenv
-
-def gisenv():
- """Returns the output from running g.gisenv (with no arguments), as a
- dictionary.
- """
- s = read_command("g.gisenv", flags='n')
- return parse_key_val(s)
-
-# interface to g.region
-
-def region():
- """Returns the output from running "g.region -g", as a dictionary."""
- s = read_command("g.region", flags='g')
- return parse_key_val(s, val_type = float)
-
-def use_temp_region():
- """Copies the current region to a temporary region with "g.region save=",
- then sets WIND_OVERRIDE to refer to that region. Installs an atexit
- handler to delete the temporary region upon termination.
- """
- name = "tmp.%s.%d" % (os.path.basename(sys.argv[0]), os.getpid())
- run_command("g.region", save = name)
- os.environ['WIND_OVERRIDE'] = name
- atexit.register(del_temp_region)
-
-def del_temp_region():
- """Unsets WIND_OVERRIDE and removes any region named by it."""
- try:
- name = os.environ.pop('WIND_OVERRIDE')
- run_command("g.remove", quiet = True, region = name)
- except:
- pass
-
-# interface to g.findfile
-
-def find_file(name, element = 'cell', mapset = None):
- """Returns the output from running g.findfile as a dictionary."""
- s = read_command("g.findfile", flags='n', element = element, file = name, mapset = mapset)
- return parse_key_val(s)
-
-# interface to g.list
-
-def list_grouped(type):
- """Returns the output from running g.list, as a dictionary where the keys
- are mapset names and the values are lists of maps in that mapset.
- """
- dashes_re = re.compile("^----+$")
- mapset_re = re.compile("<(.*)>")
- result = {}
- mapset = None
- for line in read_command("g.list", type = type).splitlines():
- if line == "":
- continue
- if dashes_re.match(line):
- continue
- m = mapset_re.search(line)
- if m:
- mapset = m.group(1)
- result[mapset] = []
- continue
- if mapset:
- result[mapset].extend(line.split())
- return result
-
-def mlist_grouped(type, mapset = None, pattern = None):
- """Returns the output from running g.mlist, as a dictionary where the keys
- are mapset names and the values are lists of maps in that mapset.
- """
- result = {}
- mapset_element = None
- for line in read_command("g.mlist", flags="m",
- type = type, mapset = mapset, pattern = pattern).splitlines():
- try:
- map, mapset_element = line.split('@')
- except ValueError:
- print >> sys.stderr, "Invalid element '%s'" % line
- continue
-
- if result.has_key(mapset_element):
- result[mapset_element].append(map)
- else:
- result[mapset_element] = [map, ]
-
- return result
-
-def _concat(xs):
- result = []
- for x in xs:
- result.extend(x)
- return result
-
-def list_pairs(type):
- """Returns the output from running g.list, as a list of (map, mapset)
- pairs.
- """
- return _concat([[(map, mapset) for map in maps]
- for mapset, maps in list_grouped(type).iteritems()])
-
-def list_strings(type):
- """Returns the output from running g.list, as a list of qualified names."""
- return ["%s@%s" % pair for pair in list_pairs(type)]
-
-# color parsing
-
-named_colors = {
- "white": (1.00, 1.00, 1.00),
- "black": (0.00, 0.00, 0.00),
- "red": (1.00, 0.00, 0.00),
- "green": (0.00, 1.00, 0.00),
- "blue": (0.00, 0.00, 1.00),
- "yellow": (1.00, 1.00, 0.00),
- "magenta": (1.00, 0.00, 1.00),
- "cyan": (0.00, 1.00, 1.00),
- "aqua": (0.00, 0.75, 0.75),
- "grey": (0.75, 0.75, 0.75),
- "gray": (0.75, 0.75, 0.75),
- "orange": (1.00, 0.50, 0.00),
- "brown": (0.75, 0.50, 0.25),
- "purple": (0.50, 0.00, 1.00),
- "violet": (0.50, 0.00, 1.00),
- "indigo": (0.00, 0.50, 1.00)}
-
-def parse_color(val, dflt = None):
- """Parses the string "val" as a GRASS colour, which can be either one of
- the named colours or an R:G:B tuple e.g. 255:255:255. Returns an
- (r,g,b) triple whose components are floating point values between 0
- and 1.
- """
- if val in named_colors:
- return named_colors[val]
-
- vals = val.split(':')
- if len(vals) == 3:
- return tuple(float(v) / 255 for v in vals)
-
- return dflt
-
-# check GRASS_OVERWRITE
-
-def overwrite():
- """Return True if existing files may be overwritten"""
- owstr = 'GRASS_OVERWRITE'
- return owstr in os.environ and os.environ[owstr] != '0'
-
-# check GRASS_VERBOSE
-
-def verbosity():
- """Return the verbosity level selected by GRASS_VERBOSE"""
- vbstr = os.getenv('GRASS_VERBOSE')
- if vbstr:
- return int(vbstr)
- else:
- return 0
-
-## 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
- """
- 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
-
-# find a program (replacement for "which")
-
-def find_program(pgm, args = []):
- """Attempt to run a program, with optional arguments. Return False
- if the attempt failed due to a missing executable, True otherwise
- """
- nuldev = file(os.devnull, 'w+')
- try:
- call([pgm] + args, stdin = nuldev, stdout = nuldev, stderr = nuldev)
- found = True
- except:
- found = False
- nuldev.close()
- 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.
- """
- 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.
- """
- try:
- os.rmdir(path)
- except:
- pass
-
-# run "v.db.connect -g ..." and parse output
-
-def vector_db(map, **args):
- """Return the database connection details for a vector map
- (interface to `v.db.connect -g').
-
- @param map vector map
-
- @return dictionary { layer : { 'layer', 'table, 'database', 'driver', 'key' }
- """
- s = read_command('v.db.connect', flags = 'g', map = map, fs = ';', **args)
- result = {}
-
- for l in s.splitlines():
- f = l.split(';')
- if len(f) != 5:
- continue
-
- if '/' in f[0]:
- f1 = f[0].split('/')
- layer = f1[0]
- name = f1[1]
- else:
- layer = f[0]
- name = ''
-
- result[int(layer)] = {
- 'layer' : layer,
- 'name' : name,
- 'table' : f[1],
- 'key' : f[2],
- 'database' : f[3],
- 'driver' : f[4] }
-
- return result
-
-def vector_layer_db(map, layer):
- """Return the database connection details for a vector map layer.
- If db connection for given layer is not defined, fatal() is called."""
- try:
- f = vector_db(map)[int(layer)]
- except KeyError:
- grass.fatal("Database connection not defined for layer %s" % layer)
-
- return f
-
-# run "db.describe -c ..." and parse output
-
-def db_describe(table, **args):
- """Return the list of columns for a database table
- (interface to `db.describe -c').
- """
- s = read_command('db.describe', flags = 'c', table = table, **args)
- if not s:
- return None
- cols = []
- result = {}
- for l in s.splitlines():
- f = l.split(':')
- key = f[0]
- f[1] = f[1].lstrip(' ')
- if key.startswith('Column '):
- n = int(key.split(' ')[1])
- cols.insert(n, f[1:])
- elif key in ['ncols', 'nrows']:
- result[key] = int(f[1])
- else:
- result[key] = f[1:]
- result['cols'] = cols
- return result
-
-# run "db.connect -p" and parse output
-
-def db_connection():
- """Return the current database connection parameters
- (interface to `db.connect -p').
- """
- s = read_command('db.connect', flags = 'p')
- return parse_key_val(s, sep = ':')
-
-# run "v.info -c ..." and parse output
-
-def vector_columns(map, layer = None, **args):
- """Return a dictionary of the columns for the database table connected to
- a vector map (interface to `v.info -c').
- """
- s = read_command('v.info', flags = 'c', map = map, layer = layer, quiet = True, **args)
- result = {}
- for line in s.splitlines():
- f = line.split('|')
- if len(f) == 2:
- result[f[1]] = f[0]
-
- return result
-
-# add vector history
-
-def vector_history(map):
- """Set the command history for a vector map to the command used to
- invoke the script (interface to `v.support').
- """
- run_command('v.support', map = map, cmdhist = os.environ['CMDLINE'])
-
-# run "v.info -t" and parse output
-
-def vector_info_topo(map):
- """Return information about a vector map (interface to `v.info -t')."""
- s = read_command('v.info', flags = 't', map = map)
- return parse_key_val(s, val_type = int)
-
-# add raster history
-
-def raster_history(map):
- """Set the command history for a raster map to the command used to
- invoke the script (interface to `r.support').
-
- @return True on success
- @return False on failure
- """
- current_mapset = gisenv()['MAPSET']
- if find_file(name = map)['mapset'] == current_mapset:
- run_command('r.support', map = map, history = os.environ['CMDLINE'])
- return True
-
- warning("Unable to write history for <%s>. Raster map <%s> not found in current mapset." % (map, map))
- return False
-
-def float_or_dms(s):
- return sum(float(x) / 60 ** n for (n, x) in enumerate(s.split(':')))
-
-# run "r.info -rgstmpud ..." and parse output
-
-def raster_info(map):
- """Return information about a raster map (interface to `r.info')."""
- s = read_command('r.info', flags = 'rgstmpud', map = map)
- kv = parse_key_val(s)
- for k in ['min', 'max', 'north', 'south', 'east', 'west']:
- kv[k] = float(kv[k])
- for k in ['nsres', 'ewres']:
- kv[k] = float_or_dms(kv[k])
- return kv
-
-# interface to r.mapcalc
-
-def mapcalc(exp, **kwargs):
- t = string.Template(exp)
- e = t.substitute(**kwargs)
- if run_command('r.mapcalc', expression = e) != 0:
- fatal("An error occurred while running r.mapcalc")
Added: grass/trunk/lib/python/raster.py
===================================================================
--- grass/trunk/lib/python/raster.py (rev 0)
+++ grass/trunk/lib/python/raster.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -0,0 +1,67 @@
+"""
+ at package grass.script.raster
+
+ at brief GRASS Python scripting module
+
+Raster related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import core, raster as grass
+
+grass.parser()
+grass.raster_history(map)
+...
+ at endcode
+
+(C) 2008-2009 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>
+"""
+
+import os
+import string
+
+from core import *
+
+# add raster history
+
+def raster_history(map):
+ """Set the command history for a raster map to the command used to
+ invoke the script (interface to `r.support').
+
+ @return True on success
+ @return False on failure
+ """
+ current_mapset = gisenv()['MAPSET']
+ if find_file(name = map)['mapset'] == current_mapset:
+ run_command('r.support', map = map, history = os.environ['CMDLINE'])
+ return True
+
+ warning("Unable to write history for <%s>. Raster map <%s> not found in current mapset." % (map, map))
+ return False
+
+# run "r.info -rgstmpud ..." and parse output
+
+def raster_info(map):
+ """Return information about a raster map (interface to `r.info')."""
+ s = read_command('r.info', flags = 'rgstmpud', map = map)
+ kv = parse_key_val(s)
+ for k in ['min', 'max', 'north', 'south', 'east', 'west']:
+ kv[k] = float(kv[k])
+ for k in ['nsres', 'ewres']:
+ kv[k] = float_or_dms(kv[k])
+ return kv
+
+# interface to r.mapcalc
+
+def mapcalc(exp, **kwargs):
+ t = string.Template(exp)
+ e = t.substitute(**kwargs)
+ if run_command('r.mapcalc', expression = e) != 0:
+ fatal("An error occurred while running r.mapcalc")
Property changes on: grass/trunk/lib/python/raster.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:keywords
+ Author Date Id
Name: svn:eol-style
+ native
Added: grass/trunk/lib/python/vector.py
===================================================================
--- grass/trunk/lib/python/vector.py (rev 0)
+++ grass/trunk/lib/python/vector.py 2009-05-21 21:16:28 UTC (rev 37345)
@@ -0,0 +1,105 @@
+"""
+ at package grass.script.vector
+
+ at brief GRASS Python scripting module
+
+Vector related functions to be used in Python scripts.
+
+Usage:
+
+ at code
+from grass.script import core, vector as grass
+
+grass.parser()
+grass.vector_db(map)
+...
+ at endcode
+
+(C) 2008-2009 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>
+"""
+
+import os
+
+from core import *
+
+# run "v.db.connect -g ..." and parse output
+
+def vector_db(map, **args):
+ """Return the database connection details for a vector map
+ (interface to `v.db.connect -g').
+
+ @param map vector map
+
+ @return dictionary { layer : { 'layer', 'table, 'database', 'driver', 'key' }
+ """
+ s = read_command('v.db.connect', flags = 'g', map = map, fs = ';', **args)
+ result = {}
+
+ for l in s.splitlines():
+ f = l.split(';')
+ if len(f) != 5:
+ continue
+
+ if '/' in f[0]:
+ f1 = f[0].split('/')
+ layer = f1[0]
+ name = f1[1]
+ else:
+ layer = f[0]
+ name = ''
+
+ result[int(layer)] = {
+ 'layer' : layer,
+ 'name' : name,
+ 'table' : f[1],
+ 'key' : f[2],
+ 'database' : f[3],
+ 'driver' : f[4] }
+
+ return result
+
+def vector_layer_db(map, layer):
+ """Return the database connection details for a vector map layer.
+ If db connection for given layer is not defined, fatal() is called."""
+ try:
+ f = vector_db(map)[int(layer)]
+ except KeyError:
+ grass.fatal("Database connection not defined for layer %s" % layer)
+
+ return f
+
+# run "v.info -c ..." and parse output
+
+def vector_columns(map, layer = None, **args):
+ """Return a dictionary of the columns for the database table connected to
+ a vector map (interface to `v.info -c').
+ """
+ s = read_command('v.info', flags = 'c', map = map, layer = layer, quiet = True, **args)
+ result = {}
+ for line in s.splitlines():
+ f = line.split('|')
+ if len(f) == 2:
+ result[f[1]] = f[0]
+
+ return result
+
+# add vector history
+
+def vector_history(map):
+ """Set the command history for a vector map to the command used to
+ invoke the script (interface to `v.support').
+ """
+ run_command('v.support', map = map, cmdhist = os.environ['CMDLINE'])
+
+# run "v.info -t" and parse output
+
+def vector_info_topo(map):
+ """Return information about a vector map (interface to `v.info -t')."""
+ s = read_command('v.info', flags = 't', map = map)
+ return parse_key_val(s, val_type = int)
Property changes on: grass/trunk/lib/python/vector.py
___________________________________________________________________
Name: svn:mime-type
+ text/x-python
Name: svn:keywords
+ Author Date Id
Name: svn:eol-style
+ native
Modified: grass/trunk/swig/python/Makefile
===================================================================
--- grass/trunk/swig/python/Makefile 2009-05-21 20:53:52 UTC (rev 37344)
+++ grass/trunk/swig/python/Makefile 2009-05-21 21:16:28 UTC (rev 37345)
@@ -39,28 +39,34 @@
include $(MODULE_TOPDIR)/include/Make/Python.make
-DSTDIR = $(ARCH_DISTDIR)/etc/python/swig
+PYDIR = $(ETC)/python
+GDIR = $(PYDIR)/grass
+DSTDIR = $(GDIR)/lib
LIBFILES := $(patsubst %,$(DSTDIR)/_%.so,$(MODULES))
PYFILES := $(patsubst %,$(DSTDIR)/%.py,$(MODULES) __init__)
-PYCFILES := $(patsubst %,$(DSTDIR)/%.pyc,$(MODULES) __init__)
default:
$(MAKE) $(DSTDIR)
- $(MAKE) $(LIBFILES) $(PYFILES) $(PYCFILES)
+ $(MAKE) $(LIBFILES) $(PYFILES)
-$(DSTDIR):
+$(PYDIR):
test -d $@ || $(MKDIR) -p $@
+$(GDIR): $(PYDIR)
+ test -d $@ || $(MKDIR) -p $@
+
+$(DSTDIR): $(GDIR)
+ test -d $@ || $(MKDIR) -p $@
+ test -f __init__.py || touch $(GDIR)/__init__.py
+ @echo "import lib" >> $(GDIR)/__init__.py
+
$(DSTDIR)/_%.so: _%.so
$(INSTALL) $< $@
$(DSTDIR)/%.py: %.py
$(INSTALL_DATA) $< $@
-$(DSTDIR)/%.pyc: %.pyc
- $(INSTALL_DATA) $< $@
-
numptr:
$(MAKE) -C NumPtr
More information about the grass-commit
mailing list