doapfiend.doaplib

Package doapfiend :: Module doaplib |
[hide private]
[frames] | no frames]

# Source Code for Module doapfiend.doaplib

      1  #!/usr/bin/env python
      2  #pylint: disable-msg=C0103
      3
      4  """
      5
      6  Library for parsing, displaying, querying and serializing DOAP
      7
      8  """
      9
     10  import sys
     11  import xmlrpclib
     12  from cStringIO import StringIO
     13  from xml.sax._exceptions import SAXParseException
     14
     15  from rdfalchemy import rdfSubject
     16  from rdflib import ConjunctiveGraph, Namespace
     17
     18  from doapfiend.utils import fetch_file
     19  from doapfiend.model import Project
     20  from doapfiend.plugins import load_plugins
     21
     22  XMLRPC_SERVER = xmlrpclib.ServerProxy('http://doapspace.org/xmlrpc/')
     23  DOAP_NS = Namespace('http://usefulinc.com/ns/doap#')
     24
     25
     26 -def follow_homepages(rdf_xml):
     27      '''
     28      If there is a 'doap:Project homepage' it will be looked up
     29      on doapspace.org using get_by_homepage to find any other
     30      DOAP. This is useful if we're looking at FOAF and a project
     31      is mentioned by homepage. It can also be used on DOAP files
     32      to search for additional DOAP files about the same project.
     33
     34      @param rdf_xml: RDF serialized as XML
     35      @type : string
     36
     37      @rtype: int
     38      @returns: 0 on sucess or 1 if there was no DOAP in the RDF
     39      '''
     40      homepages = list(get_homepages(rdf_xml))
     41      nbr_homepage_urls = len(homepages)
     42      if nbr_homepage_urls >= 1:
     43          print_doap_by_homepages(homepages)
     44      else:
     45          print 'No DOAP found in that RDF.'
     46          return 1
     47
     48
     49 -def show_links(rdf):
     50      '''
     51      If there is a 'doap:Project homepage' it will be looked up
     52      on doapspace.org using get_by_homepage to find any other
     53      DOAP. This is useful if we're looking at FOAF and a project
     54      is mentioned by homepage. It can also be used on DOAP files
     55      to search for additional DOAP files about the same project.
     56
     57      @param rdf: RDF serialized as XML
     58      @type : string
     59
     60      @rtype: int
     61      @returns: 0 on sucess or 1 if there was no DOAP in the RDF
     62      '''
     63      homepages = list(get_homepages(rdf))
     64      nbr_homepage_urls = len(homepages)
     65      if nbr_homepage_urls >= 1:
     66          for hpage_url in homepages:
     67              print "Found project homepage:", hpage_url
     68              #Search for DOAP by project homepage.
     69              hpages = query_by_homepage(hpage_url)
     70              for _src, hpage_url in hpages:
     71                  print '  Found DOAP: ', hpage_url
     72      else:
     73          print 'No DOAP found in that RDF.'
     74          return 1
     75
     76
     77 -def print_doap_by_homepages(homepages):
     78      '''
     79      Given a list of homepage URLs, search for DOAP for each and print
     80
     81      @param homepages: Project homepage
     82      @type : list
     83
     84      @rtype: None
     85      @returns: None
     86      '''
     87      for hpage_url in homepages:
     88          print "Found project homepage", hpage_url
     89          #Search for DOAP by project homepage. There may be none, one or multiple
     90          hpages = query_by_homepage(hpage_url)
     91          for _src, hpage_url in hpages:
     92              print 'Found DOAP at ', hpage_url
     93              doap_xml = fetch_doap(hpage_url)
     94              print_doap(doap_xml)
     95
     96 -def get_homepages(rdf, format='xml'):
     97      '''
     98      Find all doap:homepage in RDF
     99
    100      @param rdf: RDF
    101      @type rdf: string
    102
    103      @param format: Serialization format
    104      @type format: string
    105
    106      @rtype: generator
    107      @returns: homepages
    108      '''
    109      store = ConjunctiveGraph()
    110      store.parse(StringIO(rdf), publicID=None, format=format)
    111      if rdf_has_doap(store):
    112          for _s, o in store.subject_objects(DOAP_NS["homepage"]):
    113              yield(str(o))
    114
    115 -def rdf_has_doap(store):
    116      '''
    117      Returns True if triplestore has the DOAP namespace defined
    118
    119      @param store: triplestore
    120      @type store: rdflib ConjunctiveGraph
    121
    122      @rtype: boolean
    123      @returns: True if triplestore contains DOAP namespace
    124
    125      '''
    126      for namespace in store.namespaces():
    127          if namespace[1] == DOAP_NS:
    128              return True
    129
    130 -def load_graph(doap, format="xml", next=True):
    131      '''
    132      Load a DOAP profile into a RDFAlchemy/rdflib graph
    133
    134      Supports any serialization format rdflib can parse (xml, n3, etc.)
    135
    136      @param doap: DOAP
    137      @type doap: string
    138
    139      @param format: Serialization format we're parsing
    140      @type format: string
    141
    142      @rtype: Project
    143      @returns: a Project{rdfSubject}
    144
    145      '''
    146      rdfSubject.db = ConjunctiveGraph()
    147      try:
    148          rdfSubject.db.parse(StringIO(doap), format)
    149      except SAXParseException:
    150          sys.stderr.write("Error: Can't parse RDF/XML.\n")
    151          sys.exit(2)
    152
    153      if next:
    154          try:
    155              return Project.ClassInstances().next()
    156          except StopIteration:
    157              sys.stderr.write('No DOAP found in that RDF.\n')
    158              sys.exit(2)
    159      else:
    160          return Project
    161
    162
    163 -def get_by_pkg_index(index, project_name, proxy=None):
    164      '''
    165      Get DOAP for a package index project name
    166
    167      Builtin indexes:
    168
    169         - 'sf' SourceForge
    170         - 'fm' Freshmeat
    171         - 'py' Python Package Index
    172
    173      Note there can be other package indexes available by
    174      third party plugins.
    175
    176      @param index: Package index two letter abbreviation
    177      @type index: string
    178
    179      @param project_name: project name
    180      @type project_name: string
    181
    182      @param proxy: Optional HTTP proxy URL
    183      @type proxy: string
    184
    185      @rtype: string
    186      @return: text of file retrieved
    187
    188      '''
    189      for plugin_obj in list(load_plugins()):
    190          plugin = plugin_obj()
    191          if hasattr(plugin, 'prefix'):
    192              if plugin.prefix == index:
    193                  plugin.query = project_name
    194                  return plugin.search(proxy)
    195
    196
    197 -def query_by_homepage(url):
    198      '''
    199      Get list of URL's for DOAP given a project's homepage.
    200      The list can contain zero or multiple URLs.
    201
    202      The return format is:
    203      [(source, URL), (source, URL)...]
    204
    205      'source' is the two letter package index abbreviation or 'ex' for external.
    206      'external' meaning the DOAP was spidered on the web.
    207      Possible package indexes:
    208
    209      Current indexes:
    210
    211         - 'sf' SourceForge
    212         - 'fm' Freshmeat
    213         - 'py' Python Package Index
    214         - 'oh' Packages listed on Ohloh
    215
    216      @param url: URL of homepage of a project
    217      @type url: string
    218
    219      @rtype: list
    220      @return: A list of tuples containing URLs for DOAP found by homepage
    221
    222      '''
    223      #Should check for env variable for alternate xmplrpc server for testing?
    224      return XMLRPC_SERVER.query_by_homepage(url)
    225
    226
    227 -def print_doap(doap_xml, color=None, format='text', serializer=None,
    228          filename=None):
    229      '''
    230      Print DOAP as text, xml, or n3 etc. or to stdout or a file
    231      A callable serializer object may be passed or a name of a serializer
    232      plugin.
    233
    234      @param doap_xml: DOAP profile in RDF/XML
    235      @type doap_xml: string
    236
    237      @param format: Serialization syntax formatter name
    238      @type format: string
    239
    240      @param serializer: Instance of a serializer
    241      @type serializer: callable
    242
    243      @param filename: Optional filename to write to
    244      @type filename: string
    245
    246      @return: `serializer` or 1 if invalid serialization request
    247
    248      '''
    249      #If we were passed a callable serializer object use it,
    250      #otherwise lookup serializer by name in list of plugins
    251      if not serializer:
    252          serializer = get_serializer(format)
    253          if not serializer:
    254              sys.stderr.write('Unknown serialization requested: %s\n' % format)
    255              return 1
    256
    257      doap = serializer(doap_xml, color)
    258      if filename:
    259          try:
    260              open(filename, 'w').write(doap.encode('utf-8'))
    261          except UnicodeDecodeError:
    262              open(filename, 'w').write(doap)
    263      else:
    264          print doap
    265
    266
    267 -def get_serializer(format):
    268      '''
    269      Return a serializer instance given its name
    270
    271      @param format: Name of serializer
    272      @type format: string
    273
    274      @rtype: function
    275      @returns: Instance of a serializer
    276      '''
    277      #Get all plugins with a `serialize` method
    278      for plugin_obj in get_plugin('serialize'):
    279          plugin = plugin_obj()
    280          if plugin.name == format:
    281              return plugin.serialize
    282
    283
    284 -def get_plugin(method):
    285      """
    286      Return plugin object if `method` exists
    287
    288      @param method: name of plugin's method we're calling
    289      @type method: string
    290
    291      @returns: list of plugins with `method`
    292
    293      """
    294      all_plugins = []
    295      for plugin in load_plugins():
    296          #plugin().configure(None, None)
    297          if not hasattr(plugin, method):
    298              plugin = None
    299          else:
    300              all_plugins.append(plugin)
    301      return all_plugins
    302
    303
    304 -def fetch_doap(url, proxy=None):
    305      '''
    306      Fetch DOAP by its URL or filename
    307
    308      @param url: URL of DOAP profile in RDF/XML serialization
    309      @type url: string
    310
    311      @rtype: text
    312      @return: DOAP
    313      '''
    314      return fetch_file(url, proxy)
    315