summaryrefslogtreecommitdiff
path: root/fuse-ap.py
diff options
context:
space:
mode:
Diffstat (limited to 'fuse-ap.py')
-rw-r--r--fuse-ap.py105
1 files changed, 105 insertions, 0 deletions
diff --git a/fuse-ap.py b/fuse-ap.py
new file mode 100644
index 0000000..f3fd478
--- /dev/null
+++ b/fuse-ap.py
@@ -0,0 +1,105 @@
+import argparse
+import enum
+import errno
+import logging
+import time
+import requests
+import sys
+import stat
+
+from typing import Optional
+from threading import Thread, Lock, Event
+from queue import Queue
+
+
+import urllib.parse
+
+from fuse import FUSE, fuse_exit
+
+from de_uvok.activitypub_fuse.fuse import StatusFileSystem
+from de_uvok.activitypub_fuse.providers import (
+ ActivityPubStatusProvider,
+ MastodonStatusProvider,
+ StatusProvider,
+)
+
+
+logger = logging.getLogger(__name__)
+
+
+class APIChoice(enum.Enum):
+ ACTIVITYPUB = "ActivityPub"
+ MASTODON = "Mastodon"
+
+
+def parse_arguments():
+ parser = argparse.ArgumentParser(
+ description="Mount a read-only FUSE filesystem for ActivityPub or Mastodon"
+ )
+ parser.add_argument(
+ "mountpoint", help="The directory where the filesystem will be mounted"
+ )
+ group = parser.add_mutually_exclusive_group(required=True)
+ group.add_argument(
+ "-a", "--activitypub", action="store_true", help="Use ActivityPub API"
+ )
+ group.add_argument("-m", "--mastodon", action="store_true", help="Use Mastodon API")
+ parser.add_argument("-s", "--server", required=True, help="The server/host URL")
+ parser.add_argument(
+ "-u", "--username", required=True, help="The username to fetch statuses for"
+ )
+
+ args = parser.parse_args()
+
+ if args.activitypub:
+ args.api_choice = APIChoice.ACTIVITYPUB
+ elif args.mastodon:
+ args.api_choice = APIChoice.MASTODON
+ else:
+ parser.error("Must choose either ActivityPub or Mastodon API")
+
+ return args
+
+
+# todo: make this a loop supporting paging
+def status_fetcher(fs: StatusFileSystem, sp: StatusProvider, sig_quit: Event):
+ max_id = ""
+ while (max_id is not None) and not (sig_quit.wait(5)):
+ logger.debug("Fetch statuses.")
+ st_rep = sp.load_statuses(max_id)
+ logger.debug("Add statuses to FS.")
+ fs.add_statuses(st_rep[0])
+ max_id = st_rep[1]
+ logger.debug("Waiting to fetch statuses.")
+ logger.debug("Done.")
+
+
+def main(args):
+ quit_evt = Event()
+ t = None
+ try:
+ 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, quit_evt))
+ t.start()
+
+ FUSE(myfs, args.mountpoint, nothreads=True, foreground=True)
+ except:
+ fuse_exit()
+ raise
+ finally:
+ quit_evt.set()
+ if t:
+ t.join()
+
+
+if __name__ == "__main__":
+ logging.basicConfig(level=logging.INFO)
+ logger.setLevel(logging.DEBUG)
+ args = parse_arguments()
+ main(args)