mirror of
https://github.com/chatmail/relay.git
synced 2026-05-19 12:28:06 +00:00
back to using marshal, and a filelock
This commit is contained in:
@@ -64,44 +64,31 @@ class Notifier:
|
|||||||
self.vmail_dir = vmail_dir
|
self.vmail_dir = vmail_dir
|
||||||
self.to_notify_queue = Queue()
|
self.to_notify_queue = Queue()
|
||||||
|
|
||||||
def get_metadata_dir(self, mbox):
|
def get_metadata_dict(self, mbox):
|
||||||
"get metadata directory inside mailbox directory"
|
|
||||||
mbox_path = self.vmail_dir.joinpath(mbox)
|
mbox_path = self.vmail_dir.joinpath(mbox)
|
||||||
if not mbox_path.exists():
|
if not mbox_path.exists():
|
||||||
mbox_path.mkdir()
|
mbox_path.mkdir()
|
||||||
metadata_dir = mbox_path / "metadata"
|
return PersistentDict(mbox_path / "metadata.marshalled")
|
||||||
if not metadata_dir.exists():
|
|
||||||
metadata_dir.mkdir()
|
|
||||||
return metadata_dir
|
|
||||||
|
|
||||||
def set_token(self, mbox, token):
|
def add_token(self, mbox, token):
|
||||||
metadata_dir = self.get_metadata_dir(mbox)
|
with self.get_metadata_dict(mbox).modify() as data:
|
||||||
token_path = metadata_dir / METADATA_TOKEN_KEY
|
tokens = data.get(METADATA_TOKEN_KEY)
|
||||||
write_path = token_path.with_suffix(".tmp")
|
if tokens is None:
|
||||||
tokens = []
|
data[METADATA_TOKEN_KEY] = tokens = []
|
||||||
if token_path.exists():
|
if token not in tokens:
|
||||||
tokens = token_path.read_text().split() + [token]
|
tokens.append(token)
|
||||||
if token not in tokens:
|
|
||||||
tokens.append(token)
|
|
||||||
write_path.write_text(" ".join(tokens))
|
|
||||||
write_path.rename(token_path)
|
|
||||||
|
|
||||||
def del_token(self, mbox, token):
|
def del_token(self, mbox, token):
|
||||||
tokens = self.get_tokens(mbox)
|
with self.get_metadata_dict(mbox).modify() as data:
|
||||||
if token in tokens:
|
tokens = data.get(METADATA_TOKEN_KEY)
|
||||||
tokens.remove(token)
|
if tokens:
|
||||||
token_path = self.get_metadata_dir(mbox) / METADATA_TOKEN_KEY
|
try:
|
||||||
write_path = token_path.with_suffix(".tmp")
|
tokens.remove(token)
|
||||||
write_path.write_text(" ".join(tokens))
|
except KeyError:
|
||||||
write_path.rename(token_path)
|
pass
|
||||||
|
|
||||||
def get_tokens(self, mbox):
|
def get_tokens(self, mbox):
|
||||||
metadata_dir = self.get_metadata_dir(mbox)
|
return self.get_metadata_dict(mbox).get().get(METADATA_TOKEN_KEY, [])
|
||||||
if metadata_dir is not None:
|
|
||||||
token_path = metadata_dir / METADATA_TOKEN_KEY
|
|
||||||
if token_path.exists():
|
|
||||||
return token_path.read_text().split()
|
|
||||||
return []
|
|
||||||
|
|
||||||
def new_message_for_mbox(self, mbox):
|
def new_message_for_mbox(self, mbox):
|
||||||
self.to_notify_queue.put(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 ""
|
value = parts[2] if len(parts) > 2 else ""
|
||||||
mbox = transactions[transaction_id]["mbox"]
|
mbox = transactions[transaction_id]["mbox"]
|
||||||
if keyname[0] == "priv" and keyname[2] == METADATA_TOKEN_KEY:
|
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":
|
elif keyname[0] == "priv" and keyname[2] == "messagenew":
|
||||||
notifier.new_message_for_mbox(mbox)
|
notifier.new_message_for_mbox(mbox)
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ def test_notifier_persistence(tmp_path):
|
|||||||
assert not notifier1.get_tokens("user1@example.org")
|
assert not notifier1.get_tokens("user1@example.org")
|
||||||
assert not notifier2.get_tokens("user1@example.org")
|
assert not notifier2.get_tokens("user1@example.org")
|
||||||
|
|
||||||
notifier1.set_token("user1@example.org", "01234")
|
notifier1.add_token("user1@example.org", "01234")
|
||||||
notifier1.set_token("user3@example.org", "456")
|
notifier1.add_token("user3@example.org", "456")
|
||||||
assert notifier2.get_tokens("user1@example.org") == ["01234"]
|
assert notifier2.get_tokens("user1@example.org") == ["01234"]
|
||||||
assert notifier2.get_tokens("user3@example.org") == ["456"]
|
assert notifier2.get_tokens("user3@example.org") == ["456"]
|
||||||
notifier2.del_token("user1@example.org", "01234")
|
notifier2.del_token("user1@example.org", "01234")
|
||||||
@@ -164,7 +164,7 @@ def test_notifier_thread_run(notifier):
|
|||||||
|
|
||||||
return Result()
|
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.new_message_for_mbox("user@example.org")
|
||||||
notifier.thread_run_one(ReqMock())
|
notifier.thread_run_one(ReqMock())
|
||||||
url, data, timeout = requests[0]
|
url, data, timeout = requests[0]
|
||||||
@@ -184,14 +184,15 @@ def test_multi_device_notifier(notifier):
|
|||||||
|
|
||||||
return Result()
|
return Result()
|
||||||
|
|
||||||
notifier.set_token("user@example.org", "01234")
|
notifier.add_token("user@example.org", "01234")
|
||||||
notifier.set_token("user@example.org", "56789")
|
notifier.add_token("user@example.org", "56789")
|
||||||
notifier.new_message_for_mbox("user@example.org")
|
notifier.new_message_for_mbox("user@example.org")
|
||||||
notifier.thread_run_one(ReqMock())
|
notifier.thread_run_one(ReqMock())
|
||||||
url, data, timeout = requests[0]
|
url, data, timeout = requests[0]
|
||||||
assert data == "01234"
|
assert data == "01234"
|
||||||
url, data, timeout = requests[1]
|
url, data, timeout = requests[1]
|
||||||
assert data == "56789"
|
assert data == "56789"
|
||||||
|
assert notifier.get_tokens("user@example.org") == ["01234", "56789"]
|
||||||
|
|
||||||
|
|
||||||
def test_notifier_thread_run_gone_removes_token(notifier):
|
def test_notifier_thread_run_gone_removes_token(notifier):
|
||||||
@@ -206,10 +207,10 @@ def test_notifier_thread_run_gone_removes_token(notifier):
|
|||||||
|
|
||||||
return Result()
|
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.new_message_for_mbox("user@example.org")
|
||||||
assert notifier.get_tokens("user@example.org") == ["01234"]
|
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())
|
notifier.thread_run_one(ReqMock())
|
||||||
url, data, timeout = requests[0]
|
url, data, timeout = requests[0]
|
||||||
assert data == "01234"
|
assert data == "01234"
|
||||||
|
|||||||
Reference in New Issue
Block a user