1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#!/usr/bin/env python3
# Copyright (c) 2018, George Tokmaji
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
import os
from base import *
import sys, pdb
import errno, stat
import faulthandler
import requests, threading
sys.path.append("../larryviewer") #FIXME
HAVE_QT = False
from larryviewer import *
faulthandler.enable()
class LCModOperations(LCOperations):
_inode_list = None
_viewer = None
def __init__(self, v : LarryViewer):
super().__init__()
self._viewer = v
for i in range(v.ui.lsEntries.count()):
e = v.ui.lsEntries.item(i)
self._add_entry(llfuse.ROOT_INODE, v.ui.lsEntries.item(i).larry, True)
def _is_dir(self, inode):
return isinstance(self._inode_list[inode], Entry) or super()._is_dir(inode)
def opendir(self, inode, ctx=None):
if inode != llfuse.ROOT_INODE:
try:
self._get_inode_by_parent(inode)
except IndexError:
for f in self._inode_list[inode].files():
self._add_entry(inode, {"title" : f, "address" : self._inode_list[inode].filePath(f)})
return inode
def getattr(self, inode, ctx=None):
attr = super().getattr(inode, ctx)
if inode != llfuse.ROOT_INODE:
entry = self._inode_list[inode]
if attr.st_mode & stat.S_IFREG:
attr.st_size = self._inode_list[entry["parent_inode"]].size()
return attr
def open(self, inode, flags, ctx=None):
entry = self._inode_list[inode]
if self.getattr(inode).st_mode & stat.S_IFDIR:
raise llfuse.FUSEError(errno.EISDIR)
if flags & os.O_APPEND:
raise llfuse.FUSEError(errno.EROFS)
return inode
def read(self, inode, off, size):
entry = self._inode_list[inode]
try:
r = requests.get(entry["address"], headers={"Range" : f"bytes={off}-{off+size}"}, stream=True)
except Exception as e:
print(e)
raise llfuse.FUSEError(errno.EREMOTEIO) from e
if not r:
raise llfuse.FUSEError(errno.EREMOTEIO)
elif r.status_code == 206:
return r.raw.read(size)
else:
buf = BytesIO()
i = 0
for chunk in r.iter_content(1024):
if off <= i:
buf.write(chunk)
if off + i >= size:
break
else:
raise llfuse.FUSEError(errno.EREMOTEIO)
buf.seek(i - off)
return buf.read(size)
if __name__ == "__main__":
# Usage: ./lcfs.py <mountpoint>
cwd = os.getcwd()
os.chdir("../larryviewer") #FIXME
v = LarryViewer()
os.chdir(cwd)
for t in threading.enumerate():
if t.name in "ccanlistlarrylist":
t.join()
fuse_options = set(llfuse.default_options)
fuse_options.add("fsname=lcmodfs")
#fuse_options.add("debug")
fuse_options.discard("default_permissions")
op = LCModOperations(v)
llfuse.init(op, sys.argv[1], fuse_options)
try:
#threading.Thread(target=findBrokenEntries).start()
llfuse.main(workers=1)
except:
llfuse.close(unmount=True)
raise
llfuse.close()
|