diff options
| author | uvok | 2025-01-20 18:43:25 +0100 | 
|---|---|---|
| committer | uvok | 2025-01-21 20:27:21 +0100 | 
| commit | cd7c102ca59d2c59065e5b369ebc862104ad1607 (patch) | |
| tree | 788148ba449046593801b80af12bb945030bc415 | |
| parent | 91c02046f3da8681094c6bca32f1a2b6d7786682 (diff) | |
Add threading with fetcher loop
| -rw-r--r-- | hello-fusepy.py | 71 | 
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)  | 
