File uploads now support up to 1GB files, and display progress
This commit is contained in:
@@ -1,34 +1,8 @@
|
||||
################################################################################
|
||||
# #
|
||||
# This file is part of the Buildbotics firmware. #
|
||||
# #
|
||||
# Copyright (c) 2015 - 2018, Buildbotics LLC #
|
||||
# All rights reserved. #
|
||||
# #
|
||||
# This file ("the software") is free software: you can redistribute it #
|
||||
# and/or modify it under the terms of the GNU General Public License, #
|
||||
# version 2 as published by the Free Software Foundation. You should #
|
||||
# have received a copy of the GNU General Public License, version 2 #
|
||||
# along with the software. If not, see <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# The software is distributed in the hope that it will be useful, but #
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of #
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU #
|
||||
# Lesser General Public License for more details. #
|
||||
# #
|
||||
# You should have received a copy of the GNU Lesser General Public #
|
||||
# License along with the software. If not, see #
|
||||
# <http://www.gnu.org/licenses/>. #
|
||||
# #
|
||||
# For information regarding this software email: #
|
||||
# "Joseph Coffland" <joseph@buildbotics.com> #
|
||||
# #
|
||||
################################################################################
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
import bbctrl
|
||||
import glob
|
||||
import html
|
||||
import tornado
|
||||
from tornado import gen
|
||||
from tornado.web import HTTPError
|
||||
|
||||
@@ -36,17 +10,32 @@ from tornado.web import HTTPError
|
||||
def safe_remove(path):
|
||||
try:
|
||||
os.unlink(path)
|
||||
except OSError: pass
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
@tornado.web.stream_request_body
|
||||
class FileHandler(bbctrl.APIHandler):
|
||||
def prepare(self): pass
|
||||
def prepare(self):
|
||||
if self.request.method == 'PUT':
|
||||
self.request.connection.set_max_body_size(2 ** 30)
|
||||
|
||||
self.uploadFilename = self.request.path.split('/')[-1] \
|
||||
.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):
|
||||
if not filename:
|
||||
# Delete everything
|
||||
for path in glob.glob(self.get_upload('*')): safe_remove(path)
|
||||
for path in glob.glob(self.get_upload('*')):
|
||||
safe_remove(path)
|
||||
self.get_ctrl().preplanner.delete_all_plans()
|
||||
self.get_ctrl().state.clear_files()
|
||||
|
||||
@@ -57,26 +46,29 @@ class FileHandler(bbctrl.APIHandler):
|
||||
self.get_ctrl().preplanner.delete_plans(filename)
|
||||
self.get_ctrl().state.remove_file(filename)
|
||||
|
||||
|
||||
def put_ok(self, *args):
|
||||
gcode = self.request.files['gcode'][0]
|
||||
filename = os.path.basename(gcode['filename'].replace('\\', '/'))
|
||||
filename = filename.replace('#', '-').replace('?', '-')
|
||||
if not os.path.exists(self.get_upload()):
|
||||
os.mkdir(self.get_upload())
|
||||
|
||||
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)
|
||||
|
||||
with open(self.get_upload(filename).encode('utf8'), 'wb') as f:
|
||||
f.write(gcode['body'])
|
||||
os.sync()
|
||||
self.uploadFile.close()
|
||||
|
||||
self.get_ctrl().preplanner.invalidate(filename)
|
||||
self.get_ctrl().state.add_file(filename)
|
||||
self.get_log('FileHandler').info('GCode received: ' + filename)
|
||||
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):
|
||||
if not filename: raise HTTPError(400, 'Missing filename')
|
||||
if not filename:
|
||||
raise HTTPError(400, 'Missing filename')
|
||||
filename = os.path.basename(filename)
|
||||
|
||||
try:
|
||||
@@ -84,6 +76,7 @@ class FileHandler(bbctrl.APIHandler):
|
||||
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.")
|
||||
raise HTTPError(
|
||||
400, "Unable to read file - doesn't appear to be GCode.")
|
||||
|
||||
self.get_ctrl().state.select_file(filename)
|
||||
|
||||
Reference in New Issue
Block a user