Use dir named after user by default. Use fork to handle multiple files at once.

This commit is contained in:
Lynn Ochs 2020-05-10 10:23:36 +02:00
parent 349ee8a646
commit d672788a65

View File

@ -8,6 +8,7 @@ import sys
import argparse import argparse
import daemon import daemon
import hashlib import hashlib
import getpass
sockpath = "mailcap.sock" sockpath = "mailcap.sock"
@ -41,20 +42,16 @@ class Server(object):
retval += data retval += data
return retval return retval
def __init__(self, path="mailcap.sock", dir = None): def __init__(self, path="mailcap.sock"):
self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) self._socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
self._socket.bind(path) self._socket.bind(path)
self._socket.listen(3) self._socket.listen(3)
if dir:
if not os.path.exists(dir): if not os.path.exists(dir):
os.makedirs(dir) os.makedirs(dir)
self._dir = dir self._dir = dir
else:
self._dir = tempfile.TemporaryDirectory(prefix="mailcapd")
def close(self): def close(self):
self._socket.close() self._socket.close()
self._dir.cleanup()
def next_file(self, initial_timeout=None, timeout=5): def next_file(self, initial_timeout=None, timeout=5):
conn = self.Connection(self._socket.accept()[0]) conn = self.Connection(self._socket.accept()[0])
@ -97,7 +94,7 @@ class Server(object):
if data is None: if data is None:
return None return None
full_name = os.path.join(self._dir.name, fn) full_name = os.path.join(self._dir, fn)
append = 0 append = 0
# While the filename already exists, check if we have a hash match # While the filename already exists, check if we have a hash match
print("Trying path %s" % (full_name,)) print("Trying path %s" % (full_name,))
@ -117,9 +114,9 @@ class Server(object):
hash = hashlib.sha256() hash = hashlib.sha256()
name_parts = fn.split('.') name_parts = fn.split('.')
if len(name_parts) > 1: if len(name_parts) > 1:
full_name = os.path.join(self._dir.name, "%s-%d.%s" % ('.'.join(name_parts[:-1]), append, name_parts[-1])) full_name = os.path.join(self._dir, "%s-%d.%s" % ('.'.join(name_parts[:-1]), append, name_parts[-1]))
else: else:
full_name = os.path.join(self._dir.name, "%s-%d" % (fn, append)) full_name = os.path.join(self._dir, "%s-%d" % (fn, append))
print("Accepted filename %s" % (full_name,)) print("Accepted filename %s" % (full_name,))
conn.send(b'\x01') conn.send(b'\x01')
@ -130,7 +127,7 @@ class Server(object):
file_len = struct.unpack("!I", data)[0] file_len = struct.unpack("!I", data)[0]
# Receive the file data # Receive the file data
fn = os.path.join(self._dir.name, fn) fn = os.path.join(self._dir, fn)
with open(fn, "wb+") as f: with open(fn, "wb+") as f:
while file_len > 0: while file_len > 0:
data = conn.recv(min(4096, file_len)) data = conn.recv(min(4096, file_len))
@ -147,24 +144,35 @@ class Server(object):
def run_server(args): def run_server(args):
sv = Server(path=args.socket, dir=args.dir) sv = Server(path=args.socket, dir=args.dir)
caps = mailcap.getcaps()
open(args.pid, "w+").write(str(os.getpid())) open(args.pid, "w+").write(str(os.getpid()))
while True: while True:
rv = sv.next_file() rv = sv.next_file()
if rv: if rv:
f, mime = rv f, mime = rv
print(f, mime) print(f, mime)
caps = mailcap.getcaps()
match = mailcap.findmatch(caps, mime.split(';')[0], filename=f) match = mailcap.findmatch(caps, mime.split(';')[0], filename=f)
if match and match[0]: if match and match[0]:
pid = os.fork()
if pid != 0:
os.waitid(os.P_PID, pid, os.WEXITED)
else:
pid2 = os.fork()
if pid2 != 0:
exit(0)
else:
os.system(match[0]) os.system(match[0])
if __name__ == "__main__": if __name__ == "__main__":
tempbase = tempfile.gettempdir()
user = getpass.getuser()
parser = argparse.ArgumentParser() parser = argparse.ArgumentParser()
parser.add_argument('--pid', '-p', default=os.path.join(os.environ['HOME'], '.mailcap.pid')) parser.add_argument('--pid', '-p', default=os.path.join(os.environ['HOME'], '.mailcap.pid'))
parser.add_argument('--action', '-a', default='run', choices=['run', 'kill']) parser.add_argument('--action', '-a', default='run', choices=['run', 'kill'])
parser.add_argument('--no-daemonize', '-n', action='store_true') parser.add_argument('--no-daemonize', '-n', action='store_true')
parser.add_argument('--socket', '-s', default=os.path.join(os.environ['HOME'], '.mailcap.sock')) parser.add_argument('--socket', '-s', default=os.path.join(os.environ['HOME'], '.mailcap.sock'))
parser.add_argument('--dir', '-d', default=None) parser.add_argument('--dir', '-d', default=os.path.join(tempbase, "mailcap-server_" + user))
parser.add_argument('--force', '-f', action='store_true') parser.add_argument('--force', '-f', action='store_true')
args = parser.parse_args() args = parser.parse_args()