1"""
2Copyright 2015 Free Software Foundation, Inc.
3This file is part of GNU Radio
4
5GNU Radio Companion is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10GNU Radio Companion is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
18"""
19
20from __future__ import absolute_import, print_function
21
22import os
23import sys
24import time
25import threading
26import tempfile
27import subprocess
28
29
30class ExternalEditor(threading.Thread):
31
32    def __init__(self, editor, name, value, callback):
33        threading.Thread.__init__(self)
34        self.daemon = True
35        self._stop_event = threading.Event()
36
37        self.editor = editor
38        self.callback = callback
39        self.filename = self._create_tempfile(name, value)
40
41    def _create_tempfile(self, name, value):
42        with tempfile.NamedTemporaryFile(
43            mode='wb', prefix=name + '_', suffix='.py', delete=False,
44        ) as fp:
45            fp.write(value.encode('utf-8'))
46            return fp.name
47
48    def open_editor(self):
49        proc = subprocess.Popen(args=(self.editor, self.filename))
50        proc.poll()
51        return proc
52
53    def stop(self):
54        self._stop_event.set()
55
56    def run(self):
57        filename = self.filename
58        # print "file monitor: started for", filename
59        last_change = os.path.getmtime(filename)
60        try:
61            while not self._stop_event.is_set():
62                mtime = os.path.getmtime(filename)
63                if mtime > last_change:
64                    # print "file monitor: reload trigger for", filename
65                    last_change = mtime
66                    with open(filename, 'rb') as fp:
67                        data = fp.read().decode('utf-8')
68                    self.callback(data)
69                time.sleep(1)
70
71        except Exception as e:
72            print("file monitor crashed:", str(e), file=sys.stderr)
73        finally:
74            try:
75                os.remove(self.filename)
76            except OSError:
77                pass
78
79
80if __name__ == '__main__':
81    e = ExternalEditor('/usr/bin/gedit', "test", "content", print)
82    e.open_editor()
83    e.start()
84    time.sleep(15)
85    e.stop()
86    e.join()
87