doapfiend.plugins.text

Package doapfiend :: Package plugins :: Module text |
[hide private]
[frames] | no frames]

# Source Code for Module doapfiend.plugins.text

      1  #!/usr/bin/env python
      2
      3  # pylint: disable-msg=W0221,R0201
      4  """
      5
      6  Plain text serializer
      7  =====================
      8
      9  This plugin outputs DOAP in human-readable plain text
     10
     11  """
     12
     13  __docformat__ = 'epytext'
     14
     15  import logging
     16  import textwrap
     17  from cStringIO import StringIO
     18
     19  from rdflib import Namespace
     20  from rdfalchemy import rdfSubject
     21
     22  from doapfiend.plugins.base import Plugin
     23  from doapfiend.utils import COLOR
     24  from doapfiend.doaplib import load_graph
     25
     26
     27  FOAF = Namespace("http://xmlns.com/foaf/0.1/")
     28
     29  LOG = logging.getLogger(__name__)
     30
     31
     32 -class OutputPlugin(Plugin):
     33
     34      """Class for formatting DOAP output"""
     35
     36      #This will be the opt_parser option (--text)
     37      name = "text"
     38      enabled = False
     39      enable_opt = None
     40
     41 -    def __init__(self):
     42          '''Setup Plain Text OutputPlugin class'''
     43          super(OutputPlugin, self).__init__()
     44          self.options = None
     45
     46 -    def add_options(self, parser, output, search):
     47          """Add plugin's options to doapfiend's opt parser"""
     48          output.add_option('--%s' % self.name,
     49                  action='store_true',
     50                  dest=self.enable_opt,
     51                  help='Output DOAP as plain text (Default)')
     52          return parser, output, search
     53
     54 -    def serialize(self, doap_xml, color=False):
     55          '''
     56          Serialize RDF/XML DOAP as N3 syntax
     57
     58          @param doap_xml: DOAP in RDF/XML serialization
     59          @type doap_xml: string
     60
     61          @rtype: unicode
     62          @return: DOAP in plain text
     63          '''
     64          if hasattr(self.options, 'no_color'):
     65              color = not self.options.no_color
     66          if not color:
     67              #This has already been done if we're called from cli.py
     68              #Fix me: Need to think on this.
     69              for this in COLOR:
     70                  COLOR[this] = '\x1b[0m'
     71          if hasattr(self.options, 'quiet'):
     72              brief = self.options.quiet
     73          else:
     74              brief = False
     75
     76          printer = DoapPrinter(load_graph(doap_xml), brief, color)
     77          return printer.print_doap()
     78
     79
     80 -class DoapPrinter(object):
     81
     82      '''Prints DOAP in human readable text'''
     83
     84 -    def __init__(self, doap, brief=False, color=False):
     85          '''Initialize attributes'''
     86          self.brief = brief
     87          self.doap = doap
     88          self.text = StringIO()
     89          self.color = color
     90
     91 -    def write(self, text):
     92          '''
     93          Write to DOAP output file object
     94          '''
     95          self.text.write(text.encode('utf-8') + '\n')
     96
     97 -    def print_doap(self):
     98          '''
     99          Serialize DOAP in human readable text, optionally colorized
    100
    101          @rtype: unicode
    102          @return: DOAP as plain text
    103          '''
    104
    105          self.print_misc()
    106          if self.brief:
    107              return
    108          self.print_people()
    109          self.print_repos()
    110          self.print_releases()
    111          doap = self.text.getvalue()
    112          self.text.close()
    113          return doap
    114
    115 -    def print_misc(self):
    116          '''Prints basic DOAP metadata'''
    117          #We should be able to get this from model.py automatically,
    118          #but this lets us print in the order we like.
    119          #Maybe move this to that model.py so we don't forget to sync
    120          #when the DOAP schema changes.
    121          fields = ('name', 'shortname', 'homepage', 'shortdesc',
    122                  'description', 'old_homepage', 'created',
    123                  'download_mirror')
    124
    125          fields_verbose = ('license', 'programming_language',
    126                  'bug_database', 'screenshots', 'oper_sys',
    127                  'wiki', 'download_page', 'mailing_list')
    128
    129          for fld in fields:
    130              self.print_field(fld)
    131          if not self.brief:
    132              for fld in fields_verbose:
    133                  self.print_field(fld)
    134
    135 -    def print_repos(self):
    136          '''Prints DOAP repository metadata'''
    137          if hasattr(self.doap.cvs_repository, 'module') and \
    138                  self.doap.cvs_repository.module is not None:
    139              self.write(misc_field('CVS Module:',
    140                  self.doap.cvs_repository.module))
    141              self.write(misc_field('CVS Anon:',
    142                  self.doap.cvs_repository.anon_root))
    143              self.write(misc_field('CVS Browse:',
    144                      self.doap.cvs_repository.cvs_browse.resUri))
    145
    146          if hasattr(self.doap.svn_repository, 'location') and \
    147                  self.doap.svn_repository.location is not None:
    148              self.write(misc_field('SVN Location:',
    149                      self.doap.svn_repository.location.resUri))
    150
    151              if hasattr(self.doap.svn_repository, 'svn_browse') and \
    152                      self.doap.svn_repository.svn_browse is not None:
    153                  self.write(misc_field('SVN Browse:',
    154                          self.doap.svn_repository.svn_browse.resUri))
    155
    156 -    def print_releases(self):
    157          '''Print DOAP package release metadata'''
    158          if hasattr(self.doap, 'releases') and len(self.doap.releases) != 0:
    159              self.write(COLOR['bold'] + "Releases:" + COLOR['normal'])
    160              for release in self.doap.releases:
    161                  if release.name:
    162                      self.write(COLOR['bold'] + COLOR['cyan'] + release.name + \
    163                          COLOR['normal'])
    164                  if hasattr(release, 'created') and release.created is not None:
    165                      created = release.created
    166                  else:
    167                      created = ''
    168                  self.write(COLOR['cyan'] + '  ' + release.revision + ' ' + \
    169                          COLOR['normal'] + created)
    170                  if hasattr(release, 'changelog'):
    171                      if release.changelog:
    172                          self.write(COLOR['yellow'] + \
    173                                  release.changelog +
    174                                  COLOR['normal']
    175                                  )
    176                  for frel in release.file_releases:
    177                      self.write('   %s' % frel.resUri)
    178
    179 -    def print_people(self):
    180          '''Print all people involved in the project'''
    181          people = ['maintainer', 'developer', 'documenter', 'helper',
    182                  'tester', 'translator']
    183          for job in people:
    184              if hasattr(self.doap, job):
    185                  attribs = getattr(self.doap, job)
    186                  if len(attribs) > 0:
    187                      peeps = []
    188                      for attr in attribs:
    189                          if attr[FOAF.mbox] is None:
    190                              person = "%s" % attr[FOAF.name]
    191                          else:
    192                              mbox = attr[FOAF.mbox].resUri
    193                              if mbox.startswith('mailto:'):
    194                                  mbox = mbox[7:]
    195                                  person = "%s <%s>" % (attr[FOAF.name], mbox)
    196                              else:
    197                                  LOG.debug("mbox is invalid: %s" % mbox)
    198                                  person = "%s" % attr[FOAF.name]
    199                          peeps.append(person)
    200                      label = job.capitalize() + "s:"
    201                      #label = label.ljust(13)
    202                      self.write(misc_field(label,
    203                          ", ".join([p for p in peeps])))
    204
    205 -    def print_field(self, name):
    206          '''
    207          Print a DOAP element
    208
    209          @param name: A misc DOAP element
    210          @type name: string, list or RDFSubject
    211
    212          @rtype: None
    213          @return: Nothing
    214          '''
    215          if not hasattr(self.doap, name):
    216              return
    217          attr = getattr(self.doap, name)
    218          if attr is [] or attr is None:
    219              return
    220
    221          label = '%s' % COLOR['bold'] + pretty_name(name) + \
    222                   COLOR['normal'] + ':'
    223          label = label.ljust(21)
    224          if isinstance(attr, list):
    225              #Can have multiple values per attribute
    226              text = ""
    227              for thing in getattr(self.doap, name):
    228                  if isinstance(thing, rdfSubject):
    229                      text += thing.resUri + "\n"
    230                  else:
    231                      #unicode object
    232                      thing = thing.strip()
    233                      text += thing + "\n"
    234          else:
    235              text = getattr(self.doap, name)
    236              if isinstance(text, rdfSubject):
    237                  text = text.resUri
    238              else:
    239                  text = text.strip()
    240          if text:
    241              self.write(textwrap.fill('%s %s' % (label, text),
    242                      initial_indent='',
    243                      subsequent_indent = '              '))
    244
    245
    246 -def pretty_name(field):
    247      """
    248      Convert DOAP element name to pretty printable label
    249      Shorten some labels for formatting purposes
    250
    251      @param field: Text to be formatted
    252      @type field: C{string}
    253
    254      @return: formatted string
    255      @rtype: string
    256      """
    257      if field == 'programming_language':
    258          field = 'Prog. Lang.'
    259      elif field == 'created':
    260          field = 'DOAP Created'
    261      else:
    262          field = field.capitalize()
    263          field = field.replace('_', ' ')
    264          field = field.replace('-', ' ')
    265      return field
    266
    267
    268 -def misc_field(label, text):
    269      '''
    270      Print colorized and justified single label value pair
    271
    272      @param label: A label
    273      @type label: string
    274
    275      @param text: Text to print
    276      @type text: string
    277
    278      @rtype: string
    279      @return: Colorized, left-justified text with label
    280      '''
    281      label = label.ljust(13)
    282      label = COLOR['bold'] + label + COLOR['normal']
    283      return '%s %s' % (label, text)
    284