tahoe-lafs/allmydata/filetable.py

110 lines
3.6 KiB
Python
Raw Normal View History

import os, shutil
from zope.interface import implements
from foolscap import Referenceable
from allmydata.interfaces import RIMutableDirectoryNode
from twisted.application import service
from twisted.python import log
class DeadDirectoryNodeError(Exception):
"""The directory referenced by this node has been deleted."""
class BadDirectoryError(Exception):
"""There was a problem with the directory being referenced."""
class BadFileError(Exception):
"""The file being referenced does not exist."""
class MutableDirectoryNode(Referenceable):
implements(RIMutableDirectoryNode)
def __init__(self, basedir):
self._basedir = basedir
2006-12-04 04:11:26 +00:00
def make_subnode(self, basedir):
return self.__class__(basedir)
def validate_name(self, name):
if name == "." or name == ".." or "/" in name:
raise DeadDirectoryNodeError("bad filename component")
# these are the public methods, available to anyone who holds a reference
def list(self):
log.msg("Dir(%s).list" % self._basedir)
results = []
if not os.path.isdir(self._basedir):
raise DeadDirectoryNodeError("This directory has been deleted")
for name in os.listdir(self._basedir):
absname = os.path.join(self._basedir, name)
if os.path.isdir(absname):
2006-12-04 04:11:26 +00:00
results.append( (name, self.make_subnode(absname)) )
elif os.path.isfile(absname):
f = open(absname, "rb")
data = f.read()
f.close()
results.append( (name, data) )
# anything else is ignored
return results
remote_list = list
def get(self, name):
self.validate_name(name)
absname = os.path.join(self._basedir, name)
if os.path.isdir(absname):
return self.make_subnode(absname)
elif os.path.isfile(absname):
f = open(absname, "rb")
data = f.read()
f.close()
return data
else:
raise BadFileError("there is nothing named '%s' in this directory"
% name)
remote_get = get
def add_directory(self, name):
self.validate_name(name)
absname = os.path.join(self._basedir, name)
if os.path.isdir(absname):
raise BadDirectoryError("the directory '%s' already exists" % name)
if os.path.exists(absname):
raise BadDirectoryError("the directory '%s' already exists "
"(but isn't a directory)" % name)
os.mkdir(absname)
2006-12-04 04:11:26 +00:00
return self.make_subnode(absname)
remote_add_directory = add_directory
def add_file(self, name, data):
self.validate_name(name)
f = open(os.path.join(self._basedir, name), "wb")
f.write(data)
f.close()
remote_add_file = add_file
def remove(self, name):
self.validate_name(name)
absname = os.path.join(self._basedir, name)
if os.path.isdir(absname):
shutil.rmtree(absname)
elif os.path.isfile(absname):
os.unlink(absname)
else:
raise BadFileError("Cannot delete non-existent file '%s'" % name)
remote_remove = remove
class GlobalVirtualDrive(service.MultiService):
name = "filetable"
VDRIVEDIR = "vdrive"
def __init__(self, basedir="."):
service.MultiService.__init__(self)
vdrive_dir = os.path.join(basedir, self.VDRIVEDIR)
if not os.path.exists(vdrive_dir):
os.mkdir(vdrive_dir)
self._root = MutableDirectoryNode(vdrive_dir)
def get_root(self):
return self._root