Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions API/Classes/Base/ModelVersionClass.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import logging

from Classes.Base.CustomExceptionClass import CustomException

CURRENT_MODEL_VERSION = "5.0"


class ModelVersionError(CustomException):
def __init__(self, message, case=None, detected_version=None, expected_version=None):
payload = {
"status_code": "version_mismatch",
"case": case,
"detected_version": detected_version,
"expected_version": expected_version or CURRENT_MODEL_VERSION,
}
CustomException.__init__(self, message, status_code=409, payload=payload)


def get_model_version(genData):
if not isinstance(genData, dict):
return None

version = genData.get("modelVersion")
if version is None:
version = genData.get("osy-version")

if version is None:
return None

version = str(version).strip()
return version or None


def stamp_model_version(genData, version=CURRENT_MODEL_VERSION):
if genData is None:
return genData

version = str(version).strip() or CURRENT_MODEL_VERSION
genData["modelVersion"] = version
genData["osy-version"] = version
return genData


def validate_model_version(genData, case=None):
detected_version = get_model_version(genData)

if detected_version == CURRENT_MODEL_VERSION:
return detected_version

if case:
case_label = f"Model <b>{case}</b>"
else:
case_label = "Selected model"

if detected_version is None:
message = (
f"{case_label} is missing schema version metadata. "
f"Open the model configuration page and click <b>Update model</b> "
f"before generating data or running the solver."
)
else:
message = (
f"{case_label} uses schema version <b>{detected_version}</b>, but the current backend "
f"expects <b>{CURRENT_MODEL_VERSION}</b>. Open the model configuration page and click "
f"<b>Update model</b> before generating data or running the solver."
)

logging.warning(
"Model version mismatch for case '%s': detected=%s expected=%s",
case,
detected_version,
CURRENT_MODEL_VERSION,
)
raise ModelVersionError(
message,
case=case,
detected_version=detected_version,
expected_version=CURRENT_MODEL_VERSION,
)
2 changes: 2 additions & 0 deletions API/Classes/Case/ImportTemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from Classes.Base import Config
from Classes.Case.CaseClass import Case
from Classes.Base.FileClass import File
from Classes.Base.ModelVersionClass import stamp_model_version

class ImportTemplate():
def __init__(self,template):
Expand Down Expand Up @@ -814,6 +815,7 @@ def importProcess(self, data):
genData["osy-scenarios"] = self.defaultScenario(True)
genData["osy-constraints"] = []
genData["osy-years"] = yearsArray
stamp_model_version(genData, version)

casename = genData['osy-casename']

Expand Down
2 changes: 2 additions & 0 deletions API/Classes/Case/OsemosysClass.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import shutil
from Classes.Base import Config
from Classes.Base.FileClass import File
from Classes.Base.ModelVersionClass import validate_model_version

class Osemosys():
def __init__(self, case):
self.case = case
self.PARAMETERS = File.readParamFile(Path(Config.DATA_STORAGE, 'Parameters.json'))
self.VARIABLES = File.readParamFile(Path(Config.DATA_STORAGE, 'Variables.json'))
self.genData = File.readFile(Path(Config.DATA_STORAGE,case,'genData.json'))
validate_model_version(self.genData, case)
self.resData = File.readFile( Path(Config.DATA_STORAGE, case,'view', 'resData.json'))

#Case.__init__(self, case)
Expand Down
2 changes: 2 additions & 0 deletions API/Routes/Case/CaseRoute.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import pandas as pd
from Classes.Base import Config
from Classes.Base.FileClass import File
from Classes.Base.ModelVersionClass import stamp_model_version
from Classes.Case.CaseClass import Case
from Classes.Case.UpdateCaseClass import UpdateCase
from Classes.Case.ImportTemplate import ImportTemplate
Expand Down Expand Up @@ -248,6 +249,7 @@ def updateData():
def saveCase():
try:
genData = request.json['data']
stamp_model_version(genData)
casename = genData['osy-casename']
case = session.get('osycase', None)

Expand Down
11 changes: 10 additions & 1 deletion API/Routes/Upload/UploadRoute.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from Classes.Base import Config
from Classes.Base.FileClass import File
from Classes.Base.ModelVersionClass import stamp_model_version

upload_api = Blueprint('UploadRoute', __name__)

Expand Down Expand Up @@ -138,6 +139,12 @@ def updateStorageSet(casename):

File.writeFile( genData, genDataPath)

def stampCurrentModelVersion(casename):
genDataPath = Path(Config.DATA_STORAGE, casename, 'genData.json')
genData = File.readParamFile(genDataPath)
stamp_model_version(genData)
File.writeFile(genData, genDataPath)

def updateViewDefintions(casename):
viewDataPath = Path(Config.DATA_STORAGE,casename,'view','viewDefinitions.json')
viewDefExisting = File.readParamFile(viewDataPath)
Expand Down Expand Up @@ -371,6 +378,7 @@ def uploadCaseUnchunked_old():
elif name == '5.0':
zf.extractall(os.path.join(Config.EXTRACT_FOLDER))
updateViewDefintions(casename)
stampCurrentModelVersion(casename)
msg.append({
"message": "Model " + casename +" have been uploaded!",
"status_code": "success",
Expand Down Expand Up @@ -511,6 +519,7 @@ def handle_full_zip(file, filepath=None):
elif name == '5.0':
zf.extractall(os.path.join(Config.EXTRACT_FOLDER))
updateViewDefintions(casename)
stampCurrentModelVersion(casename)
msg.append({
"message": "Model " + casename +" have been uploaded!",
"status_code": "success",
Expand Down Expand Up @@ -652,4 +661,4 @@ def uploadXls():
except(IOError):
raise IOError
except OSError:
raise OSError
raise OSError
11 changes: 6 additions & 5 deletions API/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#import json
from Classes.Base import Config
from Classes.Base.CustomExceptionClass import CustomException
# from API.Classes.Base.SyncS3 import SyncS3
from Routes.Upload.UploadRoute import upload_api
from Routes.Case.CaseRoute import case_api
Expand Down Expand Up @@ -97,11 +98,11 @@ def add_headers(response):
#response.headers['Content-Type'] = 'application/javascript'
return response

# @app.errorhandler(CustomException)
# def handle_invalid_usage(error):
# response = jsonify(error.to_dict())
# response.status_code = error.status_code
# return response
@app.errorhandler(CustomException)
def handle_invalid_usage(error):
response = jsonify(error.to_dict())
response.status_code = error.status_code
return response

#entry point to frontend
@app.route("/", methods=['GET'])
Expand Down
2 changes: 1 addition & 1 deletion WebAPP/App/Controller/AddCase.js
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,7 @@ export default class AddCase {
});

let POSTDATA = {
"modelVersion": "5.0",
"osy-version": "5.0",
"osy-casename": casename,
"osy-desc": desc,
Expand Down Expand Up @@ -1144,4 +1145,3 @@ export default class AddCase {




7 changes: 3 additions & 4 deletions WebAPP/App/Controller/Home.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,11 @@ export default class Home {
//Sidebar.Load(casename, model.genData, model.PARAMETERS);
Osemosys.getData(casename, 'genData.json')
.then(genData => {
//console.log('genData ', genData["osy-version"])
let modelVersion = parseFloat(genData.modelVersion || genData["osy-version"] || 0);
Home.refreshPage(casename);
Message.smallBoxInfo("Case selection", casename + " is selected!", 3000);
if(parseFloat(genData["osy-version"]) < 4.5){
//console.log('manje od 4.5')
Message.bigBoxWarning("Warning", "You have selected a model created in a earlier version of this UI. In order to update to the current version click <b>Update model</b> on the configuration page.", 10000);
if(modelVersion < 5.0){
Message.bigBoxWarning("Warning", "You have selected a model created with an older schema version. Open <b>Model configuration</b> and click <b>Update model</b> before generating data or running the solver.", 10000);
}
})
});
Expand Down
3 changes: 2 additions & 1 deletion WebAPP/App/Controller/LegacyImport.js
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export default class LegacyImport {
}

let POSTDATA = {
"modelVersion": "5.0",
"osy-version": "5.0",
"osy-casename": casename,
"osy-desc": desc,
Expand Down Expand Up @@ -154,4 +155,4 @@ export default class LegacyImport {
$('#definition').toggle('slow');
});
}
}
}
42 changes: 17 additions & 25 deletions WebAPP/Classes/Base.Class.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ import { Message } from "./Message.Class.js";
import { Html } from "./Html.Class.js";
import { SyncS3 } from "./SyncS3.Class.js";

function getApiError(xhr, error) {
if (xhr && xhr.responseJSON && xhr.responseJSON.message) {
return xhr.responseJSON.message;
}
return error;
}

export class Base {
static HEROKU = 0;
static AWS_SYNC = 0;
Expand Down Expand Up @@ -29,8 +36,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -50,8 +56,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -73,8 +78,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -93,9 +97,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }

reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -114,8 +116,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -134,8 +135,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -154,9 +154,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
//custom exception
if (xhr.responseJSON && xhr.responseJSON.message) { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -175,9 +173,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
//custom exception
if (xhr.responseJSON && xhr.responseJSON.message) { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -196,9 +192,7 @@ export class Base {
resolve(result);
},
error: function (xhr, status, error) {
//custom exception
if (error == 'UNKNOWN') { error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand All @@ -219,9 +213,7 @@ export class Base {
resolve(result);
},
error: function(xhr, status, error) {
//custom exception
if(error == 'UNKNOWN'){ error = xhr.responseJSON.message }
reject(error);
reject(getApiError(xhr, error));
}
});
});
Expand Down
Loading
Loading