]> git.rkrishnan.org Git - tahoe-lafs/tahoe-lafs.git/blob - src/allmydata/nodemaker.py
update many dirnode interfaces to accept dict-of-nodes instead of dict-of-caps
[tahoe-lafs/tahoe-lafs.git] / src / allmydata / nodemaker.py
1 import weakref
2 from zope.interface import implements
3 from allmydata.interfaces import INodeMaker
4 from allmydata.immutable.filenode import FileNode, LiteralFileNode
5 from allmydata.mutable.filenode import MutableFileNode
6 from allmydata.dirnode import DirectoryNode
7 from allmydata.unknown import UnknownNode
8 from allmydata.uri import DirectoryURI, ReadonlyDirectoryURI
9
10 class NodeMaker:
11     implements(INodeMaker)
12
13     def __init__(self, storage_broker, secret_holder, history,
14                  uploader, downloader, download_cache_dirman,
15                  default_encoding_parameters, key_generator):
16         self.storage_broker = storage_broker
17         self.secret_holder = secret_holder
18         self.history = history
19         self.uploader = uploader
20         self.downloader = downloader
21         self.download_cache_dirman = download_cache_dirman
22         self.default_encoding_parameters = default_encoding_parameters
23         self.key_generator = key_generator
24
25         self._node_cache = weakref.WeakValueDictionary() # uri -> node
26
27     def _create_lit(self, cap):
28         return LiteralFileNode(cap)
29     def _create_immutable(self, cap):
30         return FileNode(cap, self.storage_broker, self.secret_holder,
31                         self.downloader, self.history,
32                         self.download_cache_dirman)
33     def _create_mutable(self, cap):
34         n = MutableFileNode(self.storage_broker, self.secret_holder,
35                             self.default_encoding_parameters,
36                             self.history)
37         return n.init_from_uri(cap)
38     def _create_dirnode(self, filenode):
39         return DirectoryNode(filenode, self, self.uploader)
40
41     def create_from_cap(self, writecap, readcap=None):
42         # this returns synchronously.
43         assert isinstance(writecap, (str, type(None))), type(writecap)
44         assert isinstance(readcap,  (str, type(None))), type(readcap)
45         cap = writecap or readcap
46         if not cap:
47             # maybe the writecap was hidden because we're in a readonly
48             # directory, and the future cap format doesn't have a readcap, or
49             # something.
50             return UnknownNode(writecap, readcap)
51         if cap in self._node_cache:
52             return self._node_cache[cap]
53         elif cap.startswith("URI:LIT:"):
54             node = self._create_lit(cap)
55         elif cap.startswith("URI:CHK:"):
56             node = self._create_immutable(cap)
57         elif cap.startswith("URI:SSK-RO:") or cap.startswith("URI:SSK:"):
58             node = self._create_mutable(cap)
59         elif cap.startswith("URI:DIR2-RO:") or cap.startswith("URI:DIR2:"):
60             if cap.startswith("URI:DIR2-RO:"):
61                 dircap = ReadonlyDirectoryURI.init_from_string(cap)
62             elif cap.startswith("URI:DIR2:"):
63                 dircap = DirectoryURI.init_from_string(cap)
64             filecap = dircap.get_filenode_uri().to_string()
65             filenode = self.create_from_cap(filecap)
66             node = self._create_dirnode(filenode)
67         else:
68             return UnknownNode(writecap, readcap) # don't cache UnknownNode
69         self._node_cache[cap] = node  # note: WeakValueDictionary
70         return node
71
72
73     def create_mutable_file(self, contents=None, keysize=None):
74         n = MutableFileNode(self.storage_broker, self.secret_holder,
75                             self.default_encoding_parameters, self.history)
76         d = self.key_generator.generate(keysize)
77         d.addCallback(n.create_with_keys, contents)
78         d.addCallback(lambda res: n)
79         return d
80
81     def create_new_mutable_directory(self, initial_children={}):
82         d = self.create_mutable_file()
83         d.addCallback(self._create_dirnode)
84         if initial_children:
85             d.addCallback(lambda n: n.set_nodes(initial_children))
86         return d