mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-05-21 17:12:32 +00:00
feat(signal): make signal-cli attachments directory configurable
The inbound attachment loop hardcoded ~/.local/share/signal-cli/attachments as the source path. That is the daemon's default on Linux but not on macOS or Windows, and breaks if the daemon was launched with XDG_DATA_HOME set. Add SignalConfig.attachments_dir as an optional override. When unset the behavior is unchanged; when set the value is run through Path.expanduser() so ~ is honored. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
971b774282
commit
9aa2ab1657
@ -296,6 +296,11 @@ class SignalConfig(Base):
|
|||||||
daemon_host: str = "localhost"
|
daemon_host: str = "localhost"
|
||||||
daemon_port: int = 8080
|
daemon_port: int = 8080
|
||||||
group_message_buffer_size: int = 20 # Number of recent group messages to keep for context
|
group_message_buffer_size: int = 20 # Number of recent group messages to keep for context
|
||||||
|
# Override the directory signal-cli writes inbound attachments to. When
|
||||||
|
# None, defaults to ~/.local/share/signal-cli/attachments (the daemon's
|
||||||
|
# platform default on Linux). Set this if the daemon is running with a
|
||||||
|
# custom XDG_DATA_HOME or on macOS/Windows where the default path differs.
|
||||||
|
attachments_dir: str | None = None
|
||||||
dm: SignalDMConfig = Field(default_factory=SignalDMConfig)
|
dm: SignalDMConfig = Field(default_factory=SignalDMConfig)
|
||||||
group: SignalGroupConfig = Field(default_factory=SignalGroupConfig)
|
group: SignalGroupConfig = Field(default_factory=SignalGroupConfig)
|
||||||
|
|
||||||
@ -749,10 +754,7 @@ class SignalChannel(BaseChannel):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# signal-cli stores attachments in ~/.local/share/signal-cli/attachments/
|
source_path = self._signal_attachments_dir() / attachment_id
|
||||||
source_path = (
|
|
||||||
Path.home() / ".local/share/signal-cli/attachments" / attachment_id
|
|
||||||
)
|
|
||||||
|
|
||||||
if source_path.exists():
|
if source_path.exists():
|
||||||
dest_path = media_dir / f"signal_{safe_filename(filename)}"
|
dest_path = media_dir / f"signal_{safe_filename(filename)}"
|
||||||
@ -864,6 +866,17 @@ class SignalChannel(BaseChannel):
|
|||||||
|
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
def _signal_attachments_dir(self) -> Path:
|
||||||
|
"""Return the directory signal-cli writes inbound attachments to.
|
||||||
|
|
||||||
|
Defaults to ``~/.local/share/signal-cli/attachments`` (the daemon's
|
||||||
|
platform default on Linux) when ``config.attachments_dir`` is unset.
|
||||||
|
"""
|
||||||
|
configured = self.config.attachments_dir
|
||||||
|
if configured:
|
||||||
|
return Path(configured).expanduser()
|
||||||
|
return Path.home() / ".local/share/signal-cli/attachments"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _normalize_signal_id(value: str) -> list[str]:
|
def _normalize_signal_id(value: str) -> list[str]:
|
||||||
"""Normalize Signal identifiers (phone/uuid/service-id) for matching."""
|
"""Normalize Signal identifiers (phone/uuid/service-id) for matching."""
|
||||||
|
|||||||
@ -3,6 +3,7 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import asyncio
|
import asyncio
|
||||||
|
from pathlib import Path
|
||||||
from unittest.mock import AsyncMock
|
from unittest.mock import AsyncMock
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
@ -71,6 +72,7 @@ def _make_channel(
|
|||||||
group_allow_from: list[str] | None = None,
|
group_allow_from: list[str] | None = None,
|
||||||
require_mention: bool = True,
|
require_mention: bool = True,
|
||||||
group_buffer_size: int = 20,
|
group_buffer_size: int = 20,
|
||||||
|
attachments_dir: str | None = None,
|
||||||
) -> SignalChannel:
|
) -> SignalChannel:
|
||||||
config = SignalConfig(
|
config = SignalConfig(
|
||||||
enabled=True,
|
enabled=True,
|
||||||
@ -87,6 +89,7 @@ def _make_channel(
|
|||||||
require_mention=require_mention,
|
require_mention=require_mention,
|
||||||
),
|
),
|
||||||
group_message_buffer_size=group_buffer_size,
|
group_message_buffer_size=group_buffer_size,
|
||||||
|
attachments_dir=attachments_dir,
|
||||||
)
|
)
|
||||||
return SignalChannel(config, MessageBus())
|
return SignalChannel(config, MessageBus())
|
||||||
|
|
||||||
@ -471,6 +474,21 @@ class TestGroupBuffer:
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class TestAttachmentsDir:
|
||||||
|
def test_default_attachments_dir(self):
|
||||||
|
ch = _make_channel()
|
||||||
|
expected = Path.home() / ".local/share/signal-cli/attachments"
|
||||||
|
assert ch._signal_attachments_dir() == expected
|
||||||
|
|
||||||
|
def test_configured_attachments_dir(self, tmp_path):
|
||||||
|
ch = _make_channel(attachments_dir=str(tmp_path / "custom"))
|
||||||
|
assert ch._signal_attachments_dir() == tmp_path / "custom"
|
||||||
|
|
||||||
|
def test_attachments_dir_expands_user(self):
|
||||||
|
ch = _make_channel(attachments_dir="~/signal-attachments")
|
||||||
|
assert ch._signal_attachments_dir() == Path.home() / "signal-attachments"
|
||||||
|
|
||||||
|
|
||||||
class TestHandleDataMessageDM:
|
class TestHandleDataMessageDM:
|
||||||
def _make_dm_channel(self, policy="open", allow_from=None) -> tuple[SignalChannel, list]:
|
def _make_dm_channel(self, policy="open", allow_from=None) -> tuple[SignalChannel, list]:
|
||||||
ch = _make_channel(dm_enabled=True, dm_policy=policy, dm_allow_from=allow_from or [])
|
ch = _make_channel(dm_enabled=True, dm_policy=policy, dm_allow_from=allow_from or [])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user