mirror of
https://github.com/MatMasIt/moodlefuse.git
synced 2025-12-15 14:44:21 +01:00
First commit
This commit is contained in:
141
FSNode.py
Normal file
141
FSNode.py
Normal file
@@ -0,0 +1,141 @@
|
||||
import stat
|
||||
import sys
|
||||
import time
|
||||
|
||||
import requests
|
||||
from markdownify import markdownify as md
|
||||
|
||||
from moodle import Category, Course, Moodle, Section, Folder, File, Label, Url
|
||||
|
||||
fileCache = {}
|
||||
|
||||
# Virtual Filesystem node
|
||||
class FSNode:
|
||||
def __init__(self, name: str, is_dir=True):
|
||||
self.name = name
|
||||
self.children = []
|
||||
self.is_dir = is_dir
|
||||
self.size = 0
|
||||
self.url = None
|
||||
|
||||
def to_stat_struct(self):
|
||||
if self.is_dir:
|
||||
return dict(
|
||||
st_mode=(stat.S_IFDIR | 0o755),
|
||||
st_ctime=time.time(),
|
||||
st_mtime=time.time(),
|
||||
st_atime=time.time(),
|
||||
st_nlink=2,
|
||||
|
||||
)
|
||||
else:
|
||||
return dict(
|
||||
st_mode=(stat.S_IFREG | 0o755),
|
||||
st_ctime=time.time(),
|
||||
st_mtime=time.time(),
|
||||
st_atime=time.time(),
|
||||
st_nlink=2,
|
||||
st_size=self.size
|
||||
)
|
||||
|
||||
def resolve_path(self, path: str):
|
||||
if path == "/":
|
||||
return self
|
||||
path_el = path.split("/")[1:]
|
||||
return self._recurse_path_traverse(path_el)
|
||||
|
||||
def _recurse_path_traverse(self, path_arr: list[str]):
|
||||
if len(path_arr) == 0:
|
||||
return self
|
||||
for child in self.children:
|
||||
if child.name == path_arr[0]:
|
||||
return child._recurse_path_traverse(path_arr[1:])
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def from_category(c: Category, m: Moodle):
|
||||
f = FSNode(c.name, True)
|
||||
for course in c.courses:
|
||||
f.children.append(FSNode.from_course(course, m))
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def from_course(c: Course, m: Moodle):
|
||||
f = FSNode(c.shortname, True)
|
||||
for s in m.get_course_content(c.id):
|
||||
f.children.append(FSNode.from_section(s, m))
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def from_section(s: Section, m: Moodle):
|
||||
f = FSNode(s.name, True)
|
||||
for mo in s.modules:
|
||||
f.children.append(FSNode.from_module(mo, m))
|
||||
if len(s.htmlcontent):
|
||||
m = FSNode("README.md", False)
|
||||
m.size = len(s.htmlcontent)
|
||||
m.url = "html#" + s.htmlcontent
|
||||
f.children.append(m)
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def from_module(mo, m: Moodle):
|
||||
if isinstance(mo, Folder):
|
||||
f = FSNode(mo.name, True)
|
||||
for el in mo.files:
|
||||
r = FSNode.from_module(el, m)
|
||||
if r is not None:
|
||||
f.children.append(r)
|
||||
return f
|
||||
elif isinstance(mo, File):
|
||||
return FSNode.from_file(mo, m)
|
||||
elif isinstance(mo, Label):
|
||||
return FSNode.from_label(mo, m)
|
||||
elif isinstance(mo, Url):
|
||||
return FSNode.from_url(mo, m)
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def from_file(el: File, m: Moodle):
|
||||
f = FSNode(el.name, False)
|
||||
f.size = el.filesize
|
||||
f.url = el.fileurl
|
||||
return f
|
||||
|
||||
def read(self, size, offset, mo: Moodle):
|
||||
global fileCache
|
||||
if sys.getsizeof(fileCache) > 3 * 100000000 and len(fileCache) > 2:
|
||||
d = {k: v for k, v in sorted(fileCache.items(), key=lambda item: item["datetime"])}
|
||||
for k in list(d.keys())[:len(d) // 2]:
|
||||
del fileCache[k]
|
||||
del d
|
||||
if self.url not in fileCache.keys():
|
||||
if self.url.startswith("html#"):
|
||||
fileCache[self.url] = {"datetime": time.time(), "content": md(self.url[5:]).encode()}
|
||||
elif self.url.startswith("url#"):
|
||||
fileCache[self.url] = {"datetime": time.time(), "content": self.url[4:].encode()}
|
||||
else:
|
||||
r = requests.get(self.url + "&token=" + mo.token)
|
||||
fileCache[self.url] = {"datetime": time.time(), "content": r.content}
|
||||
return fileCache[self.url]["content"][offset:offset + size]
|
||||
|
||||
@staticmethod
|
||||
def from_moodle(moodle: Moodle):
|
||||
f = FSNode("/", True)
|
||||
for cat in moodle.get_enrolled_categories():
|
||||
f.children.append(FSNode.from_category(cat, moodle))
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def from_label(mo: Label, m):
|
||||
f = FSNode(mo.name, False)
|
||||
f.size = len(mo.htmlcontent)
|
||||
f.url = "html#" + mo.htmlcontent
|
||||
return f
|
||||
|
||||
@staticmethod
|
||||
def from_url(mo: Url, m):
|
||||
f = FSNode(mo.name, False)
|
||||
f.size = len(mo.url)
|
||||
f.url = "url#" + mo.url
|
||||
return f
|
||||
Reference in New Issue
Block a user