diff --git a/chatmaild/src/chatmaild/metadata.py b/chatmaild/src/chatmaild/metadata.py index 2165a76d..45f509c5 100644 --- a/chatmaild/src/chatmaild/metadata.py +++ b/chatmaild/src/chatmaild/metadata.py @@ -64,44 +64,31 @@ class Notifier: self.vmail_dir = vmail_dir self.to_notify_queue = Queue() - def get_metadata_dir(self, mbox): - "get metadata directory inside mailbox directory" + def get_metadata_dict(self, mbox): mbox_path = self.vmail_dir.joinpath(mbox) if not mbox_path.exists(): mbox_path.mkdir() - metadata_dir = mbox_path / "metadata" - if not metadata_dir.exists(): - metadata_dir.mkdir() - return metadata_dir + return PersistentDict(mbox_path / "metadata.marshalled") - def set_token(self, mbox, token): - metadata_dir = self.get_metadata_dir(mbox) - token_path = metadata_dir / METADATA_TOKEN_KEY - write_path = token_path.with_suffix(".tmp") - tokens = [] - if token_path.exists(): - tokens = token_path.read_text().split() + [token] - if token not in tokens: - tokens.append(token) - write_path.write_text(" ".join(tokens)) - write_path.rename(token_path) + def add_token(self, mbox, token): + with self.get_metadata_dict(mbox).modify() as data: + tokens = data.get(METADATA_TOKEN_KEY) + if tokens is None: + data[METADATA_TOKEN_KEY] = tokens = [] + if token not in tokens: + tokens.append(token) def del_token(self, mbox, token): - tokens = self.get_tokens(mbox) - if token in tokens: - tokens.remove(token) - token_path = self.get_metadata_dir(mbox) / METADATA_TOKEN_KEY - write_path = token_path.with_suffix(".tmp") - write_path.write_text(" ".join(tokens)) - write_path.rename(token_path) + with self.get_metadata_dict(mbox).modify() as data: + tokens = data.get(METADATA_TOKEN_KEY) + if tokens: + try: + tokens.remove(token) + except KeyError: + pass def get_tokens(self, mbox): - metadata_dir = self.get_metadata_dir(mbox) - if metadata_dir is not None: - token_path = metadata_dir / METADATA_TOKEN_KEY - if token_path.exists(): - return token_path.read_text().split() - return [] + return self.get_metadata_dict(mbox).get().get(METADATA_TOKEN_KEY, []) def new_message_for_mbox(self, mbox): self.to_notify_queue.put(mbox) @@ -181,7 +168,7 @@ def handle_dovecot_request(msg, transactions, notifier): value = parts[2] if len(parts) > 2 else "" mbox = transactions[transaction_id]["mbox"] if keyname[0] == "priv" and keyname[2] == METADATA_TOKEN_KEY: - notifier.set_token(mbox, value) + notifier.add_token(mbox, value) elif keyname[0] == "priv" and keyname[2] == "messagenew": notifier.new_message_for_mbox(mbox) else: diff --git a/chatmaild/src/chatmaild/tests/test_metadata.py b/chatmaild/src/chatmaild/tests/test_metadata.py index cf53480f..a423ee2b 100644 --- a/chatmaild/src/chatmaild/tests/test_metadata.py +++ b/chatmaild/src/chatmaild/tests/test_metadata.py @@ -26,8 +26,8 @@ def test_notifier_persistence(tmp_path): assert not notifier1.get_tokens("user1@example.org") assert not notifier2.get_tokens("user1@example.org") - notifier1.set_token("user1@example.org", "01234") - notifier1.set_token("user3@example.org", "456") + notifier1.add_token("user1@example.org", "01234") + notifier1.add_token("user3@example.org", "456") assert notifier2.get_tokens("user1@example.org") == ["01234"] assert notifier2.get_tokens("user3@example.org") == ["456"] notifier2.del_token("user1@example.org", "01234") @@ -164,7 +164,7 @@ def test_notifier_thread_run(notifier): return Result() - notifier.set_token("user@example.org", "01234") + notifier.add_token("user@example.org", "01234") notifier.new_message_for_mbox("user@example.org") notifier.thread_run_one(ReqMock()) url, data, timeout = requests[0] @@ -184,14 +184,15 @@ def test_multi_device_notifier(notifier): return Result() - notifier.set_token("user@example.org", "01234") - notifier.set_token("user@example.org", "56789") + notifier.add_token("user@example.org", "01234") + notifier.add_token("user@example.org", "56789") notifier.new_message_for_mbox("user@example.org") notifier.thread_run_one(ReqMock()) url, data, timeout = requests[0] assert data == "01234" url, data, timeout = requests[1] assert data == "56789" + assert notifier.get_tokens("user@example.org") == ["01234", "56789"] def test_notifier_thread_run_gone_removes_token(notifier): @@ -206,10 +207,10 @@ def test_notifier_thread_run_gone_removes_token(notifier): return Result() - notifier.set_token("user@example.org", "01234") + notifier.add_token("user@example.org", "01234") notifier.new_message_for_mbox("user@example.org") assert notifier.get_tokens("user@example.org") == ["01234"] - notifier.set_token("user@example.org", "45678") + notifier.add_token("user@example.org", "45678") notifier.thread_run_one(ReqMock()) url, data, timeout = requests[0] assert data == "01234"