Skip to content

Commit

Permalink
Merge pull request #77 from TheVindicators/rework
Browse files Browse the repository at this point in the history
Polish up network calls with Jquery AJAX, Re-implement OpenFlight conversions, fix SpotLight bug
  • Loading branch information
cade9522 authored Nov 22, 2017
2 parents 2a74793 + f3dbd95 commit 981dad6
Show file tree
Hide file tree
Showing 12 changed files with 174 additions and 103 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ config.py
vis.sock
vis.log
app/json_save_states
app/conversion_work

# Mac stuff
.DS_Store
Expand Down
7 changes: 6 additions & 1 deletion app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,16 @@ def create_app(config_name):
app.config.from_object(config[config_name])
config[config_name].init_app

#create server-side save state directory if it doesn't exist
if not os.path.exists(app.config["JSON_STORE_DATA"]):
os.makedirs(app.config["JSON_STORE_DATA"])

#create server-side file conversion directory if it doesn't exist
if not os.path.exists(app.config["FILE_CONVERSION_WORK_DIR"]):
os.makedirs(app.config["FILE_CONVERSION_WORK_DIR"])

#properly expose IP addresses if being reversed proxy
# app.wsgi_app = ProxyFix(app.wsgi_app)
#app.wsgi_app = ProxyFix(app.wsgi_app)

#Register main web interface as blueprint
from main import main as main_blueprint
Expand Down
45 changes: 30 additions & 15 deletions app/rest/views.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from flask import render_template, request, current_app
from flask import render_template, request, current_app, jsonify
from werkzeug.utils import secure_filename
from . import rest
import json, uuid, os
import json, uuid, os, subprocess, time


#This URL (website.com/rest/debug) is used to test the website and provide debug output. It's really only a developer tool.
Expand All @@ -17,7 +17,18 @@ def rest_debug():
#javascript requests is an absolute must to prevent client lockup.
@rest.route('/convert_object', methods=["GET", "POST"])
def convert_object():
return "<json file of converted object here>"
if request.method == "POST":
try:
file_data = request.data
temp_file_name = str(int(time.time()))
with open(current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".flt", 'w+') as flt_file:
flt_file.write(file_data)
print "osgconv " + current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".flt " + current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".obj"
subprocess.check_output("osgconv " + current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".flt " + current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".obj", shell=True)
with open(current_app.config["FILE_CONVERSION_WORK_DIR"] + temp_file_name + ".obj", 'r') as converted_file:
return converted_file.read()
except Exception as e:
return str(e)



Expand All @@ -40,31 +51,35 @@ def save_state():
with open(current_app.config["JSON_STORE_DATA"] + secure_filename(str(state["project"]["uuid"])) + ".json", 'w+') as save_state_file:
save_state_file.write(json.dumps(state))
print "I'm saving: " + state["project"]["uuid"]
return state["project"]["uuid"] #Return the UUID if successful. This is used by the client to receive the UUID on the first initial save.
except:
return "FAIL" #Something went wrong. Let's be purposely dense about what went wrong.
return "FAIL" #How'd we get here? Someone trying to load the page?
return jsonify({"results": "SUCCESS", "uuid": state["project"]["uuid"]}) #Return the UUID if successful. This is used by the client to receive the UUID on the first initial save.
except IOError as error: #Disk error on save
return jsonify({"results": "FAIL", "reason": "IOERROR", "error": str(error.errno), "errorstring": str(error.strerror)})
except TypeError as error: #Save state format error
return jsonify({"results": "FAIL", "reason": "BADPOST", "error": str(error)})
except Exception as error: #Other general error
return jsonify({"results": "FAIL", "reason": "OTHER", "error": str(error)})
return jsonify({"results": "FAIL", "reason": "NOTPOST"}) #How'd we get here? Someone trying to load the page?


#This URL (website.com/rest/resume_state) is used to fetch the JSON file of the state requested by the user.
#The user requests the UUID of the specific JSON file, which is fetched and dumped back to client.
#JSON schema TBD
@rest.route('/resume_state/', methods=["GET", "POST"])
@rest.route('/resume_state', methods=["GET", "POST"])
@rest.route('/resume_state/<uuid>', methods=["GET", "POST"])
def resume_state(uuid=None):
if uuid == None: #We're looking to see which save states we have
states = ""
try:
for save_state in os.listdir(current_app.config["JSON_STORE_DATA"]):
states += save_state[:-5] + "," #Only return the UUID, remove .json ending
return str(states[:-1])
except:
return "FAIL" #Something went wrong. Let's be purposely dense about what went wrong.
if save_state[-5:] == ".json":
states += save_state[:-5] + "," #Only return the UUID, remove .json ending
return jsonify({"results": "SUCCESS", "data": str(states[:-1])})
except Exception as error: #There was an error listing the directory, return general error
return jsonify({"results": "FAIL", "reason": "OTHER", "error": str(error)})
else: #We're requesting a specific UUID to resume from.
try:

with open(current_app.config["JSON_STORE_DATA"] + secure_filename(str(uuid))+ ".json", 'r') as save_state_file:
return save_state_file.read()
except:
return "FAIL"
except Exception as error: #Other general error
return jsonify({"results": "FAIL", "reason": "OTHER", "error": str(error)})
return "FAIL" #How'd we get here?
37 changes: 18 additions & 19 deletions app/static/js/Editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -494,25 +494,24 @@ Editor.prototype = {

var objects = this.scene.children;

this.scene.length = 0;
this.scene.wingspan = 0;
this.scene.height = 0;
this.scene.x_max = 0;
this.scene.x_min = 0;
this.scene.y_max = 0;
this.scene.y_min = 0;
this.scene.z_max = 0;
this.scene.z_min = 0;
this.scene.z_short = 0;
this.scene.y_short = 0;
this.scene.antennaSnapping = false;
this.scene.x_short = [0, 0, 0, 0];
this.scene.y_short = [0, 0, 0, 0];
this.scene.z_short = [0, 0, 0, 0];
this.scene.menu = [null, null, null, null];
this.scene.posi = [0, 0, 0, 0];
this.scene.rota = [0, 0, 0 ,0];
this.scene.scal = [0, 0, 0, 0];
this.scene.length = 0;
this.scene.wingspan = 0;
this.scene.height = 0;
this.scene.x_max = 0;
this.scene.x_min = 0;
this.scene.y_max = 0;
this.scene.y_min = 0;
this.scene.z_max = 0;
this.scene.z_min = 0;
this.scene.z_short = 0;
this.scene.y_short = 0;
this.scene.antennaSnapping = false;
this.scene.x_short = [0, 0, 0, 0];
this.scene.y_short = [0, 0, 0, 0];
this.scene.z_short = [0, 0, 0, 0];
this.scene.posi = [0, 0, 0, 0];
this.scene.rota = [0, 0, 0 ,0];
this.scene.scal = [0, 0, 0, 0];

while ( objects.length > 0 ) {

Expand Down
21 changes: 21 additions & 0 deletions app/static/js/Loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,27 @@ var Loader = function ( editor ) {

break;

case 'flt':
$.ajax({
url: '/rest/convert_object',
data: file,
processData: false,
contentType: false,
dataType: "text",
success: function(data) {
console.log("Loading converted FLT->OBJ");
var object = new THREE.OBJLoader().parse( data );
object.name = filename;
editor.execute( new AddObjectCommand( object ) );
editor.setModel( object );
},
error: function() {
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to send file to server. ');
},
type: 'POST'
});
break;

case 'glb':
case 'gltf':

Expand Down
45 changes: 30 additions & 15 deletions app/static/js/Menubar.File.js
Original file line number Diff line number Diff line change
Expand Up @@ -116,22 +116,37 @@ Menubar.File = function ( editor ) {
fileInput.addEventListener( 'change', function ( event ) {

editor.loader.loadFile( fileInput.files[ 0 ] );
form.reset();

var color = 0xffffff; // create spotlight when new model imported
var intensity = 1;
var distance = 0;
var angle = Math.PI * 0.1;
var penumbra = 0;

var light = new THREE.SpotLight( color, intensity, distance, angle, penumbra );
light.name = 'SpotLight';
light.target.name = 'SpotLight Target';

light.position.set( 0, 5500, 5000 );

editor.execute( new AddObjectCommand( light ) );
if ( editor.scene.children.length == 0 ) {
var color = 0xffffff; // create spotlight when new model imported
var intensity = 1;
var distance = 0;
var angle = Math.PI * 0.1;
var penumbra = 0;
var light = new THREE.SpotLight( color, intensity, distance, angle, penumbra );
light.name = 'SpotLight';
light.target.name = 'SpotLight Target';
light.position.set( 0, 5500, 5000 );
editor.execute( new AddObjectCommand( light ) );
} else {
for( var i = 0; i < editor.scene.children.Length; i++ ) {
if ( editor.scene.children[i].type == "SpotLight" ) {
break;
} else if ( i == editor.scene.children.length - 1 ) {
var color = 0xffffff; // create spotlight when new model imported
var intensity = 1;
var distance = 0;
var angle = Math.PI * 0.1;
var penumbra = 0;
var light = new THREE.SpotLight( color, intensity, distance, angle, penumbra );
light.name = 'SpotLight';
light.target.name = 'SpotLight Target';
light.position.set( 0, 5500, 5000 );
editor.execute( new AddObjectCommand( light ) );
}
}
}

form.reset();
} );
form.appendChild( fileInput );

Expand Down
14 changes: 2 additions & 12 deletions app/static/js/Menubar.Help.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,13 @@ Menubar.Help = function ( editor ) {
options.setClass( 'options' );
container.add( options );

// Source code

var option = new UI.Row();
option.setClass( 'option' );
option.setTextContent( 'Source code' );
option.onClick( function () {

window.open( 'https://github.com/mrdoob/three.js/tree/master/editor', '_blank' )

} );
//options.add( option );

// About
// How To

var option = new UI.Row();
option.setClass( 'option' );
option.setTextContent( 'How To' );
option.setTextContent( 'How To Use' );
option.onClick( function () {

document.getElementById('readme').style.display = "block";
Expand Down
2 changes: 1 addition & 1 deletion app/static/js/Menubar.Status.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ Menubar.Status = function ( editor ) {

} );

var version = new UI.Text( 'prototype' );
var version = new UI.Text( 'v1.0.0' );
version.setClass( 'title' );
version.setOpacity( 0.5 );
container.add( version );
Expand Down
63 changes: 41 additions & 22 deletions app/static/js/Storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,24 @@ var Storage = function () {
get: function ( uuid, callback ) {

if (uuid != "None") {
var xhr = new XMLHttpRequest();

xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = JSON.parse(this.responseText);
callback(myArr);
}
};
xhr.open("GET", "/rest/resume_state/" + uuid, true);
xhr.send();
$.ajax({
url: '/rest/resume_state/' + uuid,
data: {
format: 'json'
},
dataType: 'json',
success: function (data) {
callback(data);
},
type: 'GET'
});
} else {
var transaction = database.transaction( [ 'states' ], 'readwrite' );
var objectStore = transaction.objectStore( 'states' );

var request = objectStore.get( 0 );
request.onsuccess = function ( event ) {

callback( event.target.result );

};
}

Expand All @@ -90,16 +89,36 @@ var Storage = function () {
var request = objectStore.put( data, 0 );



var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myArr = this.responseText;
callback(myArr);
}
};
xhr.open('POST', '/rest/save_state');
xhr.send(JSON.stringify(data));
$.ajax({
url: '/rest/save_state',
data: JSON.stringify(data),
contentType: "application/json",
dataType: "json",
success: function(data) {
if ( data.results == "SUCCESS" ) {
console.log('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Saved state to server as UUID', data.uuid);
if ( editor.project_uuid == "" ) {
editor.project_uuid = data.uuid; //Set the initial UUID if this the first save-state for this session.
}
} else {
if (data.reason == "IOERROR") {
// The server had a disk or permissions error. Let the user know
if (data.error == 13) { // No permission
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to save state to server. The server doesn\'t have permission to write to disk.');
} else if (data.error == 28) { // Disk full
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to save state to server. The server doesn\'t have enough space to save to disk.');
} else { //Other IO error
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to save state to server. There was an I/O Error.', data.errorstring);
}
} // Other error
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to save state to server.', data.reason, data.error);
}
},
error: function() {
console.error('[' + /\d\d\:\d\d\:\d\d/.exec(new Date())[0] + ']', 'Failed to save state to server. ');
},
type: 'POST'
});

//console.log(data);

Expand Down
4 changes: 4 additions & 0 deletions app/static/js/libs/jquery-3.2.1.min.js

Large diffs are not rendered by default.

Loading

0 comments on commit 981dad6

Please sign in to comment.