00001
00002
00003 import rospy
00004 import xml.dom.minidom
00005 import os
00006 import os.path
00007 import sys
00008 import collections
00009 import operator
00010 from urlparse import urlparse
00011 import httplib
00012
00013
00014 def get_code(url):
00015 x = urlparse(url)
00016
00017 try:
00018 conn = httplib.HTTPConnection(x.netloc)
00019 conn.request("HEAD", x.path)
00020 return conn.getresponse().status
00021 except StandardError:
00022 return None
00023
00024
00025 def get_element(doc, name):
00026 elements = manifest.getElementsByTagName(name)
00027 if len(elements) == 0:
00028 return None
00029 element = elements[0]
00030 return element
00031
00032 def get_text(doc, name):
00033 element = get_element(doc, name)
00034 if element is None or len(element.childNodes)==0:
00035 return ''
00036 return element.childNodes[0].data
00037
00038 def report(name, rdict):
00039 sorted_report = sorted(rdict.iteritems(), key=operator.itemgetter(1))
00040 print
00041 print "=" * 5, name, "="*(40-len(name))
00042 for (value, count) in sorted_report:
00043 print value, count
00044
00045 def extract_items(s, split=False):
00046 authors = []
00047 if 'Maintained by' in s:
00048 i = s.index('Maintained by')
00049 s = s[:i] + s[i+1+len('Maintained by'):]
00050
00051 for a in s.split(','):
00052 for b in a.split('and'):
00053 if split and '/' in b:
00054 b = b[:b.index('/')]
00055 authors.append(b.strip())
00056 return authors
00057
00058
00059
00060 authors = collections.defaultdict(list)
00061 descriptions = collections.defaultdict(int)
00062 briefs = collections.defaultdict(int)
00063 reviews = collections.defaultdict(int)
00064 licenses = collections.defaultdict(int)
00065 urls = collections.defaultdict(int)
00066 packages = []
00067 stacks = []
00068
00069 if len(sys.argv)<=1 or '-h' in sys.argv:
00070 print "Need to specify a directory to search through as the first parameter"
00071 print " [use the -web flag to ping the address "
00072 print " specified in the URL tag to see if it exists ] "
00073 exit(1)
00074
00075 check_urls = '-web' in sys.argv
00076
00077 for root, subFolders, files in os.walk(sys.argv[1]):
00078 if 'manifest.xml' in files:
00079 is_package = True
00080 elif 'stack.xml' in files:
00081 is_package = False
00082 else:
00083 continue
00084
00085 package = os.path.basename(root)
00086 if is_package:
00087 manifest_xml = open("%s/manifest.xml"%root, 'r').read()
00088 else:
00089 manifest_xml = open("%s/stack.xml"%root, 'r').read()
00090
00091 try:
00092 manifest = xml.dom.minidom.parseString(manifest_xml)
00093 except:
00094 continue
00095
00096 node = {'name': package}
00097
00098 author = get_text(manifest, 'author')
00099 for a_name in extract_items(author, True):
00100 authors[a_name].append(package)
00101 node['author'] = author
00102
00103 description_xml = get_element(manifest, 'description')
00104 if not description_xml:
00105 node['description'] = None
00106 node['brief'] = None
00107 else:
00108 description = get_text(manifest, 'description').strip()
00109 brief = description_xml.getAttribute('brief').strip()
00110 node['description'] = 'minimal' if description==package else 'detailed'
00111 node['brief'] = 'minimal' if brief==package else 'detailed'
00112
00113 descriptions[ node['description'] ] += 1
00114 briefs[ node['brief'] ] += 1
00115
00116 review_xml = get_element(manifest, 'review')
00117 if review_xml is None:
00118 review = None
00119 else:
00120 review = review_xml.getAttribute('status')
00121 node[ 'review' ] = review
00122 reviews[review] += 1
00123
00124 license = get_text(manifest, 'license')
00125 node[ 'license' ] = license
00126 for lic in extract_items(license):
00127 licenses[lic] += 1
00128
00129 url = get_text(manifest, 'url')
00130 if url is not None:
00131 if check_urls:
00132 url = get_code(url)
00133 else:
00134 url = 'specified'
00135 node[ 'url' ] = url
00136 urls[url] += 1
00137
00138 if is_package:
00139 packages.append(node)
00140 else:
00141 stacks.append(node)
00142
00143 lengths = collections.defaultdict(int)
00144 for d in packages + stacks:
00145 for a,b in d.iteritems():
00146 if type(b)==type(u''):
00147 b = b.encode('ascii', 'replace')
00148 if len(str(b)) > lengths[a]:
00149 lengths[a] = len(str(b))
00150 if len(str(a)) > lengths[a]:
00151 lengths[a] = len(str(a))
00152
00153 fields = ['name', 'description', 'brief', 'license', 'url', 'review', 'author']
00154
00155 if len(stacks)>0:
00156 for field in fields:
00157 print ("%%-%ds"%lengths[field])%field,
00158 print
00159
00160 for field in fields:
00161 print "=" * lengths[field],
00162 print
00163
00164 for d in stacks:
00165 for field in fields:
00166 print ("%%-%ds"%lengths[field])%str(d[field]),
00167 print
00168 print
00169
00170 if len(packages)>0:
00171 for field in fields:
00172 print ("%%-%ds"%lengths[field])%field,
00173 print
00174
00175 for field in fields:
00176 print "=" * lengths[field],
00177 print
00178
00179 for d in packages:
00180 for field in fields:
00181 val = d[field]
00182 if type(val)==type(u''):
00183 val = val.encode('ascii', 'replace')
00184 print val,
00185 n = lengths[field] - len(val)-1
00186 if n>0:
00187 print " "*n,
00188 else:
00189 print ("%%-%ds"%lengths[field])%str(val),
00190 print
00191
00192 report('Descriptions', descriptions)
00193 report('Brief Descriptions', briefs)
00194 report('Reviews', reviews)
00195 report('Licenses', licenses)
00196 report('Urls', urls)
00197 print
00198 name = "Authors"
00199 print "=" * 5, name, "="*(40-len(name))
00200 for a,c in sorted(authors.items()):
00201 a = a.encode('ascii', 'replace')
00202 print "%s %4d"%(a.strip(),len(c))
00203 print ' ',
00204 for (i,b) in enumerate(c):
00205 print "%-30s"%b,
00206 if i%3==2:
00207 print '\n ',
00208 print
00209
00210