internlm/SWE-Fixer-Train-110K huggingface dataset:
Repository: learningequality/kolibri

Issue:
User on SouD should not be able to edit their user profile
From @jamalex in bug bash: 
The FacilityUser object is read-only for single-user certificates, so these changes will not be synced back. We had a spec doc that laid out "what should be allowed on a SoUD", I think this was documented in there — we should do an audit to make sure other cases are covered as well.

https://www.notion.so/learningequality/CRITICAL-FEATURE-BUG-Users-on-SoUD-should-not-be-allowed-to-edit-their-user-profile-e5765979e7ed4fcaa694cfe7932ac4df


Discussion:

Resolving patch:
diff --git a/kolibri/plugins/user_profile/kolibri_plugin.py b/kolibri/plugins/user_profile/kolibri_plugin.py
--- a/kolibri/plugins/user_profile/kolibri_plugin.py
+++ b/kolibri/plugins/user_profile/kolibri_plugin.py
@@ -2,6 +2,7 @@
 from __future__ import print_function
 from __future__ import unicode_literals
 
+from kolibri.core.device.utils import get_device_setting
 from kolibri.core.hooks import NavigationHook
 from kolibri.core.webpack import hooks as webpack_hooks
 from kolibri.plugins import KolibriPluginBase
@@ -20,6 +21,10 @@ def url_slug(self):
 class UserAuthAsset(webpack_hooks.WebpackBundleHook):
     bundle_id = "app"
 
+    @property
+    def plugin_data(self):
+        return {"isSubsetOfUsersDevice": get_device_setting("subset_of_users_device")}
+
 
 @register_hook
 class ProfileNavAction(NavigationHook):


Test patch:
Repository: learningequality/kolibri

Issue:
Reports - Missing answered question data after upgrade from 0.14.7 to 0.15
## Observed behavior
This issue is a follow-up of https://github.com/learningequality/kolibri/pull/8818
When I'm logged in as a Coach and I go to the reports immediately after I've upgraded Kolibri from 0.14.7 to 0.15 and I attempt to go through the completed lessons or quizzes I'm not able to see the actual questions, instead I see the following text: No attempts made on this question.

## Expected behavior
All the completion details should be displayed.

## Steps to reproduce the issue
1. Install the a 0.14.7 version of Kolibri from [here](https://learningequality.org/r/kolibri-windows-setup-latest).
2. Setup a facility, create classes, users, lesson etc and complete a lesson and a quiz using exercises such as CK12's 'Make 10 (grids and number bonds)'.
3. Upgrade to the 0.15 version by Installing the following [build.](https://buildkite.com/learningequality/kolibri-python-package/builds/4467).
4. Go to Coach>Reports and observe the reports for the completed lesson and quiz. (Note that after restart of Kolibri the issue is observed only for the completed lesson while the quiz data is displayed correctly)

## Additional information

![2021-12-07_16-19-30](https://user-images.githubusercontent.com/79847249/145059555-47a4535f-9f9c-4118-b059-05487be78d51.png)

## Logs and DB files: 
[UbuntuDBlogs.zip](https://github.com/learningequality/kolibri/files/7669547/UbuntuDBlogs.zip)
[WindowsDBLogs.zip](https://github.com/learningequality/kolibri/files/7669548/WindowsDBLogs.zip)

## Usage Details
 - OS: Windows 10
 - Browser: Chrome


Discussion:
@radinamatic 
Retested today using the most recent [0.15 build](https://buildkite.com/learningequality/kolibri-python-package/builds/4548) and this issues is still extant.
cc @rtibbles @marcellamaki 
Hrm a key to thing I notice here is that the URL is incorrect, so I think there's a frontend issue here. I can look at replicating locally with the supplied DB. 
Replicated locally with your DB.

Resolving patch:
diff --git a/kolibri/core/logger/api.py b/kolibri/core/logger/api.py
--- a/kolibri/core/logger/api.py
+++ b/kolibri/core/logger/api.py
@@ -918,6 +918,7 @@ class AttemptLogViewSet(ReadOnlyValuesViewset):
     ordering = ("end_timestamp",)
 
     values = (
+        "id",
         "item",
         "start_timestamp",
         "end_timestamp",


Test patch:
Repository: learningequality/kolibri

Issue:
Use the available = true filter on the frontend for bookmarks
So that the availability filter on the backend is useful and so that learners do not see bookmarks for content that is not available.


Discussion:

Resolving patch:
diff --git a/kolibri/core/content/api.py b/kolibri/core/content/api.py
--- a/kolibri/core/content/api.py
+++ b/kolibri/core/content/api.py
@@ -1246,12 +1246,13 @@ def filter_available(self, queryset, name, value):
         queryset = queryset.annotate(
             available=Subquery(
                 models.ContentNode.objects.filter(
-                    available=True,
                     id=OuterRef("contentnode_id"),
                 ).values_list("available", flat=True)[:1]
             )
         )
 
+        return queryset.filter(available=value)
+
 
 class ContentNodeBookmarksViewset(
     BaseContentNodeMixin, BaseValuesViewset, ListModelMixin


Test patch:
Repository: learningequality/kolibri

Issue:
REMOTE_CONTENT option does not affect required storage at content import
## Observed behavior
When using the `REMOTE_CONTENT` option, the device plugin is not aware that this means that no local storage space is required in order to import content.

This means that on devices using this option, the amount of content that can be imported at one time will be artificially restricted.

## Expected behavior
Should be able to import any amount of content when `REMOTE_CONTENT` is set.

## User-facing consequences
Not able to provision servers effectively.


Discussion:
Just to clarify, does this issue also encompass or affect the "Free disk space" label show here?
![image](https://user-images.githubusercontent.com/1593835/153968525-244e0d80-99e8-40b7-96bb-9817d746a1b6.png)


Resolving patch:
diff --git a/kolibri/plugins/device/kolibri_plugin.py b/kolibri/plugins/device/kolibri_plugin.py
--- a/kolibri/plugins/device/kolibri_plugin.py
+++ b/kolibri/plugins/device/kolibri_plugin.py
@@ -9,6 +9,7 @@
 from kolibri.core.webpack.hooks import WebpackBundleHook
 from kolibri.plugins import KolibriPluginBase
 from kolibri.plugins.hooks import register_hook
+from kolibri.utils.conf import OPTIONS
 
 
 class DeviceManagementPlugin(KolibriPluginBase):
@@ -26,6 +27,7 @@ def plugin_data(self):
             "isSubsetOfUsersDevice": get_device_setting(
                 "subset_of_users_device", False
             ),
+            "isRemoteContent": OPTIONS["Deployment"]["REMOTE_CONTENT"],
         }
 
 


Test patch:
Repository: learningequality/kolibri

Issue:
choose default language based on system details

possibilities include:

* locale set on server
* language chosen during installation (see https://github.com/learningequality/kolibri-installer-windows/pull/46)


Discussion:

Resolving patch:
diff --git a/kolibri/deployment/default/settings/base.py b/kolibri/deployment/default/settings/base.py
--- a/kolibri/deployment/default/settings/base.py
+++ b/kolibri/deployment/default/settings/base.py
@@ -293,9 +293,11 @@
 }
 locale.LANG_INFO.update(EXTRA_LANG_INFO)
 
+default_language = i18n.get_system_default_language()
+
 LANGUAGE_CODE = (
-    "en"
-    if "en" in conf.OPTIONS["Deployment"]["LANGUAGES"]
+    default_language
+    if default_language in conf.OPTIONS["Deployment"]["LANGUAGES"]
     else conf.OPTIONS["Deployment"]["LANGUAGES"][0]
 )
 
diff --git a/kolibri/utils/i18n.py b/kolibri/utils/i18n.py
--- a/kolibri/utils/i18n.py
+++ b/kolibri/utils/i18n.py
@@ -2,8 +2,11 @@
 import importlib
 import io
 import json
+import locale
 import os
 
+from django.utils.translation.trans_real import to_language
+
 import kolibri
 
 
@@ -41,7 +44,7 @@ def _get_language_info():
 KOLIBRI_LANGUAGE_INFO = _get_language_info()
 
 # List of intl codes that Kolibri officially supports
-KOLIBRI_SUPPORTED_LANGUAGES = [
+KOLIBRI_SUPPORTED_LANGUAGES = {
     "ar",
     "bg-bg",
     "bn-bd",
@@ -73,4 +76,16 @@ def _get_language_info():
     "vi",
     "yo",
     "zh-hans",
-]
+}
+
+
+def get_system_default_language():
+    for loc in (locale.getlocale()[0], locale.getdefaultlocale()[0]):
+        if loc:
+            lang = to_language(loc)
+            for lang_code in (lang, lang.split("-")[0]):
+                if lang_code in KOLIBRI_SUPPORTED_LANGUAGES:
+                    return lang_code
+
+    # If all else fails we fall back to "en"
+    return "en"


Test patch:
Repository: learningequality/kolibri

Issue:
Order paginated FacilityUser queryset
## Observed behavior
The recent pagination PR for the FacilityUser did not also include an update to order the paginated results.

## Errors and logs

```
/home/richard/.pex/install/kolibri-0.15.2-py2.py3-none-any.whl.b1f6d8c79573a7c7990a890cbd916d25e85a6288/kolibri-0.15.2-py2.py3-none-any.whl/kolibri/core/utils/pagination.py:37: UnorderedObjectListWarning: Pagination may yield inconsistent results with an unordered object_list: <class 'kolibri.core.auth.models.FacilityUser'> SyncableModelQuerySet.
super(ValuesViewsetPaginator, self).init(object_list, *args, **kwargs)
```

## Expected behavior
Users should be ordered

## User-facing consequences
Confusing UI




Discussion:

Resolving patch:
diff --git a/kolibri/core/auth/api.py b/kolibri/core/auth/api.py
--- a/kolibri/core/auth/api.py
+++ b/kolibri/core/auth/api.py
@@ -298,6 +298,8 @@ class FacilityUserViewSet(ValuesViewset):
         DjangoFilterBackend,
         filters.SearchFilter,
     )
+    order_by_field = "username"
+
     queryset = FacilityUser.objects.all()
     serializer_class = FacilityUserSerializer
     filter_class = FacilityUserFilter
@@ -338,6 +340,7 @@ def consolidate(self, items, queryset):
                     roles.append(role)
             item["roles"] = roles
             output.append(item)
+        output = sorted(output, key=lambda x: x[self.order_by_field])
         return output
 
     def set_password_if_needed(self, instance, serializer):


Test patch:
diff --git a/kolibri/plugins/facility/assets/src/views/UserPage/__test__/UserPage.spec.js b/kolibri/plugins/facility/assets/src/views/UserPage/__test__/UserPage.spec.js
--- a/kolibri/plugins/facility/assets/src/views/UserPage/__test__/UserPage.spec.js
+++ b/kolibri/plugins/facility/assets/src/views/UserPage/__test__/UserPage.spec.js
@@ -1,5 +1,6 @@
 import mock from 'xhr-mock';
 import { mount, RouterLinkStub } from '@vue/test-utils';
+import VueRouter from 'vue-router';
 import makeStore from '../../../../test/makeStore';
 import UserPage from '../index';
 
@@ -7,12 +8,22 @@ jest.mock('kolibri.lib.logging');
 jest.mock('kolibri.urls');
 jest.mock('lockr');
 
+const router = new VueRouter({
+  routes: [
+    {
+      path: '/userpage/',
+      name: 'UserPage',
+    },
+  ],
+});
+
 UserPage.computed.newUserLink = () => ({});
 
 function makeWrapper() {
   const store = makeStore();
   const wrapper = mount(UserPage, {
     store,
+    router,
     stubs: {
       RouterLink: RouterLinkStub,
     },
Repository: learningequality/kolibri

Issue:
Learners not available to enroll in the class

## Observed behavior
Encountered while testing #9446, according to @rtibbles most probably a regression from the recent pagination work.

Facility has 3 new learners, but none seem available to be enrolled in the class:

![enroll-issue](https://user-images.githubusercontent.com/1457929/168927631-eec829b1-abe5-4ae8-8904-f216dc979f2b.gif)


## Errors and logs
…

## Expected behavior
Visible list of learners to enroll.

## User-facing consequences
…

## Steps to reproduce
Create learner(s) and try to enroll them in a class.

## Context
 * Kolibri version: 0.15.x branch, EXE asset from #9446  
 * Operating system: Windows 10
 * Browser: all


Discussion:

Resolving patch:
diff --git a/kolibri/core/auth/api.py b/kolibri/core/auth/api.py
--- a/kolibri/core/auth/api.py
+++ b/kolibri/core/auth/api.py
@@ -214,6 +214,9 @@ class FacilityUserFilter(FilterSet):
     exclude_member_of = ModelChoiceFilter(
         method="filter_exclude_member_of", queryset=Collection.objects.all()
     )
+    exclude_coach_for = ModelChoiceFilter(
+        method="filter_exclude_coach_for", queryset=Collection.objects.all()
+    )
     exclude_user_type = ChoiceFilter(
         choices=USER_TYPE_CHOICES,
         method="filter_exclude_user_type",
@@ -232,6 +235,16 @@ def filter_user_type(self, queryset, name, value):
     def filter_exclude_member_of(self, queryset, name, value):
         return queryset.exclude(Q(memberships__collection=value) | Q(facility=value))
 
+    def filter_exclude_coach_for(self, queryset, name, value):
+        return queryset.exclude(
+            Q(roles__in=Role.objects.filter(kind=role_kinds.COACH, collection=value))
+            | Q(
+                roles__in=Role.objects.filter(
+                    kind=role_kinds.COACH, collection_id=value.parent_id
+                )
+            )
+        )
+
     def filter_exclude_user_type(self, queryset, name, value):
         if value == "learner":
             return queryset.exclude(roles__isnull=True)


Test patch:
Repository: learningequality/kolibri

Issue:
IndexError: list index out of range
Uncaught IndexError in ContentNodeTree viewset.

Sentry Issue: [KOLIBRI-BACKEND-2A6](https://sentry.io/organizations/learningequality/issues/3382915440/?referrer=github_integration)

```
IndexError: list index out of range
(8 additional frame(s) were not displayed)
...
  File "django/utils/decorators.py", line 63, in bound_func
    return func.__get__(self, type(self))(*args2, **kwargs2)
  File "rest_framework/views.py", line 495, in dispatch
    response = self.handle_exception(exc)
  File "rest_framework/views.py", line 455, in handle_exception
    self.raise_uncaught_exception(exc)
  File "rest_framework/views.py", line 492, in dispatch
    response = handler(request, *args, **kwargs)
  File "kolibri/core/content/api.py", line 1027, in retrieve
    parent = nodes[0]
```


Discussion:

Resolving patch:
diff --git a/kolibri/core/content/api.py b/kolibri/core/content/api.py
--- a/kolibri/core/content/api.py
+++ b/kolibri/core/content/api.py
@@ -969,8 +969,12 @@ def get_grandchild_ids(self, child_ids, depth, page_size):
 
     def get_tree_queryset(self, request, pk):
         # Get the model for the parent node here - we do this so that we trigger a 404 immediately if the node
-        # does not exist (or exists but is not available).
-        parent_id = pk if pk and self.get_queryset().filter(id=pk).exists() else None
+        # does not exist (or exists but is not available, or is filtered).
+        parent_id = (
+            pk
+            if pk and self.filter_queryset(self.get_queryset()).filter(id=pk).exists()
+            else None
+        )
 
         if parent_id is None:
             raise Http404


Test patch:
diff --git a/kolibri/core/content/test/test_content_app.py b/kolibri/core/content/test/test_content_app.py
--- a/kolibri/core/content/test/test_content_app.py
+++ b/kolibri/core/content/test/test_content_app.py
@@ -422,6 +422,14 @@ def test_contentnode_tree(self):
         )
         self._recurse_and_assert([response.data], [root])
 
+    def test_contentnode_tree_filtered_queryset_node(self):
+        root = content.ContentNode.objects.get(title="root")
+        response = self.client.get(
+            reverse("kolibri:core:contentnode_tree-detail", kwargs={"pk": root.id})
+            + "?parent={}".format(uuid.uuid4().hex)
+        )
+        self.assertEqual(response.status_code, 404)
+
     @unittest.skipIf(
         getattr(settings, "DATABASES")["default"]["ENGINE"]
         == "django.db.backends.postgresql",
Repository: learningequality/kolibri

Issue:
In analytics payload, the "installer" field should indicate when a user is running Kolibri locally for dev purposes
<!--
Instructions:
 * Fill out the sections below, replace …'s with information about your issue
 * Use the 'preview' function above this text box to verify formatting before submitting
-->

### Observed behavior
Sometimes, when running Kolibri in development mode, this line:

https://github.com/learningequality/kolibri/blob/032aa228597fdd14098796d8ccd98668e6a6f5a3/kolibri/core/analytics/utils.py#L431

will return values that are indistinguishable from a device that is running Kolibri in a "production" setting.

### Expected behavior
<!--
Description of what behavior was expected but did not occur
-->

…

### User-facing consequences
<!--
Implications and real-world consequences for learners, coaches, admins, and other users of the application
-->

…

### Errors and logs
<!--
Relevant logs from:
 * the command line
 * ~/.kolibri/logs/kolibri.txt
 * the browser console

Please wrap errors in triple backticks for clean formatting like this:
```
01:10 info: something happened
01:12 error: something bad happened
```
-->

…

### Steps to reproduce
<!--
Precise steps that someone else can follow in order to see this behavior
-->

…

### Context
<!--
Tell us about your environment, including:
 * Kolibri version
 * Operating system
 * Browser
-->

…



Discussion:

Resolving patch:
diff --git a/kolibri/utils/server.py b/kolibri/utils/server.py
--- a/kolibri/utils/server.py
+++ b/kolibri/utils/server.py
@@ -1030,12 +1030,12 @@ def is_kolibri_server():
     if install_type == "Unknown":
         if on_android():
             install_type = installation_types.APK
+        elif os.environ.get("KOLIBRI_DEVELOPER_MODE", False):
+            install_type = "devserver"
         elif len(cmd_line) > 1 or "uwsgi" in cmd_line:
             launcher = cmd_line[0]
             if launcher.endswith(".pex"):
                 install_type = installation_types.PEX
-            elif "runserver" in cmd_line:
-                install_type = "devserver"
             elif launcher == "/usr/bin/kolibri":
                 install_type = is_debian_package()
             elif launcher == "uwsgi":


Test patch:
diff --git a/kolibri/utils/tests/test_server.py b/kolibri/utils/tests/test_server.py
--- a/kolibri/utils/tests/test_server.py
+++ b/kolibri/utils/tests/test_server.py
@@ -25,15 +25,7 @@ def test_pex(self):
         assert install_type == installation_types.PEX
 
     def test_dev(self):
-        sys_args = [
-            "kolibri",
-            "--debug",
-            "manage",
-            "runserver",
-            "--settings=kolibri.deployment.default.settings.dev",
-            '"0.0.0.0:8000"',
-        ]
-        with mock.patch("sys.argv", sys_args):
+        with mock.patch("os.environ", {"KOLIBRI_DEVELOPER_MODE": "True"}):
             install_type = server.installation_type()
             assert install_type == "devserver"
Repository: learningequality/kolibri

Issue:
All logging should have a timestamp
https://github.com/learningequality/kolibri/blob/d6d9f654bfd96f6f832c9a0e6f0b3c661689f9d9/kolibri/utils/logger.py

Here's the default handler:

```
DEFAULT_HANDLERS = (
    ["console"] if NO_FILE_BASED_LOGGING else ["file", "console", "file_debug"]
)
...
"console": {
    "level": DEFAULT_LEVEL,
    "class": "logging.StreamHandler",
    "formatter": "color",
},
```
Here's the formatter for console (one of two formatters that omit the timestamp, the other being `simple`):

```"color": {
    "()": "colorlog.ColoredFormatter",
    "format": "%(log_color)s%(levelname)-8s %(message)s",
    "log_colors": LOG_COLORS,
}
```


Discussion:

Resolving patch:
diff --git a/kolibri/utils/logger.py b/kolibri/utils/logger.py
--- a/kolibri/utils/logger.py
+++ b/kolibri/utils/logger.py
@@ -194,11 +194,10 @@ def get_default_logging_config(LOG_ROOT, debug=False, debug_database=False):
             "verbose": {
                 "format": "%(levelname)s %(asctime)s %(name)s %(process)d %(thread)d %(message)s"
             },
-            "simple": {"format": "%(levelname)s %(message)s"},
             "simple_date": {"format": "%(levelname)s %(asctime)s %(name)s %(message)s"},
             "color": {
                 "()": "colorlog.ColoredFormatter",
-                "format": "%(log_color)s%(levelname)-8s %(message)s",
+                "format": "%(log_color)s%(levelname)-8s %(asctime)s %(message)s",
                 "log_colors": LOG_COLORS,
             },
         },


Test patch:
Repository: learningequality/kolibri

Issue:
Ensure that our language globals `lang_direction` property is always a string
The `languageGlobals` object that is being given to `plugin_data` has been returning languages where their `lang_direction` properties are Boolean rather than a string. Using the i18n module, we should be able to rely on that value always being on of 'rtl' or 'ltr'. 

This issue was mitigated by @akolson ( https://github.com/learningequality/kolibri/pull/9863/commits/14e4f8b72e3e1b8544c014114cc7e5efcada313d ) but it always assumes that unless the string is specifically the `languageDirections.LTR` then it should be RTL.

Not sure the implications of this as it may be working reliably, however it would be good to ensure our data structures for the language globals are consistent and predictable.




Discussion:

Resolving patch:
diff --git a/kolibri/core/kolibri_plugin.py b/kolibri/core/kolibri_plugin.py
--- a/kolibri/core/kolibri_plugin.py
+++ b/kolibri/core/kolibri_plugin.py
@@ -147,7 +147,7 @@ def language_globals(self):
                 "english_name": lang_info["english_name"]
                 if lang_info
                 else get_language_info(code)["name"],
-                "lang_direction": get_language_info(code)["bidi"],
+                "lang_direction": "rtl" if get_language_info(code)["bidi"] else "ltr",
             }
         return {
             "coreLanguageMessages": self.frontend_messages(),


Test patch:
Repository: learningequality/kolibri

Issue:
Missing facility name when importing (sync) a facility
<!--
Instructions:
 * Fill out the sections below, replace …'s with information about your issue
 * Use the 'preview' function above this text box to verify formatting before submitting
-->

## Observed behavior
<!--
Description of the behavior that was observed, including screenshots or other references when applicable
-->
When you import a facility, the name is missing from the task details

![Screenshot from 2022-06-07 15-37-10](https://user-images.githubusercontent.com/819838/172494678-1a694ea5-c44b-4e4d-8775-ad801518ed51.png)


## Expected behavior
<!--
Description of what behavior was expected but did not occur
-->

It should say `Import '<facility name>'`


## Steps to reproduce
<!--
Precise steps that someone else can follow in order to see this behavior
-->
1) Go to Device > Facilities
2) Click <kbd>Import Facility</kbd>
3) Choose a peer instance, facility, and provide credentials to trigger the import
4) Observe the task's details are missing the facility name

## Context
<!--
Tell us about your environment, including:
 * Kolibri version
 * Operating system
 * Browser
-->
Kolibri 0.16.0
Ubuntu
Google Chrome



Discussion:
Noting that this is probably an issue in the frontend not setting the name in the task payload.

Resolving patch:
diff --git a/kolibri/core/auth/tasks.py b/kolibri/core/auth/tasks.py
--- a/kolibri/core/auth/tasks.py
+++ b/kolibri/core/auth/tasks.py
@@ -241,7 +241,7 @@ def validate(self, data):
             facility_name = facility.name
         else:
             facility_id = facility
-            facility_name = ""
+            facility_name = data["facility_name"]
         return {
             "extra_metadata": dict(
                 facility_id=facility_id,
@@ -353,6 +353,7 @@ def peerfacilitysync(command, **kwargs):
 
 class PeerFacilityImportJobValidator(PeerFacilitySyncJobValidator):
     facility = HexOnlyUUIDField()
+    facility_name = serializers.CharField(default="")
     username = serializers.CharField()
     password = serializers.CharField(default=NOT_SPECIFIED, required=False)
 


Test patch: