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
1 change: 1 addition & 0 deletions MyNewMethod
Submodule MyNewMethod added at 61879e
2 changes: 2 additions & 0 deletions app/blueprint.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from app.routes.setting import blp as setting_blueprint
from app.routes.simulation import blp as simulation_blueprint
from app.routes.receive import blp as receive_blueprint
from app.routes.user_preference import blp as user_preference_blueprint


# Register Blueprint
Expand All @@ -27,3 +28,4 @@ def register_routing(app):
api.register_blueprint(auralization_blueprint)
api.register_blueprint(setting_blueprint)
api.register_blueprint(receive_blueprint)
api.register_blueprint(user_preference_blueprint)
14 changes: 14 additions & 0 deletions app/models/UserPreference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
from datetime import datetime

from sqlalchemy import JSON

from app.db import db
from app.types import Setting, Status, ResourceType

class UserPreference(db.Model):
__tablename__ = "user_preferences"

id = db.Column(db.Integer, primary_key=True, autoincrement=True)
settings = db.Column(JSON, nullable=False)
createdAt = db.Column(db.String(), default=datetime.now())
updatedAt = db.Column(db.String(), default=datetime.now())
1 change: 1 addition & 0 deletions app/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@
from app.models.Simulation import Simulation
from app.models.SimulationRun import SimulationRun
from app.models.Task import Task
from app.models.UserPreference import UserPreference
10 changes: 10 additions & 0 deletions app/models/data/example_models.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[
{
"id": "1",
"name": "Measurement Room",
"description": "A description of Measurement Room.",
"thumbnailUrl": "/uploads/model_images/MeasurementRoom.png",
"fileName": "MeasurementRoom.obj",
"filePath": "example_models/MeasurementRoom.obj"
}
]
50 changes: 50 additions & 0 deletions app/models/data/example_projects.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
[
{
"project": {
"name": "Example Project",
"description": "Auto-generated example project via script",
"group": "Example Group"
},
"model": {
"directory": "example_models",
"fileName": "MeasurementRoom.obj",
"name": "MeasurementRoom",
"imagePath": "uploads/model_images/MeasurementRoom.png",
"imageFileName": "MeasurementRoom.png"
},
"simulation": {
"name": "Example Simulation",
"description": "Auto-generated simulation",
"simulationMethod": "DE",
"layerIdByMaterialId": {},
"sources": [{
"label": "Source 1",
"orderNumber": 1,
"x": 1.5,
"y": 1.5,
"z": 1.2
}],
"receivers": [
{
"label": "Receiver 1",
"orderNumber": 1,
"x": 3.0,
"y": 3.0,
"z": 1.0
}
],
"solverSettings": {
"simulationSettings": {
"sim_len_type": "edt",
"edt": 35,
"de_ir_length": 0.5,
"de_c0": 343,
"de_lc": 1
}
}
},
"material": {
"name": "Acoustic plaster 68 mm thick"
}
}
]
7 changes: 7 additions & 0 deletions app/models/data/user_preferences.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"settings": {
"hideSimulationSettingErrors": false
}
}
]
7 changes: 6 additions & 1 deletion app/routes/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from flask.views import MethodView
from flask_smorest import Blueprint, abort

from app.schemas.model_schema import ModelCreateSchema, ModelInfoSchema, ModelSchema, ModelUpdateSchema, ModelUploadImageResponseSchema
from app.schemas.model_schema import ModelCreateSchema, ModelInfoSchema, ModelSchema, ModelUpdateSchema, ModelUploadImageResponseSchema, ModelExampleSchema
from app.services import model_service

blp = Blueprint("Model", __name__, description="Model API")
Expand All @@ -22,6 +22,11 @@ class ModelUploadImage(MethodView):
def post(self):
return model_service.upload_image(request.files)

@blp.route("/models/examples")
class ModelUploadImage(MethodView):
@blp.response(200, ModelExampleSchema(many=True))
def get(self):
return model_service.get_example_models()

@blp.route("/models/<int:model_id>")
class Model(MethodView):
Expand Down
24 changes: 24 additions & 0 deletions app/routes/user_preference.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
from flask.views import MethodView
from flask_smorest import Blueprint

from app.schemas.user_preference_schema import (
UserPreferenceSchema,
UserPreferenceUpdateBodySchema,
)
from app.services import user_preference_service

blp = Blueprint("User Preference", __name__, description="User Preference API")

@blp.route("/user-preferences")
class UserPreference(MethodView):
@blp.response(200, UserPreferenceSchema(many=True))
def get(self):
return user_preference_service.get_all_user_preferences()

@blp.route("/user-preferences/<int:user_preference_id>")
class UserPreferenceDetail(MethodView):
@blp.arguments(UserPreferenceUpdateBodySchema)
@blp.response(200, UserPreferenceSchema)
def put(self, body_data, user_preference_id):
result = user_preference_service.update_user_preference(user_preference_id, body_data)
return result
11 changes: 10 additions & 1 deletion app/schemas/model_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,13 @@ class ModelUpdateSchema(Schema):
name = fields.Str(required=True)

class ModelUploadImageResponseSchema(Schema):
imagePath = fields.Str(required=True)
imagePath = fields.Str(required=True)

class ModelExampleSchema(Schema):
id = fields.Str(required=True)
name = fields.Str(required=True)
description = fields.Str(required=True)
thumbnailUrl = fields.Str(required=True)
fileName = fields.Str(required=True)
filePath = fields.Str(required=True)
modelUrl = fields.Str(required=True)
13 changes: 13 additions & 0 deletions app/schemas/user_preference_schema.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from marshmallow import Schema, fields


class UserPreferenceSchema(Schema):
id = fields.Integer()
settings = fields.Dict()
createdAt = fields.String()
updatedAt = fields.String()


class UserPreferenceUpdateBodySchema(Schema):
settings = fields.Dict()

76 changes: 76 additions & 0 deletions app/services/model_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,20 @@
import os
import uuid
import config
import shutil
import json

from flask_smorest import abort
from werkzeug.utils import secure_filename

from app.db import db
from app.models import Model
from config import FeatureToggle, DefaultConfig
from config import app_dir
from datetime import datetime

from app.services import file_service

# Create logger for this module
logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -127,3 +132,74 @@ def upload_image(files):
except Exception as ex:
logger.error(f"Error uploading image file: {ex}")
abort(500, message=f"Error uploading image file: {ex}")


def copy_example_models_to_uploads():
# 1. Define the path to the example models catalog JSON file
json_path = os.path.join(app_dir, "models", "data", "example_models.json")

if not os.path.exists(json_path):
logger.error(f"Catalog JSON not found at: {json_path}")
abort(404, "Example models catalog file not found.")

# 2. Read and parse the JSON data
with open(json_path, "r") as f:
example_models = json.load(f)

try:
# Ensure the main destination uploads folder exists before starting the loop
os.makedirs(config.DefaultConfig.UPLOAD_FOLDER, exist_ok=True)

# 3. Loop through each model item in the JSON array
for model_data in example_models:
src_relative_path = model_data.get("filePath")
if not src_relative_path:
logger.warning(f"Model ID {model_data.get('id')} is missing 'filePath'. Skipping.")
continue

src_absolute_path = os.path.join(config.basedir, src_relative_path)

# Validate if the source physical file actually exists
if not os.path.exists(src_absolute_path):
logger.error(f"Physical file not found at path: {src_absolute_path}")
abort(404, f"Example file for {model_data['name']} not found.")

# 4. Extract the file extension (.obj) and the base filename dynamically
_, file_extension = os.path.splitext(src_relative_path)
base_name = os.path.basename(src_relative_path).replace(file_extension, "")

unique_name = f"{base_name}{file_extension}"
dst_absolute_path = os.path.join(config.DefaultConfig.UPLOAD_FOLDER, unique_name)

# 6. Execute the physical file copy operation
shutil.copy2(src_absolute_path, dst_absolute_path)
logger.info(f"Successfully copied {model_data['name']} to: {dst_absolute_path}")

return {"message": "Initial full projects successfully!"}

except Exception as ex:
logger.error(f"Failed to execute example models copying method! Error: {ex}")
abort(500, f"Failed to process example models: {ex}")


def get_example_models():
json_path = os.path.join(app_dir, "models", "data", "example_models.json")

if not os.path.exists(json_path):
logger.error(f"Catalog JSON file not found at: {json_path}")
abort(404, "Example models catalog file not found.")

try:
with open(json_path, "r") as f:
example_models = json.load(f)

# Dynamically map and build the modelUrl for each item
for model in example_models:
base_url = file_service.upload_dir().rstrip("/")
model["modelUrl"] = f"{base_url}/{model['fileName']}"

return example_models

except Exception as ex:
logger.error(f"Failed to retrieve example models! Error: {ex}")
abort(500, "Internal server error while fetching example models.")
Loading
Loading