You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

91 lines
2.0 KiB

# vim: set fileencoding=utf-8 :
"""provide a trivial way to send messages between processes
messages are being sent as files to an inbox, which is a directory, using a
filename as a marker
recv_all() is delivering all messages, which are newer than the marker file
after completion reading is touching the marker file
to re-read messages touch the marker file with an older timestamp or just
delete the marker file to re-read all messages
"""
# Minimail
# Copyleft 2019, p≡p foundation
# this file is under GNU General Public License 3.0
from secrets import token_urlsafe
from time import sleep
def unlock(inbox):
"clear the inbox from lockfile"
lockfile = inbox / "lock"
try:
lockfile.unlink()
except:
pass
class Lock:
"lock inbox context to be used by with statement"
def __init__(self, inbox):
self.inbox = inbox
def __exit__(self, *exc):
unlock(self.inbox)
def __enter__(self):
lockfile = self.inbox / "lock"
while lockfile.is_file():
sleep(1)
lockfile.touch()
def send(inbox, msg):
"send msg to inbox in MIME format"
with Lock(inbox):
name = token_urlsafe(16) + ".eml"
with open(inbox / name, "wb") as f:
f.write(str(msg).encode())
def newer(file1, file2=None):
"return True if file1 is newer than file2"
if not file1.is_file():
return False
elif not file2.is_file():
return True
stat1 = file1.stat()
stat2 = file2.stat()
return stat1.st_mtime > stat2.st_mtime
def recv_all(inbox, marker):
"""receive a list of new MIME messages from inbox, which are newer than the
marker file"""
r = []
while not r:
for p in inbox.glob("*.eml"):
if newer(p, inbox / marker):
with Lock(inbox):
with open(p, "rb") as f:
t = f.read(-1)
r.append(t)
if not r:
sleep(1)
(inbox / marker).touch(exist_ok=True)
return r