""" PyFuse client for the Tahoe distributed file system. See http://allmydata.org/ """ # Read-only for now. # Portions copied from the file contrib/fuse/tahoe_fuse.py distributed # with Tahoe 1.0.0. import os, sys from objectfs import ObjectFs from handler import Handler import simplejson import urllib ### Config: TahoeConfigDir = '~/.tahoe' ### Utilities for debug: def log(msg, *args): print msg % args class TahoeConnection: def __init__(self, confdir): self.confdir = confdir self._init_url() def _init_url(self): if os.path.exists(os.path.join(self.confdir, 'node.url')): self.url = file(os.path.join(self.confdir, 'node.url'), 'rb').read().strip() if not self.url.endswith('/'): self.url += '/' else: f = open(os.path.join(self.confdir, 'webport'), 'r') contents = f.read() f.close() fields = contents.split(':') proto, port = fields[:2] assert proto == 'tcp' port = int(port) self.url = 'http://localhost:%d/' % (port,) def get_root(self): # For now we just use the same default as the CLI: rootdirfn = os.path.join(self.confdir, 'private', 'root_dir.cap') f = open(rootdirfn, 'r') cap = f.read().strip() f.close() return TahoeDir(self, canonicalize_cap(cap)) class TahoeNode: def __init__(self, conn, uri): self.conn = conn self.uri = uri def get_metadata(self): f = self._open('?t=json') json = f.read() f.close() return simplejson.loads(json) def _open(self, postfix=''): url = '%suri/%s%s' % (self.conn.url, self.uri, postfix) log('*** Fetching: %r', url) return urllib.urlopen(url) class TahoeDir(TahoeNode): def listdir(self): flag, md = self.get_metadata() assert flag == 'dirnode' result = [] for name, (childflag, childmd) in md['children'].items(): if childflag == 'dirnode': cls = TahoeDir else: cls = TahoeFile result.append((str(name), cls(self.conn, childmd['ro_uri']))) return result class TahoeFile(TahoeNode): def size(self): rawsize = self.get_metadata()[1]['size'] return rawsize def read(self): return self._open().read() def canonicalize_cap(cap): cap = urllib.unquote(cap) i = cap.find('URI:') assert i != -1, 'A cap must contain "URI:...", but this does not: ' + cap return cap[i:] def main(mountpoint, basedir): conn = TahoeConnection(basedir) root = conn.get_root() handler = Handler(mountpoint, ObjectFs(root)) handler.loop_forever() if __name__ == '__main__': basedir = os.path.expanduser(TahoeConfigDir) for i, arg in enumerate(sys.argv): if arg == '--basedir': basedir = sys.argv[i+1] sys.argv[i:i+2] = [] [mountpoint] = sys.argv[1:] main(mountpoint, basedir)