summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hello-fusepy.py71
1 files changed, 52 insertions, 19 deletions
diff --git a/hello-fusepy.py b/hello-fusepy.py
index fdeec00..a02bd9f 100644
--- a/hello-fusepy.py
+++ b/hello-fusepy.py
@@ -2,9 +2,12 @@ import argparse
import enum
import errno
import logging
+import time
import requests
import sys
import stat
+from threading import Thread, Lock
+from queue import Queue
from datetime import datetime as dtp
from fuse import (
@@ -18,6 +21,9 @@ from fuse import (
import urllib.parse
+logger = logging.getLogger(__name__)
+
+
class APIChoice(enum.Enum):
ACTIVITYPUB = "ActivityPub"
MASTODON = "Mastodon"
@@ -130,14 +136,13 @@ class MastodonStatusProvider(StatusProvider):
class StatusFileSystem(Operations, LoggingMixIn):
- def __init__(self, api: APIChoice, server: str, user: str):
- self.statuses: list[Status] = []
+ def __init__(self):
+ self._lock = Lock()
+
+ with self._lock:
+ self.statuses: list[Status] = []
+
self.fd = 0
- self.api = api
- if api == APIChoice.MASTODON:
- self.status_provider = MastodonStatusProvider(server, user)
- else:
- self.status_provider = ActivityPubStatusProvider(server, user)
def getattr(self, path, fh=None):
(uid, gid, _) = fuse_get_context()
@@ -148,7 +153,9 @@ class StatusFileSystem(Operations, LoggingMixIn):
"st_uid": uid,
"st_gid": gid,
}
- found = next((s for s in self.statuses if s.id == path[1:]), None)
+ with self._lock:
+ found = next((s for s in self.statuses if s.id == path[1:]), None)
+
if found:
published_dt = dtp.fromisoformat(found.published)
pubunix = published_dt.timestamp()
@@ -164,24 +171,29 @@ class StatusFileSystem(Operations, LoggingMixIn):
raise FuseOSError(errno.ENOENT)
def list_dir(self) -> list[str]:
- return [s.id for s in self.statuses]
+ with self._lock:
+ return [s.id for s in self.statuses]
def readdir(self, path, fh):
dir_entries = []
if path != "/":
raise FuseOSError(errno.ENOENT)
dir_entries = [".", ".."]
- if not self.statuses:
- self.statuses = self.status_provider.load_statuses()
dir_entries += self.list_dir()
return dir_entries
+ def add_statuses(self, statuses: list[Status]):
+ with self._lock:
+ self.statuses.extend(statuses)
+
def open(self, path, flags):
self.fd += 1
return self.fd
def read(self, path, size, offset, fh):
- found = next(s for s in self.statuses if s.id == path[1:])
+ with self._lock:
+ found = next(s for s in self.statuses if s.id == path[1:])
+
if found:
return found.content.encode("utf8")
raise FuseOSError(errno.ENOENT)
@@ -215,21 +227,42 @@ def parse_arguments():
return args
+# todo: make this a loop supporting paging
+def status_fetcher(fs: StatusFileSystem, sp: StatusProvider):
+ logger.debug("Waiting to fetch statuses.")
+ time.sleep(5)
+ logger.debug("Fetch statuses.")
+ st = sp.load_statuses()
+ logger.debug("Add statuses to FS.")
+ fs.add_statuses(st)
+ logger.debug("Wait...")
+ time.sleep(5)
+ logger.debug("Done.")
+
def main(args):
try:
- FUSE(
- StatusFileSystem(args.api_choice, args.server, args.username),
- args.mountpoint,
- nothreads=True,
- foreground=True,
- )
+ if args.api_choice == APIChoice.MASTODON:
+ status_provider = MastodonStatusProvider(args.server, args.username)
+ else:
+ status_provider = ActivityPubStatusProvider(args.server, args.username)
+
+ myfs = StatusFileSystem()
+
+ t = Thread(target=status_fetcher, args=(myfs, status_provider))
+ t.start()
+
+ f = FUSE(myfs, args.mountpoint, nothreads=True, foreground=True)
except:
fuse_exit()
raise
+ finally:
+ # q.join()
+ t.join()
if __name__ == "__main__":
- logging.basicConfig(level=logging.DEBUG)
+ logging.basicConfig(level=logging.INFO)
+ logger.setLevel(logging.DEBUG)
args = parse_arguments()
main(args)