From 4598fb63e8faadc492cd1635f0ed4d2e46437dd3 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sat, 24 Feb 2024 13:31:40 +0300 Subject: [PATCH 1/4] Style: Sort import alphabetically --- native/textern.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native/textern.py b/native/textern.py index 1d50d66..146665f 100755 --- a/native/textern.py +++ b/native/textern.py @@ -12,8 +12,8 @@ import struct import sys import tempfile -import urllib.parse import time +import urllib.parse try: from inotify_simple import INotify, flags From dab83c0050cb97ab37307b9f7cd9e8c9eeb7ba2e Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sat, 24 Feb 2024 15:04:33 +0300 Subject: [PATCH 2/4] Feat: Remove submodule `inotify_simple` --- .gitmodules | 3 --- Makefile | 3 +-- native/inotify_simple | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) delete mode 100644 .gitmodules delete mode 160000 native/inotify_simple diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index efa0918..0000000 --- a/.gitmodules +++ /dev/null @@ -1,3 +0,0 @@ -[submodule "native/inotify_simple"] - path = native/inotify_simple - url = https://github.com/chrisjbillington/inotify_simple diff --git a/Makefile b/Makefile index 4e6185b..7c3dc80 100644 --- a/Makefile +++ b/Makefile @@ -26,11 +26,10 @@ native/textern.json: .PHONY: native-install native-install: native/textern.json - @if ! test -f native/inotify_simple/.git; then echo "Missing inotify_simple submodule! Try 'git submodule update --init'."; false; fi mkdir -p $(DESTDIR)$(MOZILLA_NATIVE) cp -f native/textern.json $(DESTDIR)$(MOZILLA_NATIVE) mkdir -p $(DESTDIR)$(LIBEXEC)/textern - cp -rf native/textern.py native/inotify_simple $(DESTDIR)$(LIBEXEC)/textern + cp -rf native/textern.py $(DESTDIR)$(LIBEXEC)/textern .PHONY: native-uninstall native-uninstall: diff --git a/native/inotify_simple b/native/inotify_simple deleted file mode 160000 index 979648c..0000000 --- a/native/inotify_simple +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 979648cefa83dda61611ed9d8fb1fe4b644950be From fe84b6c15a660e49df62ec927574745d29928e29 Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sat, 24 Feb 2024 15:13:54 +0300 Subject: [PATCH 3/4] Feat: Install `watchdog` as dependency Install `watchdog` as a dependency into a virtual environment. This allows to use different versions of Python without relying on a particular commit of a submodule (the latest version of `watchdog` (4.0) requires Python 3.8). Run make PYTHON=python3.7 USER=1 native-install to set particular Python version. --- Makefile | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 7c3dc80..dafcd4c 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ else endif LIBEXEC ?= $(PREFIX)/libexec +PYTHON ?= python3 .PHONY: all all: @@ -29,7 +30,11 @@ native-install: native/textern.json mkdir -p $(DESTDIR)$(MOZILLA_NATIVE) cp -f native/textern.json $(DESTDIR)$(MOZILLA_NATIVE) mkdir -p $(DESTDIR)$(LIBEXEC)/textern - cp -rf native/textern.py $(DESTDIR)$(LIBEXEC)/textern + $(PYTHON) -m venv $(DESTDIR)$(LIBEXEC)/textern/venv + $(DESTDIR)$(LIBEXEC)/textern/venv/bin/python -m pip install watchdog + sed "s@#!/usr/bin/env python3@#!$(DESTDIR)$(LIBEXEC)/textern/venv/bin/python@" \ + < native/textern.py > $(DESTDIR)$(LIBEXEC)/textern/textern.py + chmod a+x $(DESTDIR)$(LIBEXEC)/textern/textern.py .PHONY: native-uninstall native-uninstall: From 6f5c3dacdff71f19305a1ea3dac928e66ad9419b Mon Sep 17 00:00:00 2001 From: Oleg Broytman Date: Sat, 24 Feb 2024 14:43:52 +0300 Subject: [PATCH 4/4] Feat: Use `watchdog` instead of `inotify` `watchdog` is much more portable. Fixes: #46. --- native/textern.py | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/native/textern.py b/native/textern.py index 146665f..c10245b 100755 --- a/native/textern.py +++ b/native/textern.py @@ -15,12 +15,8 @@ import time import urllib.parse -try: - from inotify_simple import INotify, flags -except ImportError: - # fall-back to the old import pattern for git-submodule use-case (PR#57) - from inotify_simple.inotify_simple import INotify, flags - +from watchdog.events import FileSystemEventHandler +from watchdog.observers import Observer BACKUP_RETENTION_SECS = 24 * 60 * 60 @@ -97,14 +93,28 @@ def get(self, relfn): return f.read(), self._tmpfiles[relfn] +class CloseEventHandler(FileSystemEventHandler): + def __init__(self, tmp_mgr): + super(CloseEventHandler, self).__init__() + self.tmp_mgr = tmp_mgr + + def on_closed(self, event): + super(CloseEventHandler, self).on_closed(event) + handle_close_event(os.path.basename(event.src_path), self.tmp_mgr) + + def main(): - with INotify() as ino, TmpManager() as tmp_mgr: - ino.add_watch(tmp_mgr.tmpdir, flags.CLOSE_WRITE) + with TmpManager() as tmp_mgr: + event_handler = CloseEventHandler(tmp_mgr) + observer = Observer() + observer.schedule(event_handler, tmp_mgr.tmpdir) + observer.start() loop = asyncio.get_event_loop() loop.add_reader(sys.stdin.buffer, handle_stdin, tmp_mgr) - loop.add_reader(ino.fd, handle_inotify_event, ino, tmp_mgr) loop.run_forever() loop.close() + observer.stop() + observer.join() def handle_stdin(tmp_mgr): @@ -201,15 +211,14 @@ async def handle_message_new_text(tmp_mgr, msg): } -def handle_inotify_event(ino, tmp_mgr): - for event in ino.read(): - # this check is relevant in the case where we're handling the inotify - # event caused by tmp_mgr.new(), but then an exception occurred in - # handle_message() which caused the tmpfile to already be deleted - if event.name in tmp_mgr: - text, id = tmp_mgr.get(event.name) - send_text_update(id, text) - tmp_mgr.backup(event.name) +def handle_close_event(relfn, tmp_mgr): + # this check is relevant in the case where we're handling the inotify + # event caused by tmp_mgr.new(), but then an exception occurred in + # handle_message() which caused the tmpfile to already be deleted + if relfn in tmp_mgr: + text, id = tmp_mgr.get(relfn) + send_text_update(id, text) + tmp_mgr.backup(relfn) def send_text_update(id, text):