help.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
  4. # Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
  5. #
  6. # This program is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # This program is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. """
  19. tool/help.py: Help screen routines for the 'mmgen-tool' utility
  20. """
  21. from .common import tool_cmd_base
  22. import mmgen.main_tool as main_tool
  23. def main_help():
  24. from ..util import pretty_format
  25. def do():
  26. for clsname,cmdlist in main_tool.mods.items():
  27. cls = main_tool.get_mod_cls(clsname)
  28. cls_doc = cls.__doc__.strip().split('\n')
  29. for l in cls_doc:
  30. if l is cls_doc[0]:
  31. l += ':'
  32. l = l.replace('\t','',1)
  33. if l:
  34. l = l.replace('\t',' ')
  35. yield l[0].upper() + l[1:]
  36. else:
  37. yield ''
  38. yield ''
  39. max_w = max(map(len,cmdlist))
  40. for cmdname in cmdlist:
  41. code = getattr(cls,cmdname)
  42. if code.__doc__:
  43. yield ' {:{}} - {}'.format(
  44. cmdname,
  45. max_w,
  46. pretty_format(
  47. code.__doc__.strip().split('\n')[0].strip(),
  48. width = 79-(max_w+7),
  49. pfx = ' '*(max_w+5)).lstrip()
  50. )
  51. yield ''
  52. return '\n'.join(do())
  53. def usage(cmdname=None,exit_val=1):
  54. m1 = """
  55. USAGE INFORMATION FOR MMGEN-TOOL COMMANDS:
  56. Arguments with only type specified in square brackets are required
  57. Arguments with both type and default value specified in square brackets are
  58. optional; if used, they must be supplied in the form ‘name=value’
  59. """
  60. m2 = """
  61. To force a command to read from STDIN instead of file (for commands taking
  62. a filename as their first argument), substitute "-" for the filename.
  63. EXAMPLES:
  64. Generate a random Bech32 public/private keypair for LTC:
  65. $ mmgen-tool -r0 --coin=ltc --type=bech32 randpair
  66. Generate a DASH compressed public key address from the supplied WIF key:
  67. $ mmgen-tool --coin=dash --type=compressed wif2addr XJkVRC3eGKurc9Uzx1wfQoio3yqkmaXVqLMTa6y7s3M3jTBnmxfw
  68. Generate a well-known burn address:
  69. $ mmgen-tool hextob58chk 000000000000000000000000000000000000000000
  70. Generate a random 12-word seed phrase:
  71. $ mmgen-tool -r0 mn_rand128
  72. Same as above, but get additional entropy from user:
  73. $ mmgen-tool mn_rand128
  74. Encode bytes from a file to base 58:
  75. $ mmgen-tool bytestob58 /etc/timezone pad=20
  76. Reverse a hex string:
  77. $ mmgen-tool hexreverse "deadbeefcafe"
  78. Same as above, but use a pipe:
  79. $ echo "deadbeefcafe" | mmgen-tool hexreverse -
  80. """
  81. from ..util import Msg,Msg_r,fmt,die,capfirst
  82. if cmdname:
  83. from ..globalvars import g
  84. for mod,cmdlist in main_tool.mods.items():
  85. if cmdname in cmdlist:
  86. cls = main_tool.get_mod_cls(mod)
  87. docstr = getattr(cls,cmdname).__doc__.strip()
  88. Msg('{a}\n\nUSAGE: {b} {c} {d}{e}'.format(
  89. a = capfirst( docstr.split('\n')[0].strip() ),
  90. b = g.prog_name,
  91. c = cmdname,
  92. d = main_tool.create_call_sig(cmdname,cls),
  93. e = '\n\n' + fmt('\n'.join(docstr.split('\n')[1:]),strip_char='\t').rstrip()
  94. if '\n' in docstr else '' ))
  95. break
  96. else:
  97. die(1,f'{cmdname!r}: no such tool command')
  98. else:
  99. Msg(fmt(m1,strip_char='\t'))
  100. for clsname,cmdlist in main_tool.mods.items():
  101. cls = main_tool.get_mod_cls(clsname)
  102. cls_info = cls.__doc__.strip().split('\n')[0]
  103. Msg(' {}{}:\n'.format( cls_info[0].upper(), cls_info[1:] ))
  104. max_w = max(map(len,cmdlist))
  105. for cmdname in cmdlist:
  106. Msg(f' {cmdname:{max_w}} {main_tool.create_call_sig(cmdname,cls)}')
  107. Msg('')
  108. Msg_r(' ' + fmt(m2,strip_char='\t'))
  109. import sys
  110. sys.exit(exit_val)
  111. class tool_cmd(tool_cmd_base):
  112. "help/usage commands"
  113. def help(self,command_name=''):
  114. "display usage information for a single command or all commands"
  115. usage(command_name,exit_val=0)
  116. def usage(self,command_name=''):
  117. "display usage information for a single command"
  118. usage(command_name,exit_val=0)