summaryrefslogtreecommitdiff
path: root/grc/gui/external_editor.py
blob: 58467c2785b222f6cdd465baa47a0261145abdad (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
"""
Copyright 2015 Free Software Foundation, Inc.
This file is part of GNU Radio

SPDX-License-Identifier: GPL-2.0-or-later

"""

from __future__ import absolute_import, print_function

import os
import sys
import time
import threading
import tempfile
import subprocess


class ExternalEditor(threading.Thread):

    def __init__(self, editor, name, value, callback):
        threading.Thread.__init__(self)
        self.daemon = True
        self._stop_event = threading.Event()

        self.editor = editor
        self.callback = callback
        self.filename = self._create_tempfile(name, value)

    def _create_tempfile(self, name, value):
        with tempfile.NamedTemporaryFile(
            mode='wb', prefix=name + '_', suffix='.py', delete=False,
        ) as fp:
            fp.write(value.encode('utf-8'))
            return fp.name

    def open_editor(self):
        proc = subprocess.Popen(args=(self.editor, self.filename))
        proc.poll()
        return proc

    def stop(self):
        self._stop_event.set()

    def run(self):
        filename = self.filename
        # print "file monitor: started for", filename
        last_change = os.path.getmtime(filename)
        try:
            while not self._stop_event.is_set():
                mtime = os.path.getmtime(filename)
                if mtime > last_change:
                    # print "file monitor: reload trigger for", filename
                    last_change = mtime
                    with open(filename, 'rb') as fp:
                        data = fp.read().decode('utf-8')
                    self.callback(data)
                time.sleep(1)

        except Exception as e:
            print("file monitor crashed:", str(e), file=sys.stderr)
        finally:
            try:
                os.remove(self.filename)
            except OSError:
                pass


if __name__ == '__main__':
    e = ExternalEditor('/usr/bin/gedit', "test", "content", print)
    e.open_editor()
    e.start()
    time.sleep(15)
    e.stop()
    e.join()