from copy import deepcopy from typing import List, Optional from django.db import models, transaction from meanings.models import LexicalUnit, Synset from semantics.models import PredefinedSelectionalPreference, RelationalSelectionalPreference, ArgumentRole, \ RoleType, Argument, Frame, SelectionalPreferenceRelation from . import choices class UnifiedFrameQueryset(models.QuerySet): def for_lexical_unit(self, lexical_unit): return self.filter(unified_frame_2_slowal_frame__slowal_frame__lexical_units=lexical_unit) class UnifiedFrame(models.Model): status = models.TextField( max_length=10, choices=choices.UnifiedFrameStatus.choices, default=choices.UnifiedFrameStatus.PROCESSING, ) title = models.CharField(max_length=200, default=None, blank=True, null=True) objects = models.Manager.from_queryset(UnifiedFrameQueryset)() def sorted_arguments(self): # TODO: zaimplementowac wlasciwe sortowanie return UnifiedFrameArgument.objects.filter(frame=self) def __str__(self): return '%s: %s' % (self.opinion, ' + '.join([str(arg) for arg in self.sorted_arguments()])) @transaction.atomic def extract_frames_to( self, slowal_frames: List[Frame], new_frame: Optional["UnifiedFrame"] = None ) -> "UnifiedFrame": new_unified_frame_arguments = None if not new_frame: new_frame = UnifiedFrame.objects.create() new_frame.save() unified_frame_arguments = UnifiedFrameArgument.objects.filter(unified_frame=self) old_2_new_argument_mapping = {} for unified_frame_argument in unified_frame_arguments: new_unified_frame_argument = UnifiedFrameArgument.objects.create( role_type=unified_frame_argument.role_type, role=unified_frame_argument.role, unified_frame=new_frame) new_unified_frame_argument.proposed_roles.set(unified_frame_argument.proposed_roles.all()) new_unified_frame_argument.save() old_2_new_argument_mapping[unified_frame_argument.id] = new_unified_frame_argument.id else: new_unified_frame_arguments = UnifiedFrameArgument.objects.filter(unified_frame=new_frame).all() unified_frame_arguments = UnifiedFrameArgument.objects.filter(unified_frame=self).all() if len(new_unified_frame_arguments) < len(unified_frame_arguments): raise Exception('Target frame has to little arguments, required: ' + len(unified_frame_arguments)+', but found: '+len(new_unified_frame_arguments)) for slowal_frame in slowal_frames: mapping = UnifiedFrame2SlowalFrameMapping.objects.get(unified_frame=self, slowal_frame=slowal_frame) mapping.unified_frame = new_frame mapping.save() argument_mappings = UnifiedFrameArgumentSlowalFrameMapping.objects.filter(unified_frame_mapping=mapping) for i, argument_mapping in enumerate(argument_mappings): if new_unified_frame_arguments is None: argument_mapping.unified_agrument_id = old_2_new_argument_mapping[argument_mapping.unified_agrument_id] else: argument_mapping.unified_agrument_id = new_unified_frame_arguments[i] argument_mapping.save() # curr_mapping = UnifiedFrame2SlowalFrameMapping.objects.filter(unified_frame=self).all() # if len(curr_mapping) == 0: # unified_frame_arguments = UnifiedFrameArgument.objects.filter(unified_frame=self).all() # unified_frame_arguments.delete() # self.delete() return new_frame @transaction.atomic def duplicate( self, new_frame_title: Optional = None ) -> "UnifiedFrame": new_frame = UnifiedFrame.objects.create(title=new_frame_title) new_frame.save() unified_frame_arguments = UnifiedFrameArgument.objects.filter(unified_frame=self) for unified_frame_argument in unified_frame_arguments: new_unified_frame_argument = UnifiedFrameArgument.objects.create( role_type=unified_frame_argument.role_type, role=unified_frame_argument.role, unified_frame=new_frame) new_unified_frame_argument.proposed_roles.set(unified_frame_argument.proposed_roles.all()) new_unified_frame_argument.save() return new_frame class UnifiedFrameArgument(models.Model): role_type = models.ForeignKey(RoleType, on_delete=models.PROTECT, default=None, blank=True, null=True) #rola - wybrana przez użytkownika role = models.ForeignKey(ArgumentRole, on_delete=models.PROTECT, default=None, blank=True, null=True) #role zaproponowane przez system unifikacyjny proposed_roles = models.ManyToManyField(ArgumentRole, related_name='proposed_roles') #3 typy preferencji - wybrane przez użytkownika predefined = models.ManyToManyField(PredefinedSelectionalPreference) synsets = models.ManyToManyField(Synset) relations = models.ManyToManyField('UnifiedRelationalSelectionalPreference') #odwołanie do ramy unified_frame = models.ForeignKey(UnifiedFrame, related_name='unified_arguments', default=None, blank=True, null=True, on_delete=models.PROTECT) def __str__(self): return str(self.role) class UnifiedRelationalSelectionalPreference(models.Model): relation = models.ForeignKey(SelectionalPreferenceRelation, on_delete=models.PROTECT) to = models.ForeignKey(UnifiedFrameArgument,on_delete=models.PROTECT) def __str__(self): return '%s -> %s' % (self.relation, self.to) class UnifiedFrame2SlowalFrameMapping(models.Model): removed = models.BooleanField(default=False) unified_frame = models.ForeignKey(UnifiedFrame, related_name='unified_frame_2_slowal_frame', on_delete=models.PROTECT) slowal_frame = models.OneToOneField(Frame, related_name='slowal_frame_2_unified_frame', on_delete=models.PROTECT) class UnifiedFrameArgumentSlowalFrameMapping(models.Model): unified_agrument = models.ForeignKey(UnifiedFrameArgument, related_name='unified_agrument_mapping', on_delete=models.PROTECT) slowal_agrument = models.ForeignKey(Argument, related_name='slowal_agrument_mapping', on_delete=models.PROTECT) unified_frame_mapping = models.ForeignKey(UnifiedFrame2SlowalFrameMapping, related_name='unified_frame_argument_mapping', on_delete=models.PROTECT)