kinetic-devel/bin/roslocate

230 lines
7.3 KiB
Python
Executable File

#!/usr/bin/env python
#
# Software License Agreement (BSD License)
#
# Copyright (c) 2009 Morgan Quigley
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following
# disclaimer in the documentation and/or other materials provided
# with the distribution.
# * Neither the name of Stanford University nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
"""
usage: roslocate COMMAND PARAMS
currently supported commands:
roslocate describe PACKAGE-OR-STACK
roslocate svn PACKAGE-OR-STACK
roslocate repo PACKAGE-OR-STACK
roslocate type PACKAGE-OR-STACK
roslocate list
roslocate list-stacks
roslocate search KEYWORD
"""
import os
import sys
import itertools
import time
import datetime
from xml.dom.minidom import parse
def get_text(nodes):
s = ""
for node in nodes:
for n2 in node.childNodes:
if n2.nodeType == n2.TEXT_NODE:
s = s + n2.data
return s
def get_cache_path():
try:
cpath = "%s/.roslocate_megamanifest.xml" % os.environ['ROS_ROOT']
f = open(cpath, 'a')
f.close()
return cpath
except IOError:
return "%s/.ros/roslocate_megamanifest.xml" % os.environ['HOME']
def download_megamanifest(cpath):
#print "downloading megamanifest to %s" % cpath
uris = ['http://ros.org/browse/megamanifest.xml']
for uri in uris:
#print "trying %s" % uri
if (os.system("wget %s -q -O %s" % (uri, cpath)) != 0):
#print "couldn't download from %s" % uri
continue
else:
os.utime(cpath, None)
return True
return False
def get_stack_cache_path():
try:
cpath = "%s/.roslocate_megastack.xml" % os.environ['ROS_ROOT']
f = open(cpath, 'a')
f.close()
return cpath
except IOError:
return "%s/.ros/roslocate_megastack.xml" % os.environ['HOME']
def download_megastack(cpath):
#print "downloading megastack to %s" % cpath
uris = ['http://ros.org/browse/megastack.xml']
for uri in uris:
#print "trying %s" % uri
if (os.system("wget %s -q -O %s" % (uri, cpath)) != 0):
#print "couldn't download from %s" % uri
continue
else:
os.utime(cpath, None)
return True
return False
def load_megamanifest():
cpath = get_cache_path()
if not os.path.exists(cpath) or os.path.getsize(cpath) == 0:
if not download_megamanifest(cpath):
print "couldn't download megamanifest..."
exit(1)
cache_age = datetime.datetime.now() - \
datetime.datetime.fromtimestamp(os.path.getmtime(cpath))
cache_age_secs = cache_age.seconds + cache_age.days * 3600 * 24
#print "cache is %d seconds old" % cache_age_secs
if cache_age_secs > 3600 * 8:
download_megamanifest(cpath)
return parse(cpath) # megamanifest
def load_megastack():
cpath = get_stack_cache_path()
if not os.path.exists(cpath) or os.path.getsize(cpath) == 0:
if not download_megastack(cpath):
print "couldn't download megastack..."
exit(1)
cache_age = datetime.datetime.now() - \
datetime.datetime.fromtimestamp(os.path.getmtime(cpath))
cache_age_secs = cache_age.seconds + cache_age.days * 3600 * 24
#print "cache is %d seconds old" % cache_age_secs
if cache_age_secs > 3600 * 8:
download_megastack(cpath)
return parse(cpath) # megastack
def usage():
print __doc__ % vars()
exit(1)
def describe(pkgs, stacks, name):
for pkg in pkgs:
if pkg.attributes['name'].value == name:
print ""
print "Package: %s"%name
print "Repository: %s " % pkg.attributes['repo_host'].value
print "License: %s" % get_text(pkg.getElementsByTagName('license')).strip()
print ""
print "Author(s): %s" % get_text(pkg.getElementsByTagName('author'))
print "Description: %s" % get_text(pkg.getElementsByTagName('description'))
print "ROS dependencies: %s" % (", ".join([dep.attributes['package'].value for dep in pkg.getElementsByTagName('depend')]))
print ""
return
for s in stacks:
if s.attributes['name'].value == name:
print ""
print "Stack: %s"%name
print "Repository: %s " % s.attributes['repo_host'].value
print "License: %s" % get_text(s.getElementsByTagName('license')).strip()
print ""
print "Author(s): %s" % get_text(s.getElementsByTagName('author'))
print "Description: %s" % get_text(s.getElementsByTagName('description'))
print "ROS dependencies: %s" % (", ".join([dep.attributes['stack'].value for dep in s.getElementsByTagName('depend')]))
print ""
return
print "No package or stack named %s found in the (known) public ROS repositories" % name
def type_(pkgs, stacks, name):
for e in pkgs:
if e.attributes['name'].value == name:
print "package"
return
for e in stacks:
if e.attributes['name'].value == name:
print "stack"
return
print "unknown"
def svn(pkgs, stacks, name):
for e in itertools.chain(pkgs, stacks):
if e.attributes['name'].value == name:
print "%s%s" % (e.attributes['repo_host'].value, e.attributes['path'].value)
return
def repo(pkgs, stacks, name):
for e in itertools.chain(pkgs, stacks):
if e.attributes['name'].value == name:
print "%s" % e.attributes['repo_host'].value
return
def list_all(elements):
for e in elements:
print e.attributes['name'].value
def search(pkgs, stacks, keyword):
for e in itertools.chain(pkgs, stacks):
desc = e.getElementsByTagName('description')
if get_text(desc).lower().find(keyword.lower()) > 0:
print e.attributes['name'].value
def roslocate_main():
if len(sys.argv) < 2:
usage()
mm = load_megamanifest()
pkgs = mm.getElementsByTagName('package')
ms = load_megastack()
stacks = ms.getElementsByTagName('stack')
if sys.argv[1] == "describe":
describe(pkgs, stacks, sys.argv[2])
elif sys.argv[1] == "svn":
svn(pkgs, stacks, sys.argv[2])
elif sys.argv[1] == "repo":
repo(pkgs, stacks, sys.argv[2])
elif sys.argv[1] == "list":
list_all(pkgs)
elif sys.argv[1] == "list-stacks":
list_all(stacks)
elif sys.argv[1] == "search":
search(pkgs, stacks, sys.argv[2])
elif sys.argv[1] == "type":
type_(pkgs, stacks, sys.argv[2])
else:
usage()
roslocate_main()