GRASS Programmer's Manual  6.4.2(2012)
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
update_menudata.py
Go to the documentation of this file.
1 """!
2 @brief Support script for wxGUI - only for developers needs. Updates
3 menudata.xml file.
4 
5 Parse all GRASS modules in the search path ('bin' & 'script') and
6 updates: - description (i.e. help) - keywords
7 
8 Prints warning for missing modules.
9 
10 (C) 2008-2010 by the GRASS Development Team
11 This program is free software under the GNU General Public
12 License (>=v2). Read the file COPYING that comes with GRASS
13 for details.
14 
15 Usage: python support/update_menudata.py [-d]
16 
17  -d - dry run (prints diff, file is not updated)
18 
19 @author Martin Landa <landa.martin gmail.com>
20 """
21 
22 import os
23 import sys
24 import tempfile
25 try:
26  import xml.etree.ElementTree as etree
27 except ImportError:
28  import elementtree.ElementTree as etree # Python <= 2.4
29 
30 from grass.script import core as grass
31 from grass.script import task as gtask
32 
33 sys.path.append('gui_modules')
34 import menudata
35 
37  """!Parse modules' interface"""
38  modules = dict()
39 
40  # list of modules to be ignored
41  ignore = [ 'mkftcap',
42  'g.parser',
43  'r.mapcalc',
44  'r3.mapcalc',
45  'vcolors' ]
46 
47  count = len(globalvar.grassCmd['all'])
48  i = 0
49  for module in globalvar.grassCmd['all']:
50  i += 1
51  if i % 10 == 0:
52  grass.info('* %d/%d' % (i, count))
53  if module in ignore:
54  continue
55  try:
56  interface = gtask.parse_interface(module)
57  except:
58  grass.error(module)
59  continue
60  modules[interface.name] = { 'label' : interface.label,
61  'desc' : interface.description,
62  'keywords': interface.keywords }
63 
64  return modules
65 
66 def updateData(data, modules):
67  """!Update menu data tree"""
68  # list of modules to be ignored
69  ignore = ['v.type_wrapper.py',
70  'vcolors']
71 
72  menu_modules = list()
73  for node in data.tree.getiterator():
74  if node.tag != 'menuitem':
75  continue
76 
77  item = dict()
78  for child in node.getchildren():
79  item[child.tag] = child.text
80 
81  if 'command' not in item:
82  continue
83 
84  if item['command'] in ignore:
85  continue
86 
87  module = item['command'].split(' ')[0]
88  if module not in modules:
89  grass.warning("'%s' not found in modules" % item['command'])
90  continue
91 
92  if modules[module]['label']:
93  desc = modules[module]['label']
94  else:
95  desc = modules[module]['desc']
96  if node.find('handler').text == 'OnMenuCmd':
97  node.find('help').text = desc
98 
99  if 'keywords' not in modules[module]:
100  grass.warning('%s: keywords missing' % module)
101  else:
102  if node.find('keywords') is None:
103  node.insert(2, etree.Element('keywords'))
104  grass.warning("Adding tag 'keywords' to '%s'" % module)
105  node.find('keywords').text = ','.join(modules[module]['keywords'])
106 
107  menu_modules.append(item['command'])
108 
109  for module in modules.keys():
110  if module not in menu_modules:
111  grass.warning("'%s' not available from the menu" % module)
112 
113 def writeData(data, file = None):
114  """!Write updated menudata.xml"""
115  if file is None:
116  file = os.path.join('xml', 'menudata.xml')
117 
118  try:
119  data.tree.write(file)
120  except IOError:
121  print >> sys.stderr, "'%s' not found. Please run the script from 'gui/wxpython'." % file
122  return
123 
124  try:
125  f = open(file, 'a')
126  try:
127  f.write('\n')
128  finally:
129  f.close()
130  except IOError:
131  print >> sys.stderr, "ERROR: Unable to write to menudata file."
132 
133 def main(argv = None):
134  if argv is None:
135  argv = sys.argv
136 
137  if len(argv) > 1 and argv[1] == '-d':
138  printDiff = True
139  else:
140  printDiff = False
141 
142  if len(argv) > 1 and argv[1] == '-h':
143  print >> sys.stderr, __doc__
144  return 1
145 
146  nuldev = file(os.devnull, 'w+')
147  grass.info("Step 1: running make...")
148  grass.call(['make'], stderr = nuldev)
149  grass.info("Step 2: parsing modules...")
150  modules = dict()
151  modules = parseModules()
152  grass.info("Step 3: reading menu data...")
153  data = menudata.ManagerData()
154  grass.info("Step 4: updating menu data...")
155  updateData(data, modules)
156 
157  if printDiff:
158  tempFile = tempfile.NamedTemporaryFile()
159  grass.info("Step 5: diff menu data...")
160  writeData(data, tempFile.name)
161 
162  grass.call(['diff', '-u',
163  os.path.join('xml', 'menudata.xml'),
164  tempFile.name], stderr = nuldev)
165  else:
166  grass.info("Step 5: writing menu data (menudata.xml)...")
167  writeData(data)
168 
169  return 0
170 
171 if __name__ == '__main__':
172  if os.getenv("GISBASE") is None:
173  sys.exit("You must be in GRASS GIS to run this program.")
174 
175  sys.path.append(os.path.join(os.getenv("GISBASE"), 'etc', 'wxpython', 'gui_modules'))
176  import menudata
177  import menuform
178  import globalvar
179 
180  sys.exit(main())