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
15 fuse.fuse_python_api = (0, 2)
17 class RouteStat(fuse.Stat):
19 RouteStat is a descendent of fuse.Stat, defined to make sure that
20 all of the necessary attributes are always defined
34 class RouteFS(fuse.Fuse):
36 RouteFS: Web 2.0 for filesystems
38 Any method that will be used as the controller in a Routes mapping
39 (either by explicitly specifying the controller or by using the
40 ':controller' variable) must be added to RouteFS.controllers
43 def __init__(self, *args, **kwargs):
44 super(RouteFS, self).__init__(*args, **kwargs)
46 self.map.create_regs(self.controllers)
51 This property should be overridden by descendents of RouteFS
52 to define the routing for the filesystem
56 m.connect(':controller')
60 def _get_file(self, path):
62 Find the filesystem entry object for a given path
64 match = self.map.match(path)
67 controller = match.pop('controller')
68 result = getattr(self, controller)(**match)
71 if type(result) is str:
73 if type(result) is list:
74 result = Directory(result)
77 def readdir(self, path, offset):
79 If the path referred to is a directory, return the elements of
82 return self._get_file(path).readdir(offset)
84 def getattr(self, path):
86 Return the stat information for a path
88 The stat information for a directory, symlink, or file is
89 predetermined based on which it is.
91 return self._get_file(path).getattr()
93 def read(self, path, length, offset):
95 If the path specified is a file, return the requested portion
98 return self._get_file(path).read(length, offset)
100 def readlink(self, path):
102 If the path specified is a symlink, return the target
104 return self._get_file(path).readlink()
106 def write(self, path, buf, offset):
108 If the path specified is a file, call the appropriate member
111 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):
125 class NoEntry(TreeKey):
128 def readdir(self, offset):
130 def read(self, length, offset):
134 def write(self, length, offset):
137 class TreeEntry(TreeKey):
140 def __new__(cls, contents, mode=None):
141 return super(TreeEntry, cls).__new__(cls, contents)
143 def __init__(self, contents, mode=None):
145 self.mode = self.default_mode
149 super(TreeEntry, self).__init__(contents)
151 class Directory(TreeEntry, list):
153 A dummy class representing a filesystem entry that should be a
160 st.st_mode = stat.S_IFDIR | self.mode
164 def readdir(self, offset):
165 for member in ['.', '..'] + self:
166 yield fuse.Direntry(str(member))
168 class Symlink(TreeEntry, str):
170 A dummy class representing something that should be a symlink
176 st.st_mode = stat.S_IFLNK | self.mode
178 st.st_size = len(self)
184 class File(TreeEntry, str):
186 A dummy class representing something that should be a file
192 st.st_mode = stat.S_IFREG | self.mode
194 st.st_size = len(self)
197 def read(self, length, offset):
198 return self[offset:offset + length]
202 A convenience function for initializing a RouteFS filesystem
204 server = cls(version="%prog " + fuse.__version__,
205 usage=fuse.Fuse.fusage,
206 dash_s_do='setsingle')
207 server.parse(values=server, errex=1)
210 from dictfs import DictFS
212 __all__ = ['RouteFS', 'DictFS', 'Symlink', 'Directory', 'File', 'main']