Skip to content

Commit

Permalink
feat: add explanation with category in the Nutri-Score and Eco-Score …
Browse files Browse the repository at this point in the history
…knowledge panels when not applicable (#6844)

* not-applicable ecoscore and nutriscore attributes and panels #6092 #6774

* not-applicable ecoscore and nutriscore attributes and panels #6092 #6774

* not-applicable ecoscore and nutriscore attributes and panels #6092 #6774

* Update lib/ProductOpener/Lang.pm

Co-authored-by: Alex Garel <alex@garel.org>

* add test for category exempted from ecoscore

Co-authored-by: Alex Garel <alex@garel.org>
  • Loading branch information
stephanegigandet and alexgarel committed Jun 3, 2022
1 parent 111e0af commit 1c95c8a
Show file tree
Hide file tree
Showing 13 changed files with 298 additions and 25 deletions.
33 changes: 28 additions & 5 deletions lib/ProductOpener/Attributes.pm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,9 @@ use ProductOpener::Lang qw/:all/;
use ProductOpener::Display qw/:all/;
use ProductOpener::Ecoscore qw/:all/;

use Data::DeepAccess qw(deep_get);


=head1 CONFIGURATION
=head2 Attribute groups and attributes
Expand Down Expand Up @@ -463,7 +466,7 @@ sub compute_attribute_nutriscore($$) {
my $attribute_ref = initialize_attribute($attribute_id, $target_lc);

# Nutri-Score A, B, C, D or E
if (defined $product_ref->{nutriscore_data}) {
if ((defined $product_ref->{nutriscore_grade}) and ($product_ref->{nutriscore_grade} =~ /^[a-e]$/)) {
$attribute_ref->{status} = "known";

my $nutriscore_data_ref = $product_ref->{nutriscore_data};
Expand Down Expand Up @@ -543,13 +546,17 @@ sub compute_attribute_nutriscore($$) {
}

# Nutri-Score not-applicable: alcoholic beverages, baby food etc.
elsif (has_tag($product_ref,"misc","en:nutriscore-not-applicable")) {
elsif (has_tag($product_ref,"nutrition_grades","not-applicable")) {
$attribute_ref->{status} = "known";
$attribute_ref->{icon_url} = "$static_subdomain/images/attributes/nutriscore-not-applicable.svg";
$attribute_ref->{match} = 0;
if ($target_lc ne "data") {
$attribute_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_not_applicable_title");
$attribute_ref->{description} = lang_in_other_lc($target_lc, "attribute_nutriscore_not_applicable_description");
$attribute_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_not_applicable_title");
$attribute_ref->{description} = f_lang_in_lc($target_lc, "f_attribute_nutriscore_not_applicable_description", {
category => display_taxonomy_tag_name($target_lc, "categories",
deep_get($product_ref, qw/nutriscore_data nutriscore_not_applicable_for_category/))
}
);
$attribute_ref->{description_short} = lang_in_other_lc($target_lc, "attribute_nutriscore_not_applicable_description_short");
}
}
Expand Down Expand Up @@ -656,14 +663,30 @@ sub compute_attribute_ecoscore($$$) {
}
$attribute_ref->{icon_url} = "$static_subdomain/images/attributes/ecoscore-$grade.svg";
}
# Eco-Score is not-applicable
elsif ((defined $product_ref->{ecoscore_grade}) and ($product_ref->{ecoscore_grade} eq "not-applicable")) {
$attribute_ref->{status} = "unknown";
$attribute_ref->{icon_url} = "$static_subdomain/images/attributes/ecoscore-unknown.svg";
$attribute_ref->{match} = 0;
if ($target_lc ne "data") {
$attribute_ref->{title} = lang_in_other_lc($target_lc, "attribute_ecoscore_not_applicable_title");
$attribute_ref->{description} = f_lang_in_lc($target_lc, "f_attribute_ecoscore_not_applicable_description", {
category => display_taxonomy_tag_name($target_lc, "categories",
deep_get($product_ref, qw/ecoscore_data ecoscore_not_applicable_for_category/))
}
);
$attribute_ref->{description_short} = lang_in_other_lc($target_lc, "attribute_ecoscore_not_applicable_description_short");
}
}
# Eco-Score is unknown
else {
$attribute_ref->{status} = "unknown";
$attribute_ref->{icon_url} = "$static_subdomain/images/attributes/ecoscore-unknown.svg";
$attribute_ref->{match} = 0;
if ($target_lc ne "data") {
$attribute_ref->{title} = lang_in_other_lc($target_lc, "attribute_ecoscore_unknown_title");
$attribute_ref->{description} = lang_in_other_lc($target_lc, "attribute_ecoscore_unknown_description");
$attribute_ref->{description_short} = lang_in_other_lc($target_lc, "attribute_ecoscore_unknown_description_short");
$attribute_ref->{description_short} = lang_in_other_lc($target_lc, "attribute_ecoscore_unknown_description_short");
}
}

Expand Down
9 changes: 7 additions & 2 deletions lib/ProductOpener/Display.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8863,7 +8863,11 @@ sub data_to_display_nutriscore_and_nutrient_levels($) {
push @nutriscore_warnings, lang("nutriscore_not_applicable");
$result_data_ref->{nutriscore_grade} = "not-applicable";
$result_data_ref->{nutriscore_unknown_reason} = "not_applicable";
$result_data_ref->{nutriscore_unknown_reason_short} = lang("nutriscore_not_applicable_short");
$result_data_ref->{nutriscore_unknown_reason_short} = f_lang("f_attribute_nutriscore_not_applicable_description", {
category => display_taxonomy_tag_name($lc, "categories",
deep_get($product_ref, qw/nutriscore_data nutriscore_not_applicable_for_category/))
}
);
}
else {

Expand Down Expand Up @@ -8895,7 +8899,8 @@ sub data_to_display_nutriscore_and_nutrient_levels($) {
$result_data_ref->{nutriscore_warnings} = \@nutriscore_warnings;
}

if (defined $product_ref->{nutriscore_data}) {
# Display the details of the computation of the Nutri-Score if we computed one
if ((defined $product_ref->{nutriscore_grade}) and ($product_ref->{nutriscore_grade} =~ /^[a-e]$/)) {
$result_data_ref->{nutriscore_details} = display_nutriscore_calculation_details($product_ref->{nutriscore_data});
}

Expand Down
3 changes: 2 additions & 1 deletion lib/ProductOpener/Food.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1572,7 +1572,8 @@ sub compute_nutrition_score($) {
if (has_tag($product_ref, "categories", $category_id)) {
$product_ref->{"nutrition_grades_tags"} = [ "not-applicable" ];
add_tag($product_ref,"misc","en:nutriscore-not-applicable");
$product_ref->{nutrition_score_debug} = "no nutriscore for category $category_id" . " - ";;
$product_ref->{nutrition_score_debug} = "no nutriscore for category $category_id" . " - ";
$product_ref->{nutriscore_data} = {nutriscore_not_applicable_for_category => $category_id};
last;
}
}
Expand Down
22 changes: 20 additions & 2 deletions lib/ProductOpener/KnowledgePanels.pm
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ use ProductOpener::PackagerCodes qw/:all/;

use JSON::PP;
use Encode;
use Data::DeepAccess qw(deep_get);

=head1 FUNCTIONS
Expand Down Expand Up @@ -555,6 +556,18 @@ sub create_ecoscore_panel($$$) {
create_panel_from_json_template("ecoscore_total", "api/knowledge-panels/environment/ecoscore/total.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
}
# Eco-Score is not applicable
elsif ((defined $product_ref->{ecoscore_grade}) and ($product_ref->{ecoscore_grade} eq "not-applicable")) {
my $panel_data_ref = {};
$panel_data_ref->{subtitle} = f_lang_in_lc($target_lc, "f_attribute_ecoscore_not_applicable_description", {
category => display_taxonomy_tag_name($target_lc, "categories",
deep_get($product_ref, qw/ecoscore_data ecoscore_not_applicable_for_category/))
}
);
create_panel_from_json_template("ecoscore", "api/knowledge-panels/environment/ecoscore/ecoscore_not_applicable.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
}
# Eco-Score is unknown
else {
my $panel_data_ref = {};
create_panel_from_json_template("ecoscore", "api/knowledge-panels/environment/ecoscore/ecoscore_unknown.tt.json",
Expand Down Expand Up @@ -792,8 +805,13 @@ sub create_nutriscore_panel($$$) {

my $panel_data_ref = data_to_display_nutriscore_and_nutrient_levels($product_ref);

$panel_data_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_" . $panel_data_ref->{nutriscore_grade} . "_description_short");

if ($panel_data_ref->{nutriscore_grade} eq "not-applicable") {
$panel_data_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_not_applicable_title");
}
else {
$panel_data_ref->{title} = lang_in_other_lc($target_lc, "attribute_nutriscore_" . $panel_data_ref->{nutriscore_grade} . "_description_short");
}

# Nutri-Score panel: score + details
create_panel_from_json_template("nutriscore", "api/knowledge-panels/health/nutriscore/nutriscore.tt.json",
$panel_data_ref, $product_ref, $target_lc, $target_cc);
Expand Down
46 changes: 45 additions & 1 deletion lib/ProductOpener/Lang.pm
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ BEGIN
&lang
&lang_sprintf
&f_lang
&f_lang_in_lc
&lang_in_other_lc
%lang_lc
Expand Down Expand Up @@ -210,14 +211,57 @@ If a translation is not available, the function returns English.
In the .po translation files, we use the msgctxt field for the string id.
=head4 variables hash reference $variables_ref
Reference to a hash that contains values for the variables that will be replaced.
=cut

sub f_lang($$) {

my $stringid = shift;
my $variables_ref = shift;

my $translation = lang($stringid);
return f_lang_in_lc($lc, $stringid, $variables_ref);
}


=head2 f_lang_in_lc ( $target_lc, $stringid, $variables_ref )
Returns a translation for a specific string id with specific arguments
in the language $target_lc.
The translation is stored using Python's f-string format with
named parameters between { }.
e.g. "This is a string with {a_variable} and {another_variable}."
Variables between { } are interpolated with the corresponding entry
in the $variables_ref hash reference.
If a translation is not available, the function returns English.
=head3 Arguments
=head4 target language $target_lc
=head4 string id $stringid
In the .po translation files, we use the msgctxt field for the string id.
=head4 variables hash reference $variables_ref
Reference to a hash that contains values for the variables that will be replaced.
=cut

sub f_lang_in_lc($$$) {

my $target_lc = shift;
my $stringid = shift;
my $variables_ref = shift;

my $translation = $Lang{$stringid}{$target_lc};
if (defined $translation) {
# look for string keys between { } and replace them with the corresponding
# value in $variables_ref hash reference
Expand Down
30 changes: 24 additions & 6 deletions po/common/common.pot
Original file line number Diff line number Diff line change
Expand Up @@ -4652,8 +4652,13 @@ msgid "Nutri-Score not-applicable"
msgstr "Nutri-Score not-applicable"

msgctxt "attribute_nutriscore_not_applicable_description_short"
msgid "Exempted category"
msgstr "Exempted category"
msgid "Not-applicable for the category"
msgstr "Not-applicable for the category"

# variable names between { } must not be translated
msgctxt "f_attribute_nutriscore_not_applicable_description"
msgid "Not-applicable for the category: {category}"
msgstr "Not-applicable for the category: {category}"

msgctxt "attribute_nutriscore_a_description_short"
msgid "Very good nutritional quality"
Expand Down Expand Up @@ -5365,6 +5370,23 @@ msgctxt "delete_user_process"
msgid "User deleted."
msgstr "User deleted."

msgctxt "attribute_ecoscore_not_applicable_title"
msgid "Eco-Score not yet applicable"
msgstr "Eco-Score not yet applicable"

msgctxt "attribute_ecoscore_not_applicable_description_short"
msgid "Not yet applicable for the category"
msgstr "Not yet applicable for the category"

# variable names between { } must not be translated
msgctxt "f_attribute_ecoscore_not_applicable_description"
msgid "Not yet applicable for the category: {category}"
msgstr "Not yet applicable for the category: {category}"

msgctxt "ecoscore_not_applicable_coming_soon"
msgid "The Eco-Score is not yet applicable for this category, but we are working on adding support for it."
msgstr "The Eco-Score is not yet applicable for this category, but we are working on adding support for it."

msgctxt "attribute_ecoscore_unknown_title"
msgid "Eco-Score not computed"
msgstr "Eco-Score not computed"
Expand Down Expand Up @@ -5984,10 +6006,6 @@ msgctxt "f_energy_expenditure_for_weight_in_kg_lb"
msgid "Energy expenditure for a person weighting {kg} kg / {lb} lb"
msgstr "Energy expenditure for a person weighting {kg} kg / {lb} lb"

msgctxt "nutriscore_not_applicable_short"
msgid "Not applicable for this product"
msgstr "Not applicable for this product"

msgctxt "nutriscore_missing_category_short"
msgid "Missing category"
msgstr "Missing category"
Expand Down
30 changes: 24 additions & 6 deletions po/common/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -4672,8 +4672,13 @@ msgid "Nutri-Score not-applicable"
msgstr "Nutri-Score not-applicable"

msgctxt "attribute_nutriscore_not_applicable_description_short"
msgid "Exempted category"
msgstr "Exempted category"
msgid "Not-applicable for the category"
msgstr "Not-applicable for the category"

# variable names between { } must not be translated
msgctxt "f_attribute_nutriscore_not_applicable_description"
msgid "Not-applicable for the category: {category}"
msgstr "Not-applicable for the category: {category}"

msgctxt "attribute_nutriscore_a_description_short"
msgid "Very good nutritional quality"
Expand Down Expand Up @@ -4845,6 +4850,23 @@ msgctxt "attribute_ecoscore_grade_title"
msgid "Eco-Score %s"
msgstr "Eco-Score %s"

msgctxt "attribute_ecoscore_not_applicable_title"
msgid "Eco-Score not yet applicable"
msgstr "Eco-Score not yet applicable"

msgctxt "attribute_ecoscore_not_applicable_description_short"
msgid "Not yet applicable for the category"
msgstr "Not yet applicable for the category"

# variable names between { } must not be translated
msgctxt "f_attribute_ecoscore_not_applicable_description"
msgid "Not yet applicable for the category: {category}"
msgstr "Not yet applicable for the category: {category}"

msgctxt "ecoscore_not_applicable_coming_soon"
msgid "The Eco-Score is not yet applicable for this category, but we are working on adding support for it."
msgstr "The Eco-Score is not yet applicable for this category, but we are working on adding support for it."

msgctxt "attribute_ecoscore_unknown_title"
msgid "Eco-Score not computed"
msgstr "Eco-Score not computed"
Expand Down Expand Up @@ -6006,10 +6028,6 @@ msgctxt "f_energy_expenditure_for_weight_in_kg_lb"
msgid "Energy expenditure for a person weighting {kg} kg / {lb} lb"
msgstr "Energy expenditure for a person weighting {kg} kg / {lb} lb"

msgctxt "nutriscore_not_applicable_short"
msgid "Not applicable for this product"
msgstr "Not applicable for this product"

msgctxt "nutriscore_missing_category_short"
msgid "Missing category"
msgstr "Missing category"
Expand Down
26 changes: 24 additions & 2 deletions po/common/fr.po
Original file line number Diff line number Diff line change
Expand Up @@ -4513,8 +4513,13 @@ msgid "Nutri-Score not-applicable"
msgstr "Nutri-Score non applicable"

msgctxt "attribute_nutriscore_not_applicable_description_short"
msgid "Exempted category"
msgstr "Catégorie exemptée"
msgid "Not-applicable for the category"
msgstr "Non applicable pour la catégorie"

# variable names between { } must not be translated
msgctxt "f_attribute_nutriscore_not_applicable_description"
msgid "Not-applicable for the category: {category}"
msgstr "Non applicable pour la catégorie : {category}"

msgctxt "attribute_nutriscore_a_description_short"
msgid "Very good nutritional quality"
Expand Down Expand Up @@ -5222,6 +5227,23 @@ msgctxt "delete_user_process"
msgid "User deleted."
msgstr "Utilisateur supprimé."

msgctxt "attribute_ecoscore_not_applicable_title"
msgid "Eco-Score not yet applicable"
msgstr "Eco-Score pas encore applicable"

msgctxt "attribute_ecoscore_not_applicable_description_short"
msgid "Not yet applicable for the category"
msgstr "Pas encore applicable pour la catégorie"

# variable names between { } must not be translated
msgctxt "f_attribute_ecoscore_not_applicable_description"
msgid "Not yet applicable for the category: {category}"
msgstr "Pas encore applicable pour la catégorie : {category}"

msgctxt "ecoscore_not_applicable_coming_soon"
msgid "The Eco-Score is not yet applicable for this category, but we are working on adding support for it."
msgstr "L'Eco-Score n'est pas encore applicable pour cette catégorie, mais nous travaillons pour l'ajouter."

msgctxt "attribute_ecoscore_unknown_title"
msgid "Eco-Score not computed"
msgstr "Eco-Score non calculé"
Expand Down
7 changes: 7 additions & 0 deletions t/ecoscore.t
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,13 @@ my @tests = (
categories_tags=>["en:butters"],
}
],
[
'exempted-category-sodas',
{
lc => "en",
categories_tags=>["en:sodas"],
}
],
[
'label-organic',
{
Expand Down
21 changes: 21 additions & 0 deletions t/expected_test_results/ecoscore/exempted-category-sodas.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"categories_tags" : [
"en:sodas"
],
"ecoscore_data" : {
"adjustments" : {},
"ecoscore_not_applicable_for_category" : "en:sodas",
"status" : "unknown"
},
"ecoscore_grade" : "not-applicable",
"ecoscore_tags" : [
"not-applicable"
],
"lc" : "en",
"misc_tags" : [
"en:ecoscore-extended-data-not-computed",
"en:ecoscore-not-applicable",
"en:ecoscore-not-computed"
],
"packagings" : []
}

0 comments on commit 1c95c8a

Please sign in to comment.