import logging from os.path import isfile from tfw.internals.networking import Scope from tfw.internals.inotify import InotifyObserver from .file_manager import FileManager LOG = logging.getLogger(__name__) BUILD_ARTIFACTS = ( "*.a", "*.class", "*.dll", "*.dylib", "*.elf", "*.exe", "*.jar", "*.ko", "*.la", "*.lib", "*.lo", "*.o", "*.obj", "*.out", "*.py[cod]", "*.so", "*.so.*", "*.tar.gz", "*.zip", "*__pycache__*" ) class IdeHandler: keys = ['ide'] def __init__(self, *, patterns, initial_file=''): self.connector = None self.filemanager = FileManager(patterns) self._initial_file = initial_file self.monitor = InotifyObserver( path=self.filemanager.parents, exclude=BUILD_ARTIFACTS ) self.monitor.on_modified = self._reload_frontend self.monitor.start() self.commands = { 'ide.read' : self.read, 'ide.write' : self.write } @property def initial_file(self): if not isfile(self._initial_file): self._initial_file = self.filemanager.files[0] return self._initial_file def _reload_frontend(self, event): # pylint: disable=unused-argument self.send_message({'key': 'ide.reload'}) def send_message(self, message): self.connector.send_message(message, scope=Scope.WEBSOCKET) def read(self, message): if message.get('files'): self.filemanager.patterns = message['files'] try: message['content'] = self.filemanager.read_file(message['filename']) except PermissionError: message['content'] = 'You have no permission to open that file :(' except FileNotFoundError: message['content'] = 'This file was removed :(' except Exception: # pylint: disable=broad-except message['content'] = 'Failed to read file :(' def write(self, message): try: self.filemanager.write_file(message['filename'], message['content']) except Exception: # pylint: disable=broad-except LOG.exception('Error writing file!') del message['content'] def handle_event(self, message, _): try: if message['filename'] == '': message['filename'] = self.initial_file 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) def cleanup(self): self.monitor.stop()