]> arthur.barton.de Git - bup.git/blobdiff - lib/bup/helpers.py
Honor git config pack.packSizeLimit when set
[bup.git] / lib / bup / helpers.py
index 6226866388d825cf53e719de6ce1a2b02ccbbc73..86ac90f5793d2d38ba1a5d84c1460376e022781c 100644 (file)
@@ -9,6 +9,12 @@ import hashlib, heapq, math, operator, time, grp, tempfile
 
 from bup import _helpers
 
+
+class Nonlocal:
+    """Helper to deal with Python scoping issues"""
+    pass
+
+
 sc_page_size = os.sysconf('SC_PAGE_SIZE')
 assert(sc_page_size > 0)
 
@@ -62,6 +68,38 @@ else:
     fdatasync = _fdatasync
 
 
+def partition(predicate, stream):
+    """Returns (leading_matches_it, rest_it), where leading_matches_it
+    must be completely exhausted before traversing rest_it.
+
+    """
+    stream = iter(stream)
+    ns = Nonlocal()
+    ns.first_nonmatch = None
+    def leading_matches():
+        for x in stream:
+            if predicate(x):
+                yield x
+            else:
+                ns.first_nonmatch = (x,)
+                break
+    def rest():
+        if ns.first_nonmatch:
+            yield ns.first_nonmatch[0]
+            for x in stream:
+                yield x
+    return (leading_matches(), rest())
+
+
+def stat_if_exists(path):
+    try:
+        return os.stat(path)
+    except OSError as e:
+        if e.errno != errno.ENOENT:
+            raise
+    return None
+
+
 # Write (blockingly) to sockets that may or may not be in blocking mode.
 # We need this because our stderr is sometimes eaten by subprocesses
 # (probably ssh) that sometimes make it nonblocking, if only temporarily,
@@ -1126,3 +1164,22 @@ def valid_save_name(name):
         if part.startswith('.') or part.endswith('.lock'):
             return False
     return True
+
+
+_period_rx = re.compile(r'^([0-9]+)(s|min|h|d|w|m|y)$')
+
+def period_as_secs(s):
+    if s == 'forever':
+        return float('inf')
+    match = _period_rx.match(s)
+    if not match:
+        return None
+    mag = int(match.group(1))
+    scale = match.group(2)
+    return mag * {'s': 1,
+                  'min': 60,
+                  'h': 60 * 60,
+                  'd': 60 * 60 * 24,
+                  'w': 60 * 60 * 24 * 7,
+                  'm': 60 * 60 * 24 * 31,
+                  'y': 60 * 60 * 24 * 366}[scale]