helpers.py 2.8 KB

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