helpers.py 3.3 KB

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