helpers.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import argparse
  2. from datetime import datetime
  3. import grp
  4. import pwd
  5. import re
  6. def format_time(t):
  7. """Format datetime suitable for fixed length list output
  8. """
  9. if (datetime.now() - t).days < 365:
  10. return t.strftime('%b %d %H:%M')
  11. else:
  12. return t.strftime('%b %d %Y')
  13. def format_file_mode(mod):
  14. """Format file mode bits for list output
  15. """
  16. def x(v):
  17. return ''.join(v & m and s or '-'
  18. for m, s in ((4, 'r'), (2, 'w'), (1, 'x')))
  19. return '%s%s%s' % (x(mod / 64), x(mod / 8), x(mod))
  20. def format_file_size(v):
  21. """Format file size into a human friendly format
  22. """
  23. if v > 1024 * 1024 * 1024:
  24. return '%.2f GB' % (v / 1024. / 1024. / 1024.)
  25. elif v > 1024 * 1024:
  26. return '%.2f MB' % (v / 1024. / 1024.)
  27. elif v > 1024:
  28. return '%.2f kB' % (v / 1024.)
  29. else:
  30. return str(v)
  31. class IntegrityError(Exception):
  32. """
  33. """
  34. def memoize(function):
  35. cache = {}
  36. def decorated_function(*args):
  37. try:
  38. return cache[args]
  39. except KeyError:
  40. val = function(*args)
  41. cache[args] = val
  42. return val
  43. return decorated_function
  44. @memoize
  45. def uid2user(uid):
  46. try:
  47. return pwd.getpwuid(uid).pw_name
  48. except KeyError:
  49. return None
  50. @memoize
  51. def user2uid(user):
  52. try:
  53. return pwd.getpwnam(user).pw_uid
  54. except KeyError:
  55. return None
  56. @memoize
  57. def gid2group(gid):
  58. try:
  59. return grp.getgrgid(gid).gr_name
  60. except KeyError:
  61. return None
  62. @memoize
  63. def group2gid(group):
  64. try:
  65. return grp.getgrnam(group).gr_gid
  66. except KeyError:
  67. return None
  68. class Location(object):
  69. loc_re = re.compile(r'^((?:(?P<user>[^@]+)@)?(?P<host>[^:]+):)?'
  70. r'(?P<path>[^:]*)(?:::(?P<archive>[^:]+))?$')
  71. def __init__(self, text):
  72. loc = self.loc_re.match(text)
  73. loc = loc and loc.groupdict()
  74. if not loc:
  75. raise ValueError
  76. self.user = loc['user']
  77. self.host = loc['host']
  78. self.path = loc['path']
  79. if not self.host and not self.path:
  80. raise ValueError
  81. self.archive = loc['archive']
  82. def __str__(self):
  83. text = ''
  84. if self.user:
  85. text += '%s@' % self.user
  86. if self.host:
  87. text += '%s::' % self.host
  88. if self.path:
  89. text += self.path
  90. if self.archive:
  91. text += ':%s' % self.archive
  92. return text
  93. def __repr__(self):
  94. return "Location('%s')" % self
  95. def location_validator(archive=None):
  96. def validator(text):
  97. try:
  98. loc = Location(text)
  99. except ValueError:
  100. raise argparse.ArgumentTypeError('Invalid location format: "%s"' % text)
  101. if archive is True and not loc.archive:
  102. raise argparse.ArgumentTypeError('"%s": No archive specified' % text)
  103. elif archive is False and loc.archive:
  104. raise argparse.ArgumentTypeError('"%s" No archive can be specified' % text)
  105. return loc
  106. return validator