[GRASS-SVN] r66990 - in grass/trunk/scripts: . g.search.module g.search.module/testsuite
svn_grass at osgeo.org
svn_grass at osgeo.org
Mon Nov 30 13:09:22 PST 2015
Author: jachym
Date: 2015-11-30 13:09:22 -0800 (Mon, 30 Nov 2015)
New Revision: 66990
Added:
grass/trunk/scripts/g.search.module/
grass/trunk/scripts/g.search.module/Makefile
grass/trunk/scripts/g.search.module/g.search.module.html
grass/trunk/scripts/g.search.module/g.search.module.py
grass/trunk/scripts/g.search.module/testsuite/
grass/trunk/scripts/g.search.module/testsuite/test_g_search_module.py
Modified:
grass/trunk/scripts/Makefile
Log:
Adding new g.search.module script
Modified: grass/trunk/scripts/Makefile
===================================================================
--- grass/trunk/scripts/Makefile 2015-11-30 17:57:27 UTC (rev 66989)
+++ grass/trunk/scripts/Makefile 2015-11-30 21:09:22 UTC (rev 66990)
@@ -21,6 +21,7 @@
g.extension \
g.extension.all \
g.manual \
+ g.search.module \
i.colors.enhance \
i.image.mosaic \
i.in.spotvgt \
Added: grass/trunk/scripts/g.search.module/Makefile
===================================================================
--- grass/trunk/scripts/g.search.module/Makefile (rev 0)
+++ grass/trunk/scripts/g.search.module/Makefile 2015-11-30 21:09:22 UTC (rev 66990)
@@ -0,0 +1,7 @@
+MODULE_TOPDIR = ../..
+
+PGM = g.search.module
+
+include $(MODULE_TOPDIR)/include/Make/Script.make
+
+default: script
Added: grass/trunk/scripts/g.search.module/g.search.module.html
===================================================================
--- grass/trunk/scripts/g.search.module/g.search.module.html (rev 0)
+++ grass/trunk/scripts/g.search.module/g.search.module.html 2015-11-30 21:09:22 UTC (rev 66990)
@@ -0,0 +1,69 @@
+<h2>DESCRIPTION</h2>
+
+<em>r.search.module</em> searches for given keyword in GRASS modules name,
+description, keywords and optionally manpages too.
+
+<h2>NOTES</h2>
+
+There can be more keywords, <em>g.search.module</em> will search for each of them
+
+<h2>EXAMPLE</h2>
+
+Search all modules, where keywords <em>buffer</em> OR <em>clip</em> can be found
+<div class="code"><pre>
+GRASS> g.search.module buffer,clip
+
+r.circle
+ keywords: raster,buffer,geometry,circle
+ description: Creates a raster map containing concentric rings around a
+ given point.
+
+r.buffer.lowmem
+ keywords: raster,buffer
+ description: Creates a raster map showing buffer zones surrounding cells
+ that contain non-NULL category values. This is the low-
+ memory alternative to the classic r.buffer module.
+
+r.buffer
+ keywords: raster,buffer
+ description: Creates a raster map showing buffer zones surrounding cells
+ that contain non-NULL category values.
+</pre></div>
+
+Search all modules, where keywords <em>overlay</em> AND <em>clip</em> can be
+found with some fancy terminal output
+<div class="code"><pre>
+GRASS> g.search.module clip,overlay -a -c
+
+v.overlay
+ keywords: vector,geometry,spatial query,intersection,union,clip
+ description: Overlays two vector maps.;
+</pre></div>
+
+Search in manual pages too
+<div class="code"><pre>
+GRASS> g.search.module -m kapri
+
+db.execute
+ keywords: database,attribute table,SQL
+ description: Executes any SQL statement. For SELECT statements use
+ 'db.select'.
+
+db.select
+ keywords: database,attribute table,SQL
+ description: Selects data from attribute table. Performs SQL query
+ statement(s).
+</pre></div>
+
+<h2>SEE ALSO</h2>
+
+<em>
+ <a href="g.manual.html">g.manual</a>,
+ <a href="g.search.map.html">g.search.map</a>,
+</em>
+
+<h2>AUTHORS</h2>
+
+Jachym Cepicky, OpenGeoLabs s.r.o., Czech Republic
+
+<p><i>Last changed: $Date: 2015-05-12 23:11:59 +0200 (Út, 12 kvě 2015) $</i>
Added: grass/trunk/scripts/g.search.module/g.search.module.py
===================================================================
--- grass/trunk/scripts/g.search.module/g.search.module.py (rev 0)
+++ grass/trunk/scripts/g.search.module/g.search.module.py 2015-11-30 21:09:22 UTC (rev 66990)
@@ -0,0 +1,235 @@
+#!/usr/bin/env python
+############################################################################
+#
+# MODULE: g.search.module
+# AUTHOR(S): Jachym Cepicky <jachym.cepicky gmail.com>
+# PURPOSE: g.search.module in grass modules using keywords
+# COPYRIGHT: (C) 2015-2016 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.
+#
+#############################################################################
+
+#%module
+#% description: Search in GRASS modules using keywords
+#% keyword: general
+#% keyword: modules
+#% keyword: search
+#%end
+#%option
+#% key: keyword
+#% multiple: yes
+#% type: string
+#% description: Keyword to be searched
+#% required : yes
+#%end
+#%flag
+#% key: a
+#% description: Display only modules where all keywords are available (AND), default: OR
+#% guisection: Output
+#%end
+#%flag
+#% key: m
+#% description: Search in manual pages too (can be slow)
+#% guisection: Output
+#%end
+#%flag
+#% key: c
+#% description: Use colorized (more readable) output to terminal
+#% guisection: Output
+#%end
+#%flag
+#% key: g
+#% description: Shell script format
+#% guisection: Output
+#%end
+#%flag
+#% key: j
+#% description: JSON format
+#% guisection: Output
+#%end
+
+import os
+import sys
+
+from grass.script.utils import diff_files, try_rmdir
+from grass.script import core as grass
+
+try:
+ import xml.etree.ElementTree as etree
+except ImportError:
+ import elementtree.ElementTree as etree # Python <= 2.4
+
+COLORIZE=False
+
+def main():
+ global COLORIZE
+ keywords = options['keyword'].lower().split(',')
+ AND = flags['a']
+ manpages = flags['m']
+ out_format = None
+ if flags['g']:
+ out_format = 'shell'
+ elif flags['j']:
+ out_format = 'json'
+ else:
+ COLORIZE = flags['c']
+
+ modules = _search_module(keywords, AND, manpages)
+
+ print_results(modules, out_format)
+
+def print_results(data, out_format=None):
+ """
+ Print result of the searching method
+
+ each data item should have
+
+ {
+ 'name': name of the item,
+ 'attributes': {
+ # list of attributes to be shown too
+ }
+ }
+
+ :param list.<dict> data: input list of found data items
+ :param str out_format: output format 'shell', 'json', None
+ """
+
+ if not out_format:
+ _print_results(data)
+
+ elif out_format == 'shell':
+ _print_results_shell(data)
+
+ elif out_format == 'json':
+ _print_results_json(data)
+
+def _print_results_shell(data):
+ """Print just the name attribute"""
+
+ for item in data:
+ print item['name']
+
+def _print_results_json(data):
+ """Print JSON output"""
+
+ import json
+ print json.dumps(data, sort_keys=True, indent=4, separators=(',', ': '))
+
+def _print_results(data):
+
+ import textwrap
+
+ for item in data:
+ print '\n{}'.format(colorize(item['name'], attrs=['bold']))
+ for attr in item['attributes']:
+ out = '{}: {}'.format(attr, item['attributes'][attr])
+ out = textwrap.wrap(out, width=79, initial_indent=4*' ',
+ subsequent_indent=4*' '+len(attr)*' '+' ')
+ for line in out:
+ print line
+
+def colorize(text, attrs=None, pattern=None):
+ """Colorize given text input
+
+ :param string text: input text to be colored
+ :param list.<string> attrs: list of attributes as defined in termcolor package
+ :param string pattern: text to be highlighted in input text
+ :return: colored string
+ """
+
+
+ if COLORIZE:
+ from termcolor import colored
+ else:
+ def colored(pattern, attrs):
+ return pattern
+
+ if pattern:
+ return text.replace(pattern, colored(pattern, attrs=attrs))
+ else:
+ return colored(text, attrs=attrs)
+
+def _search_module(keywords, logical_and=False, manpages=False):
+ """Search modules by given keywords
+
+ :param list.<str> keywords: list of keywords
+ :param boolean logical_and: use AND (default OR)
+ :param boolean manpages: search in manpages too
+ :return dict: modules
+ """
+
+ WXGUIDIR = os.path.join(os.getenv("GISBASE"), "gui", "wxpython")
+ filename = os.path.join(WXGUIDIR, 'xml', 'module_items.xml')
+ menudata_file = open(filename, 'r')
+
+ menudata = etree.parse(menudata_file)
+ menudata_file.close()
+
+ items = menudata.findall('module-item')
+
+ found_modules = []
+ for item in items:
+ name = item.attrib['name']
+ description = item.find('description').text
+ module_keywords = item.find('keywords').text
+
+ found = [False]
+ if logical_and:
+ found = [False] * len(keywords)
+
+ for idx in range(len(keywords)):
+ keyword = keywords[idx]
+ keyword_found = False
+
+ keyword_found = _basic_search(keyword, name, description, module_keywords)
+
+ if not keyword_found and manpages:
+ keyword_found = _manpage_search(keyword, name)
+
+ if keyword_found:
+ if logical_and:
+ found[idx] = True
+ else:
+ found = [True]
+
+ description = colorize(description,
+ attrs=['underline'],
+ pattern=keyword)
+ module_keywords = colorize(module_keywords,
+ attrs=['underline'],
+ pattern=keyword)
+
+ if False not in found:
+ found_modules.append({
+ 'name': name,
+ 'attributes': {
+ 'keywords': module_keywords,
+ 'description': description
+ }
+ })
+
+ return found_modules
+
+def _basic_search(pattern, name, description, module_keywords):
+
+ if name.lower().find(pattern) > -1 or\
+ description.lower().find(pattern) > -1 or\
+ module_keywords.lower().find(pattern) > -1:
+
+ return True
+ else:
+ return False
+
+def _manpage_search(pattern, name):
+
+ manpage = grass.read_command('g.manual', flags='m', entry=name)
+
+ return manpage.lower().find(pattern) > -1
+
+if __name__ == "__main__":
+ options, flags = grass.parser()
+ sys.exit(main())
Property changes on: grass/trunk/scripts/g.search.module/g.search.module.py
___________________________________________________________________
Added: svn:executable
+ *
Added: grass/trunk/scripts/g.search.module/testsuite/test_g_search_module.py
===================================================================
--- grass/trunk/scripts/g.search.module/testsuite/test_g_search_module.py (rev 0)
+++ grass/trunk/scripts/g.search.module/testsuite/test_g_search_module.py 2015-11-30 21:09:22 UTC (rev 66990)
@@ -0,0 +1,64 @@
+"""
+TEST: test_g_search_module.py
+
+AUTHOR(S): Jachym Cepicky <jachym.cepicky gmail com>
+
+PURPOSE: Test g.search.module script outputs
+
+COPYRIGHT: (C) 2015 Jachym Ceppicky, and 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.
+"""
+
+from grass.gunittest.case import TestCase
+from grass.gunittest.main import test
+from grass.gunittest.gmodules import SimpleModule
+
+import termcolor
+
+import os
+
+
+class TestSearchModule(TestCase):
+
+ def test_terminal_output(self):
+ """ """
+ module = SimpleModule('g.search.module', keyword="water")
+ self.assertModule(module)
+ stdout = module.outputs.stdout
+ self.assertEqual(stdout.split()[0], 'r.watershed')
+
+ def test_json_output(self):
+ import json
+ module = SimpleModule('g.search.module', keyword="water", flags="j")
+ self.assertModule(module)
+ stdout = json.loads(module.outputs.stdout)
+ self.assertEqual(len(stdout), 6, 'Six modules found')
+ self.assertEqual(stdout[3]['name'], 'r.basins.fill', 'r.basins.fill')
+ self.assertTrue('keywords' in stdout[3]['attributes'])
+
+ def test_shell_outout(self):
+ module = SimpleModule('g.search.module', keyword="water", flags="g")
+ self.assertModule(module)
+ stdout = module.outputs.stdout.split()
+ self.assertEqual(len(stdout), 6)
+ self.assertEqual(stdout[3], 'r.basins.fill')
+
+ def test_colored_terminal(self):
+ module = SimpleModule('g.search.module', keyword="water", flags="c")
+ self.assertModule(module)
+ stdout = module.outputs.stdout.split()
+ self.assertEqual(stdout[0],
+ termcolor.colored('r.watershed',
+ attrs=['bold']))
+
+ def test_manual_pages(self):
+ module = SimpleModule('g.search.module', keyword="kapri", flags="gm")
+ self.assertModule(module)
+ stdout = module.outputs.stdout.split()
+ self.assertEqual(len(stdout), 2)
+
+if __name__ == '__main__':
+ test()
More information about the grass-commit
mailing list