1.1 --- a/WebStack/Repositories/Directory.py Sat Nov 19 23:59:54 2005 +0000
1.2 +++ b/WebStack/Repositories/Directory.py Sun Nov 20 00:00:39 2005 +0000
1.3 @@ -26,7 +26,7 @@
1.4
1.5 "A directory repository providing session-like access to files."
1.6
1.7 - def __init__(self, path, fsencoding=None):
1.8 + def __init__(self, path, fsencoding=None, delay=1):
1.9
1.10 """
1.11 Initialise the repository using the given 'path' to indicate the
1.12 @@ -37,12 +37,17 @@
1.13 character encoding used by the filesystem to represent filenames. By
1.14 default, the default encoding is detected (or Unicode objects are used
1.15 if appropriate).
1.16 +
1.17 + The optional 'delay' argument specifies the time in seconds between each
1.18 + poll of an opened repository file when that file is found to be locked
1.19 + for editing.
1.20 """
1.21
1.22 if not os.path.exists(path):
1.23 os.mkdir(path)
1.24 self.path = path
1.25 self.fsencoding = fsencoding
1.26 + self.delay = delay
1.27
1.28 # Guess the filesystem encoding.
1.29
1.30 @@ -71,7 +76,14 @@
1.31 return name
1.32
1.33 def keys(self):
1.34 - return map(self._convert_fsname, os.listdir(self.path))
1.35 + # NOTE: Special names converted using a simple rule.
1.36 + l = []
1.37 + for name in os.listdir(self.path):
1.38 + if name.endswith(".edit"):
1.39 + l.append(name[:-5])
1.40 + else:
1.41 + l.append(name)
1.42 + return map(self._convert_fsname, l)
1.43
1.44 def full_path(self, key):
1.45 return os.path.join(self.path, self._convert_name(key))
1.46 @@ -93,23 +105,58 @@
1.47 results.append(self[key])
1.48 return results
1.49
1.50 - def __getitem__(self, key):
1.51 - f = open(os.path.join(self.path, self._convert_name(key)), "rb")
1.52 - s = ""
1.53 - try:
1.54 - s = f.read()
1.55 - finally:
1.56 - f.close()
1.57 - return s
1.58 + def _wait_for_file(self, key):
1.59 + filename = self.full_path(key)
1.60 + if os.path.exists(filename) or os.path.exists(filename + ".edit"):
1.61 + while 1:
1.62 + try:
1.63 + os.rename(filename, filename + ".edit")
1.64 + except OSError:
1.65 + time.sleep(self.delay)
1.66 + else:
1.67 + break
1.68 + return filename, 1
1.69 + else:
1.70 + return filename, 0
1.71
1.72 def __delitem__(self, key):
1.73 - os.remove(os.path.join(self.path, self._convert_name(key)))
1.74 + filename = self.full_path(key)
1.75 + if os.path.exists(filename) or os.path.exists(filename + ".edit"):
1.76 + while 1:
1.77 + try:
1.78 + os.remove(filename)
1.79 + except OSError:
1.80 + time.sleep(self.delay)
1.81 + else:
1.82 + break
1.83 + else:
1.84 + raise KeyError, key
1.85 +
1.86 + def __getitem__(self, key):
1.87 + filename, exists = self._wait_for_file(key)
1.88 + if not exists:
1.89 + raise KeyError, key
1.90 + try:
1.91 + f = open(filename + ".edit", "rb")
1.92 + s = ""
1.93 + try:
1.94 + s = f.read()
1.95 + finally:
1.96 + f.close()
1.97 + finally:
1.98 + os.rename(filename + ".edit", filename)
1.99 +
1.100 + return s
1.101
1.102 def __setitem__(self, key, value):
1.103 - f = open(os.path.join(self.path, self._convert_name(key)), "wb")
1.104 + filename, exists = self._wait_for_file(key)
1.105 try:
1.106 - f.write(value)
1.107 + f = open(filename + ".edit", "wb")
1.108 + try:
1.109 + f.write(value)
1.110 + finally:
1.111 + f.close()
1.112 finally:
1.113 - f.close()
1.114 + os.rename(filename + ".edit", filename)
1.115
1.116 # vim: tabstop=4 expandtab shiftwidth=4