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 plain text
     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, get_list=True), 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_list = doap
     88          self.doap = None
     89          self.text = StringIO()
     90          self.color = color
     91
     92 -    def write(self, text):
     93          '''
     94          Write to DOAP output file object
     95          '''
     96          self.text.write(text.encode('utf-8') + '\n')
     97
     98 -    def print_doap(self):
     99          '''
    100          Serialize DOAP in human readable text, optionally colorized
    101
    102          @rtype: unicode
    103          @return: DOAP as plain text
    104          '''
    105          for doap in self.doap_list:
    106              self.doap = doap
    107              self.print_misc()
    108              if self.brief:
    109                  return
    110              self.print_people()
    111              self.print_repos()
    112              self.print_releases()
    113          doap = self.text.getvalue()
    114          self.text.close()
    115          return doap
    116
    117 -    def print_misc(self):
    118          '''Prints basic DOAP metadata'''
    119          #We should be able to get this from model.py automatically,
    120          #but this lets us print in the order we like.
    121          #Maybe move this to that model.py so we don't forget to sync
    122          #when the DOAP schema changes.
    123          fields = ('name', 'shortname', 'homepage', 'shortdesc',
    124                  'description', 'old_homepage', 'created',
    125                  'download_mirror')
    126
    127          fields_verbose = ('license', 'programming_language',
    128                  'bug_database', 'screenshots', 'oper_sys',
    129                  'wiki', 'download_page', 'mailing_list')
    130
    131          for fld in fields:
    132              self.print_field(fld)
    133          if not self.brief:
    134              for fld in fields_verbose:
    135                  self.print_field(fld)
    136
    137 -    def print_repos(self):
    138          '''Prints DOAP repository metadata'''
    139          if hasattr(self.doap.cvs_repository, 'module') and \
    140                  self.doap.cvs_repository.module is not None:
    141              self.write(misc_field('CVS Module:',
    142                  self.doap.cvs_repository.module))
    143              self.write(misc_field('CVS Anon:',
    144                  self.doap.cvs_repository.anon_root))
    145              self.write(misc_field('CVS Browse:',
    146                      self.doap.cvs_repository.cvs_browse.resUri))
    147
    148          if hasattr(self.doap.svn_repository, 'location') and \
    149                  self.doap.svn_repository.location is not None:
    150              self.write(misc_field('SVN Location:',
    151                      self.doap.svn_repository.location.resUri))
    152
    153              if hasattr(self.doap.svn_repository, 'svn_browse') and \
    154                      self.doap.svn_repository.svn_browse is not None:
    155                  self.write(misc_field('SVN Browse:',
    156                          self.doap.svn_repository.svn_browse.resUri))
    157
    158 -    def print_releases(self):
    159          '''Print DOAP package release metadata'''
    160          if hasattr(self.doap, 'releases') and len(self.doap.releases) != 0:
    161              self.write(COLOR['bold'] + "Releases:" + COLOR['normal'])
    162              for release in self.doap.releases:
    163                  if release.name:
    164                      self.write(COLOR['bold'] + COLOR['cyan'] + release.name + \
    165                          COLOR['normal'])
    166                  if hasattr(release, 'created') and release.created is not None:
    167                      created = release.created
    168                  else:
    169                      created = ''
    170                  self.write(COLOR['cyan'] + '  ' + release.revision + ' ' + \
    171                          COLOR['normal'] + created)
    172                  if hasattr(release, 'changelog'):
    173                      if release.changelog:
    174                          self.write(COLOR['yellow'] + \
    175                                  release.changelog +
    176                                  COLOR['normal']
    177                                  )
    178                  for frel in release.file_releases:
    179                      self.write('   %s' % frel.resUri)
    180
    181 -    def print_people(self):
    182          '''Print all people involved in the project'''
    183          people = ['maintainer', 'developer', 'documenter', 'helper',
    184                  'tester', 'translator']
    185          for job in people:
    186              if hasattr(self.doap, job):
    187                  attribs = getattr(self.doap, job)
    188                  if len(attribs) > 0:
    189                      peeps = []
    190                      for attr in attribs:
    191                          if attr[FOAF.mbox] is None:
    192                              person = "%s" % attr[FOAF.name]
    193                          else:
    194                              mbox = attr[FOAF.mbox].resUri
    195                              if mbox.startswith('mailto:'):
    196                                  mbox = mbox[7:]
    197                                  person = "%s <%s>" % (attr[FOAF.name], mbox)
    198                              else:
    199                                  LOG.debug("mbox is invalid: %s" % mbox)
    200                                  person = "%s" % attr[FOAF.name]
    201                          peeps.append(person)
    202                      label = job.capitalize() + "s:"
    203                      #label = label.ljust(13)
    204                      self.write(misc_field(label,
    205                          ", ".join([p for p in peeps])))
    206
    207 -    def print_field(self, name):
    208          '''
    209          Print a DOAP element
    210
    211          @param name: A misc DOAP element
    212          @type name: string, list or RDFSubject
    213
    214          @rtype: None
    215          @return: Nothing
    216          '''
    217          if not hasattr(self.doap, name):
    218              return
    219          attr = getattr(self.doap, name)
    220          if attr is [] or attr is None:
    221              return
    222
    223          label = '%s' % COLOR['bold'] + pretty_name(name) + \
    224                   COLOR['normal'] + ':'
    225          label = label.ljust(21)
    226          if isinstance(attr, list):
    227              #Can have multiple values per attribute
    228              text = ""
    229              for thing in getattr(self.doap, name):
    230                  if isinstance(thing, rdfSubject):
    231                      text += thing.resUri + "\n"
    232                  else:
    233                      #unicode object
    234                      thing = thing.strip()
    235                      text += thing + "\n"
    236          else:
    237              text = getattr(self.doap, name)
    238              if isinstance(text, rdfSubject):
    239                  text = text.resUri
    240              else:
    241                  text = text.strip()
    242          if text:
    243              if text.startswith('http://'):
    244                  self.write('%s %s' % (label, text.strip()))
    245              else:
    246                  self.write(textwrap.fill('%s %s' % (label, text),
    247                          initial_indent='',
    248                          subsequent_indent = '              '))
    249
    250
    251 -def pretty_name(field):
    252      """
    253      Convert DOAP element name to pretty printable label
    254      Shorten some labels for formatting purposes
    255
    256      @param field: Text to be formatted
    257      @type field: C{string}
    258
    259      @return: formatted string
    260      @rtype: string
    261      """
    262      if field == 'programming_language':
    263          field = 'Prog. Lang.'
    264      elif field == 'created':
    265          field = 'DOAP Created'
    266      else:
    267          field = field.capitalize()
    268          field = field.replace('_', ' ')
    269          field = field.replace('-', ' ')
    270      return field
    271
    272
    273 -def misc_field(label, text):
    274      '''
    275      Print colorized and justified single label value pair
    276
    277      @param label: A label
    278      @type label: string
    279
    280      @param text: Text to print
    281      @type text: string
    282
    283      @rtype: string
    284      @return: Colorized, left-justified text with label
    285      '''
    286      label = label.ljust(13)
    287      label = COLOR['bold'] + label + COLOR['normal']
    288      return '%s %s' % (label, text)
    289