GRASS Programmer's Manual  6.4.2(2012)
update_menudata.py
Go to the documentation of this file.
00001 """!
00002 @brief Support script for wxGUI - only for developers needs. Updates
00003 menudata.xml file.
00004 
00005 Parse all GRASS modules in the search path ('bin' & 'script') and
00006 updates: - description (i.e. help) - keywords
00007 
00008 Prints warning for missing modules.
00009 
00010 (C) 2008-2010 by the GRASS Development Team
00011 This program is free software under the GNU General Public
00012 License (>=v2). Read the file COPYING that comes with GRASS
00013 for details.
00014 
00015 Usage: python support/update_menudata.py [-d]
00016 
00017  -d - dry run (prints diff, file is not updated)
00018 
00019 @author Martin Landa <landa.martin gmail.com>
00020 """
00021 
00022 import os
00023 import sys
00024 import tempfile
00025 try:
00026     import xml.etree.ElementTree as etree
00027 except ImportError:
00028     import elementtree.ElementTree as etree # Python <= 2.4
00029 
00030 from grass.script import core as grass
00031 from grass.script import task as gtask
00032 
00033 sys.path.append('gui_modules')
00034 import menudata
00035 
00036 def parseModules():
00037     """!Parse modules' interface"""
00038     modules = dict()
00039     
00040     # list of modules to be ignored
00041     ignore =  [ 'mkftcap',
00042                 'g.parser',
00043                 'r.mapcalc',
00044                 'r3.mapcalc',
00045                 'vcolors' ]
00046     
00047     count = len(globalvar.grassCmd['all'])
00048     i = 0
00049     for module in globalvar.grassCmd['all']:
00050         i += 1
00051         if i % 10 == 0:
00052             grass.info('* %d/%d' % (i, count))
00053         if module in ignore:
00054             continue
00055         try:
00056             interface = gtask.parse_interface(module)
00057         except:
00058             grass.error(module)
00059             continue
00060         modules[interface.name] = { 'label'   : interface.label,
00061                                     'desc'    : interface.description,
00062                                     'keywords': interface.keywords }
00063         
00064     return modules
00065 
00066 def updateData(data, modules):
00067     """!Update menu data tree"""
00068     # list of modules to be ignored
00069     ignore = ['v.type_wrapper.py',
00070               'vcolors']
00071     
00072     menu_modules = list()    
00073     for node in data.tree.getiterator():
00074         if node.tag != 'menuitem':
00075             continue
00076 
00077         item = dict()
00078         for child in node.getchildren():
00079             item[child.tag] = child.text
00080         
00081         if 'command' not in item:
00082             continue
00083         
00084         if item['command'] in ignore:
00085             continue
00086         
00087         module = item['command'].split(' ')[0]
00088         if module not in modules:
00089             grass.warning("'%s' not found in modules" % item['command'])
00090             continue
00091         
00092         if modules[module]['label']:
00093             desc = modules[module]['label']
00094         else:
00095             desc = modules[module]['desc']
00096         if node.find('handler').text == 'OnMenuCmd':
00097             node.find('help').text = desc
00098         
00099         if 'keywords' not in modules[module]:
00100             grass.warning('%s: keywords missing' % module)
00101         else:
00102             if node.find('keywords') is None:
00103                 node.insert(2, etree.Element('keywords'))
00104                 grass.warning("Adding tag 'keywords' to '%s'" % module)
00105             node.find('keywords').text = ','.join(modules[module]['keywords'])
00106         
00107         menu_modules.append(item['command'])
00108     
00109     for module in modules.keys():
00110         if module not in menu_modules:
00111             grass.warning("'%s' not available from the menu" % module)
00112     
00113 def writeData(data, file = None):
00114     """!Write updated menudata.xml"""
00115     if file is None:
00116         file = os.path.join('xml', 'menudata.xml')
00117     
00118     try:
00119         data.tree.write(file)
00120     except IOError:
00121         print >> sys.stderr, "'%s' not found. Please run the script from 'gui/wxpython'." % file
00122         return
00123     
00124     try:
00125         f = open(file, 'a')
00126         try:
00127             f.write('\n')
00128         finally:
00129             f.close()
00130     except IOError:
00131         print >> sys.stderr, "ERROR: Unable to write to menudata file."
00132     
00133 def main(argv = None):
00134     if argv is None:
00135         argv = sys.argv
00136 
00137     if len(argv) > 1 and argv[1] == '-d':
00138         printDiff = True
00139     else:
00140         printDiff = False
00141 
00142     if len(argv) > 1 and argv[1] == '-h':
00143         print >> sys.stderr, __doc__
00144         return 1
00145     
00146     nuldev = file(os.devnull, 'w+')
00147     grass.info("Step 1: running make...")
00148     grass.call(['make'], stderr = nuldev)
00149     grass.info("Step 2: parsing modules...")
00150     modules = dict()
00151     modules = parseModules()
00152     grass.info("Step 3: reading menu data...")
00153     data = menudata.ManagerData()
00154     grass.info("Step 4: updating menu data...")
00155     updateData(data, modules)
00156     
00157     if printDiff:
00158         tempFile = tempfile.NamedTemporaryFile()
00159         grass.info("Step 5: diff menu data...")
00160         writeData(data, tempFile.name)
00161         
00162         grass.call(['diff', '-u',
00163                     os.path.join('xml', 'menudata.xml'),
00164                     tempFile.name], stderr = nuldev)
00165     else:
00166         grass.info("Step 5: writing menu data (menudata.xml)...")
00167         writeData(data)
00168         
00169     return 0
00170 
00171 if __name__ == '__main__':
00172     if os.getenv("GISBASE") is None:
00173         sys.exit("You must be in GRASS GIS to run this program.")
00174     
00175     sys.path.append(os.path.join(os.getenv("GISBASE"), 'etc', 'wxpython', 'gui_modules'))
00176     import menudata
00177     import menuform
00178     import globalvar
00179     
00180     sys.exit(main())
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines