Repository: learningequality/kolibri

Issue:
CSV headers are not internationalized

### Observed behavior

I still don't get internationalized headers. Added all .po files back in 0d438101d6ccfc07a85ca4e48705ff795d4c14e4

Strings appear to exist:

https://github.com/learningequality/kolibri/blob/f47428ada9e1b1e836e63e186ab05eafd78fdd94/kolibri/locale/es_419/LC_MESSAGES/django.po#L34-L68


Have both .mo and .po locally:

![image](https://user-images.githubusercontent.com/2367265/81131681-cb315000-8f00-11ea-963f-c19052be6456.png)

exporting in spanish:

![image](https://user-images.githubusercontent.com/2367265/81131714-e00de380-8f00-11ea-8a44-a5db8cd4f14b.png)

Headers are still in English

![image](https://user-images.githubusercontent.com/2367265/81131777-219e8e80-8f01-11ea-9c2f-c03b44f96269.png)


### Expected behavior

Headers should be in spanish





Discussion:

Resolving patch:
diff --git a/kolibri/core/auth/management/commands/bulkexportusers.py b/kolibri/core/auth/management/commands/bulkexportusers.py
--- a/kolibri/core/auth/management/commands/bulkexportusers.py
+++ b/kolibri/core/auth/management/commands/bulkexportusers.py
@@ -39,16 +39,16 @@
 # TODO: decide whether these should be internationalized
 labels = OrderedDict(
     (
-        ("id", _("Database ID ({})".format("UUID"))),
-        ("username", _("Username ({})".format("USERNAME"))),
-        ("password", _("Password ({})".format("PASSWORD"))),
-        ("full_name", _("Full name ({})".format("FULL_NAME"))),
+        ("id", _("Database ID ({})").format("UUID")),
+        ("username", _("Username ({})").format("USERNAME")),
+        ("password", _("Password ({})").format("PASSWORD")),
+        ("full_name", _("Full name ({})").format("FULL_NAME")),
         ("kind", _("User type ({})").format("USER_TYPE")),
-        ("id_number", _("Identifier ({})".format("IDENTIFIER"))),
-        ("birth_year", _("Birth year ({})".format("BIRTH_YEAR"))),
-        ("gender", _("Gender ({})".format("GENDER"))),
-        ("enrolled", _("Learner enrollment ({})".format("ENROLLED_IN"))),
-        ("assigned", _("Coach assignment ({})".format("ASSIGNED_TO"))),
+        ("id_number", _("Identifier ({})").format("IDENTIFIER")),
+        ("birth_year", _("Birth year ({})").format("BIRTH_YEAR")),
+        ("gender", _("Gender ({})").format("GENDER")),
+        ("enrolled", _("Learner enrollment ({})").format("ENROLLED_IN")),
+        ("assigned", _("Coach assignment ({})").format("ASSIGNED_TO")),
     )
 )
 
@@ -99,6 +99,23 @@ def map_output(obj):
     return mapped_obj
 
 
+def translate_labels():
+    global labels
+    labels = OrderedDict(
+        (
+            ("username", _("Username ({})").format("USERNAME")),
+            ("password", _("Password ({})").format("PASSWORD")),
+            ("full_name", _("Full name ({})").format("FULL_NAME")),
+            ("kind", _("User type ({})").format("USER_TYPE")),
+            ("id_number", _("Identifier ({})").format("IDENTIFIER")),
+            ("birth_year", _("Birth year ({})").format("BIRTH_YEAR")),
+            ("gender", _("Gender ({})").format("GENDER")),
+            ("enrolled", _("Learner enrollment ({})").format("ENROLLED_IN")),
+            ("assigned", _("Coach assignment ({})").format("ASSIGNED_TO")),
+        )
+    )
+
+
 def csv_file_generator(facility, filepath, overwrite=True):
     if not overwrite and os.path.exists(filepath):
         raise ValueError("{} already exists".format(filepath))
@@ -212,6 +229,7 @@ def handle_async(self, *args, **options):
         # set language for the translation of the messages
         locale = settings.LANGUAGE_CODE if not options["locale"] else options["locale"]
         translation.activate(locale)
+        translate_labels()
 
         self.overall_error = []
         filepath = self.get_filepath(options)
diff --git a/kolibri/core/auth/management/commands/bulkimportusers.py b/kolibri/core/auth/management/commands/bulkimportusers.py
--- a/kolibri/core/auth/management/commands/bulkimportusers.py
+++ b/kolibri/core/auth/management/commands/bulkimportusers.py
@@ -69,17 +69,17 @@
 INVALID_UUID = 12
 
 MESSAGES = {
-    UNEXPECTED_EXCEPTION: _("Unexpected exception [{}]: {}"),
-    TOO_LONG: _("'{}' is too long"),
-    INVALID: _("Not a valid '{}'"),
-    DUPLICATED_USERNAME: _("Duplicated Username"),
+    UNEXPECTED_EXCEPTION: _("Unexpected error [{}]: {}"),
+    TOO_LONG: _("Value in column '{}' is too many characters"),
+    INVALID: _("Invalid value in column '{}'"),
+    DUPLICATED_USERNAME: _("Username is duplicated"),
     INVALID_USERNAME: _(
         "Username only can contain characters, numbers and underscores"
     ),
     REQUIRED_COLUMN: _("The column '{}' is required"),
-    INVALID_HEADER: _("Mix of valid and/or invalid header labels found in first row"),
+    INVALID_HEADER: _("Invalid header label found in the first row"),
     NO_FACILITY: _(
-        "No default facility exists, please make sure to provision this device before running this command"
+        "No default facility exists. Make sure to provision this device before importing"
     ),
     FILE_READ_ERROR: _("Error trying to read csv file: {}"),
     FILE_WRITE_ERROR: _("Error trying to write csv file: {}"),
diff --git a/kolibri/core/tasks/api.py b/kolibri/core/tasks/api.py
--- a/kolibri/core/tasks/api.py
+++ b/kolibri/core/tasks/api.py
@@ -665,11 +665,13 @@ def exportuserstocsv(self, request):
         facility = request.user.facility.id
         job_type = "EXPORTUSERSTOCSV"
         job_metadata = {"type": job_type, "started_by": request.user.pk}
+        locale = get_language_from_request(request)
 
         job_id = priority_queue.enqueue(
             call_command,
             "bulkexportusers",
             facility=facility,
+            locale=locale,
             overwrite="true",
             extra_metadata=job_metadata,
             track_progress=True,


Test patch: