Package ternate :: Module cli
[hide private]
[frames] | no frames]

Source Code for Module ternate.cli

  1   
  2  # pylint: disable-msg=C0103 
  3  ''' 
  4   
  5  cli.py 
  6  ====== 
  7   
  8  Command-line tool for creating FOAF and homepages for Gentoo Linux Developers 
  9   
 10  Author: Rob Cakebread <pythonhead@gentoo.org> 
 11   
 12  License : GPL-2 
 13   
 14  ''' 
 15   
 16  __docformat__ = 'epytext' 
 17  __revision__ = '$Revision:  $'[11:-1].strip() 
 18   
 19   
 20  import sha 
 21  import sys 
 22  import logging 
 23  import optparse 
 24  from cStringIO import StringIO 
 25   
 26  from lxml import etree 
 27  from rdflib.Graph import ConjunctiveGraph as CGraph 
 28  from rdflib import Namespace, Literal, BNode, RDF, URIRef 
 29   
 30  from ternate.utils import COLOR 
 31  from ternate.__init__ import __version__ as VERSION 
 32   
 33  FOAF = Namespace('http://xmlns.com/foaf/0.1/') 
 34  RDFS = Namespace('http://www.w3.org/2000/01/rdf-schema#') 
 35  DOAP = Namespace('http://usefulinc.com/ns/doap#') 
 36  GENTOO = Namespace('http://www.gentoo.org/ns/gentoo#') 
 37  HERD = Namespace('http://www.gentoo.org/ns/herd#') 
 38   
39 -def create_foaf_file(ldap, friends=[]):
40 '''Serialize FOAF''' 41 graph = CGraph() 42 #Make some nice looking namespaces so rdflib doesn't use numbers 43 #in the serialization (3_: etc.) 44 graph.bind('foaf', FOAF) 45 graph.bind('rdfs', RDFS) 46 graph.bind('doap', DOAP) 47 graph.bind('herd', HERD) 48 graph.bind('gentoo', GENTOO) 49 50 person = add_foaf_node(graph, FOAF, ldap) 51 52 #We'll add an option to add friends on the command-line by their developer nick 53 for friend in friends: 54 knows = add_foaf_node(graph, FOAF, friend) 55 ## add the seeAlso link 56 graph.add((knows, RDFS['seeAlso'], URIRef(friend.get_foaf_url()))) 57 graph.add((person, FOAF['knows'], knows)) 58 59 return graph.serialize(format="pretty-xml")
60
61 -def add_foaf_node(graph, FOAF, ldap):
62 ''' 63 Create a BNode for a Person 64 65 TODO: Create mbox_sha1sum checksum from devname@gentoo.org 66 Is there a birthday on Gentoo's LDAP? 67 ''' 68 nick = ldap['uid'] 69 mbox = sha.new() 70 mbox.update('mailto:%s' % ldap['mail']) 71 #node = BNode() 72 node = URIRef("me") 73 # add the ldap data 74 graph.add((node, RDF.type, FOAF['Person'] )) 75 graph.add((node, FOAF['nick'], Literal(nick))) 76 graph.add((node, FOAF['name'], Literal(ldap['cn']))) 77 graph.add((node, GENTOO['gentooJoin'], Literal(ldap['gentooJoin']))) 78 graph.add((node, FOAF['homepage'], URIRef('http://dev.gentoo.org/~%s' % nick))) 79 graph.add((node, FOAF['mbox_sha1sum'], Literal(mbox.hexdigest()))) 80 #This is private LDAP, maybe it's available via passwd. Should add option. 81 #graph.add((node, FOAF['dateOfBirth'], Literal(ldap['birthday']))) 82 return node
83
84 -def get_ldap_info(ldap_file):
85 ''' 86 Parses the output of perl_ldap and creates a dictionary with the info 87 we want to use in FOAF 88 89 ''' 90 fields = ['uid', 'cn', 'gentooLocation', 'gentooRoles', 'lat', 'lon', 91 'gentooJoin', 'mail', 'gpgkey', 'gentooStatus'] 92 93 ldap = open(ldap_file).readlines() 94 ldap_dict = {} 95 96 for line in ldap: 97 if ':' in line: 98 key, value = line.split(':') 99 key = key.strip() 100 if key in fields: 101 ldap_dict[key] = value.strip() 102 return ldap_dict
103
104 -def ldap_to_foaf(ldap_file):
105 ''' 106 Get a dictionary of developer LDAP metadata and return a FOAF rendering 107 ''' 108 ldap = get_ldap_info(ldap_file) 109 return create_foaf_file(ldap)
110
111 -def foaf_to_guidexml(foaf_path):
112 ''' 113 Run an XSLT transform of foaf.rdf with developer.xsl stylesheet and get 114 nice Gentoo GuideXML output 115 ''' 116 transform = etree.XSLT(etree.fromstring(FOAF_XSL)) 117 doc = etree.parse(open(foaf_path, 'r')) 118 result_tree = transform(doc) 119 out = StringIO() 120 out.write("") 121 result_tree.write(out) 122 return out.getvalue()
123 124
125 -class Ternate(object):
126 127 '''`Ternate` class''' 128
129 - def __init__(self):
130 '''Initialize attributes, set logger''' 131 self.options = None 132 self.log = logging.getLogger('ternate') 133 self.log.addHandler(logging.StreamHandler())
134
135 - def set_log_level(self):
136 '''Set log level according to command-line options''' 137 if self.options.verbose: 138 self.log.setLevel(logging.INFO) 139 elif self.options.quiet: 140 self.log.setLevel(logging.ERROR) 141 #elif self.options.debug: 142 # self.log.setLevel(logging.DEBUG) 143 else: 144 self.log.setLevel(logging.WARN)
145
146 - def run(self):
147 ''' 148 Run ternate command specified on command-line 149 150 @rtype: int 151 @returns: 0 success or 1 failure 152 153 ''' 154 opt_parser = self.setup_opt_parser() 155 (self.options, remaining_args) = opt_parser.parse_args() 156 if remaining_args: 157 opt_parser.print_help() 158 return 1 159 self.set_log_level() 160 161 if self.options.ternate_version: 162 return ternate_version() 163 164 if self.options.no_color: 165 for this in COLOR: 166 COLOR[this] = '\x1b[0m' 167 if self.options.foaf: 168 print ldap_to_foaf(self.options.foaf) 169 return 170 171 elif self.options.guidexml: 172 print foaf_to_guidexml(self.options.guidexml) 173 return 174 else: 175 opt_parser.print_help() 176 return 1
177
178 - def setup_opt_parser(self):
179 ''' 180 Setup the optparser 181 182 @rtype: opt_parser.OptionParser 183 @return: Option parser 184 185 ''' 186 usage = 'usage: %prog [options]' 187 opt_parser = optparse.OptionParser(usage=usage) 188 189 opt_parser.add_option('--version', action='store_true', 190 dest='ternate_version', default=False, 191 help='Show ternate version and exit.') 192 193 opt_parser.add_option('-p', '--http-proxy', action='store', 194 dest='proxy', default=False, 195 help='Specify http proxy URL if you use one.') 196 197 opt_parser.add_option('-l', '--ldap', action='store', 198 dest='ldap', default=False, 199 metavar='username', 200 help='Fetch LDAP info for <username>') 201 202 opt_parser.add_option('-f', '--foaf', action='store', 203 dest='foaf', default=False, 204 metavar='LDAP file', 205 help='Create FOAF from LDAP info') 206 207 opt_parser.add_option('-g', '--guidexml', action='store', 208 dest='guidexml', default=False, 209 metavar='FOAF file', 210 help='Create GuideXML from LDAP info') 211 212 opt_parser.add_option('-C', '--no-color', action='store_true', 213 dest='no_color', default=False, 214 help="Don't use color in output") 215 216 opt_parser.add_option('-q', '--quiet', action='store_true', 217 dest='quiet', default=False, help="Show less output") 218 219 opt_parser.add_option('-v', '--verbose', action='store_true', 220 dest='verbose', default=False, help="Show more output") 221 222 return opt_parser
223 224
225 -def ternate_version():
226 '''Print ternate version''' 227 print VERSION
228 229
230 -def main():
231 '''Let's do it.''' 232 my_ternate = Ternate() 233 return my_ternate.run()
234 235 236 if __name__ == '__main__': 237 sys.exit(main()) 238 239 240 FOAF_XSL = '''<?xml version="1.0"?> 241 <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:doap="http://usefulinc.com/ns/doap#" xmlns:herd="http://www.gentoo.org/ns/herd#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:foaf="http://xmlns.com/foaf/0.1/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="1.0" xml:lang="en" xmlns:air="http://www.megginson.com/exp/ns/airports#" xmlns:wn="http://xmlns.com/wordnet/1.6/" xmlns:contact="http://www.w3.org/2000/10/swap/pim/contact#" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#"> 242 <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 243 <xsl:key name="indi" match="foaf:Person" use="@rdf:about"/> 244 <xsl:template match="/"> 245 <guide link="/developer.xml"> 246 <title> 247 <xsl:value-of select="/rdf:RDF/foaf:Person[@rdf:about='me']/foaf:name"/> 248 </title> 249 <author title="Author"> 250 <xsl:element name="mail"> 251 <xsl:attribute name="link"> 252 <xsl:value-of select="/rdf:RDF/foaf:Person[@rdf:about='me']/foaf:nick"/> 253 </xsl:attribute> 254 </xsl:element> 255 </author> 256 <abstract> 257 This is the developer homepage of <xsl:value-of select="/rdf:RDF/foaf:Person[@rdf:about='me']/foaf:nick"/> 258 </abstract> 259 <!-- The content of this document is licensed under the CC-BY-SA license --> 260 <!-- See http://creativecommons.org/licenses/by-sa/2.5 --> 261 <license/> 262 <version>0.1</version> 263 <date>2008-06-27</date> 264 <chapter> 265 <title>Developer Info</title> 266 <section> 267 <title>Vitals</title> 268 <body> 269 <xsl:for-each select="rdf:RDF/foaf:Person[@rdf:about='me']"> 270 <xsl:element name="a"> 271 <xsl:attribute name="name"> 272 <xsl:value-of select="@rdf:about='me'"/> 273 </xsl:attribute> 274 </xsl:element> 275 <dl> 276 <!-- We're in trouble if they add another nick since we want to do stuff with the Gentoo developer nick. So we should make a 'holdsAccount' and use the username from it --> 277 <dt>Nick: </dt> 278 <dd> 279 <xsl:value-of select="foaf:nick"/> 280 </dd> 281 <xsl:if test="foaf:gender"> 282 <dt>Gender: </dt> 283 <dd> 284 <xsl:value-of select="foaf:gender"/> 285 </dd> 286 </xsl:if> 287 <dt>Mailbox sha1sum : </dt> 288 <xsl:for-each select="foaf:mbox_sha1sum"> 289 <dd> 290 <xsl:value-of select="."/> 291 </dd> 292 </xsl:for-each> 293 <dt>Homepage : </dt> 294 <xsl:for-each select="foaf:homepage"> 295 <dd> 296 <xsl:element name="uri"> 297 <xsl:value-of select="@rdf:resource"/> 298 </xsl:element> 299 </dd> 300 </xsl:for-each> 301 <xsl:if test="foaf:weblog"> 302 <dt>Blog : </dt> 303 <xsl:for-each select="foaf:weblog"> 304 <dd> 305 <xsl:element name="uri"> 306 <xsl:value-of select="@rdf:resource"/> 307 </xsl:element> 308 </dd> 309 </xsl:for-each> 310 </xsl:if> 311 <xsl:if test="foaf:based_near"> 312 <dt>Location : </dt> 313 <xsl:for-each select="foaf:based_near/geo:Point"> 314 <dd> 315 <xsl:text>Lattitude </xsl:text><xsl:value-of select="geo:lat"/> 316 </dd> 317 <dd> 318 <xsl:text>Longitude </xsl:text><xsl:value-of select="geo:long"/> 319 </dd> 320 321 </xsl:for-each> 322 </xsl:if> 323 324 <xsl:if test="foaf:openid"> 325 <dt>OpenID : </dt> 326 <xsl:for-each select="foaf:openid"> 327 <dd> 328 <xsl:element name="uri"> 329 <xsl:value-of select="@rdf:resource"/> 330 </xsl:element> 331 </dd> 332 </xsl:for-each> 333 </xsl:if> 334 <xsl:if test="foaf:currentProject/herd:Project"> 335 <dt>Herds : </dt> 336 <dd> 337 <xsl:for-each select="foaf:currentProject/herd:Project"> 338 <xsl:apply-templates select="."/> 339 </xsl:for-each> 340 </dd> 341 </xsl:if> 342 343 <xsl:if test="foaf:currentProject/doap:Project"> 344 <dt>Other OSS Projects : </dt> 345 <xsl:for-each select="foaf:currentProject/doap:Project"> 346 <dd> 347 <xsl:element name="uri"> 348 <xsl:attribute name="link"><xsl:value-of select="doap:homepage/@rdf:resource"/></xsl:attribute> 349 <xsl:apply-templates select="."/> 350 </xsl:element> 351 </dd> 352 </xsl:for-each> 353 </xsl:if> 354 <dt>Stats : </dt> 355 <dd> 356 <xsl:element name="uri"> 357 <xsl:attribute name="link"> 358 http://cia.navi.cx/stats/author/<xsl:value-of select="/rdf:RDF/foaf:Person/foaf:nick"/> 359 </xsl:attribute> 360 Commits 361 </xsl:element> 362 </dd> 363 364 <dd> 365 <xsl:element name="uri"> 366 <xsl:attribute name="link"> 367 <xsl:text>http://bugs.gentoo.org/buglist.cgi?bug_status=NEW;bug_status=ASSIGNED;bug_status=REOPENED;email1=</xsl:text><xsl:value-of select="/rdf:RDF/foaf:Person/foaf:nick"/><xsl:text>%40gentoo.org;emailtype1=exact;emailassigned_to1=1;emailreporter1=1</xsl:text></xsl:attribute> 368 <xsl:text>Bugs</xsl:text> 369 </xsl:element> 370 </dd> 371 372 <xsl:if test="foaf:JabberID"> 373 <dt>Jabber Id : </dt> 374 <xsl:for-each select="foaf:jabberID"> 375 <dd> 376 <xsl:value-of select="."/> 377 </dd> 378 </xsl:for-each> 379 </xsl:if> 380 381 <xsl:if test="foaf:holdsAccount"> 382 <dt>Misc Accounts : </dt> 383 <xsl:for-each select="foaf:holdsAccount/foaf:OnlineAccount"> 384 <dd> 385 <xsl:choose> 386 <xsl:when test="@rdf:about"> 387 <xsl:element name="uri"> 388 <xsl:attribute name="link"><xsl:value-of select="@rdf:about"/></xsl:attribute> 389 <xsl:value-of select="foaf:accountName"/> 390 <xsl:text> - </xsl:text> 391 <xsl:value-of select="foaf:accountServiceHomepage/@rdf:resource"/> 392 </xsl:element> 393 </xsl:when> 394 <xsl:otherwise> 395 <xsl:value-of select="foaf:accountName"/> 396 <xsl:text> - </xsl:text> 397 <xsl:element name="uri"> 398 <xsl:attribute name="link"><xsl:value-of select="foaf:accountProfilePage/@rdf:resource"/></xsl:attribute> 399 <xsl:value-of select="foaf:accountProfilePage/@rdf:resource"/> 400 </xsl:element> 401 </xsl:otherwise> 402 </xsl:choose> 403 </dd> 404 </xsl:for-each> 405 406 </xsl:if> 407 <xsl:for-each select="foaf:depiction"> 408 <dt>Photos : </dt> 409 <dd> 410 <xsl:element name="img"> 411 <xsl:attribute name="src"> 412 <xsl:value-of select="@rdf:resource"/> 413 </xsl:attribute> 414 <xsl:value-of select="@rdf:resource"/> 415 </xsl:element> 416 </dd> 417 </xsl:for-each> 418 </dl> 419 </xsl:for-each> 420 </body> 421 </section> 422 </chapter> 423 </guide> 424 </xsl:template> 425 </xsl:stylesheet> 426 ''' 427