+class RouteFS(fuse.Fuse):
+ """
+ RouteFS: Web 2.0 for filesystems
+ """
+ __metaclass__ = RouteMeta
+ def __init__(self, *args, **kwargs):
+ super(RouteFS, self).__init__(*args, **kwargs)
+
+ self.map = self.make_map()
+ self.map.create_regs(self.controller_list)
+
+ def make_map(self):
+ """
+ This method should be overridden by descendents of RouteFS to
+ define the routing for the filesystem
+ """
+ m = routes.Mapper()
+
+ m.connect(':controller')
+
+ return m
+
+ @classmethod
+ def controllers(cls, lst):
+ cls.controller_list = lst
+
+ def _get_file(self, path):
+ """
+ Find the filesystem entry object for a given path
+ """
+ match = self.map.match(path)
+ if match is None:
+ return
+ controller = match.pop('controller')
+ result = getattr(self, controller)(**match)
+ return result
+
+ def readdir(self, path, offset):
+ """
+ If the path referred to is a directory, return the elements of
+ that diectory
+ """
+ obj = self._get_file(path)
+ if type(obj) is not Directory:
+ return
+ else:
+ for member in ['.', '..'] + obj:
+ yield fuse.Direntry(str(member))
+
+ def getattr(self, path):
+ """
+ Return the stat information for a path
+
+ The stat information for a directory, symlink, or file is
+ predetermined based on which it is.
+ """
+ obj = self._get_file(path)
+ if obj is None:
+ return -errno.ENOENT
+
+ st = RouteStat()
+ if type(obj) is Directory:
+ st.st_mode = stat.S_IFDIR | 0755
+ st.st_nlink = 2
+ elif type(obj) is Symlink:
+ st.st_mode = stat.S_IFLNK | 0777
+ st.st_nlink = 1
+ st.st_size = len(obj)
+ else:
+ st.st_mode = stat.S_IFREG | 0444
+ st.st_nlink = 1
+ st.st_size = len(obj)
+
+ return st
+
+ def read(self, path, length, offset):
+ """
+ If the path specified is a file, return the requested portion
+ of the file
+ """
+ obj = self._get_file(path)
+ if obj is None:
+ return -errno.ENOENT
+ elif type(obj) in (Directory, Symlink):
+ return -errno.EINVAL
+ else:
+ return obj[offset:offset + length]
+
+ def readlink(self, path):
+ """
+ If the path specified is a symlink, return the target
+ """
+ obj = self._get_file(path)
+ if type(obj) is not Symlink:
+ return -errno.EINVAL
+ else:
+ return obj
+
+class Directory(list):
+ """
+ A dummy class representing a filesystem entry that should be a
+ directory
+ """
+ pass
+
+class Symlink(str):
+ """
+ A dummy class representing something that should be a symlink
+ """