[GRASS-SVN] r53375 - grass/trunk/scripts/g.extension
svn_grass at osgeo.org
svn_grass at osgeo.org
Fri Oct 12 07:41:56 PDT 2012
Author: lucadelu
Date: 2012-10-12 07:41:55 -0700 (Fri, 12 Oct 2012)
New Revision: 53375
Modified:
grass/trunk/scripts/g.extension/g.extension.py
Log:
fix hardcoded url for modules.xml; clean code using spyder
Modified: grass/trunk/scripts/g.extension/g.extension.py
===================================================================
--- grass/trunk/scripts/g.extension/g.extension.py 2012-10-12 12:54:26 UTC (rev 53374)
+++ grass/trunk/scripts/g.extension/g.extension.py 2012-10-12 14:41:55 UTC (rev 53375)
@@ -111,10 +111,8 @@
import re
import atexit
import shutil
-import glob
import zipfile
import tempfile
-import shutil
from urllib2 import urlopen, HTTPError
@@ -133,7 +131,7 @@
for prog in ('svn', 'make', 'gcc'):
if not grass.find_program(prog, ['--help']):
grass.fatal(_("'%s' required. Please install '%s' first.") % (prog, prog))
-
+
# expand prefix to class name
def expand_module_class_name(c):
name = { 'd' : 'display',
@@ -149,7 +147,7 @@
'v' : 'vector',
'wx' : 'gui/wxpython'
}
-
+
return name.get(c, c)
# list installed extensions
@@ -159,6 +157,7 @@
return get_installed_modules(force)
+
def get_installed_toolboxes(force = False):
fXML = os.path.join(options['prefix'], 'toolboxes.xml')
if not os.path.exists(fXML):
@@ -173,13 +172,14 @@
write_xml_toolboxes(fXML)
return []
fo.close()
-
+
ret = list()
for tnode in tree.findall('toolbox'):
ret.append(tnode.get('code'))
-
+
return ret
+
def get_installed_modules(force = False):
fXML = os.path.join(options['prefix'], 'modules.xml')
if not os.path.exists(fXML):
@@ -188,7 +188,7 @@
else:
grass.warning(_("No metadata file available"))
return []
-
+
# read XML file
fo = open(fXML, 'r')
try:
@@ -198,18 +198,18 @@
write_xml_modules(fXML)
return []
fo.close()
-
+
ret = list()
for tnode in tree.findall('task'):
ret.append(tnode.get('name').strip())
-
+
return ret
# list extensions (read XML file from grass.osgeo.org/addons)
-def list_available_extensions():
+def list_available_extensions(url):
if flags['t']:
grass.message(_("List of available extensions (toolboxes):"))
- tlist = list_available_toolboxes()
+ tlist = list_available_toolboxes(url)
for toolbox_code, toolbox_data in tlist.iteritems():
if flags['g']:
print 'toolbox_name=' + toolbox_data['name']
@@ -217,18 +217,18 @@
else:
print '%s (%s)' % (toolbox_data['name'], toolbox_code)
if flags['c'] or flags['g']:
- list_available_modules(toolbox_data['modules'])
+ list_available_modules(url, toolbox_data['modules'])
else:
if toolbox_data['modules']:
print os.linesep.join(map(lambda x: '* ' + x, toolbox_data['modules']))
else:
grass.message(_("List of available extensions (modules):"))
- list_available_modules()
-
-def list_available_toolboxes():
+ list_available_modules(url)
+
+
+def list_available_toolboxes(url):
tdict = dict()
-
- url = "http://grass.osgeo.org/addons/grass%s/toolboxes.xml" % version[0]
+ url = url + "toolboxes.xml"
try:
f = urlopen(url)
tree = etree.fromstring(f.read())
@@ -238,37 +238,40 @@
tdict[tnode.get('code')] = { 'name' : tnode.get('name'),
'correlate' : clist,
'modules' : mlist }
-
+
for cnode in tnode.findall('correlate'):
clist.append(cnode.get('name'))
-
+
for mnode in tnode.findall('task'):
mlist.append(mnode.get('name'))
except HTTPError:
grass.fatal(_("Unable to fetch metadata file"))
-
+
return tdict
-def get_toolbox_modules(name):
+
+def get_toolbox_modules(url, name):
tlist = list()
-
- url = "http://grass.osgeo.org/addons/grass%s/toolboxes.xml" % version[0]
+
+ url = url + "toolboxes.xml"
+
try:
f = urlopen(url)
tree = etree.fromstring(f.read())
for tnode in tree.findall('toolbox'):
if name == tnode.get('code'):
for mnode in tnode.findall('task'):
- tlist.append(mnode.get('name'))
+ tlist.append(mnode.get('name'))
break
except HTTPError:
grass.fatal(_("Unable to fetch metadata file"))
-
+
return tlist
-def list_available_modules(mlist = None):
+
+def list_available_modules(url, mlist = None):
# try to download XML metadata file first
- url = "http://grass.osgeo.org/addons/grass%s/modules.xml" % version[0]
+ url = url + "modules.xml"
grass.debug("url=%s" % url, 1)
try:
f = urlopen(url)
@@ -276,7 +279,7 @@
tree = etree.fromstring(f.read())
except:
grass.fatal(_("Unable to parse '%s'") % url)
-
+
for mnode in tree.findall('task'):
name = mnode.get('name').strip()
if mlist and name not in mlist:
@@ -288,7 +291,7 @@
keyw = mnode.find('keywords').text
if not keyw:
keyw = ''
-
+
if flags['g']:
print 'name=' + name
print 'description=' + desc
@@ -311,14 +314,13 @@
grass.warning(_("Flag 'c' ignored, metadata file not available"))
if flags['g']:
grass.warning(_("Flag 'g' ignored, metadata file not available"))
-
+
prefix = ['d', 'db', 'g', 'i', 'm', 'ps',
'p', 'r', 'r3', 's', 'v']
- nprefix = len(prefix)
for d in prefix:
modclass = expand_module_class_name(d)
grass.verbose(_("Checking for '%s' modules...") % modclass)
-
+
url = '%s/%s' % (options['svnurl'], modclass)
grass.debug("url = %s" % url, debug = 2)
try:
@@ -326,7 +328,7 @@
except HTTPError:
grass.debug(_("Unable to fetch '%s'") % url, debug = 1)
continue
-
+
for line in f.readlines():
# list extensions
sline = pattern.search(line)
@@ -335,7 +337,7 @@
name = sline.group(2).rstrip('/')
if name.split('.', 1)[0] == d:
print name
-
+
# get_wxgui_extensions()
# list wxGUI extensions
@@ -344,14 +346,14 @@
grass.debug('Fetching list of wxGUI extensions from GRASS-Addons SVN (be patient)...')
pattern = re.compile(r'(<li><a href=".+">)(.+)(</a></li>)', re.IGNORECASE)
grass.verbose(_("Checking for '%s' modules...") % 'gui/wxpython')
-
+
url = '%s/%s' % (options['svnurl'], 'gui/wxpython')
grass.debug("url = %s" % url, debug = 2)
f = urlopen(url)
if not f:
grass.warning(_("Unable to fetch '%s'") % url)
return
-
+
for line in f.readlines():
# list extensions
sline = pattern.search(line)
@@ -360,9 +362,10 @@
name = sline.group(2).rstrip('/')
if name not in ('..', 'Makefile'):
mlist.append(name)
-
+
return mlist
+
def cleanup():
if remove_tmpdir:
grass.try_rmdir(tmpdir)
@@ -394,16 +397,17 @@
for fnode in bnode.findall('file'):
fo.write('%s<file>%s</file>\n' % \
(' ' * indent, os.path.join(options['prefix'], fnode.text)))
- indent -= 4
+ indent -= 4
fo.write('%s</binary>\n' % (' ' * indent))
fo.write('%s<libgis revision="%s" />\n' % \
(' ' * indent, libgisRev))
indent -= 4
fo.write('%s</task>\n' % (' ' * indent))
-
+
fo.write('</addons>\n')
fo.close()
+
def write_xml_toolboxes(name, tree = None):
fo = open(name, 'w')
fo.write('<?xml version="1.0" encoding="UTF-8"?>\n')
@@ -423,28 +427,28 @@
(' ' * indent, mnode.get('name')))
indent -= 4
fo.write('%s</toolbox>\n' % (' ' * indent))
-
+
fo.write('</addons>\n')
fo.close()
-
+
# install extension - toolbox or module
-def install_extension():
+def install_extension(url):
gisbase = os.getenv('GISBASE')
if not gisbase:
grass.fatal(_('$GISBASE not defined'))
-
+
if options['extension'] in get_installed_extensions(force = True):
grass.warning(_("Extension <%s> already installed. Re-installing...") % options['extension'])
-
+
if flags['t']:
grass.message(_("Installing toolbox <%s>...") % options['extension'])
- mlist = get_toolbox_modules(options['extension'])
+ mlist = get_toolbox_modules(url, options['extension'])
else:
mlist = [options['extension']]
if not mlist:
grass.warning(_("Nothing to install"))
return
-
+
ret = 0
for module in mlist:
if sys.platform == "win32":
@@ -456,10 +460,10 @@
if not flags['d']:
grass.verbose(_("Updating manual page for <%s>...") % module)
update_manual_page(module)
-
+
if flags['d']:
return
-
+
if ret != 0:
grass.warning(_('Installation failed, sorry. Please check above error messages.'))
else:
@@ -472,9 +476,10 @@
'GRASS_ADDON_BASE environment variable (see "g.manual variables")'))
# update local meta-file when installing new extension (toolbox / modules)
-def install_toolbox_xml(name):
+def install_toolbox_xml(url, name):
# read metadata from remote server (toolboxes)
- url = "http://grass.osgeo.org/addons/grass%s/toolboxes.xml" % version[0]
+ url = url + "toolboxes.xml"
+
data = dict()
try:
f = urlopen(url)
@@ -483,11 +488,11 @@
clist = list()
for cnode in tnode.findall('correlate'):
clist.append(cnode.get('code'))
-
+
mlist = list()
for mnode in tnode.findall('task'):
mlist.append(mnode.get('name'))
-
+
code = tnode.get('code')
data[code] = {
'name' : tnode.get('name'),
@@ -496,31 +501,31 @@
}
except HTTPError:
grass.error(_("Unable to read metadata file from the remote server"))
-
+
if not data:
grass.warning(_("No metadata available"))
return
if name not in data:
grass.warning(_("No metadata available for <%s>") % name)
return
-
+
fXML = os.path.join(options['prefix'], 'toolboxes.xml')
# create an empty file if not exists
if not os.path.exists(fXML):
write_xml_modules(fXML)
-
+
# read XML file
fo = open(fXML, 'r')
tree = etree.fromstring(fo.read())
fo.close()
-
+
# update tree
tnode = None
for node in tree.findall('toolbox'):
if node.get('code') == name:
tnode = node
break
-
+
tdata = data[name]
if tnode is not None:
# update existing node
@@ -532,23 +537,25 @@
# create new node for task
tnode = etree.Element('toolbox', attrib = { 'name' : tdata['name'], 'code' : name })
tree.append(tnode)
-
+
for cname in tdata['correlate']:
cnode = etree.Element('correlate', attrib = { 'code' : cname })
tnode.append(cnode)
for tname in tdata['modules']:
mnode = etree.Element('task', attrib = { 'name' : tname })
tnode.append(mnode)
-
+
write_xml_toolboxes(fXML, tree)
-def install_extension_xml(mlist):
+
+def install_extension_xml(url, mlist):
if len(mlist) > 1:
# read metadata from remote server (toolboxes)
- install_toolbox_xml(options['extension'])
-
+ install_toolbox_xml(url, options['extension'])
+
# read metadata from remote server (modules)
- url = "http://grass.osgeo.org/addons/grass%s/modules.xml" % version[0]
+ url = url + "modules.xml"
+
data = {}
try:
f = urlopen(url)
@@ -557,7 +564,7 @@
name = mnode.get('name')
if name not in mlist:
continue
-
+
fList = list()
bnode = mnode.find('binary')
windows = sys.platform == 'win32'
@@ -570,23 +577,23 @@
if path[0] == 'scripts':
path[-1] += '.py'
fList.append(os.path.sep.join(path))
-
+
desc = mnode.find('description').text
if not desc:
desc = ''
keyw = mnode.find('keywords').text
if not keyw:
keyw = ''
-
+
data[name] = {
'desc' : desc,
'keyw' : keyw,
'files' : fList,
}
-
+
except HTTPError:
grass.error(_("Unable to read metadata file from the remote server"))
-
+
if not data:
grass.warning(_("No metadata available"))
return
@@ -595,12 +602,12 @@
# create an empty file if not exists
if not os.path.exists(fXML):
write_xml_modules(fXML)
-
+
# read XML file
fo = open(fXML, 'r')
tree = etree.fromstring(fo.read())
fo.close()
-
+
# update tree
for name in mlist:
tnode = None
@@ -608,11 +615,11 @@
if node.get('name') == name:
tnode = node
break
-
+
if name not in data:
grass.warning(_("No metadata found for <%s>") % name)
continue
-
+
ndata = data[name]
if tnode is not None:
# update existing node
@@ -647,23 +654,23 @@
bnode.append(fnode)
tnode.append(bnode)
tree.append(tnode)
-
+
write_xml_modules(fXML, tree)
-
+
# install extension on MS Windows
def install_extension_win(name):
### TODO: do not use hardcoded url - http://wingrass.fsv.cvut.cz/grassXX/addonsX.X.X
grass.message(_("Downloading precompiled GRASS Addons <%s>...") % options['extension'])
url = "http://wingrass.fsv.cvut.cz/grass%s%s/addons" % (version[0], version[1])
grass.debug("url=%s" % url, 1)
-
+
try:
f = urlopen(url + '/' + name + '.zip')
-
+
# create addons dir if not exists
if not os.path.exists(options['prefix']):
os.mkdir(options['prefix'])
-
+
# download data
fo = tempfile.TemporaryFile()
fo.write(f.read())
@@ -677,11 +684,11 @@
outfile = open(os.path.join(options['prefix'], name), 'wb')
outfile.write(zfobj.read(name))
outfile.close()
-
+
fo.close()
except HTTPError:
grass.fatal(_("GRASS Addons <%s> not found") % name)
-
+
return 0
# install extension on other plaforms
@@ -692,19 +699,19 @@
url = options['svnurl'] + '/' + moduleclass + '/' + name
if classchar == 'wx' and not flags['s']:
grass.fatal(_("Installation of wxGUI extension requires -%s flag.") % 's')
-
+
grass.message(_("Fetching <%s> from GRASS-Addons SVN (be patient)...") % name)
-
+
os.chdir(tmpdir)
if grass.verbosity() <= 2:
outdev = open(os.devnull, 'w')
else:
outdev = sys.stdout
-
+
if grass.call(['svn', 'checkout',
url], stdout = outdev) != 0:
grass.fatal(_("GRASS Addons <%s> not found") % name)
-
+
dirs = { 'bin' : os.path.join(tmpdir, name, 'bin'),
'docs' : os.path.join(tmpdir, name, 'docs'),
'html' : os.path.join(tmpdir, name, 'docs', 'html'),
@@ -713,7 +720,7 @@
'scripts' : os.path.join(tmpdir, name, 'scripts'),
'etc' : os.path.join(tmpdir, name, 'etc'),
}
-
+
if classchar != 'wx':
makeCmd = ['make',
'MODULE_TOPDIR=%s' % gisbase.replace(' ', '\ '),
@@ -722,56 +729,56 @@
'RESTDIR=%s' % dirs['rest'],
'MANDIR=%s' % dirs['man'],
'SCRIPTDIR=%s' % dirs['scripts'],
- 'ETC=%s' % os.path.join(dirs['etc'],name)
+ 'ETC=%s' % os.path.join(dirs['etc'], name)
]
else:
makeCmd = ['make',
'MODULE_TOPDIR=%s' % gisbase.replace(' ', '\ ')
]
-
+
installCmd = ['make',
'MODULE_TOPDIR=%s' % gisbase,
'ARCH_DISTDIR=%s' % os.path.join(tmpdir, name),
'INST_DIR=%s' % options['prefix'],
'install'
]
-
+
if flags['d']:
grass.message(_("To compile run:"))
sys.stderr.write(' '.join(makeCmd) + '\n')
grass.message(_("To install run:"))
sys.stderr.write(' '.join(installCmd) + '\n')
return 0
-
+
os.chdir(os.path.join(tmpdir, name))
-
+
grass.message(_("Compiling..."))
if 0 != grass.call(makeCmd,
stdout = outdev):
grass.fatal(_('Compilation failed, sorry. Please check above error messages.'))
-
+
if flags['i'] or classchar == 'wx':
return 0
-
+
grass.message(_("Installing..."))
-
+
return grass.call(installCmd,
stdout = outdev)
-
+
# remove existing extension - toolbox or module
def remove_extension(force = False):
if flags['t']:
mlist = get_toolbox_modules(options['extension'])
else:
mlist = [options['extension']]
-
+
if force:
grass.verbose(_("List of removed files:"))
else:
grass.info(_("Files to be removed (use flag 'f' to force removal):"))
-
+
remove_modules(mlist, force)
-
+
if force:
grass.message(_("Updating metadata file..."))
remove_extension_xml(mlist)
@@ -779,26 +786,26 @@
else:
grass.warning(_("Extension <%s> not removed.\n"
"Re-run '%s' with 'f' flag to force removal") % (options['extension'], 'g.extension'))
-
+
# remove existing extension(s) (reading XML file)
def remove_modules(mlist, force = False):
# try to read XML metadata file first
fXML = os.path.join(options['prefix'], 'modules.xml')
installed = get_installed_modules()
-
+
if os.path.exists(fXML):
f = open(fXML, 'r')
tree = etree.fromstring(f.read())
f.close()
else:
tree = None
-
+
for name in mlist:
if name not in installed:
# try even if module does not seem to be available,
# as the user may be trying to get rid of left over cruft
grass.warning(_("Extension <%s> not found") % name)
-
+
if tree is not None:
flist = []
for task in tree.findall('task'):
@@ -807,7 +814,7 @@
for f in task.find('binary').findall('file'):
flist.append(f.text)
break
-
+
if flist:
removed = False
err = list()
@@ -823,7 +830,7 @@
err.append((_("Unable to remove file '%s'") % fpath))
if force and not removed:
grass.fatal(_("Extension <%s> not found") % name)
-
+
if err:
for e in err:
grass.error(e)
@@ -831,7 +838,7 @@
remove_extension_std(name, force)
else:
remove_extension_std(name, force)
-
+
# remove exising extension (using standard files layout)
def remove_extension_std(name, force = False):
for fpath in [os.path.join(options['prefix'], 'bin', name),
@@ -851,19 +858,19 @@
fXML = os.path.join(options['prefix'], 'toolboxes.xml')
if not os.path.exists(fXML):
return
-
+
# read XML file
fo = open(fXML, 'r')
tree = etree.fromstring(fo.read())
fo.close()
-
+
for node in tree.findall('toolbox'):
if node.get('code') != name:
continue
tree.remove(node)
-
+
write_xml_toolboxes(fXML, tree)
-
+
def remove_extension_xml(modules):
if len(modules) > 1:
# update also toolboxes metadata
@@ -872,20 +879,20 @@
fXML = os.path.join(options['prefix'], 'modules.xml')
if not os.path.exists(fXML):
return
-
+
# read XML file
fo = open(fXML, 'r')
tree = etree.fromstring(fo.read())
fo.close()
-
+
for name in modules:
for node in tree.findall('task'):
if node.get('name') != name:
continue
tree.remove(node)
-
+
write_xml_modules(fXML, tree)
-
+
# check links in CSS
def check_style_files(fil):
dist_file = os.path.join(os.getenv('GISBASE'), 'docs', 'html', fil)
@@ -895,19 +902,19 @@
return
try:
- shutil.copyfile(dist_file,addons_file)
+ shutil.copyfile(dist_file, addons_file)
except OSError, e:
grass.fatal(_("Unable to create '%s': %s") % (addons_file, e))
-
+
def create_dir(path):
if os.path.isdir(path):
return
-
+
try:
os.makedirs(path)
except OSError, e:
grass.fatal(_("Unable to create '%s': %s") % (path, e))
-
+
grass.debug("'%s' created" % path)
def check_dirs():
@@ -924,7 +931,7 @@
def update_manual_page(module):
if module.split('.', 1)[0] == 'wx':
return # skip for GUI modules
-
+
# read original html file
htmlfile = os.path.join(options['prefix'], 'docs', 'html', module + '.html')
try:
@@ -945,17 +952,17 @@
if match.group(1).replace('.html', '') in addons:
continue
pos.append(match.start(1))
-
+
if not pos:
return # no match
-
+
# replace file URIs
prefix = 'file://' + '/'.join([os.getenv('GISBASE'), 'docs', 'html'])
ohtml = shtml[:pos[0]]
for i in range(1, len(pos)):
ohtml += prefix + '/' + shtml[pos[i-1]:pos[i]]
ohtml += prefix + '/' + shtml[pos[-1]:]
-
+
# write updated html file
try:
f = open(htmlfile, 'w')
@@ -964,27 +971,33 @@
grass.fatal(_("Unable for write manual page: %s") % e)
else:
f.close()
-
+
def main():
# check dependecies
if sys.platform != "win32":
check_progs()
-
+
# define path
if flags['s']:
options['prefix'] = os.environ['GISBASE']
if options['prefix'] == '$GRASS_ADDON_BASE':
if not os.getenv('GRASS_ADDON_BASE'):
- major_version = int(grass.version()['version'].split('.', 1)[0])
grass.warning(_("GRASS_ADDON_BASE is not defined, "
"installing to ~/.grass%s/addons") % version[0])
options['prefix'] = os.path.join(os.environ['HOME'], '.grass%s' % version[0], 'addons')
else:
options['prefix'] = os.environ['GRASS_ADDON_BASE']
-
+ if options['svnurl'] == 'http://svn.osgeo.org/grass/grass-addons/grass7':
+ xmlurl = "http://grass.osgeo.org/addons/grass%s" % version[0]
+ else:
+ xmlurl = options['svnurl']
+
+ if not xmlurl.endswith('/'):
+ xmlurl = xmlurl + "/"
+
# list available extensions
if flags['l'] or flags['c'] or flags['g']:
- list_available_extensions()
+ list_available_extensions(xmlurl)
return 0
elif flags['a']:
elist = get_installed_extensions()
@@ -1004,20 +1017,20 @@
else:
if not options['extension']:
grass.fatal(_('You need to define an extension name or use -l/c/g/a'))
-
+
if flags['d']:
if options['operation'] != 'add':
grass.warning(_("Flag 'd' is relevant only to 'operation=add'. Ignoring this flag."))
else:
global remove_tmpdir
remove_tmpdir = False
-
+
if options['operation'] == 'add':
check_dirs()
- install_extension()
+ install_extension(xmlurl)
else: # remove
remove_extension(flags['f'])
-
+
return 0
if __name__ == "__main__":
More information about the grass-commit
mailing list