+ sh = shell.Shell()
+ try:
+ cell = parse_last_quote(sh.eval("fs", "whichcell", "-path", dir))
+ except shell.CallError:
+ return (0, None)
+ except OSError as e:
+ if e.errno == errno.ENOENT:
+ return (0, None)
+ raise
+ mount = None
+ while dir:
+ try:
+ volume = parse_last_quote(sh.eval("fs", "lsmount", dir))[1:]
+ break
+ except shell.CallError:
+ dir = os.path.dirname(dir)
+ except OSError as e:
+ if e.errno == errno.ENOENT:
+ return (0, None)
+ raise
+ if not volume: return (0, None)
+ try:
+ result = sh.eval("vos", "examine", "-id", volume, "-cell", cell).splitlines()
+ except OSError:
+ try:
+ result = sh.eval("/usr/sbin/vos", "examine", "-id", volume, "-cell", cell).splitlines()
+ except OSError:
+ return (0, None)
+ except shell.CallError:
+ return (0, None)
+ try:
+ usage = int(result[0].split()[3])
+ limit = int(result[3].split()[1]) # XXX: FRAGILE
+ except ValueError:
+ raise QuotaParseError("vos examine output was:\n\n" + "\n".join(result))
+ return (usage, limit)
+
+# XXX: Possibly in the wrong module
+def get_disk_usage(dir=None, excluded_dir=".git"):
+ """
+ Recursively determines the disk usage of a directory, excluding
+ .git directories. Value is in bytes.
+ """
+ if dir is None: dir = os.getcwd()
+ sum_sizes = 0
+ for root, _, files in os.walk(dir):
+ for name in files:
+ if not os.path.join(root, name).startswith(dir + excluded_dir):
+ file = os.path.join(root, name)
+ try:
+ if os.path.islink(file): continue
+ sum_sizes += os.path.getsize(file)
+ except OSError as e:
+ if e.errno == errno.ENOENT:
+ logging.warning("%s disappeared before we could stat", file)
+ else:
+ raise
+ return sum_sizes
+
+class QuotaParseError(wizard.Error):
+ """Could not parse quota information."""
+ def __init__(self, msg):
+ self.msg = msg
+ def __str__(self):
+ return """