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.
109 lines
2.4 KiB
109 lines
2.4 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 path of 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 1.2
|
|
# Copyleft 2019, 2020, p≡p foundation
|
|
|
|
# this file is under GNU General Public License 3.0
|
|
|
|
|
|
import os
|
|
from secrets import token_urlsafe
|
|
from time import sleep
|
|
from random import random
|
|
|
|
|
|
# set timing to None for random timing
|
|
timing = None
|
|
|
|
|
|
def snooze():
|
|
if timing is None:
|
|
sleep(random()/2)
|
|
else:
|
|
sleep(timing)
|
|
|
|
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():
|
|
snooze()
|
|
lockfile.touch()
|
|
|
|
|
|
def send(inbox, msg, marker):
|
|
"send msg to inbox in MIME format"
|
|
|
|
snooze()
|
|
with Lock(inbox):
|
|
name = marker + "_" + token_urlsafe(16) + ".eml"
|
|
with open(inbox / name, "wb") as f:
|
|
f.write(str(msg).encode())
|
|
|
|
|
|
def newer(file, stamp):
|
|
"return True if file is newer than timestamp stamp"
|
|
|
|
if not file.is_file():
|
|
return False
|
|
|
|
if stamp is None:
|
|
return True
|
|
|
|
stat = file.stat()
|
|
return stat.st_mtime > stamp.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:
|
|
with Lock(inbox):
|
|
try:
|
|
stamp = (inbox / marker).stat()
|
|
except:
|
|
stamp = None
|
|
l = [ path for path in inbox.glob("*.eml") ]
|
|
(inbox / marker).touch(exist_ok=True)
|
|
for p in reversed(l):
|
|
if newer(p, stamp):
|
|
with open(p, "rb") as f:
|
|
txt = f.read(-1)
|
|
r.append((p, txt))
|
|
if not r:
|
|
snooze()
|
|
|
|
return r
|
|
|
|
|