2 RouteFS is a base class for developing read-only FUSE filesystems that
3 lets you focus on the directory tree instead of the system calls.
5 RouteFS uses the Routes library developed for Pylons. URLs were
6 inspired by filesystems, and now you can have filesystems inspired by
18 fuse.fuse_python_api = (0, 2)
21 class RouteStat(fuse.Stat):
23 RouteStat is a descendent of fuse.Stat, defined to make sure that
24 all of the necessary attributes are always defined
39 class RouteFS(fuse.Fuse):
41 RouteFS: Web 2.0 for filesystems
43 def __init__(self, *args, **kwargs):
44 super(RouteFS, self).__init__(*args, **kwargs)
46 self.map = self.make_map()
50 This method should be overridden by descendents of RouteFS to
51 define the routing for the filesystem
55 m.connect('{controller}')
59 def _get_file(self, path):
61 Find the filesystem entry object for a given path
63 match = self.map.match(path)
66 controller = match.pop('controller')
67 result = getattr(self, controller)(**match)
70 if type(result) is str:
72 if type(result) is list:
73 result = Directory(result)
76 def readdir(self, path, offset):
78 If the path referred to is a directory, return the elements of
81 return self._get_file(path).readdir(offset)
83 def getattr(self, path):
85 Return the stat information for a path
87 The stat information for a directory, symlink, or file is
88 predetermined based on which it is.
90 return self._get_file(path).getattr()
92 def read(self, path, length, offset):
94 If the path specified is a file, return the requested portion
97 return self._get_file(path).read(length, offset)
99 def readlink(self, path):
101 If the path specified is a symlink, return the target
103 return self._get_file(path).readlink()
105 def write(self, path, buf, offset):
107 If the path specified is a file, call the appropriate member
110 return self._get_file(path).write(buf, offset)
113 class TreeKey(object):
116 def readdir(self, offset):
118 def read(self, length, offset):
122 def write(self, length, offset):
126 class NoEntry(TreeKey):
129 def readdir(self, offset):
131 def read(self, length, offset):
135 def write(self, length, offset):
139 class TreeEntry(TreeKey):
142 def __new__(cls, contents, mode=None):
143 return super(TreeEntry, cls).__new__(cls, contents)
145 def __init__(self, contents, mode=None):
147 self.mode = self.default_mode
151 super(TreeEntry, self).__init__(contents)
154 class Directory(TreeEntry, list):
156 A dummy class representing a filesystem entry that should be a
163 st.st_mode = stat.S_IFDIR | self.mode
167 def readdir(self, offset):
168 for member in ['.', '..'] + self:
169 yield fuse.Direntry(str(member))
172 class Symlink(TreeEntry, str):
174 A dummy class representing something that should be a symlink
180 st.st_mode = stat.S_IFLNK | self.mode
182 st.st_size = len(self)
189 class File(TreeEntry, str):
191 A dummy class representing something that should be a file
197 st.st_mode = stat.S_IFREG | self.mode
199 st.st_size = len(self)
202 def read(self, length, offset):
203 return self[offset:offset + length]
208 A convenience function for initializing a RouteFS filesystem
210 server = cls(version="%prog " + fuse.__version__,
211 usage=fuse.Fuse.fusage,
212 dash_s_do='setsingle')
213 server.parse(values=server, errex=1)
217 from dictfs import DictFS
219 __all__ = ['RouteFS', 'DictFS', 'Symlink', 'Directory', 'File', 'main']