commit:     4ca72a8d531a7a794b1973a01f792836bb42ed18
Author:     Brian Dolbec <dolsen <AT> gentoo <DOT> org>
AuthorDate: Sat Jan  3 18:13:18 2015 +0000
Commit:     Brian Dolbec <dolsen <AT> gentoo <DOT> org>
CommitDate: Mon Jan  5 22:14:35 2015 +0000
URL:        
http://sources.gentoo.org/gitweb/?p=proj/gentoo-keys.git;a=commit;h=4ca72a8d

Initial py2man pkg for auto-generating our man pages

---
 py2man/__init__.py |   1 +
 py2man/manpages.py | 172 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 py2man/options.py  |  93 +++++++++++++++++++++++++++++
 3 files changed, 266 insertions(+)

diff --git a/py2man/__init__.py b/py2man/__init__.py
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/py2man/__init__.py
@@ -0,0 +1 @@
+

diff --git a/py2man/manpages.py b/py2man/manpages.py
new file mode 100644
index 0000000..2490fcc
--- /dev/null
+++ b/py2man/manpages.py
@@ -0,0 +1,172 @@
+#
+#-*- coding:utf-8 -*-
+
+
+import os
+from datetime import datetime
+
+from .options import LONG_OPTIONS, SHORT_OPTS
+
+
+ActionStr = '.BR gkeys-%s (1),'
+
+ExampleHeader = '''.SH Example'''
+
+BreakStr = '''.br
+%s'''
+
+SubCmdStr = '''.IP %(cmd)s
+%(cmd-desc)s'''
+
+SubCmdHdr = '.SH \\  %s'
+
+class ManPage(object):
+
+    def __init__(self, prog, version, template, path):
+        self.prog = prog
+        self.version = version
+        self.template = template
+        self.path = path
+
+
+    @staticmethod
+    def gen_opts(options):
+        _opts = list()
+        for opt in options:
+            _opts.append(SHORT_OPTS.get(opt))
+        return _opts
+
+
+    @staticmethod
+    def gen_optsStr(firstline, data, opts):
+        indent = '                                 '
+        escapes = 15
+        wrapl = 72 + escapes
+        output = []
+        line = firstline.rstrip('%(opts)s') % data
+        ll = len(line)
+        l1 = True
+        for opt in opts:
+            if (ll + len(SHORT_OPTS[opt])) < wrapl:
+                line = line + '%s ' % SHORT_OPTS[opt]
+                ll = len(line)
+            else:
+                if l1:
+                    output.append(line)
+                    l1 = False
+                else:
+                    output.append(BreakStr % line)
+                line = indent + '%s ' % SHORT_OPTS[opt]
+                ll = len(line)
+        return '\n'.join(output)
+
+
+    @staticmethod
+    def gen_actions(actions):
+        acts = []
+        for act in actions:
+            if not act.startswith("--"):
+                acts.append(ActionStr % act)
+        return '\n'.join(acts)
+
+
+    @staticmethod
+    def gen_options(options):
+        _opts = []
+        for opt in options:
+            _opts.append(LONG_OPTIONS[opt])
+        return '\n'.join(_opts)
+
+
+    @staticmethod
+    def gen_example(text):
+        example = []
+        if text:
+            for line in text.split('\n'):
+                if line and line[0] in [' ']:
+                    example.append(line)
+                else:
+                    example.append(BreakStr % line)
+        return '\n'.join(example)
+
+
+    @staticmethod
+    def gen_subcmd(cmds):
+        #print(cmds.values())
+        output = []
+        for cmd in list(cmds):
+            print(cmd)
+            if cmd.startswith('--'):
+                output.append(SubCmdHdr % cmd.strip('-').upper())
+            else:
+                output.append(SubCmdStr % {'cmd': cmd, 'cmd-desc': cmds[cmd]})
+        return '\n'.join(output)
+
+
+    def make_subpage(self, action, Action_Map, actions):
+        '''Create and saves one sub-command man page using the
+        classes template definition setting'''
+        actions.remove(action)
+        # remove the help group separators
+        actions = [x for x in actions if not x.startswith("---")]
+        data = {}
+        data['prog'] = self.prog
+        data['version'] = self.version
+        data['date'] = datetime.strftime(datetime.today(),'%B %d, %Y')
+        data['action'] = action
+        data['actions'] = self.gen_actions(actions)
+        data['options'] = self.gen_options(Action_Map[action]['options'])
+        data['desc'] = Action_Map[action]['desc']
+        data['long_desc'] = Action_Map[action]['long_desc']
+        if Action_Map[action]['example']:
+            data['example'] = self.gen_example(Action_Map[action]['example'])
+            data['exampleheader'] = ExampleHeader
+        else:
+            data['example'] = ''
+            data['exampleheader'] = ''
+        doc = []
+        for line in self.template.split('\n'):
+            if '%(opts)s' in line:
+                doc.append(self.gen_optsStr(
+                    line, data, Action_Map[action]['options']))
+            else:
+                doc.append(line % data)
+        filepath = os.path.join(self.path, "%s-%s.1" % (self.prog, action))
+        with open(filepath, 'w', encoding='utf-8') as man:
+            man.write('\n'.join(doc))
+
+
+    def make_subpages(self, Action_Map, actions):
+        '''Create man pages for all sub-commands listed
+
+        @param prog: string of the base application command
+        @param version: string to embed in the man pages
+        @param Action_Map: Dictionary of sub-command actions and other data
+        @param actions: list of keys in Action_Map to generate pages for
+        @param location: string, path to save the newly created man pages
+        '''
+        for action in actions:
+            self.make_subpage(action, Action_Map, actions)
+
+
+    def make_prog(self, prog_map):
+        data = {}
+        data['prog'] = self.prog
+        data['version'] = self.version
+        data['date'] = datetime.strftime(datetime.today(),'%B %d, %Y')
+        data['actions'] = self.gen_actions(list(prog_map['sub-cmds']))
+        data['options'] = self.gen_options(prog_map['options'])
+        data['desc'] = prog_map['desc']
+        data['long_desc'] = prog_map['long_desc']
+        data['sub-cmds'] = self.gen_subcmd(prog_map['sub-cmds'])
+        doc = []
+        for line in self.template.split('\n'):
+                doc.append(line % data)
+        filepath = os.path.join(self.path, "%s.1" % (self.prog))
+        with open(filepath, 'w', encoding='utf-8') as man:
+            man.write('\n'.join(doc))
+
+    def read_template(self, path, filename):
+        filepath = os.path.join(path, filename)
+        with open(filepath, 'r', encoding='utf-8') as template:
+            self.template = template.read()

diff --git a/py2man/options.py b/py2man/options.py
new file mode 100644
index 0000000..1beb132
--- /dev/null
+++ b/py2man/options.py
@@ -0,0 +1,93 @@
+#
+#-*- coding:utf-8 -*-
+
+from collections import OrderedDict
+
+
+LONG_OPTIONS = OrderedDict({
+    'help': '''.IP "-h, --help"
+show this help message and exit''',
+    'status': '''.IP "-A, --status"
+Toggles the active status of a member for LDAP searches''',
+    'all': '''.IP "-a, --all"
+Toggles matching all input arguments for searches''',
+    'category': '''.IP "-C \\fICATEGORY\\fR, --category \\fICATEGORY"
+The category name of the seed file being added to.
+.br
+This name must be listed in the gkeys.conf file's
+[seeds], [seedurls] and [verify-seeds] sections''',
+    'cleankey': '''.IP " --clean-key"
+Clean the key from the keyring due to failures.''',
+    'cleanseed': '''.IP " --clean-seed"
+Clean the seed from the seedfile due to failures.
+.br
+Used during binary keyring release creation.''',
+    'config': '''.IP "-c \\fICONFIG\\fR, --config \\fICONFIG\\fR"
+The path to an alternate config file''',
+    'debug': '''.IP "-D, --debug 
\\fI{WARNING,INFO,FATAL,NOTSET,WARN,DEBUG,ERROR,CRITICAL}\\fR"
+The logging level to set for the logfile''',
+    'dest': '''.IP "-d \\fIDESTINATION\\fR, --dest \\fIDESTINATION"
+The category name of the seed file being added to.''',
+    'exact': '''.IP "-e, --exact"
+Use CASE matching in searches''',
+    'file': '''.IP "-F \\fIFILENAME\\fR, --file \\fIFILENAME"
+The path/URL to use for the (signed) file''',
+    '1file': '''.IP "-F \\fIFILENAME\\fR, --file \\fIFILENAME"
+The path/URL to use for the (signed) file''',
+    'fingerprint': '''.IP "-f \\fIFINGERPRINT\\fR, --fingerprint 
\\fIFINGERPRINT"
+The fingerprint(s) of the the key(s) or subkey(s)''',
+    'gpgsearch': '''.IP "-g, --gpgsearch"
+Do a gpg search operation, rather than a gkey search''',
+    'homedir': '''.IP "-H \\fIHOMEDIR\\fR, --file \\fIHOMEDIR"
+The destination for the generated key''',
+    'keyid': '''.IP "-i \\fIKEYID\\fR, --keyid \\fIKEYID"
+The long keyid of the gpg key to search for''',
+    'keyring': '''.IP "-k \\fIKEYRING\\fR, --keyring \\fIKEYRING"
+The name of the keyring to use for verification, etc.''',
+    'keys': '''.IP "-K \\fIKEYS\\fR, --keys \\fIKEYS"
+The fingerprint(s) of the primary keys in the keyring.''',
+    'mail': '''.IP "-m \\fIEMAIL\\fR, --mail \\fIEMAIL"
+The email address to search for or use.''',
+    'nick': '''.IP "-n \\fINICK\\fR, --nick \\fINICK"
+The nick of the user whose gkey seed is being added''',
+    'name': '''.IP "-N \\fINAME\\fR, --name \\fINAME"
+The name of the user whose gkey seed is being added''',
+    'keydir': '''.IP "-r \\fIKEYDIR\\fR, --keydir \\fIKEYDIR"
+The key directory the key is to be installed to''',
+    'signature': '''.IP "-s \\fISIGNATURE\\fR, --signature \\fISIGNATURE"
+The path/URL to use for the signature.''',
+    'spec': '''.IP "-S \\fISPEC\\fR, --psec \\fISPEC"
+The spec file to use from the gkeys-gen.conf file.''',
+    'timestamp': '''.IP "-t, --timestamp"
+Turn on timestamp use.''',
+    'uid': '''.IP "-u \\fIUID\\fR, --uid \\fIUID"
+The user id(s) (and email) of the key(s) being added (optional)''',
+})
+
+SHORT_OPTS = OrderedDict({
+    'help': '[\\fB\\-h\\fR]',
+    'status': '[\\fB\\-A\\fR]',
+    'all': '[\\fB\\-a\\fR]',
+    'category': '[\\fB\\-C\\fR \\fICATEGORY\\fR]',
+    'cleankey': '[\\fB\\-\\-cleankey\\fR]',
+    'cleanseed': '[\\fB\\-\\-cleanseed\\fR]',
+    'dest': '[\\fB\\-d\\fR \\fIDESTINATION\\fR]',
+    'exact': '[\\fB\\-e\\fR]',
+    'file': '[\\fB\\-F\\fR \\fIFILENAME\\fR]',
+    '1file': '[\\fB\\-F\\fR \\fIFILENAME\\fR]',
+    'fingerprint': '[\\fB\\-f\\fR \\fIFINGERPRINT\\fR [\\fIFINGERPRINT\\fR 
...]]',
+    'gpgsearch': '[\\fB\\-g\\fR]',
+    'homedir': '[\\fB\\-H\\fR \\fIHOMEDIR\\fR]',
+    'keyid': '[\\fB\\-i\\fR \\fIKEYID\\fR [\\fIKEYID\\fR ...]]',
+    'keyring': '[\\fB\\-k\\fR \\fIKEYRING\\fR]',
+    'keys': '[\\fB\\-K\\fR [\\fIKEYS\\fR [\\fIKEYS\\fR ...]]]',
+    'mail': '[\\fB\\-m\\fR \\fIEMAIL\\fR]',
+    'nick': '[\\fB\\-n\\fR \\fINICK\\fR]',
+    'name': '[\\fB\\-N\\fR [\\fINAME\\fR [\\fINAME\\fR ...]]]',
+    '1name': '[\\fB\\-N\\fR \\fINAME\\fR]',
+    'keydir': '[\\fB\\-r\\fR \\fIKEYDIR\\fR]',
+    'signature': '[\\fB\\-s\\fR \\fISIGNATURE\\fR]',
+    'spec': '[\\fB\\-S\\fR \\fISPEC\\fR]',
+    'timestamp': '[\\fB\\-t\\fR]',
+    'uid': '[\\fB\\-u\\fR [\\fIUID\\fR [\\fIUID\\fR ...]]]',
+})

Reply via email to