21
21
import base64
22
22
23
23
24
- def api_update_gloss_fields (dataset , language_code = 'en' ):
24
+ def names_of_update_gloss_fields (dataset , language_code ):
25
25
activate (language_code )
26
26
27
27
dataset_languages = dataset .translation_languages .all ()
@@ -32,18 +32,15 @@ def api_update_gloss_fields(dataset, language_code='en'):
32
32
33
33
language_fields = annotationidglosstranslation_fields + lemmaidglosstranslation_fields
34
34
35
- api_fields_2024 = []
36
- fieldnames = FIELDS ['main' ] + FIELDS ['phonology' ] + FIELDS ['semantics' ] + ['inWeb' , 'isNew' , 'excludeFromEcv' , 'senses' ]
35
+ verbose_field_names = []
36
+ fieldnames = FIELDS ['main' ] + FIELDS ['phonology' ] + FIELDS ['semantics' ] + ['inWeb' , 'isNew' , 'excludeFromEcv' ]
37
37
gloss_fields = [Gloss .get_field (fname ) for fname in fieldnames if fname in Gloss .get_field_names ()]
38
38
39
- # TO DO
40
- extra_columns = ['Sign Languages' , 'Dialects' ,
41
- 'Relations to other signs' , 'Relations to foreign signs' , 'Tags' , 'Notes' ]
42
-
39
+ activate (language_code )
43
40
for field in gloss_fields :
44
- api_fields_2024 .append (field .verbose_name .title ())
41
+ verbose_field_names .append (field .verbose_name .title ())
45
42
46
- return language_fields , api_fields_2024
43
+ return language_fields , verbose_field_names
47
44
48
45
49
46
def internal_language_fields (dataset , language_code ):
@@ -63,7 +60,7 @@ def internal_language_fields(dataset, language_code):
63
60
def update_gloss_columns_to_value_dict_keys (dataset , language_code ):
64
61
"""
65
62
Function to create mapping dictionaries for the different label representations
66
- Called from gloss_update
63
+ Called from gloss_pre_update
67
64
Representations:
68
65
1. Human readable labels (multilingual, with language name in parentheses)
69
66
2. JSON keys (multilingual, with colon before language name)
@@ -101,7 +98,7 @@ def update_gloss_columns_to_value_dict_keys(dataset, language_code):
101
98
human_readable_to_json [human_readable_lemma ] = lemma_api_field_name
102
99
human_readable_to_json [human_readable_annotation ] = annotation_api_field_name
103
100
104
- fieldnames = FIELDS ['main' ] + FIELDS ['phonology' ] + FIELDS ['semantics' ] + ['inWeb' , 'isNew' , 'excludeFromEcv' , 'senses' ]
101
+ fieldnames = FIELDS ['main' ] + FIELDS ['phonology' ] + FIELDS ['semantics' ] + ['inWeb' , 'isNew' , 'excludeFromEcv' ]
105
102
gloss_fields = [Gloss .get_field (fname ) for fname in fieldnames if fname in Gloss .get_field_names ()]
106
103
107
104
for field in gloss_fields :
@@ -116,21 +113,21 @@ def get_gloss_update_human_readable_value_dict(request):
116
113
value_dict = dict ()
117
114
for field in post_data .keys ():
118
115
value = post_data .get (field , '' )
119
- value_dict [field ] = value . strip ()
116
+ value_dict [field ] = value
120
117
return value_dict
121
118
122
119
123
120
def check_fields_can_be_updated (value_dict , dataset , language_code ):
124
- language_fields , api_fields_2024 = api_update_gloss_fields (dataset , language_code )
121
+ activate (language_code )
122
+ language_fields , gloss_fields = names_of_update_gloss_fields (dataset , language_code )
123
+ available_fields = language_fields + gloss_fields
125
124
errors = dict ()
126
125
for field in value_dict .keys ():
127
- if field not in api_fields_2024 and field not in language_fields :
128
- errors [field ] = _ ("Field update not available" )
129
- if field == "Senses" :
130
- new_senses , formatting_error_senses = convert_string_to_dict_of_list_of_lists (value_dict [field ])
131
- if formatting_error_senses :
132
- errors [field ] = formatting_error_senses
133
-
126
+ if field in gloss_fields or field in language_fields :
127
+ continue
128
+ errors [field ] = _ ("Field name not found in fields that can be updated." )
129
+ if errors :
130
+ errors ["Available Fields" ] = ", " .join (available_fields )
134
131
return errors
135
132
136
133
@@ -311,25 +308,29 @@ def detect_type_related_problems_for_gloss_update(changes, dataset, language_cod
311
308
continue
312
309
if field in language_fields :
313
310
continue
314
- if field in ['Senses' , 'senses' ]:
315
- continue
316
311
if isinstance (field , FieldChoiceForeignKey ):
317
312
field_choice_category = field .field_choice_category
318
313
try :
319
314
fieldchoice = FieldChoice .objects .get (field = field_choice_category , name__iexact = new_value )
315
+ continue
320
316
except (ObjectDoesNotExist , MultipleObjectsReturned ):
321
317
normalised_choice = normalize_field_choice (new_value )
322
318
try :
323
319
fieldchoice = FieldChoice .objects .get (field = field_choice_category , name__iexact = normalised_choice )
320
+ continue
324
321
except (ObjectDoesNotExist , MultipleObjectsReturned ):
325
322
errors [field .verbose_name .title ()] = gettext ('NOT FOUND: ' ) + new_value
326
- elif isinstance (field , models .ForeignKey ) and field .related_model == Handshape :
323
+ continue
324
+ if isinstance (field , models .ForeignKey ) and field .related_model == Handshape :
327
325
try :
328
326
handshape = Handshape .objects .get (name__iexact = new_value )
327
+ continue
329
328
except (ObjectDoesNotExist , MultipleObjectsReturned ):
330
329
errors [field .verbose_name .title ()] = gettext ('NOT FOUND: ' ) + new_value
331
- elif field .__class__ .__name__ == 'BooleanField' :
332
- if new_value not in ['true' , 'True' , 'TRUE' , 'false' , 'False' , 'FALSE' , 'Neutral' , 'None' ]:
330
+ continue
331
+ if field .__class__ .__name__ == 'BooleanField' :
332
+ normalised_boolean_string = new_value .lower ()
333
+ if normalised_boolean_string not in ['true' , 'false' , 'neutral' , 'ja' , 'nee' ]:
333
334
errors [field .verbose_name .title ()] = gettext ('NOT FOUND: ' ) + new_value
334
335
elif field .name == 'semField' :
335
336
type_check = type_check_multiselect ('SemField' , new_value , language_code )
@@ -517,50 +518,42 @@ def get_original_senses_value(gloss):
517
518
return senses_dict
518
519
519
520
520
- def gloss_update (gloss , update_fields_dict , language_code ):
521
+ def gloss_pre_update (gloss , input_fields_dict , language_code ):
521
522
522
523
dataset = gloss .lemma .dataset
523
- language_fields , api_fields_2024 = api_update_gloss_fields (dataset , language_code )
524
+ language_fields , gloss_fields = names_of_update_gloss_fields (dataset , language_code )
524
525
human_readable_to_internal , human_readable_to_json = update_gloss_columns_to_value_dict_keys (dataset , language_code )
525
- combined_fields = api_fields_2024
526
+ # initial value of fields is put in combined_fields variable
527
+ combined_fields = gloss_fields
526
528
for language_field in language_fields :
527
529
gloss_dict_language_field = human_readable_to_json [language_field ]
528
530
combined_fields .append (gloss_dict_language_field )
529
- gloss_data_dict = gloss .get_fields_dict (combined_fields , language_code )
531
+ # retrieve what the packages knows for these fields
532
+ gloss_package_data_dict = gloss .get_fields_dict (combined_fields , language_code )
530
533
fields_to_update = dict ()
531
- for human_readable_field , new_field_value in update_fields_dict .items ():
534
+ for human_readable_field , new_field_value in input_fields_dict .items ():
532
535
if not new_field_value :
533
536
continue
537
+ if human_readable_field not in gloss_package_data_dict .keys ():
538
+ # ignore the field if it's not visible to the API user
539
+ continue
540
+ original_value = gloss_package_data_dict [human_readable_field ]
541
+
534
542
if human_readable_field in language_fields :
535
543
gloss_language_field = human_readable_to_json [human_readable_field ]
536
- original_value = gloss_data_dict [gloss_language_field ]
537
544
gloss_field = human_readable_to_internal [human_readable_field ]
538
545
fields_to_update [gloss_field ] = (original_value , new_field_value )
539
546
continue
540
- if human_readable_field == 'Senses' :
541
- original_value = get_original_senses_value (gloss )
542
- new_senses , errors = convert_string_to_dict_of_list_of_lists (new_field_value )
543
- if errors :
544
- # already checked at a previous step
545
- continue
546
- if original_value != new_senses :
547
- fields_to_update [human_readable_field ] = (original_value , new_senses )
547
+ if human_readable_field not in human_readable_to_internal .keys ():
548
+ # if this field is not available, ignore it
548
549
continue
549
- elif human_readable_field not in gloss_data_dict .keys ():
550
- # new value
551
- original_value = ''
552
- gloss_field = human_readable_to_internal [human_readable_field ]
553
- fields_to_update [gloss_field ] = (original_value , new_field_value )
550
+ if original_value in ['False' ] and new_field_value in ['' , 'False' ]:
551
+ # treat empty as False
554
552
continue
555
- if human_readable_field in human_readable_to_internal .keys ():
556
- original_value = gloss_data_dict [human_readable_field ]
557
- if original_value in ['False' ] and new_field_value in ['' , 'False' ]:
558
- # treat empty as False
559
- continue
560
- if new_field_value == original_value :
561
- continue
562
- gloss_field = human_readable_to_internal [human_readable_field ]
563
- fields_to_update [gloss_field ] = (original_value , new_field_value )
553
+ if new_field_value == original_value :
554
+ continue
555
+ gloss_field = human_readable_to_internal [human_readable_field ]
556
+ fields_to_update [gloss_field ] = (original_value , new_field_value )
564
557
return fields_to_update
565
558
566
559
@@ -583,14 +576,14 @@ def api_update_gloss(request, datasetid, glossid):
583
576
errors [gettext ("Dataset" )] = gettext ("Dataset ID does not exist." )
584
577
results ['errors' ] = errors
585
578
results ['updatestatus' ] = "Failed"
586
- return JsonResponse (results , safe = False )
579
+ return JsonResponse (results , status = 400 )
587
580
588
581
change_permit_datasets = get_objects_for_user (request .user , 'change_dataset' , Dataset )
589
582
if dataset not in change_permit_datasets :
590
583
errors [gettext ("Dataset" )] = gettext ("No change permission for dataset." )
591
584
results ['errors' ] = errors
592
585
results ['updatestatus' ] = "Failed"
593
- return JsonResponse (results , safe = False )
586
+ return JsonResponse (results , status = 400 )
594
587
595
588
try :
596
589
gloss_id = int (glossid )
@@ -600,60 +593,70 @@ def api_update_gloss(request, datasetid, glossid):
600
593
errors [gettext ("Gloss" )] = gettext ("Gloss ID must be a number." )
601
594
results ['errors' ] = errors
602
595
results ['updatestatus' ] = "Failed"
603
- return JsonResponse (results , safe = False )
596
+ return JsonResponse (results , status = 400 )
604
597
605
598
gloss = Gloss .objects .filter (id = gloss_id , archived = False ).first ()
606
599
607
600
if not gloss :
608
601
errors [gettext ("Gloss" )] = gettext ("Gloss not found." )
609
602
results ['errors' ] = errors
610
603
results ['updatestatus' ] = "Failed"
611
- return JsonResponse (results , safe = False )
604
+ return JsonResponse (results , status = 400 )
612
605
613
606
if not gloss .lemma :
614
607
errors [gettext ("Gloss" )] = gettext ("Gloss does not have a lemma." )
615
608
results ['errors' ] = errors
616
609
results ['updatestatus' ] = "Failed"
617
- return JsonResponse (results , safe = False )
610
+ return JsonResponse (results , status = 400 )
618
611
619
612
if gloss .lemma .dataset != dataset :
620
613
errors [gettext ("Gloss" )] = gettext ("Gloss not found in the dataset." )
621
614
results ['errors' ] = errors
622
615
results ['updatestatus' ] = "Failed"
623
- return JsonResponse (results , safe = False )
616
+ return JsonResponse (results , status = 400 )
624
617
625
618
if not request .user .has_perm ('dictionary.change_gloss' ):
626
619
errors [gettext ("Gloss" )] = gettext ("No change gloss permission." )
627
620
results ['errors' ] = errors
628
621
results ['updatestatus' ] = "Failed"
629
- return JsonResponse (results , safe = False )
622
+ return JsonResponse (results , status = 400 )
630
623
631
624
value_dict = get_gloss_update_human_readable_value_dict (request )
625
+
632
626
errors = check_fields_can_be_updated (value_dict , dataset , interface_language_code )
633
627
if errors :
628
+ # "Field name not found in fields that can be updated."
634
629
results ['errors' ] = errors
635
630
results ['updatestatus' ] = "Failed"
636
- return JsonResponse (results , safe = False )
631
+ return JsonResponse (errors , status = 400 )
637
632
638
- fields_to_update = gloss_update (gloss , value_dict , interface_language_code )
633
+ fields_to_update = gloss_pre_update (gloss , value_dict , interface_language_code )
639
634
errors = detect_type_related_problems_for_gloss_update (fields_to_update , dataset , interface_language_code )
640
635
if errors :
636
+ # "New value has wrong type."
641
637
results ['errors' ] = errors
642
638
results ['updatestatus' ] = "Failed"
643
- return JsonResponse (results , safe = False )
639
+ return JsonResponse (results , status = 400 )
644
640
645
641
errors = check_constraints_on_gloss_language_fields (gloss , interface_language_code , fields_to_update )
646
642
if errors :
643
+ # "Constraint violation on language fields."
647
644
results ['errors' ] = errors
648
645
results ['updatestatus' ] = "Failed"
649
- return JsonResponse (results , safe = False )
646
+ return JsonResponse (results , status = 400 )
650
647
651
- gloss_update_do_changes (request .user , gloss , fields_to_update , interface_language_code )
648
+ try :
649
+ gloss_update_do_changes (request .user , gloss , fields_to_update , interface_language_code )
650
+ except (TransactionManagementError , ValueError , IntegrityError ):
651
+ errors ['Exception' ] = "Transaction management error."
652
+ results ['errors' ] = errors
653
+ results ['updatestatus' ] = "Failed"
654
+ return JsonResponse (results , status = 400 )
652
655
653
656
results ['errors' ] = {}
654
- results ['updatestatus' ] = "Success "
657
+ results ['updatestatus' ] = "Gloss successfully updated. "
655
658
656
- return JsonResponse (results , safe = False )
659
+ return JsonResponse (results , status = 201 )
657
660
658
661
659
662
def check_confirmed (value_dict ):
0 commit comments