mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-22 14:22:25 +00:00
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
|
|
||
|
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
|
||
|
|
||
|
def validate_name(self, name):
|
||
|
if name == "." or name == ".." or "/" in name:
|
||
|
raise DeadDirectoryNodeError("bad filename component")
|
||
|
|
||
|
# this is private
|
||
|
def get_child(self, name):
|
||
|
self.validate_name(name)
|
||
|
absname = os.path.join(self._basedir, name)
|
||
|
if os.path.isdir(absname):
|
||
|
return MutableDirectoryNode(absname)
|
||
|
raise DeadDirectoryNodeError("no such directory")
|
||
|
|
||
|
# 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):
|
||
|
results.append( (name, MutableDirectoryNode(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 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)
|
||
|
return MutableDirectoryNode(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)
|
||
|
|
||
|
|
||
|
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
|
||
|
|