def prepare(self): if self.request.method.upper() == 'POST': if 'expected_size' in self.request.arguments: self.request.connection.set_max_body_size( int(self.get_argument('expected_size'))) try: total = int(self.request.headers.get("Content-Length", "0")) except KeyError: total = 0 self.multipart_streamer = MultiPartStreamer(total)
def prepare(self): if self.request.method.lower() == "post": # Set this request's max_body_size to 20 GB self.request.connection.set_max_body_size(20 * self.GB) try: total = int(self.request.headers.get("Content-Length", "0")) except KeyError: total = 0 self.ps = MultiPartStreamer(total) print 'Upload Video Prepared'
class UploadVideoHandler(BaseHandler): """ @api {post} /uploadVideo/ Upload Video @apiName UploadVideo @apiVersion 0.2.0 @apiGroup Upload @apiDescription This route will create a new project and upload a video to it. @apiParam {File} video The video file to analyze. This can have any file extension. @apiSuccess {String} identifier The project identifier. This will be used to reference the project in all other requests. @apiError error_message The error message to display. """ def prepare(self): if self.request.method.lower() == "post": # Set this request's max_body_size to 20 GB self.request.connection.set_max_body_size(20 * self.GB) try: total = int(self.request.headers.get("Content-Length", "0")) except KeyError: total = 0 self.ps = MultiPartStreamer(total) print 'Upload Video Prepared' def data_received(self, chunk): self.ps.data_received(chunk) def post(self): try: self.ps.data_complete() # If multiple files called "video" are sent, we pick the first one video_part = self.ps.get_parts_by_name("video")[0] self.identifier = str(uuid4()) if video_part: create_project(self.identifier, video_part) else: print "video_part was None" self.error_message = "Error decoding video upload" raise tornado.web.HTTPError(status_code=500) except Exception as e: print "could not complete streaming of data parts" self.error_message = "Error uploading video: " + str(e) raise tornado.web.HTTPError(status_code=500) finally: self.ps.release_parts() self.write({'identifier': self.identifier}) self.finish()
class UploadHandler(tornado.web.RequestHandler): """ Upload log file Tornado request handler: handles page requests and POST data """ def initialize(self): self.multipart_streamer = None def prepare(self): if self.request.method.upper() == 'POST': if 'expected_size' in self.request.arguments: self.request.connection.set_max_body_size( int(self.get_argument('expected_size'))) try: total = int(self.request.headers.get("Content-Length", "0")) except KeyError: total = 0 self.multipart_streamer = MultiPartStreamer(total) def data_received(self, data): if self.multipart_streamer: self.multipart_streamer.data_received(data) def get(self): template = _ENV.get_template(UPLOAD_TEMPLATE) self.write(template.render()) def post(self): if self.multipart_streamer: try: self.multipart_streamer.data_complete() form_data = self.multipart_streamer.get_values([ 'description', 'email', 'allowForAnalysis', 'obfuscated', 'source', 'type', 'feedback', 'windSpeed', 'rating', 'videoUrl', 'public', 'vehicleName' ]) description = cgi.escape( form_data['description'].decode("utf-8")) email = form_data['email'].decode("utf-8") upload_type = 'personal' if 'type' in form_data: upload_type = form_data['type'].decode("utf-8") source = 'webui' title = '' # may be used in future... if 'source' in form_data: source = form_data['source'].decode("utf-8") obfuscated = 0 if 'obfuscated' in form_data: if form_data['obfuscated'].decode("utf-8") == 'true': obfuscated = 1 allow_for_analysis = 0 if 'allowForAnalysis' in form_data: if form_data['allowForAnalysis'].decode("utf-8") == 'true': allow_for_analysis = 1 feedback = '' if 'feedback' in form_data: feedback = cgi.escape( form_data['feedback'].decode("utf-8")) wind_speed = -1 rating = '' stored_email = '' video_url = '' is_public = 0 vehicle_name = '' if upload_type == 'flightreport': try: wind_speed = int( cgi.escape(form_data['windSpeed'].decode("utf-8"))) except ValueError: wind_speed = -1 rating = cgi.escape(form_data['rating'].decode("utf-8")) if rating == 'notset': rating = '' stored_email = email # get video url & check if valid video_url = cgi.escape( form_data['videoUrl'].decode("utf-8"), quote=True) if not validate_url(video_url): video_url = '' if 'vehicleName' in form_data: vehicle_name = cgi.escape( form_data['vehicleName'].decode("utf-8")) # always allow for statistical analysis allow_for_analysis = 1 if 'public' in form_data: if form_data['public'].decode("utf-8") == 'true': is_public = 1 file_obj = self.multipart_streamer.get_parts_by_name( 'filearg')[0] upload_file_name = file_obj.get_filename() while True: log_id = str(uuid.uuid4()) new_file_name = get_log_filename(log_id) if not os.path.exists(new_file_name): break # read file header & check if really an ULog file header_len = len(ULog.HEADER_BYTES) if (file_obj.get_payload_partial(header_len) != ULog.HEADER_BYTES): if upload_file_name[-7:].lower() == '.px4log': raise CustomHTTPError( 400, 'Invalid File. This seems to be a px4log file. ' 'Upload it to <a href="http://logs.uaventure.com" ' 'target="_blank">logs.uaventure.com</a>.') raise CustomHTTPError(400, 'Invalid File') print('Moving uploaded file to', new_file_name) file_obj.move(new_file_name) if obfuscated == 1: # TODO: randomize gps data, ... pass # generate a token: secure random string (url-safe) token = str(binascii.hexlify(os.urandom(16)), 'ascii') # Load the ulog file but only if not uploaded via CI. # Then we open the DB connection. ulog = None if source != 'CI': ulog_file_name = get_log_filename(log_id) ulog = load_ulog_file(ulog_file_name) # put additional data into a DB con = sqlite3.connect(get_db_filename()) cur = con.cursor() cur.execute( 'insert into Logs (Id, Title, Description, ' 'OriginalFilename, Date, AllowForAnalysis, Obfuscated, ' 'Source, Email, WindSpeed, Rating, Feedback, Type, ' 'videoUrl, Public, Token) values ' '(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [ log_id, title, description, upload_file_name, datetime.datetime.now(), allow_for_analysis, obfuscated, source, stored_email, wind_speed, rating, feedback, upload_type, video_url, is_public, token ]) if ulog is not None: update_vehicle_db_entry(cur, ulog, log_id, vehicle_name) con.commit() url = '/plot_app?log=' + log_id full_plot_url = 'http://' + get_domain_name() + url delete_url = 'http://'+get_domain_name()+ \ '/edit_entry?action=delete&log='+log_id+'&token='+token if upload_type == 'flightreport' and is_public: send_flightreport_email( email_notifications_config['public_flightreport'], full_plot_url, description, feedback, DBData.rating_str_static(rating), DBData.wind_speed_str_static(wind_speed), delete_url, stored_email) # also generate the additional DB entry # (we may have the log already loaded in 'ulog', however the # lru cache will make it very quick to load it again) generate_db_data_from_log_file(log_id, con) con.commit() cur.close() con.close() # TODO: now that we have loaded the ulog already, add more # information to the notification email (airframe, ...) # send notification emails send_notification_email(email, full_plot_url, description, delete_url) # do not redirect for QGC if source != 'QGroundControl': self.redirect(url) except CustomHTTPError: raise except: print('Error when handling POST data', sys.exc_info()[0], sys.exc_info()[1]) raise CustomHTTPError(500) finally: self.multipart_streamer.release_parts() def write_error(self, status_code, **kwargs): html_template = """ <html><title>Error {status_code}</title> <body>HTTP Error {status_code}{error_message}</body> </html> """ error_message = '' if 'exc_info' in kwargs: e = kwargs["exc_info"][1] if isinstance(e, CustomHTTPError) and e.error_message: error_message = ': ' + e.error_message self.write( html_template.format(status_code=status_code, error_message=error_message))
class UploadHandler(tornado.web.RequestHandler): def initialize(self): self.ps = None def prepare(self): if self.request.method.upper() == 'POST': if 'expected_size' in self.request.arguments: self.request.connection.set_max_body_size( int(self.get_argument('expected_size'))) try: total = int(self.request.headers.get("Content-Length", "0")) except KeyError: total = 0 self.ps = MultiPartStreamer(total) def data_received(self, data): if self.ps: self.ps.data_received(data) def get(self): template = env.get_template(UPLOAD_TEMPLATE) self.write(template.render()) def post(self): if self.ps: try: self.ps.data_complete() form_data = self.ps.get_values([ 'description', 'email', 'allowForAnalysis', 'obfuscated', 'source' ]) description = cgi.escape( form_data['description'].decode("utf-8")) email = form_data['email'].decode("utf-8") source = 'webui' title = '' # may be used in future... if 'source' in form_data: source = form_data['source'].decode("utf-8") obfuscated = 0 if 'obfuscated' in form_data: if form_data['obfuscated'].decode("utf-8") == 'true': obfuscated = 1 allow_for_analysis = 0 if 'allowForAnalysis' in form_data: if form_data['allowForAnalysis'].decode("utf-8") == 'true': allow_for_analysis = 1 file_obj = self.ps.get_parts_by_name('filearg')[0] upload_file_name = file_obj.get_filename() while True: log_id = str(uuid.uuid4()) new_file_name = get_log_filename(log_id) if not os.path.exists(new_file_name): break # read file header & check if really an ULog file header_len = len(ULog.HEADER_BYTES) if (file_obj.get_payload_partial(header_len) != ULog.HEADER_BYTES): if upload_file_name[-7:].lower() == '.px4log': raise CustomHTTPError( 400, 'Invalid File. This seems to be a px4log file. ' 'Upload it to <a href="http://logs.uaventure.com" ' 'target="_blank">logs.uaventure.com</a>.') raise CustomHTTPError(400, 'Invalid File') print('Moving uploaded file to', new_file_name) file_obj.move(new_file_name) if obfuscated == 1: # TODO: randomize gps data, ... pass # put additional data into a DB con = sqlite3.connect(get_db_filename()) cur = con.cursor() cur.execute( 'insert into Logs (Id, Title, Description, ' 'OriginalFilename, Date, AllowForAnalysis, Obfuscated, ' 'Source) values (?, ?, ?, ?, ?, ?, ?, ?)', [ log_id, title, description, upload_file_name, datetime.datetime.now(), allow_for_analysis, obfuscated, source ]) con.commit() cur.close() con.close() url = '/plot_app?log=' + log_id send_notification_email(email, 'http://' + get_domain_name() + url, description) # do not redirect for QGC if not source == 'QGroundControl': self.redirect(url) except CustomHTTPError: raise except: print('Error when handling POST data', sys.exc_info()[0], sys.exc_info()[1]) raise CustomHTTPError(500) finally: self.ps.release_parts() def write_error(self, status_code, **kwargs): html_template = """ <html><title>Error {status_code}</title> <body>HTTP Error {status_code}{error_message}</body> </html> """ error_message = '' if 'exc_info' in kwargs: e = kwargs["exc_info"][1] if isinstance(e, CustomHTTPError) and e.error_message: error_message = ': ' + e.error_message self.write( html_template.format(status_code=status_code, error_message=error_message))