helpers.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import argparse
  2. import grp
  3. import logging
  4. import pwd
  5. import re
  6. def memoize(function):
  7. cache = {}
  8. def decorated_function(*args):
  9. try:
  10. return cache[args]
  11. except KeyError:
  12. val = function(*args)
  13. cache[args] = val
  14. return val
  15. return decorated_function
  16. @memoize
  17. def uid2user(uid):
  18. try:
  19. return pwd.getpwuid(uid).pw_name
  20. except KeyError:
  21. return None
  22. @memoize
  23. def user2uid(user):
  24. try:
  25. return pwd.getpwnam(user).pw_uid
  26. except KeyError:
  27. return None
  28. @memoize
  29. def gid2group(gid):
  30. try:
  31. return grp.getgrgid(gid).gr_name
  32. except KeyError:
  33. return None
  34. @memoize
  35. def group2gid(group):
  36. try:
  37. return grp.getgrnam(group).gr_gid
  38. except KeyError:
  39. return None
  40. class LevelFilter(logging.Filter):
  41. """Filter that counts record levels
  42. """
  43. def __init__(self, *args, **kwargs):
  44. logging.Filter.__init__(self, *args, **kwargs)
  45. self.count = {}
  46. def filter(self, record):
  47. self.count.setdefault(record.levelname, 0)
  48. self.count[record.levelname] += 1
  49. return record
  50. class Location(object):
  51. loc_re = re.compile(r'^((?:(?P<user>[^@]+)@)?(?P<host>[^:]+):)?'
  52. r'(?P<path>[^:]*)(?:::(?P<archive>[^:]+))?$')
  53. def __init__(self, text):
  54. loc = self.loc_re.match(text)
  55. loc = loc and loc.groupdict()
  56. if not loc:
  57. raise ValueError
  58. self.user = loc['user']
  59. self.host = loc['host']
  60. self.path = loc['path']
  61. if not self.host and not self.path:
  62. raise ValueError
  63. self.archive = loc['archive']
  64. def __str__(self):
  65. text = ''
  66. if self.user:
  67. text += '%s@' % self.user
  68. if self.host:
  69. text += '%s::' % self.host
  70. if self.path:
  71. text += self.path
  72. if self.archive:
  73. text += ':%s' % self.archive
  74. return text
  75. def __repr__(self):
  76. return "Location('%s')" % self
  77. def location_validator(archive=None):
  78. def validator(text):
  79. try:
  80. loc = Location(text)
  81. except ValueError:
  82. raise argparse.ArgumentTypeError('Invalid location format: "%s"' % text)
  83. if archive is True and not loc.archive:
  84. raise argparse.ArgumentTypeError('"%s": No archive specified' % text)
  85. elif archive is False and loc.archive:
  86. raise argparse.ArgumentTypeError('"%s" No archive can be specified' % text)
  87. return loc
  88. return validator
  89. def pretty_size(v):
  90. if v > 1024 * 1024 * 1024:
  91. return '%.2f GB' % (v / 1024. / 1024. / 1024.)
  92. elif v > 1024 * 1024:
  93. return '%.2f MB' % (v / 1024. / 1024.)
  94. elif v > 1024:
  95. return '%.2f kB' % (v / 1024.)
  96. else:
  97. return str(v)