1import contextlib
2import os
3import stat
4
5from whistle import Event
6
7ENCODING = "utf-8"
8
9
10class FileEvent(Event):
11    def __init__(self, filename, executable, override):
12        super(FileEvent, self).__init__()
13        self.executable = executable
14        self.filename = filename
15        self.override = override
16
17
18@contextlib.contextmanager
19def File(dispatcher, name, *, executable=False, override=False):
20    event = FileEvent(name, executable, override)
21
22    if event.override or not os.path.exists(event.filename):
23        with open(event.filename, "w+", encoding=ENCODING) as f:
24            event.file = f
25            event = dispatcher.dispatch("medikit.on_file_opened", event)
26            yield f
27            event.file = None
28
29        if event.executable and os.path.exists(event.filename):
30            st = os.stat(event.filename)
31            os.chmod(event.filename, st.st_mode | stat.S_IEXEC)
32
33        dispatcher.dispatch("medikit.on_file_closed", event)
34    else:
35        with open("/dev/null", "w", encoding=ENCODING) as f:
36            yield f
37
38
39@contextlib.contextmanager
40def NullFile(dispatcher, name, *, executable=False, override=False):
41    event = FileEvent(name, executable, override)
42
43    if event.override or not os.path.exists(event.filename):
44        with open("/dev/null", "w", encoding=ENCODING) as f:
45            event.file = f
46            event = dispatcher.dispatch("medikit.on_file_opened", event)
47            yield f
48            event.file = None
49
50        dispatcher.dispatch("medikit.on_file_closed", event)
51    else:
52        with open("/dev/null", "w", encoding=ENCODING) as f:
53            yield f
54