shared.py 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. #!/usr/bin/env python3
  2. #
  3. # mmgen = Multi-Mode GENerator, a command-line cryptocurrency wallet
  4. # Copyright (C)2013-2022 The MMGen Project <mmgen@tuta.io>
  5. # Licensed under the GNU General Public License, Version 3:
  6. # https://www.gnu.org/licenses
  7. # Public project repositories:
  8. # https://github.com/mmgen/mmgen
  9. # https://gitlab.com/mmgen/mmgen
  10. """
  11. tw.shared: classes and functions shared by all tracking wallet classes
  12. """
  13. from ..objmethods import Hilite,InitErrors,MMGenObject
  14. from ..obj import TwComment
  15. from ..addr import MMGenID
  16. class TwMMGenID(str,Hilite,InitErrors,MMGenObject):
  17. color = 'orange'
  18. width = 0
  19. trunc_ok = False
  20. def __new__(cls,proto,id_str):
  21. if type(id_str) == cls:
  22. return id_str
  23. try:
  24. ret = addr = disp = MMGenID(proto,id_str)
  25. sort_key,idtype = (ret.sort_key,'mmgen')
  26. except Exception as e:
  27. try:
  28. coin,addr = id_str.split(':',1)
  29. assert coin == proto.base_coin.lower(),(
  30. f'not a string beginning with the prefix {proto.base_coin.lower()!r}:' )
  31. assert addr.isascii() and addr.isalnum(), 'not an ASCII alphanumeric string'
  32. ret,sort_key,idtype,disp = (id_str,'z_'+id_str,'non-mmgen','non-MMGen')
  33. addr = proto.coin_addr(addr)
  34. except Exception as e2:
  35. return cls.init_fail(e,id_str,e2=e2)
  36. me = str.__new__(cls,ret)
  37. me.obj = ret
  38. me.disp = disp
  39. me.addr = addr
  40. me.sort_key = sort_key
  41. me.type = idtype
  42. me.proto = proto
  43. return me
  44. @classmethod
  45. def fmtc(cls,twmmid,*args,**kwargs):
  46. return super().fmtc(twmmid.disp,*args,**kwargs)
  47. # non-displaying container for TwMMGenID,TwComment
  48. class TwLabel(str,InitErrors,MMGenObject):
  49. exc = 'BadTwLabel'
  50. passthru_excs = ('BadTwComment',)
  51. def __new__(cls,proto,text):
  52. if type(text) == cls:
  53. return text
  54. try:
  55. ts = text.split(None,1)
  56. mmid = TwMMGenID(proto,ts[0])
  57. comment = TwComment(ts[1] if len(ts) == 2 else '')
  58. me = str.__new__( cls, mmid + (' ' + comment if comment else '') )
  59. me.mmid = mmid
  60. me.comment = comment
  61. me.proto = proto
  62. return me
  63. except Exception as e:
  64. return cls.init_fail(e,text)
  65. def get_tw_label(proto,s):
  66. """
  67. raise an exception on a malformed comment, return None on an empty or invalid label
  68. """
  69. try:
  70. return TwLabel(proto,s)
  71. except Exception as e:
  72. if type(e).__name__ == 'BadTwComment': # do it this way to avoid importing .exception
  73. raise
  74. else:
  75. return None