summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/dbus/org.parley.Transcription1.service2
-rw-r--r--extension/extension.js1
-rw-r--r--pyproject.toml5
-rwxr-xr-xscripts/install-dev1
-rw-r--r--src/parley/config.py8
-rw-r--r--src/parley/controller.py4
-rw-r--r--src/parley/daemon.py42
-rw-r--r--src/parley/desktop.py4
-rw-r--r--src/parley/ibus_engine.py8
-rw-r--r--src/parley/persistence.py4
-rw-r--r--src/parley/transcription.py10
-rw-r--r--tests/test_controller.py5
-rw-r--r--tests/test_persistence.py8
-rw-r--r--tests/test_transcription.py12
14 files changed, 59 insertions, 55 deletions
diff --git a/data/dbus/org.parley.Transcription1.service b/data/dbus/org.parley.Transcription1.service
index cc5d2cf..ab3610c 100644
--- a/data/dbus/org.parley.Transcription1.service
+++ b/data/dbus/org.parley.Transcription1.service
@@ -1,4 +1,4 @@
[D-BUS Service]
Name=org.parley.Transcription1
-Exec=/bin/false
+Exec=/usr/bin/parleyd
SystemdService=parley.service
diff --git a/extension/extension.js b/extension/extension.js
index 00ce517..465e7db 100644
--- a/extension/extension.js
+++ b/extension/extension.js
@@ -160,7 +160,6 @@ class Indicator extends PanelMenu.Button {
this._proxy[`${method}Remote`]((_result, error) => {
if (error) {
console.error(`Parley ${method} failed: ${error.message}`);
- Main.notifyError('Parley', error.message);
}
});
}
diff --git a/pyproject.toml b/pyproject.toml
index cf91954..f3455c5 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -24,3 +24,8 @@ where = ["src"]
[tool.pytest.ini_options]
testpaths = ["tests"]
+
+[tool.ruff.lint.per-file-ignores]
+"src/parley/ctl.py" = ["E402"]
+"src/parley/daemon.py" = ["E402"]
+"src/parley/ibus_engine.py" = ["E402"]
diff --git a/scripts/install-dev b/scripts/install-dev
index d21bc46..a2eb660 100755
--- a/scripts/install-dev
+++ b/scripts/install-dev
@@ -16,6 +16,7 @@ install -m644 data/dbus/org.parley.Transcription1.service \
systemctl --user daemon-reload
systemctl --user enable parley.service
+systemctl --user reset-failed parley.service
systemctl --user restart parley.service
echo "Installed local development service from $root"
diff --git a/src/parley/config.py b/src/parley/config.py
index 4ba1202..923812c 100644
--- a/src/parley/config.py
+++ b/src/parley/config.py
@@ -40,9 +40,7 @@ class Config:
prototype = _prototype_root()
data_home = _default_data_home()
ffmpeg = os.environ.get("PARLEY_FFMPEG") or shutil.which("ffmpeg") or "ffmpeg"
- installed_model = (
- data_home / "parley/models/parakeet-unified-en-0.6b-Q8_0.gguf"
- )
+ installed_model = data_home / "parley/models/parakeet-unified-en-0.6b-Q8_0.gguf"
default_model = (
installed_model
if installed_model.is_file()
@@ -66,9 +64,7 @@ class Config:
auto_insert=os.environ.get("PARLEY_AUTO_INSERT", "0").lower()
in {"1", "true", "yes", "on"},
insertion_mode=os.environ.get("PARLEY_INSERTION_MODE", "clipboard"),
- notifications_enabled=os.environ.get(
- "PARLEY_NOTIFICATIONS", "0"
- ).lower()
+ notifications_enabled=os.environ.get("PARLEY_NOTIFICATIONS", "0").lower()
in {"1", "true", "yes", "on"},
)
diff --git a/src/parley/controller.py b/src/parley/controller.py
index 58091cf..567544f 100644
--- a/src/parley/controller.py
+++ b/src/parley/controller.py
@@ -117,9 +117,7 @@ class Controller:
lambda error=error: self._worker_failed(token, workspace, error)
)
else:
- self.dispatch(
- lambda: self._worker_succeeded(token, workspace, text, path)
- )
+ self.dispatch(lambda: self._worker_succeeded(token, workspace, text, path))
def _worker_succeeded(
self,
diff --git a/src/parley/daemon.py b/src/parley/daemon.py
index 121ff24..4330cc6 100644
--- a/src/parley/daemon.py
+++ b/src/parley/daemon.py
@@ -26,9 +26,11 @@ INTERFACE = BUS_NAME
class Daemon:
def __init__(self, config: Config | None = None) -> None:
- xml = files("parley.interfaces").joinpath(
- "org.parley.Transcription1.xml"
- ).read_text(encoding="utf-8")
+ xml = (
+ files("parley.interfaces")
+ .joinpath("org.parley.Transcription1.xml")
+ .read_text(encoding="utf-8")
+ )
self.node_info = Gio.DBusNodeInfo.new_for_xml(xml)
self.interface_info = self.node_info.interfaces[0]
resolved_config = config or Config.from_environment()
@@ -70,7 +72,7 @@ class Daemon:
def _on_bus_acquired(self, connection: Gio.DBusConnection, name: str) -> None:
self.connection = connection
- self.registration_id = connection.register_object(
+ self.registration_id = connection.register_object_with_closures2(
OBJECT_PATH,
self.interface_info,
self._method_call,
@@ -81,9 +83,7 @@ class Daemon:
def _on_name_acquired(self, connection: Gio.DBusConnection, name: str) -> None:
print(f"Parley daemon owns {name}", file=sys.stderr)
- def _on_name_lost(
- self, connection: Gio.DBusConnection | None, name: str
- ) -> None:
+ def _on_name_lost(self, connection: Gio.DBusConnection | None, name: str) -> None:
print(f"error: could not own D-Bus name {name}", file=sys.stderr)
self.loop.quit()
@@ -139,12 +139,8 @@ class Daemon:
str(self.controller.last_transcript_path or ""),
),
"LastError": GLib.Variant("s", self.controller.last_error),
- "InsertionMode": GLib.Variant(
- "s", self.controller.config.insertion_mode
- ),
- "AutoInsert": GLib.Variant(
- "b", self.controller.config.auto_insert
- ),
+ "InsertionMode": GLib.Variant("s", self.controller.config.insertion_mode),
+ "AutoInsert": GLib.Variant("b", self.controller.config.auto_insert),
}
return values[property_name]
@@ -171,9 +167,7 @@ class Daemon:
else:
copy_text(text)
message = "copied; press Ctrl+V to insert"
- self._emit(
- "InsertionFinished", GLib.Variant("(sbs)", (backend, True, message))
- )
+ self._emit("InsertionFinished", GLib.Variant("(sbs)", (backend, True, message)))
def _open_transcript_folder(self) -> None:
directory = self.controller.config.transcript_dir
@@ -187,8 +181,10 @@ class Daemon:
def _on_transcript(self, text, path) -> None:
self._emit("TranscriptReady", GLib.Variant("(ss)", (text, str(path))))
self._properties_changed(
- "LastTranscript", GLib.Variant("s", text),
- "LastTranscriptPath", GLib.Variant("s", str(path)),
+ "LastTranscript",
+ GLib.Variant("s", text),
+ "LastTranscriptPath",
+ GLib.Variant("s", str(path)),
)
clipboard_error = None
try:
@@ -207,7 +203,11 @@ class Daemon:
"InsertionFinished",
GLib.Variant("(sbs)", ("ibus", False, str(error))),
)
- fallback = "Copied; press Ctrl+V" if clipboard_error is None else "Transcript saved"
+ fallback = (
+ "Copied; press Ctrl+V"
+ if clipboard_error is None
+ else "Transcript saved"
+ )
self._notify("Automatic insertion unavailable", fallback)
else:
self._emit(
@@ -240,9 +240,7 @@ class Daemon:
def _emit(self, name: str, parameters: GLib.Variant) -> None:
if self.connection is not None:
- self.connection.emit_signal(
- None, OBJECT_PATH, INTERFACE, name, parameters
- )
+ self.connection.emit_signal(None, OBJECT_PATH, INTERFACE, name, parameters)
def _quit(self) -> bool:
self.loop.quit()
diff --git a/src/parley/desktop.py b/src/parley/desktop.py
index 37f8a7f..3802985 100644
--- a/src/parley/desktop.py
+++ b/src/parley/desktop.py
@@ -54,4 +54,6 @@ def open_folder(path: Path) -> None:
stderr=subprocess.DEVNULL,
)
except OSError as error:
- raise DesktopIntegrationError(f"could not open transcript folder: {error}") from error
+ raise DesktopIntegrationError(
+ f"could not open transcript folder: {error}"
+ ) from error
diff --git a/src/parley/ibus_engine.py b/src/parley/ibus_engine.py
index 6f0e642..a14a139 100644
--- a/src/parley/ibus_engine.py
+++ b/src/parley/ibus_engine.py
@@ -57,18 +57,16 @@ class IBusIntegration:
raise IBusInsertionError("IBus is unavailable")
engine = ParleyIBusEngine.focused
if engine is None:
- raise IBusInsertionError(
- "Parley does not own the focused input context"
- )
+ raise IBusInsertionError("Parley does not own the focused input context")
return engine.commit(text)
def close(self) -> None:
self._closed = True
if self._reconnect_source:
- GLib.source_remove(self._reconnect_source)
+ GLib.Source.remove(self._reconnect_source)
self._reconnect_source = 0
if self._activation_source:
- GLib.source_remove(self._activation_source)
+ GLib.Source.remove(self._activation_source)
self._activation_source = 0
self._clear_connection()
diff --git a/src/parley/persistence.py b/src/parley/persistence.py
index c5bab79..bd004d8 100644
--- a/src/parley/persistence.py
+++ b/src/parley/persistence.py
@@ -10,9 +10,7 @@ from typing import Callable
Clock = Callable[[], datetime]
-def save_transcript(
- text: str, directory: Path, *, clock: Clock | None = None
-) -> Path:
+def save_transcript(text: str, directory: Path, *, clock: Clock | None = None) -> Path:
"""Atomically save UTF-8 text and return its collision-safe path."""
directory.mkdir(parents=True, exist_ok=True)
now = (clock or (lambda: datetime.now().astimezone()))()
diff --git a/src/parley/transcription.py b/src/parley/transcription.py
index 87ce66a..0735bb2 100644
--- a/src/parley/transcription.py
+++ b/src/parley/transcription.py
@@ -14,7 +14,7 @@ def parse_jsonl(output: str) -> str:
for line in output.splitlines():
try:
row = json.loads(line)
- except (json.JSONDecodeError, TypeError):
+ except json.JSONDecodeError, TypeError:
continue
if not isinstance(row, dict) or row.get("type") == "batch_header":
continue
@@ -54,9 +54,13 @@ class Transcriber:
"--batch-jsonl",
]
try:
- process = subprocess.Popen(command, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ process = subprocess.Popen(
+ command, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
+ )
except OSError as error:
- raise TranscriptionError(f"could not start transcription: {error}") from error
+ raise TranscriptionError(
+ f"could not start transcription: {error}"
+ ) from error
with self._lock:
self._process = process
try:
diff --git a/tests/test_controller.py b/tests/test_controller.py
index 61c291e..b57cb69 100644
--- a/tests/test_controller.py
+++ b/tests/test_controller.py
@@ -55,7 +55,10 @@ class ControllerTests(unittest.TestCase):
received = []
controller = Controller(
self.config,
- on_transcript=lambda text, path: (received.append((text, path)), ready.set()),
+ on_transcript=lambda text, path: (
+ received.append((text, path)),
+ ready.set(),
+ ),
)
controller.recorder = FakeRecorder()
controller.transcriber = FakeTranscriber()
diff --git a/tests/test_persistence.py b/tests/test_persistence.py
index eecb378..d8ae257 100644
--- a/tests/test_persistence.py
+++ b/tests/test_persistence.py
@@ -18,9 +18,7 @@ class PersistenceTests(unittest.TestCase):
def test_writes_utf8_with_one_final_newline(self) -> None:
path = save_transcript("héllo\n\n", self.directory, clock=lambda: self.now)
self.assertEqual(path.read_text(encoding="utf-8"), "héllo\n")
- self.assertEqual(
- path.name, "transcript_2026-07-24_12-34-56_123456+0000.txt"
- )
+ self.assertEqual(path.name, "transcript_2026-07-24_12-34-56_123456+0000.txt")
def test_uses_counter_on_collision(self) -> None:
first = save_transcript("one", self.directory, clock=lambda: self.now)
@@ -32,7 +30,9 @@ class PersistenceTests(unittest.TestCase):
def test_leaves_no_temporary_file(self) -> None:
save_transcript("text", self.directory, clock=lambda: self.now)
- self.assertFalse(any(path.suffix == ".tmp" for path in self.directory.iterdir()))
+ self.assertFalse(
+ any(path.suffix == ".tmp" for path in self.directory.iterdir())
+ )
if __name__ == "__main__":
diff --git a/tests/test_transcription.py b/tests/test_transcription.py
index 916aac2..e79bb2b 100644
--- a/tests/test_transcription.py
+++ b/tests/test_transcription.py
@@ -6,11 +6,13 @@ from parley.transcription import parse_jsonl
class ParseJsonlTests(unittest.TestCase):
def test_skips_header_and_malformed_lines(self) -> None:
- output = '\n'.join([
- 'runtime diagnostic',
- '{"type":"batch_header","count":1}',
- '{"file":"recording.wav","text":"hello world"}',
- ])
+ output = "\n".join(
+ [
+ "runtime diagnostic",
+ '{"type":"batch_header","count":1}',
+ '{"file":"recording.wav","text":"hello world"}',
+ ]
+ )
self.assertEqual(parse_jsonl(output), "hello world")
def test_reports_error_row(self) -> None: