import os import tempfile import bbctrl import glob import tornado from tornado import gen from tornado.web import HTTPError from tornado.escape import url_unescape def safe_remove(path): try: os.unlink(path) except OSError: pass @tornado.web.stream_request_body class FileHandler(bbctrl.APIHandler): def prepare(self): if self.request.method == 'PUT': self.request.connection.set_max_body_size(2 ** 30) filename = self.request.path.split('/')[-1] self.uploadFilename = url_unescape(filename) \ .encode("ascii", errors="replace") \ .decode() \ .replace('\\', '_') \ .replace('/', '_') \ .replace('#', '-') \ .replace('?', '-') self.uploadFile = tempfile.NamedTemporaryFile("wb") def data_received(self, data): if self.request.method == 'PUT': self.uploadFile.write(data) def delete_ok(self, filename): allFiles = self.get_ctrl().state.return_files() if not filename: # Delete everything for path in glob.glob(self.get_upload('*')): self.get_log('FileHandler').info('path ' + path) safe_remove(path) self.get_ctrl().preplanner.delete_all_plans() self.get_ctrl().state.clear_files() else: # Delete a single file filename = os.path.basename(filename) self.get_log('FileHandler').info('filename ' + filename) safe_remove(self.get_upload(filename)) self.get_ctrl().preplanner.delete_plans(filename) self.get_ctrl().state.remove_file(filename) def put_ok(self, *args): if not os.path.exists(self.get_upload()): os.mkdir(self.get_upload()) filename = self.get_upload(self.uploadFilename).encode('utf8') safe_remove(filename) os.link(self.uploadFile.name, filename) self.uploadFile.close() del (self.uploadFile) self.get_ctrl().preplanner.invalidate(self.uploadFilename) self.get_ctrl().state.add_file(self.uploadFilename) self.get_log('FileHandler').info( 'GCode received: ' + self.uploadFilename) del (self.uploadFilename) @gen.coroutine def get(self, filename): self.get_log('FileHandler').info( 'FileName: ' + filename) if not filename: raise HTTPError(400, 'Missing filename') if filename.startswith('/EgZjaHJvbWUqCggBEAAYsQMYgAQyBggAEEUYOTIKCAE'): filebasename = os.path.basename(url_unescape(filename.replace("EgZjaHJvbWUqCggBEAAYsQMYgAQyBggAEEUYOTIKCAE", ""))) else: filebasename = os.path.basename(url_unescape(filename)) self.get_log('FileHandler').info( 'FileBaseName: ' + filebasename) try: with open(self.get_upload(filebasename).encode('utf8'), 'r') as f: self.write(f.read()) except Exception: self.get_ctrl().state.select_file('') raise HTTPError( 400, "Unable to read file - doesn't appear to be GCode.") if not filename.startswith('/EgZjaHJvbWUqCggBEAAYsQMYgAQyBggAEEUYOTIKCAE'): self.get_ctrl().state.select_file(filebasename)