diff options
Diffstat (limited to 'hello-fusepy.py')
-rw-r--r-- | hello-fusepy.py | 71 |
1 files changed, 45 insertions, 26 deletions
diff --git a/hello-fusepy.py b/hello-fusepy.py index a02bd9f..1db302b 100644 --- a/hello-fusepy.py +++ b/hello-fusepy.py @@ -6,7 +6,9 @@ import time import requests import sys import stat -from threading import Thread, Lock + +from typing import Optional +from threading import Thread, Lock, Event from queue import Queue from datetime import datetime as dtp @@ -42,7 +44,7 @@ class Status(object): class StatusProvider: - def load_statuses(self) -> list[Status]: + def load_statuses(self, max_id="") -> tuple[list[Status], Optional[str]]: raise NotImplementedError def _fallback_not_found(self): @@ -57,24 +59,30 @@ class ActivityPubStatusProvider(StatusProvider): self.server = server self.user = user - def load_statuses(self) -> list[Status]: + def load_statuses(self, max_id="") -> tuple[list[Status], Optional[str]]: url = api_url_ap_template.format(server=self.server, user=self.user) + if max_id: + url += "&" + urllib.parse.urlencode({"max_id": max_id}) + logger.debug("Get AP status from %s", url) res = requests.get(url) if res.status_code == 404: - return self._fallback_not_found() + return self._fallback_not_found(), None try: res.raise_for_status() except requests.exceptions.RequestException as e: logging.error("Request error: %s", e) - return self._fallback_error(getattr(e, "message", str(e))) + return self._fallback_error(getattr(e, "message", str(e))), None stats = res.json() status_items = stats.get("orderedItems", None) if not status_items: - return self._fallback_error("Malformed content in querying AP outbox.") + return ( + self._fallback_error("Malformed content in querying AP outbox."), + None, + ) - return [ + ss = [ Status( s["object"]["id"].split("/")[-1], s["object"]["content"], @@ -86,6 +94,7 @@ class ActivityPubStatusProvider(StatusProvider): and all(key in s["object"] for key in ["id", "content", "published"]) and len(s["object"]["content"]) ] + return ss, ss[-1].id class MastodonStatusProvider(StatusProvider): @@ -94,36 +103,41 @@ class MastodonStatusProvider(StatusProvider): self.user = user self.userid = 0 - def load_statuses(self) -> list[Status]: + def load_statuses(self, max_id="") -> tuple[list[Status], Optional[str]]: url = api_url_m_lookup_template.format(server=self.server) url += "?" + urllib.parse.urlencode({"acct": self.user}) res = requests.get(url) if res.status_code == 404: - return self._fallback_not_found() + return self._fallback_not_found(), None try: res.raise_for_status() except requests.exceptions.RequestException as e: logging.error("Request error: %s", e) - return self._fallback_error(getattr(e, "message", str(e))) + return self._fallback_error(getattr(e, "message", str(e))), None user = res.json() self.userid = user.get("id", None) if not self.userid: - return self._fallback_error("Malformed content in querying user ID.") + return self._fallback_error("Malformed content in querying user ID."), None url = api_url_m_status_template.format( server=self.server, uid=urllib.parse.quote(self.userid) ) + + if max_id: + url += "?" + urllib.parse.urlencode({"max_id": max_id}) + logger.debug("Get Masto status from %s", url) + res = requests.get(url) if res.status_code == 404: - return self._fallback_not_found() + return self._fallback_not_found(), None try: res.raise_for_status() except requests.exceptions.RequestException as e: logging.error("Request error: %s", e) - return self._fallback_error(getattr(e, "message", str(e))) + return self._fallback_error(getattr(e, "message", str(e))), None statuses = res.json() - return [ + ss = [ Status( s["id"], s["content"], @@ -133,6 +147,7 @@ class MastodonStatusProvider(StatusProvider): if all(key in s for key in ["id", "content", "created_at"]) and len(s["content"]) ] + return ss, ss[-1].id class StatusFileSystem(Operations, LoggingMixIn): @@ -227,20 +242,23 @@ 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) +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) @@ -249,7 +267,7 @@ def main(args): myfs = StatusFileSystem() - t = Thread(target=status_fetcher, args=(myfs, status_provider)) + t = Thread(target=status_fetcher, args=(myfs, status_provider, quit_evt)) t.start() f = FUSE(myfs, args.mountpoint, nothreads=True, foreground=True) @@ -257,8 +275,9 @@ def main(args): fuse_exit() raise finally: - # q.join() - t.join() + quit_evt.set() + if t: + t.join() if __name__ == "__main__": |