debugging stat on generated files
This commit is contained in:
parent
23d3773a58
commit
7f6d86d8db
59
fs.py
59
fs.py
|
@ -2,28 +2,62 @@
|
||||||
|
|
||||||
import os, sys, shutil, pathlib
|
import os, sys, shutil, pathlib
|
||||||
from fuse import FUSE, FuseOSError, Operations
|
from fuse import FUSE, FuseOSError, Operations
|
||||||
|
from collections import namedtuple
|
||||||
|
|
||||||
|
Translator = namedtuple('Translator', ['mode', 'output_filename', 'command'])
|
||||||
|
|
||||||
class FilterFS(Operations):
|
class FilterFS(Operations):
|
||||||
def __init__(self, source, cache):
|
def __init__(self, source, cache):
|
||||||
self.source = source
|
self.source = source
|
||||||
self.cache = cache
|
self.cache = cache
|
||||||
def _original(self, path):
|
|
||||||
print(path)
|
def _mkparents(self, f):
|
||||||
|
pathlib.Path(os.path.dirname(f)).mkdir(parents = True, exist_ok = True)
|
||||||
|
def _parse(self, s):
|
||||||
|
if not s.startswith('/!/'):
|
||||||
|
return None
|
||||||
|
s = s[3:]
|
||||||
|
components = s.split('/')
|
||||||
|
return Translator(
|
||||||
|
mode = int(components[0], base=8),
|
||||||
|
output_filename = components[1], # TODO: forbid ../ attacks
|
||||||
|
command = '/'.join(components[2:])
|
||||||
|
)
|
||||||
|
def _peek(self, why, path):
|
||||||
|
print('peek', path)
|
||||||
p = os.path.join(self.source, path.lstrip('/'))
|
p = os.path.join(self.source, path.lstrip('/'))
|
||||||
if os.path.islink(p):
|
if os.path.islink(p):
|
||||||
rl = os.readlink(p)
|
rl = os.readlink(p)
|
||||||
if rl.startswith('/!/'):
|
if rl.startswith('/!/'):
|
||||||
cached_output = os.path.join(self.cache, path.lstrip('/'))
|
get = os.path.join(self.cache, 'get', path.lstrip('/'))
|
||||||
|
peek = os.path.join(self.cache, 'peek', path.lstrip('/'))
|
||||||
|
if os.path.exists(get):
|
||||||
|
p = get
|
||||||
|
else:
|
||||||
|
translator = self._parse(rl)
|
||||||
|
p = peek
|
||||||
|
self._mkparents(p)
|
||||||
|
pathlib.Path(p).touch()
|
||||||
|
os.chmod(p, translator.mode)
|
||||||
|
return p
|
||||||
|
|
||||||
|
def _get(self, why, path):
|
||||||
|
print('get', why, path)
|
||||||
|
p = os.path.join(self.source, path.lstrip('/'))
|
||||||
|
if os.path.islink(p):
|
||||||
|
rl = os.readlink(p)
|
||||||
|
if rl.startswith('/!/'):
|
||||||
|
cached_output = os.path.join(self.cache, 'get', path.lstrip('/'))
|
||||||
if not os.path.exists(cached_output):
|
if not os.path.exists(cached_output):
|
||||||
rl = rl[3:]
|
translator = self._parse(rl)
|
||||||
d = os.path.dirname(p)
|
d = os.path.dirname(p)
|
||||||
# begin hack
|
# begin hack
|
||||||
old_cwd = os.getcwd()
|
old_cwd = os.getcwd()
|
||||||
os.chdir(d)
|
os.chdir(d)
|
||||||
os.system(rl)
|
os.system(translator.command)
|
||||||
os.chdir(old_cwd)
|
os.chdir(old_cwd)
|
||||||
pathlib.Path(os.path.dirname(cached_output)).mkdir(parents = True, exist_ok = True)
|
self._mkparents(cached_output)
|
||||||
shutil.move(os.path.join(d, 'out'), cached_output)
|
shutil.move(os.path.join(d, translator.output_filename), cached_output)
|
||||||
# end hack
|
# end hack
|
||||||
p = cached_output
|
p = cached_output
|
||||||
return p
|
return p
|
||||||
|
@ -32,13 +66,14 @@ class FilterFS(Operations):
|
||||||
def readdir(self, path, fh):
|
def readdir(self, path, fh):
|
||||||
yield '.'
|
yield '.'
|
||||||
yield '..'
|
yield '..'
|
||||||
if os.path.isdir(self._original(path)):
|
orig = self._get("readdir", path)
|
||||||
for d in os.listdir(self._original(path)):
|
if os.path.isdir(orig):
|
||||||
|
for d in os.listdir(orig):
|
||||||
yield d
|
yield d
|
||||||
|
|
||||||
# directory, file etc.
|
# directory, file etc.
|
||||||
def getattr(self, path, file_handle = None):
|
def getattr(self, path, file_handle = None):
|
||||||
st = os.lstat(self._original(path))
|
st = os.lstat(self._peek("getattr", path))
|
||||||
return {
|
return {
|
||||||
'st_mode': st.st_mode, # 0o100775 file, 0o40775 dir
|
'st_mode': st.st_mode, # 0o100775 file, 0o40775 dir
|
||||||
#'st_ino': 42,
|
#'st_ino': 42,
|
||||||
|
@ -46,7 +81,7 @@ class FilterFS(Operations):
|
||||||
'st_nlink': st.st_nlink,
|
'st_nlink': st.st_nlink,
|
||||||
'st_uid': st.st_uid,
|
'st_uid': st.st_uid,
|
||||||
'st_gid': st.st_gid,
|
'st_gid': st.st_gid,
|
||||||
'st_size': st.st_size,
|
'st_size': 999999999999999, #st.st_size, # TODO: max file size
|
||||||
'st_atime': st.st_atime,
|
'st_atime': st.st_atime,
|
||||||
'st_mtime': st.st_mtime,
|
'st_mtime': st.st_mtime,
|
||||||
'st_ctime': st.st_ctime,
|
'st_ctime': st.st_ctime,
|
||||||
|
@ -54,7 +89,7 @@ class FilterFS(Operations):
|
||||||
|
|
||||||
# file
|
# file
|
||||||
def open(self, path, flags):
|
def open(self, path, flags):
|
||||||
return os.open(self._original(path), flags)
|
return os.open(self._get("open", path), flags)
|
||||||
def read(self, path, length, offset, file_handle):
|
def read(self, path, length, offset, file_handle):
|
||||||
os.lseek(file_handle, offset, os.SEEK_SET)
|
os.lseek(file_handle, offset, os.SEEK_SET)
|
||||||
return os.read(file_handle, length)
|
return os.read(file_handle, length)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
/!/lame -vbr -b 240 foo.ogg output.mp3; mv output.mp3 out
|
/!/100644/out.mp3/ffmpeg -i foo.ogg -acodec libmp3lame -map_metadata 0:s:0 out.mp3
|
BIN
source/foo.ogg
BIN
source/foo.ogg
Binary file not shown.
|
@ -1 +1 @@
|
||||||
/!/tr '[:lower:]' '[:upper:'] < aaa > out
|
/!/10644/out/tr '[:lower:]' '[:upper:'] < aaa > out
|
Loading…
Reference in New Issue
Block a user