Skip to content

Commit

Permalink
Merge branch 'dev' into irr-label-table
Browse files Browse the repository at this point in the history
  • Loading branch information
andykawabata committed Jul 3, 2024
2 parents 93f49f7 + b238b0c commit 519edc1
Show file tree
Hide file tree
Showing 8 changed files with 184 additions and 70 deletions.
8 changes: 5 additions & 3 deletions backend/django/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,13 @@ class Meta:
fields = ["allow_coders_view_labels"]

def __init__(self, *args, **kwargs):
percentage_irr = kwargs.pop('percentage_irr')
percentage_irr = kwargs.pop("percentage_irr")
super(ProjectUpdateAdvancedForm, self).__init__(*args, **kwargs)
if percentage_irr > 0:
self.fields['allow_coders_view_labels'].widget.attrs['disabled'] = 'disabled'
self.fields["allow_coders_view_labels"].widget.attrs[
"disabled"
] = "disabled"


class LabelForm(forms.ModelForm):
class Meta:
Expand Down Expand Up @@ -276,7 +279,6 @@ class Meta:

allow_coders_view_labels = forms.BooleanField(initial=False, required=False)


def clean(self):
use_active_learning = self.cleaned_data.get("use_active_learning")
use_default_batch_size = self.cleaned_data.get("use_default_batch_size")
Expand Down
4 changes: 3 additions & 1 deletion backend/django/core/urls/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
),
re_path(r"^unassign_data/(?P<data_pk>\d+)/$", api_annotate.unassign_data),
re_path(r"^skip_data/(?P<data_pk>\d+)/$", api_annotate.skip_data),
re_path(r"^verify_label/(?P<data_pk>\d+)/$", api_annotate.verify_label),
re_path(
r"^toggle_verify_label/(?P<data_pk>\d+)/$", api_annotate.toggle_verify_label
),
re_path(
r"^enter_coding_page/(?P<project_pk>\d+)/$", api_annotate.enter_coding_page
),
Expand Down
79 changes: 51 additions & 28 deletions backend/django/core/views/api_annotate.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ def unassign_data(request, data_pk):

@api_view(["POST"])
@permission_classes((IsCoder,))
def verify_label(request, data_pk):
"""Take a data label that was not verified, and verify it.
def toggle_verify_label(request, data_pk):
"""Either verify or unverify a data item.
Args:
request: The POST request
Expand All @@ -227,15 +227,22 @@ def verify_label(request, data_pk):
return Response(response)
elif DataLabel.objects.filter(data=data).count() > 1:
response["error"] = (
"ERROR: This data has multiple labels. This shouldn't "
"be possible with unverified data as it is pre-labeled."
"ERROR: This data has multiple labels which only occurs for incomplete IRR data which cannot be verified."
)
else:
VerifiedDataLabel.objects.create(
data_label=DataLabel.objects.get(data=data),
verified_timestamp=timezone.now(),
verified_by=request.user.profile,
)
datalabel = DataLabel.objects.get(data=data)
# if it's verified, un-verify it.
if VerifiedDataLabel.objects.filter(data_label=datalabel).exists():
VerifiedDataLabel.objects.filter(
data_label=datalabel,
).delete()
else:
# the data is not verified so we verify it
VerifiedDataLabel.objects.create(
data_label=DataLabel.objects.get(data=data),
verified_timestamp=timezone.now(),
verified_by=request.user.profile,
)

return Response(response)

Expand Down Expand Up @@ -1030,15 +1037,31 @@ def get_label_history(request, project_pk):
current_page = 1
page = int(current_page) - 1

page_size = 100
all_data = Data.objects.filter(pk__in=total_data_list).order_by("text")
metadata_objects = MetaDataField.objects.filter(project=project)
sort_by = request.GET.get("sort-by")
reverse = request.GET.get("reverse", "false").lower() == "true"
sort_options = {
'data': 'text',
'label': 'datalabel__label__name',
'profile': 'datalabel__profile__user__username',
'timestamp': 'datalabel__timestamp',
'verified': 'datalabel__verified__pk',
'verified_by': 'datalabel__verified__verified_by__user__username',
'pre_loaded': 'datalabel__pre_loaded'
}

order_field = sort_options.get(sort_by, 'text')

if reverse:
order_field = '-' + order_field

all_data = Data.objects.filter(pk__in=total_data_list).order_by(order_field)

# filter the results by the search terms
text_filter = request.GET.get("Text")
if text_filter is not None and text_filter != "":
all_data = all_data.filter(text__icontains=text_filter)

metadata_objects = MetaDataField.objects.filter(project=project)
for m in metadata_objects:
m_filter = request.GET.get(str(m))
if m_filter is not None and m_filter != "":
Expand All @@ -1047,24 +1070,27 @@ def get_label_history(request, project_pk):
).values_list("data__pk", flat=True)
all_data = all_data.filter(pk__in=data_with_metadata_filter)

page_size = 100
total_pages = math.ceil(len(all_data) / page_size)

pre_sorted = False
page_data = all_data[page * page_size : min((page + 1) * page_size, len(all_data))]
# get the metadata IDs needed for metadata editing

page_data_metadata_ids = [
d["metadata"] for d in DataMetadataIDSerializer(page_data, many=True).data
]

page_data = DataSerializer(page_data, many=True).data

# derive the metadata fields in the forms needed for the table
all_metadata = [c.popitem("metadata")[1] for c in page_data]
all_metadata_formatted = [
page_metadata = [c.popitem("metadata")[1] for c in page_data]
page_metadata_formatted = [
{c.split(":")[0].replace(" ", "_"): c.split(":")[1] for c in inner_list}
for inner_list in all_metadata
for inner_list in page_metadata
]

data_df = pd.DataFrame(page_data).rename(columns={"pk": "id", "text": "data"})
data_df["metadataIDs"] = page_data_metadata_ids
data_df["metadata"] = page_metadata
data_df["formattedMetadata"] = page_metadata_formatted

if len(data_df) == 0:
return Response(
{
Expand Down Expand Up @@ -1095,13 +1121,15 @@ def get_label_history(request, project_pk):
labeled_data_df["pre_loaded"] = labeled_data_df["pre_loaded"].apply(
lambda x: "Yes" if x else "No"
)
labeled_data_df["edit"] = "yes"
labeled_data_df["edit"] = labeled_data_df["verified"].apply(
lambda verified: "No" if verified == "Yes" else "Yes"
)
labeled_data_df["label"] = labeled_data_df["labelID"].apply(
lambda x: label_dict[x]
)

if len(irr_data_df) > 0:
irr_data_df["edit"] = "no"
irr_data_df["edit"] = "No"
irr_data_df["label"] = irr_data_df["labelID"].apply(lambda x: label_dict[x])
irr_data_df["verified"] = (
"N/A (IRR)" # Technically resolved IRR is verified but perhaps not this user's specific label so just NA
Expand All @@ -1116,9 +1144,9 @@ def get_label_history(request, project_pk):
# merge the data info with the label info
if len(all_labeled_stuff) > 0:
data_df = data_df.merge(all_labeled_stuff, on=["id"], how="left")
data_df["edit"] = data_df["edit"].fillna("yes")
data_df["edit"] = data_df["edit"].fillna("Yes")
else:
data_df["edit"] = "yes"
data_df["edit"] = "Yes"
data_df["label"] = ""
data_df["profile"] = ""
data_df["timestamp"] = ""
Expand All @@ -1129,12 +1157,7 @@ def get_label_history(request, project_pk):
# TODO: annotate uses pk while everything else uses ID. Let's fix this
data_df["pk"] = data_df["id"]

# now add back on the metadata fields
results = data_df.fillna("").to_dict(orient="records")
for i in range(len(results)):
results[i]["metadata"] = all_metadata[i]
results[i]["formattedMetadata"] = all_metadata_formatted[i]
results[i]["metadataIDs"] = page_data_metadata_ids[i]

return Response(
{
Expand Down
12 changes: 6 additions & 6 deletions backend/django/core/views/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ def done(self, form_list, form_dict, **kwargs):
proj_obj.percentage_irr = advanced_data["percentage_irr"]
proj_obj.num_users_irr = advanced_data["num_users_irr"]
proj_obj.classifier = advanced_data["classifier"]
proj_obj.allow_coders_view_labels = advanced_data["allow_coders_view_labels"]
proj_obj.allow_coders_view_labels = advanced_data[
"allow_coders_view_labels"
]

# use the data dedup choice to set dedup property of metadata fields
proj_obj.dedup_on = data.cleaned_data["dedup_on"]
Expand Down Expand Up @@ -444,13 +446,12 @@ def form_valid(self, form):
else:
return self.render_to_response(context)


class ProjectUpdateAdvanced(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
form_class = ProjectUpdateAdvancedForm
template_name = "projects/update/advanced.html"
permission_denied_message = (
"You must be an Admin or Project Creator to access the Advanced Project Settings Update page."
)
permission_denied_message = "You must be an Admin or Project Creator to access the Advanced Project Settings Update page."
raise_exception = True

def test_func(self):
Expand All @@ -465,7 +466,7 @@ def get_form_kwargs(self):
# pass the percentage_irr to the form
kwargs = super().get_form_kwargs()
project = self.get_object()
kwargs['percentage_irr'] = project.percentage_irr
kwargs["percentage_irr"] = project.percentage_irr
return kwargs

def form_valid(self, form):
Expand All @@ -478,7 +479,6 @@ def form_valid(self, form):
return self.render_to_response(context)



class ProjectUpdateData(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
form_class = DataUpdateWizardForm
Expand Down
Loading

0 comments on commit 519edc1

Please sign in to comment.