2019-06-10 13:32:45 +00:00
|
|
|
import logging
|
2018-01-10 15:47:25 +00:00
|
|
|
|
2019-07-24 13:17:16 +00:00
|
|
|
from tfw.internals.networking import Scope
|
|
|
|
from tfw.internals.inotify import InotifyObserver
|
|
|
|
|
|
|
|
from .file_manager import FileManager
|
2018-03-25 14:06:59 +00:00
|
|
|
|
2019-05-20 12:52:02 +00:00
|
|
|
LOG = logging.getLogger(__name__)
|
2018-02-08 13:45:07 +00:00
|
|
|
|
2019-06-27 12:48:27 +00:00
|
|
|
BUILD_ARTIFACTS = (
|
2019-06-27 12:12:01 +00:00
|
|
|
"*.a",
|
|
|
|
"*.class",
|
|
|
|
"*.dll",
|
|
|
|
"*.dylib",
|
|
|
|
"*.elf",
|
|
|
|
"*.exe",
|
|
|
|
"*.jar",
|
|
|
|
"*.ko",
|
|
|
|
"*.la",
|
|
|
|
"*.lib",
|
|
|
|
"*.lo",
|
|
|
|
"*.o",
|
|
|
|
"*.obj",
|
|
|
|
"*.out",
|
|
|
|
"*.py[cod]",
|
|
|
|
"*.so",
|
|
|
|
"*.so.*",
|
|
|
|
"*.tar.gz",
|
|
|
|
"*.zip",
|
|
|
|
"*__pycache__*"
|
2019-06-27 12:48:27 +00:00
|
|
|
)
|
2019-06-24 12:29:31 +00:00
|
|
|
|
|
|
|
|
2019-07-24 13:17:16 +00:00
|
|
|
class IdeHandler:
|
2019-08-08 13:05:37 +00:00
|
|
|
keys = ['ide']
|
2019-08-30 12:45:53 +00:00
|
|
|
type_id = 'ControlEventHandler'
|
2019-08-07 07:44:03 +00:00
|
|
|
|
2019-09-02 13:49:38 +00:00
|
|
|
def __init__(self, *, patterns, initial_file=None):
|
2019-07-30 13:17:29 +00:00
|
|
|
self.connector = None
|
2019-08-07 07:44:03 +00:00
|
|
|
self.filemanager = FileManager(patterns)
|
2019-09-02 13:49:38 +00:00
|
|
|
self._initial_file = initial_file or ''
|
2019-09-27 13:16:08 +00:00
|
|
|
self._ignore_inotify_src = ''
|
2018-05-24 14:19:04 +00:00
|
|
|
|
2019-06-28 13:11:02 +00:00
|
|
|
self.monitor = InotifyObserver(
|
2019-08-07 07:44:03 +00:00
|
|
|
path=self.filemanager.parents,
|
2019-06-28 13:11:02 +00:00
|
|
|
exclude=BUILD_ARTIFACTS
|
|
|
|
)
|
2019-06-27 12:48:27 +00:00
|
|
|
self.monitor.on_modified = self._reload_frontend
|
2019-06-24 12:29:31 +00:00
|
|
|
self.monitor.start()
|
2018-06-04 19:20:36 +00:00
|
|
|
|
|
|
|
self.commands = {
|
2019-08-07 07:44:03 +00:00
|
|
|
'ide.read' : self.read,
|
|
|
|
'ide.write' : self.write
|
2018-06-04 19:20:36 +00:00
|
|
|
}
|
2018-01-10 15:47:25 +00:00
|
|
|
|
2019-09-02 13:49:38 +00:00
|
|
|
def _reload_frontend(self, event): # pylint: disable=unused-argument
|
2019-09-27 13:16:08 +00:00
|
|
|
if self._ignore_inotify_src == event.src_path:
|
|
|
|
self._ignore_inotify_src = ''
|
|
|
|
return
|
2019-09-02 13:49:38 +00:00
|
|
|
self.send_message({'key': 'ide.reload'})
|
|
|
|
|
2019-08-07 07:44:03 +00:00
|
|
|
@property
|
|
|
|
def initial_file(self):
|
2019-09-02 13:49:38 +00:00
|
|
|
if not self.filemanager.is_allowed(self._initial_file):
|
2019-08-07 07:44:03 +00:00
|
|
|
self._initial_file = self.filemanager.files[0]
|
|
|
|
return self._initial_file
|
|
|
|
|
2019-07-12 21:25:16 +00:00
|
|
|
def send_message(self, message):
|
2019-07-30 13:17:29 +00:00
|
|
|
self.connector.send_message(message, scope=Scope.WEBSOCKET)
|
2019-06-27 12:48:27 +00:00
|
|
|
|
2019-09-02 13:49:38 +00:00
|
|
|
def handle_event(self, message, _):
|
|
|
|
try:
|
|
|
|
self.commands[message['key']](message)
|
|
|
|
message['files'] = self.filemanager.files
|
|
|
|
self.send_message(message)
|
|
|
|
except KeyError:
|
|
|
|
LOG.error('IGNORING MESSAGE: Invalid message received: %s', message)
|
|
|
|
|
2019-08-07 07:44:03 +00:00
|
|
|
def read(self, message):
|
2019-09-02 14:21:19 +00:00
|
|
|
if 'patterns' in message:
|
|
|
|
self.filemanager.patterns = message['patterns']
|
2020-05-29 09:57:54 +00:00
|
|
|
self.monitor.paths = self.filemanager.parents
|
2018-03-30 15:50:20 +00:00
|
|
|
try:
|
2019-09-04 13:13:40 +00:00
|
|
|
message['filename'] = self.filemanager.find_file(
|
|
|
|
message.get('filename') or self.initial_file
|
|
|
|
)
|
2019-08-07 07:44:03 +00:00
|
|
|
message['content'] = self.filemanager.read_file(message['filename'])
|
2019-09-02 13:49:38 +00:00
|
|
|
except (PermissionError, ValueError):
|
2019-08-07 07:44:03 +00:00
|
|
|
message['content'] = 'You have no permission to open that file :('
|
2018-03-30 15:50:20 +00:00
|
|
|
except FileNotFoundError:
|
2019-09-02 13:49:38 +00:00
|
|
|
message['content'] = 'This file does not exist :('
|
2018-03-30 16:11:38 +00:00
|
|
|
except Exception: # pylint: disable=broad-except
|
2019-08-07 07:44:03 +00:00
|
|
|
message['content'] = 'Failed to read file :('
|
2019-09-02 13:49:38 +00:00
|
|
|
LOG.exception('Error reading file!')
|
2018-06-01 14:20:20 +00:00
|
|
|
|
2019-08-07 07:44:03 +00:00
|
|
|
def write(self, message):
|
2018-03-30 15:50:20 +00:00
|
|
|
try:
|
2019-09-27 13:16:08 +00:00
|
|
|
self._ignore_inotify_src = message['filename']
|
2019-08-07 07:44:03 +00:00
|
|
|
self.filemanager.write_file(message['filename'], message['content'])
|
2019-09-02 13:49:38 +00:00
|
|
|
except KeyError:
|
|
|
|
LOG.error('You must provide a filename to write!')
|
2018-03-30 16:11:38 +00:00
|
|
|
except Exception: # pylint: disable=broad-except
|
2018-03-30 15:50:20 +00:00
|
|
|
LOG.exception('Error writing file!')
|
2019-08-07 07:44:03 +00:00
|
|
|
del message['content']
|
2018-02-09 14:04:00 +00:00
|
|
|
|
2018-02-13 14:38:46 +00:00
|
|
|
def cleanup(self):
|
|
|
|
self.monitor.stop()
|