store metadata in a per-mbox dir

This commit is contained in:
holger krekel 2024-03-27 12:45:05 +01:00
parent 8ee6ca1b80
commit a8765d8847
2 changed files with 41 additions and 31 deletions

View File

@ -24,26 +24,35 @@ DICTPROXY_TRANSACTION_CHARS = "SBC"
class Notifier: class Notifier:
def __init__(self, metadata_dir): def __init__(self, vmail_dir):
self.metadata_dir = metadata_dir self.vmail_dir = vmail_dir
self.to_notify_queue = Queue() self.to_notify_queue = Queue()
def set_token(self, guid, token): def get_metadata_dir(self, mbox):
guid_path = self.metadata_dir.joinpath(guid) mbox_path = self.vmail_dir.joinpath(mbox)
if not guid_path.exists(): if not mbox_path.exists():
guid_path.mkdir() mbox_path.mkdir()
token_path = guid_path / "token" metadata_dir = mbox_path / "metadata"
if not metadata_dir.exists():
metadata_dir.mkdir()
return metadata_dir
def set_token(self, mbox, token):
metadata_dir = self.get_metadata_dir(mbox)
token_path = metadata_dir / "token"
write_path = token_path.with_suffix(".tmp") write_path = token_path.with_suffix(".tmp")
write_path.write_text(token) write_path.write_text(token)
write_path.rename(token_path) write_path.rename(token_path)
def del_token(self, guid): def del_token(self, mbox):
self.metadata_dir.joinpath(guid).joinpath("token").unlink(missing_ok=True) metadata_dir = self.get_metadata_dir(mbox)
if metadata_dir is not None:
metadata_dir.joinpath("token").unlink(missing_ok=True)
def get_token(self, guid): def get_token(self, mbox):
guid_path = self.metadata_dir / guid metadata_dir = self.get_metadata_dir(mbox)
if guid_path.exists(): if metadata_dir is not None:
token_path = guid_path / "token" token_path = metadata_dir / "token"
if token_path.exists(): if token_path.exists():
return token_path.read_text() return token_path.read_text()
@ -95,7 +104,6 @@ def handle_dovecot_request(msg, transactions, notifier):
# Lpriv/43f5f508a7ea0366dff30200c15250e3/devicetoken\tlkj123poi@c2.testrun.org # Lpriv/43f5f508a7ea0366dff30200c15250e3/devicetoken\tlkj123poi@c2.testrun.org
keyparts = parts[0].split("/") keyparts = parts[0].split("/")
if keyparts[0] == "priv": if keyparts[0] == "priv":
# guid = keyparts[1]
keyname = keyparts[2] keyname = keyparts[2]
mbox = parts[1] mbox = parts[1]
if keyname == "devicetoken": if keyname == "devicetoken":

View File

@ -10,30 +10,32 @@ from chatmaild.metadata import (
@pytest.fixture @pytest.fixture
def notifier(tmp_path): def notifier(tmp_path):
metadata_dir = tmp_path.joinpath("metadata") vmail_dir = tmp_path.joinpath("vmaildir")
metadata_dir.mkdir() vmail_dir.mkdir()
return Notifier(metadata_dir) return Notifier(vmail_dir)
def test_notifier_persistence(tmp_path): def test_notifier_persistence(tmp_path):
metadata_dir = tmp_path.joinpath("metadata") vmail_dir = tmp_path
metadata_dir.mkdir() vmail_dir.joinpath("user1@example.org").mkdir()
notifier1 = Notifier(metadata_dir) vmail_dir.joinpath("user3@example.org").mkdir()
notifier2 = Notifier(metadata_dir)
assert notifier1.get_token(guid="guid00") is None
assert notifier2.get_token(guid="guid00") is None
notifier1.set_token("guid00", "01234") notifier1 = Notifier(vmail_dir)
notifier1.set_token("guid03", "456") notifier2 = Notifier(vmail_dir)
assert notifier2.get_token("guid00") == "01234" assert notifier1.get_token("user1@example.org") is None
assert notifier2.get_token("guid03") == "456" assert notifier2.get_token("user1@example.org") is None
notifier2.del_token("guid00")
assert notifier1.get_token("guid00") is None notifier1.set_token("user1@example.org", "01234")
notifier1.set_token("user3@example.org", "456")
assert notifier2.get_token("user1@example.org") == "01234"
assert notifier2.get_token("user3@example.org") == "456"
notifier2.del_token("user1@example.org")
assert notifier1.get_token("user1@example.org") is None
def test_notifier_delete_without_set(notifier): def test_notifier_delete_without_set(notifier):
notifier.del_token("guid00") notifier.del_token("user@example.org")
assert not notifier.get_token("guid00") assert not notifier.get_token("user@example.org")
def test_handle_dovecot_request_lookup_fails(notifier): def test_handle_dovecot_request_lookup_fails(notifier):