Created
April 10, 2013 05:26
-
-
Save steveandroulakis/5352040 to your computer and use it in GitHub Desktop.
Proof of concept that produces a virtual FUSE-mountable file/directory structure from a python dictionary. Uses python-fuse.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
# Proof of concept that produces a virtual FUSE-mountable | |
# file/directory structure from a python dictionary | |
# By Steve Androulakis <http://github.com/steveandroulakis> | |
# Requires FUSE (linux: use package manager to install) | |
# Requires python-fuse pip install fuse-python | |
# USE: | |
# Mount: ./dict-fuse.py mnt -f | |
# Unmount: fusermount -u -z mnt | |
import fuse | |
import stat | |
import time | |
DEBUG = True | |
fuse.fuse_python_api = (0, 2) | |
# Use same timestamp for all files | |
_file_timestamp = int(time.time()) | |
# FILES[directory/file/path] = (size_in_bytes, is_directory) | |
FILES = dict() | |
FILES['/file1'] = (15, False) | |
FILES['/file2'] = (15, False) | |
FILES['/directory'] = (0, True) | |
FILES['/directory/file3'] = (15, False) | |
FILES['/directory/file4'] = (15, False) | |
FILES['/directory/anotherdirectory'] = (0, True) | |
FILES['/directory/anotherdirectory/file5'] = (15, False) | |
FILES['/directory/anotherdirectory/file6'] = (15, False) | |
def file_array_to_list(files): | |
# files need to be returned in this format | |
#FILES = [('file1', 15, False), ('file2', 15, False), ('directory', 15, True)] | |
l = list() | |
for key, val in files.iteritems(): | |
l.append((file_from_key(key), val[0], val[1])) | |
return l | |
def file_from_key(key): | |
return key.rsplit("/")[-1] | |
class MyStat(fuse.Stat): | |
""" | |
Convenient class for Stat objects. | |
Set up the stat object with appropriate | |
values depending on constructor args. | |
""" | |
def __init__(self, is_dir, size): | |
print self | |
fuse.Stat.__init__(self) | |
if is_dir: | |
self.st_mode = stat.S_IFDIR | 0555 | |
self.st_nlink = 2 | |
else: | |
self.st_mode = stat.S_IFREG | 0444 | |
self.st_nlink = 1 | |
self.st_size = size | |
self.st_atime = _file_timestamp | |
self.st_mtime = _file_timestamp | |
self.st_ctime = _file_timestamp | |
class MyFS(fuse.Fuse): | |
def __init__(self, *args, **kw): | |
fuse.Fuse.__init__(self, *args, **kw) | |
def getattr(self, path): | |
print path | |
print "^ getattr" | |
#size = entry.text and len(entry.text.strip()) or 0 | |
#IsDir | |
if path == "/": | |
return MyStat(True, 0) | |
else: | |
return MyStat(FILES[path][1], FILES[path][0]) | |
def getdir(self, path): | |
if DEBUG: | |
print 'getdir called:', path | |
return file_array_to_list(FILES) | |
def readdir(self, path, offset): | |
if DEBUG: | |
print path | |
print offset | |
print "^readdir" | |
for e in '.', '..': | |
yield fuse.Direntry(e) | |
path_depth = path.count('/') | |
for key, val in FILES.iteritems(): | |
key_depth = key.count('/') | |
if path == "/": | |
path_depth = 0 | |
if key_depth == path_depth + 1: | |
yield(fuse.Direntry(file_from_key(key))) | |
def read(self, path, leng, offset): | |
# returns this regardless of what file is read | |
# kind of like Bill Murray and Wu Tang at the bar | |
# http://videosift.com/video/Bill-Murray-Bartends-at-SXSW-Only-serves-people-tequila | |
data = "Test test test" | |
return data | |
if __name__ == '__main__': | |
fs = MyFS() | |
fs.parse(errex=1) | |
fs.main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment