Skip to content

Commit e7c265a

Browse files
committed
✨ Add default projects
1 parent f4a61bc commit e7c265a

14 files changed

Lines changed: 257 additions & 11 deletions

File tree

backend/config/defaultProjects/Single Year Example.urbs

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

backend/config/defaultProjectsLoaded/Simple Example.urbs

Lines changed: 1 addition & 0 deletions
Large diffs are not rendered by default.

backend/projects/api/configupload.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ def upload(request, project_name):
4848
if Project.objects.filter(user=request.user, name=project_name).exists():
4949
return HttpResponse("Project name already exists", status=409)
5050

51-
config = json.loads(request.body)
51+
readConfig(request.user, project_name, json.loads(request.body))
52+
return HttpResponse("Project created")
53+
54+
55+
def readConfig(user, project_name, config):
5256
if "CO2 limit" in config["global"]:
5357
co2limit = config["global"]["CO2 limit"]
5458
else:
@@ -58,7 +62,7 @@ def upload(request, project_name):
5862
else:
5963
costlimit = 35000000000
6064
project = Project(
61-
user=request.user, name=project_name, co2limit=co2limit, costlimit=costlimit
65+
user=user, name=project_name, co2limit=co2limit, costlimit=costlimit
6266
)
6367
project.save()
6468

@@ -96,7 +100,7 @@ def upload(request, project_name):
96100

97101
if "demand" in dataCommodity:
98102
demand = Demand(
99-
name="",
103+
name="imported",
100104
commodity=commodity,
101105
description="",
102106
steps=dataCommodity["demand"],
@@ -222,5 +226,3 @@ def upload(request, project_name):
222226
steps=dataBuySellPrice,
223227
)
224228
buysellprice.save()
225-
226-
return HttpResponse("Project created")

backend/projects/api/excelupload.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ def upload(request, project_name):
163163
site, com = key.split(".")
164164
demand = Demand(
165165
commodity=coms[site][com],
166-
name="Sum",
166+
name="imported",
167167
quantity=1,
168168
steps=demand_tab[key].tolist()[1::],
169169
)
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from django.contrib.auth.models import AbstractUser
2+
from django.http import HttpResponse, JsonResponse
3+
4+
from projects.api.configupload import readConfig
5+
from projects.models import Project, DefProjectLoaded, DefProject
6+
7+
8+
def initUser(user: AbstractUser):
9+
for default in DefProjectLoaded.objects.all():
10+
readConfig(user, default.preset.name, default.preset.config)
11+
12+
13+
def list_def_projects(_):
14+
defs = list(DefProject.objects.order_by("name").values("name").all())
15+
return JsonResponse(defs, safe=False)
16+
17+
18+
def load_default(request, project_name):
19+
preset = DefProject.objects.get(name=project_name)
20+
21+
if Project.objects.filter(user=request.user, name=project_name).exists():
22+
return HttpResponse("A project with this name already exists", status=409)
23+
if project_name == "__new":
24+
return HttpResponse("Invalid name", status=400)
25+
26+
readConfig(request.user, project_name, preset.config)
27+
28+
return HttpResponse("Project created")

backend/projects/management/commands/load_config.py

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
DefStorage,
1414
DefSupIm,
1515
DefDemand,
16+
DefProject,
17+
DefProjectLoaded,
1618
)
1719

1820

@@ -31,8 +33,8 @@ def handle(self, *args, **options):
3133
demands = {}
3234

3335
for filename in os.listdir(folder_path):
34-
if filename.endswith(".json"):
35-
file_path = os.path.join(folder_path, filename)
36+
file_path = os.path.join(folder_path, filename)
37+
if os.path.isfile(file_path) and filename.endswith(".json"):
3638
try:
3739
with open(file_path, "r") as file:
3840
print(f"Loading {filename}... ", end="")
@@ -218,6 +220,53 @@ def handle(self, *args, **options):
218220
def_demand.save()
219221
print("\033[92mOK\033[0m")
220222

223+
DefProject.objects.all().delete()
224+
for filename in os.listdir(os.path.join(folder_path, "defaultProjects")):
225+
file_path = os.path.join(folder_path, "defaultProjects", filename)
226+
if os.path.isfile(file_path) and filename.endswith(".urbs"):
227+
try:
228+
with open(file_path, "r") as file:
229+
name = ".".join(filename.split(".")[:-1])
230+
print(f"Loading default project {name}... ", end="")
231+
data = json.load(file)
232+
233+
preset = DefProject()
234+
preset.name = name
235+
preset.config = data
236+
preset.save()
237+
238+
print("\033[92mOK\033[0m")
239+
except Exception as e:
240+
self.stdout.write(
241+
self.style.ERROR(f"Error processing file {filename}: {e}")
242+
)
243+
exit(1)
244+
245+
for filename in os.listdir(os.path.join(folder_path, "defaultProjectsLoaded")):
246+
file_path = os.path.join(folder_path, "defaultProjectsLoaded", filename)
247+
if os.path.isfile(file_path) and filename.endswith(".urbs"):
248+
try:
249+
with open(file_path, "r") as file:
250+
name = ".".join(filename.split(".")[:-1])
251+
print(f"Loading default project (loaded) {name}... ", end="")
252+
data = json.load(file)
253+
254+
preset = DefProject()
255+
preset.name = name
256+
preset.config = data
257+
preset.save()
258+
259+
default = DefProjectLoaded()
260+
default.preset = preset
261+
default.save()
262+
263+
print("\033[92mOK\033[0m")
264+
except Exception as e:
265+
self.stdout.write(
266+
self.style.ERROR(f"Error processing file {filename}: {e}")
267+
)
268+
exit(1)
269+
221270

222271
def getDefault(dict, key, default):
223272
if key in dict:
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Generated by Django 5.1.4 on 2025-07-07 10:48
2+
3+
import django.db.models.deletion
4+
import uuid
5+
from django.db import migrations, models
6+
7+
8+
class Migration(migrations.Migration):
9+
10+
dependencies = [
11+
('projects', '0009_remove_buysellprice_type'),
12+
]
13+
14+
operations = [
15+
migrations.CreateModel(
16+
name='DefProject',
17+
fields=[
18+
('name', models.CharField(max_length=255, primary_key=True, serialize=False, unique=True)),
19+
('config', models.JSONField()),
20+
],
21+
),
22+
migrations.CreateModel(
23+
name='DefProjectLoaded',
24+
fields=[
25+
('id', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)),
26+
('preset', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='projects.defproject')),
27+
],
28+
),
29+
]

backend/projects/models.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,3 +303,13 @@ class SimulationResult(models.Model):
303303
status = models.IntegerField(choices=SimulationResultStatus.choices(), null=True)
304304
result = models.JSONField(null=True)
305305
log = models.TextField(null=True)
306+
307+
308+
class DefProject(models.Model):
309+
name = models.CharField(primary_key=True, max_length=255, null=False, unique=True)
310+
config = models.JSONField(null=False)
311+
312+
313+
class DefProjectLoaded(models.Model):
314+
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
315+
preset = models.ForeignKey(DefProject, on_delete=models.CASCADE, null=False)

backend/projects/urls.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
dsm,
1616
buysellprice,
1717
timevareff,
18+
projectpresets,
1819
)
1920

2021
urlpatterns = [
@@ -178,4 +179,13 @@
178179
"project/<str:project_name>/configupload/",
179180
configupload.upload,
180181
),
182+
# default projects
183+
path(
184+
"def_projects/",
185+
projectpresets.list_def_projects,
186+
),
187+
path(
188+
"def_projects/<str:project_name>/load/",
189+
projectpresets.load_default,
190+
),
181191
]

backend/security/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from django.views.decorators.csrf import ensure_csrf_cookie
1111
from django.views.decorators.http import require_POST
1212

13+
from projects.api.projectpresets import initUser
14+
1315

1416
def get_csrf(request):
1517
response = JsonResponse({"detail": "CSRF cookie set"})
@@ -67,7 +69,9 @@ def register(request):
6769
return JsonResponse({"detail": "Password is too short"}, status=400)
6870

6971
try:
70-
User.objects.create_user(**data).save()
72+
user = User.objects.create_user(**data)
73+
user.save()
74+
initUser(user)
7175
except IntegrityError:
7276
return JsonResponse(
7377
{"detail": "User with this name already exists"}, status=409

0 commit comments

Comments
 (0)