Skip to content
Draft
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
23 changes: 23 additions & 0 deletions factsheet/migrations/0012_locktable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Generated by Django 3.2.23 on 2024-02-26 07:41

from django.db import migrations, models
import django.utils.timezone


class Migration(migrations.Migration):

dependencies = [
('factsheet', '0011_scenariobundleaccesscontrol'),
]

operations = [
migrations.CreateModel(
name='LockTable',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('resource_name', models.CharField(max_length=400)),
('timeout_time', models.DateTimeField(default=django.utils.timezone.now)),
('transaction_id', models.CharField(max_length=400)),
],
),
]
5 changes: 5 additions & 0 deletions factsheet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,8 @@ class ScenarioBundleAccessControl(models.Model):
@classmethod
def load_by_uid(cls, uid):
return ScenarioBundleAccessControl.objects.filter(bundle_id=uid).first()

class LockTable(models.Model):
resource_name = CharField(max_length=400)
timeout_time = DateTimeField(default=timezone.now)
transaction_id = CharField(max_length=400)
63 changes: 59 additions & 4 deletions factsheet/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import sys
from owlready2 import get_ontology
from pathlib import Path
import datetime as dt

from rest_framework.decorators import (
api_view,
Expand All @@ -36,7 +37,7 @@

from django.contrib.auth.decorators import login_required

from .models import OEKG_Modifications, ScenarioBundleAccessControl
from .models import OEKG_Modifications, ScenarioBundleAccessControl, LockTable
from login import models as login_models

from factsheet.permission_decorator import only_if_user_is_owner_of_scenario_bundle
Expand Down Expand Up @@ -928,7 +929,7 @@ def update_factsheet(request, *args, **kwargs):
old_state=in_first.serialize(format="json-ld"),
new_state=in_second.serialize(format="json-ld"),
)
# OEKG_Modifications_instance.save()
OEKG_Modifications_instance.save()

response = JsonResponse(
"factsheet updated!", safe=False, content_type="application/json"
Expand Down Expand Up @@ -1426,8 +1427,7 @@ def delete_entities(request, *args, **kwargs):
return response


@login_required
def update_an_entity(request, *args, **kwargs):
def perform_entity_update(request, *args, **kwargs):
"""
Updates an entity in OEKG. The minimum requirements for updating an entity are the type, the old label, and the new label.

Expand Down Expand Up @@ -1465,6 +1465,28 @@ def update_an_entity(request, *args, **kwargs):
return response


@login_required
def update_an_entity(request, *args, **kwargs):
#find resource (entity) name
request_body = json.loads(request.body)
entity_iri = request_body["entity_iri"]

#generate transaction id
now = dt.datetime.now().isoformat(timespec="seconds")
t_id = "t_" + str(now)

if(acquire_lock(entity_iri, 300, t_id)): #if the entity is not locked
response = perform_entity_update(request, *args, **kwargs)
print("________________________ Entity edited successfully!")
release_lock(entity_iri, t_id)
return response
else:
print("________________________ Entity is currently being edited!")
response = JsonResponse(
"entity not updated!", safe=False, content_type="application/json")
return response


def get_all_factsheets(request, *args, **kwargs):
all_factsheets = []
for s, p, o in oekg.triples((None, RDF.type, OEO.OEO_00010252)):
Expand Down Expand Up @@ -1849,3 +1871,36 @@ def filter_scenario_view(request):
html_content = render(request, "partials/related_oekg_scenarios.html", context).content.decode("utf-8")
# Render the template with the context
return HttpResponse(html_content)

def acquire_lock(r_name: str, timeout_in_s: int, t_id: str) -> bool:
#retrieve existing lock for entity
existing_lock = LockTable.objects.filter(resource_name = r_name)

#get timeout time for new lock (based on timeout_in_s)
new_timeout = (dt.datetime.now(dt.timezone.utc) + dt.timedelta(seconds=timeout_in_s)).isoformat(
timespec="seconds")

if not (existing_lock): #if no lock exists, insert one
new_lock = LockTable(resource_name = r_name, timeout_time = new_timeout, transaction_id = t_id)
new_lock.save()
return True
else:
current_lock = LockTable.objects.get(resource_name = r_name)
currtimeout = current_lock.timeout_time #find timeout time for active lock
if(currtimeout < dt.datetime.now(dt.timezone.utc)): #if lock is timed out
current_lock.transaction_id = t_id
current_lock.timeout_time = new_timeout
current_lock.save()
return True
return False #if there's an active, not timed out lock, return False

def release_lock(r_name: str, t_id: str) -> bool:
try:
current_lock = LockTable.objects.get(resource_name = r_name)
current_lock.delete()
return True
except:
print("________________________ Could not Delete")
return False

LockTable