Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge release-v0.16.x into develop #11371

Merged
merged 78 commits into from
Oct 8, 2023
Merged
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
44b92da
Add temporary reference to KDS fork
MisRob Sep 1, 2023
7441007
Add useKShow to apiSpec
MisRob Sep 1, 2023
4080bd6
Fetch lesson sizes before commiting new lessons
MisRob Aug 31, 2023
eca698d
Add loader when toggling lessons
MisRob Sep 1, 2023
2cc02bc
Don't use force deletion when cleaning up resources for content remov…
rtibbles Sep 15, 2023
ecee1be
Tweak which models to exclude from schema generation.
rtibbles Sep 15, 2023
804f581
Set the admin imported flag during resource import.
rtibbles Sep 15, 2023
eb2da96
Clean up admin imported flags, except in content request cleanups.
rtibbles Sep 15, 2023
8338d8b
Decrease time to sync
vkWeb Sep 19, 2023
0243928
Add another field to check on to
vkWeb Sep 19, 2023
0fbacd7
Don't access db
vkWeb Sep 19, 2023
f425a79
Fix outdated test
vkWeb Sep 19, 2023
ab03b39
Rectify update_instance as well with tests
vkWeb Sep 19, 2023
fdd49bd
solved Navigation issue from attached drive
ShivangRawat30 Sep 19, 2023
481c37b
Add tests and a bit clean
vkWeb Sep 25, 2023
8b6cba8
Bump @babel/core from 7.22.20 to 7.23.0
dependabot[bot] Sep 26, 2023
0df01d0
Persist admin_imported flag across channel metadata upgrades.
rtibbles Sep 26, 2023
f9e52d8
Merge pull request #11299 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 26, 2023
d43ab6d
Merge pull request #11271 from vkWeb/time-decrease
bjester Sep 26, 2023
695c078
Add cautionary code comment.
rtibbles Sep 26, 2023
9a3b44e
Merge pull request #11254 from rtibbles/im_an_admin_import_and_im_okay
rtibbles Sep 26, 2023
37a0d19
Bump axios from 1.5.0 to 1.5.1
dependabot[bot] Sep 27, 2023
eb9628b
Bump glob from 10.3.7 to 10.3.9
dependabot[bot] Sep 27, 2023
9f4e579
Bump markdown-it from 13.0.1 to 13.0.2
dependabot[bot] Sep 27, 2023
e1a79f9
Bump autoprefixer from 10.4.15 to 10.4.16
dependabot[bot] Sep 27, 2023
216fb32
Merge branch 'release-v0.16.x' into coach-loading
MisRob Sep 27, 2023
4f5d2d3
Replace temporary fork reference by the latest KDS
MisRob Sep 27, 2023
1bd8914
Merge pull request #11305 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 27, 2023
0d07311
Merge pull request #11307 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 27, 2023
33a7b9d
Merge pull request #11308 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 27, 2023
a86b996
Merge pull request #11309 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 27, 2023
6257a5c
Merge pull request #11201 from MisRob/coach-loading
MisRob Sep 27, 2023
d86a484
Bump glob from 10.3.9 to 10.3.10
dependabot[bot] Sep 28, 2023
d8ecd41
Merge pull request #11312 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 28, 2023
ea1ee36
Fixed the reference for the missing string
radinamatic Sep 28, 2023
601fcd0
No results for not visible lessons
radinamatic Sep 28, 2023
0e0348a
Fixes performance regression. Uses capabilities to properly check if …
rtibbles Sep 28, 2023
c78ab9f
Bump postcss-scss from 4.0.8 to 4.0.9
dependabot[bot] Sep 29, 2023
37f23a8
Merge pull request #11318 from learningequality/dependabot/npm_and_ya…
rtibbles Sep 29, 2023
c12d143
Disabling additional user import until multiple user syncing is working
AllanOXDi Sep 14, 2023
9b355e3
added a route to the loading task page when a single user has been im…
AllanOXDi Sep 15, 2023
4308258
added a TO DO
AllanOXDi Sep 15, 2023
6d35989
routed a user away from the import users page onclicking the import b…
AllanOXDi Sep 22, 2023
6efd729
capitalized TODO text
AllanOXDi Sep 29, 2023
9188e6a
Imrproved naming for readability
radinamatic Sep 29, 2023
48b414d
Merge pull request #11313 from radinamatic/no-results
rtibbles Sep 29, 2023
46b21c0
Merge pull request #11242 from AllanOXDi/prevent_multiple_user_imports
rtibbles Sep 29, 2023
cc8e657
Merge pull request #11317 from rtibbles/we_can_rebuild_it_we_have_the…
marcellamaki Sep 29, 2023
cd42526
Some minor linting fixes that became apparent after linting updates, …
rtibbles Sep 29, 2023
595ff11
bugfix- birth year selction
haldaranup Sep 29, 2023
8d0c638
changed backRoute() in selectConentPage/index.js
ShivangRawat30 Oct 1, 2023
3a7b39d
minor change
ShivangRawat30 Oct 1, 2023
d0e141c
Bump core-js from 3.32.2 to 3.33.0
dependabot[bot] Oct 2, 2023
03bed2b
Merge pull request #11343 from learningequality/dependabot/npm_and_ya…
rtibbles Oct 2, 2023
4f9787c
Merge pull request #11339 from rtibbles/linting_fixes
rtibbles Oct 2, 2023
9b083ec
format
haldaranup Oct 3, 2023
7f5427e
Linting: let to const for date variable
haldaranup Oct 3, 2023
b421175
linting errors fixed
ShivangRawat30 Oct 3, 2023
6251a50
Merge pull request #11337 from haldaranup/bugfix-birth-year-selction
rtibbles Oct 3, 2023
2832114
Pass dummy auth token to testing script.
rtibbles Oct 3, 2023
9b02095
Fix linting.
rtibbles Oct 3, 2023
53e4072
Merge pull request #11272 from ShivangRawat30/11187
rtibbles Oct 3, 2023
b536b58
stub out KCircularLoader in failing test
thanksameeelian Sep 29, 2023
1022ed6
update KDS reference to current HEAD of release-v1.5.x branch
thanksameeelian Oct 3, 2023
a061ef2
Merge pull request #11315 from thanksameeelian/side-panel-opening-aft…
MisRob Oct 4, 2023
6caef65
Merge pull request #11347 from rtibbles/tweak_script
rtibbles Oct 4, 2023
9e1bdc5
Migrates the OSUser associated with a facility user when migrating us…
rtibbles Oct 3, 2023
b11412e
Reference exception properly.
rtibbles Oct 4, 2023
0001015
Merge pull request #11348 from rtibbles/migrate_os_user
rtibbles Oct 4, 2023
1797e14
Deleted the responsiveWindowMixin from user_auth
ShivangRawat30 Oct 5, 2023
bfc0430
Add regression tests to ecosystem tests to ensure that recreated obje…
rtibbles Oct 3, 2023
0bfe2dd
Upgrade morango to 0.6.18.
rtibbles Oct 5, 2023
c509e0e
Bump csv-parse from 5.5.0 to 5.5.1
dependabot[bot] Oct 6, 2023
f7442ef
kolibri-tools: Accept multiple --namespace/--searchPath arguments
pwithnall Sep 22, 2023
5925dda
Merge pull request #11360 from learningequality/dependabot/npm_and_ya…
rtibbles Oct 6, 2023
a5992fb
Merge pull request #11359 from rtibbles/now_you_see_it_now_you_dont
rtibbles Oct 7, 2023
358bb82
Merge pull request #11357 from endlessm/kolibri-tools-more-namespaces
rtibbles Oct 8, 2023
23a5b6e
Merge pull request #11354 from ShivangRawat30/11332
rtibbles Oct 8, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions integration_testing/scripts/run_kolibri_app_mode.py
Original file line number Diff line number Diff line change
@@ -21,10 +21,9 @@ def SERVING(self, port):
self.port = port

def RUN(self):
start_url = (
"http://127.0.0.1:{port}".format(port=self.port)
+ interface.get_initialize_url()
)
start_url = "http://127.0.0.1:{port}".format(
port=self.port
) + interface.get_initialize_url(auth_token="1234")
print("Kolibri running at: {start_url}".format(start_url=start_url))


2 changes: 2 additions & 0 deletions kolibri/core/assets/src/core-app/apiSpec.js
Original file line number Diff line number Diff line change
@@ -18,6 +18,7 @@ import UiAlert from 'kolibri-design-system/lib/keen/UiAlert';
import responsiveWindowMixin from 'kolibri-design-system/lib/KResponsiveWindowMixin';
import responsiveElementMixin from 'kolibri-design-system/lib/KResponsiveElementMixin';
import useKResponsiveWindow from 'kolibri-design-system/lib/useKResponsiveWindow';
import useKShow from 'kolibri-design-system/lib/composables/useKShow';
import UiIconButton from 'kolibri-design-system/lib/keen/UiIconButton'; // temp hack
import * as vueCompositionApi from '@vue/composition-api';
import logging from '../logging';
@@ -228,6 +229,7 @@ export default {
},
composables: {
useKResponsiveWindow,
useKShow,
useMinimumKolibriVersion,
useUser,
},
7 changes: 2 additions & 5 deletions kolibri/core/assets/src/views/sortable/DragContainer.vue
Original file line number Diff line number Diff line change
@@ -115,20 +115,17 @@
}

@keyframes bounce-in {
from {
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}

0% {
transform: scale3d(1.05, 1.05, 1.05);
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}

50% {
transform: scale3d(0.98, 0.98, 0.98);
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}

to {
100% {
transform: scale3d(1, 1, 1);
animation-timing-function: cubic-bezier(0.215, 0.61, 0.355, 1);
}
Original file line number Diff line number Diff line change
@@ -85,8 +85,12 @@
methods: {
makeYearOptions(max, min) {
return range(max, min, -1).map(n => {
// Because of timezone, year could be mismatched when localized in any
// timezone that less than UTC. for ex- 2022 will be shown instead of 2023
const date = new Date();
date.setFullYear(n);
return {
label: this.$formatDate(String(n), { year: 'numeric' }),
label: this.$formatDate(String(date), { year: 'numeric' }),
value: String(n),
};
});
5 changes: 2 additions & 3 deletions kolibri/core/auth/tasks.py
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@
from kolibri.core.tasks.exceptions import JobNotFound
from kolibri.core.tasks.exceptions import UserCancelledError
from kolibri.core.tasks.job import JobStatus
from kolibri.core.tasks.job import Priority
from kolibri.core.tasks.job import State
from kolibri.core.tasks.main import job_storage
from kolibri.core.tasks.permissions import IsAdminForJob
@@ -627,9 +628,7 @@ def stop_request_soud_sync(server, user):
stoppeerusersync(server, user)


@register_task(
queue=soud_sync_queue,
)
@register_task(queue=soud_sync_queue, priority=Priority.HIGH, status_fn=status_fn)
def request_soud_sync(server, user, queue_id=None, ttl=4):
"""
Make a request to the serverurl endpoint to sync this SoUD (Subset of Users Device)
52 changes: 52 additions & 0 deletions kolibri/core/auth/test/test_morango_integration.py
Original file line number Diff line number Diff line change
@@ -383,6 +383,7 @@ def test_scenarios(self, servers):
s1.create_model(Role, collection_id=fac.id, user_id=alk_user.id, kind="admin")
s0.create_model(Role, collection_id=fac.id, user_id=alk_user.id, kind="admin")
s1.sync(s0, facility)
s2.sync(s0, facility)
role = Role.objects.using(s1.db_alias).get(user=alk_user)
admin_role = Store.objects.using(s1.db_alias).get(id=role.id)
self.assertTrue(admin_role.conflicting_serialized_data)
@@ -397,6 +398,41 @@ def test_scenarios(self, servers):
)
self.assertTrue(Store.objects.using(s1.db_alias).get(id=alk_user.id).deleted)

# assert deleted object is transitively propagated
s2.sync(s1, facility)
self.assertFalse(
FacilityUser.objects.using(s2.db_alias)
.filter(username="Antemblowind")
.exists()
)
self.assertTrue(Store.objects.using(s2.db_alias).get(id=alk_user.id).deleted)

# assert deletion takes priority over update
alk_user = FacilityUser.objects.using(s0.db_alias).create(
username="Antemblowind", facility=facility
)
# Sync to both devices
s1.sync(s0, facility)
s2.sync(s0, facility)

# delete on s0
s0.delete_model(FacilityUser, id=alk_user.id)
# update on s1
s1.update_model(FacilityUser, alk_user.id, username="Antemblowind2")
# Sync deletion to s2
s2.sync(s0, facility)
self.assertFalse(
FacilityUser.objects.using(s2.db_alias).filter(id=alk_user.id).exists()
)
# Sync update to s2
s2.sync(s1, facility)
self.assertFalse(
FacilityUser.objects.using(s2.db_alias).filter(id=alk_user.id).exists()
)
self.assertFalse(
FacilityUser.objects.using(s1.db_alias).filter(id=alk_user.id).exists()
)

# # role deletion and re-creation
# Change roles for users
alto_user = FacilityUser.objects.using(s1.db_alias).get(
@@ -847,6 +883,22 @@ def test_single_user_assignment_sync(self, servers):
self.assert_existence(
self.tablet, kind, assignment_id, should_exist=False
)
if disable_assignment == self.deactivate:
# If we're deactivating the assignment, try reactivating it to check that we
# can make it active again
self.set_active_state(self.laptop_a, kind, assignment_id, True)
self.sync_full_facility_servers()
self.assert_existence(
self.tablet, kind, assignment_id, should_exist=False
)
self.assert_existence(
self.laptop_b, kind, assignment_id, should_exist=True
)
self.sync_single_user(self.laptop_a)
# import IPython; IPython.embed()
self.assert_existence(
self.tablet, kind, assignment_id, should_exist=True
)

# Create exam on Laptop A, single-user sync to tablet, then modify exam on Laptop A and
# single-user sync again to check that "updating" works
Original file line number Diff line number Diff line change
@@ -93,6 +93,7 @@ class ContentContentnode(Base):
learner_needs_bitmask_0 = Column(BigInteger)
learning_activities_bitmask_0 = Column(BigInteger)
ancestors = Column(Text)
admin_imported = Column(Boolean)
parent_id = Column(ForeignKey("content_contentnode.id"), index=True)

lang = relationship("ContentLanguage")
24 changes: 18 additions & 6 deletions kolibri/core/content/management/commands/deletecontent.py
Original file line number Diff line number Diff line change
@@ -20,7 +20,9 @@
logger = logging.getLogger(__name__)


def delete_metadata(channel, node_ids, exclude_node_ids, force_delete):
def delete_metadata(
channel, node_ids, exclude_node_ids, force_delete, ignore_admin_flags
):
# Only delete all metadata if we are not doing selective deletion
delete_all_metadata = not (node_ids or exclude_node_ids)

@@ -31,7 +33,9 @@ def delete_metadata(channel, node_ids, exclude_node_ids, force_delete):
)

# If we have been passed node ids do not do a full deletion pass
set_content_invisible(channel.id, node_ids, exclude_node_ids)
set_content_invisible(
channel.id, node_ids, exclude_node_ids, not ignore_admin_flags
)
# If everything has been made invisible, delete all the metadata
delete_all_metadata = delete_all_metadata or not channel.root.available

@@ -123,11 +127,20 @@ def add_arguments(self, parser):
help="Ensure removal of files",
)

parser.add_argument(
"--ignore_admin_flags",
action="store_false",
dest="ignore_admin_flags",
default=True,
help="Don't modify admin_imported values when deleting content",
)

def handle_async(self, *args, **options):
channel_id = options["channel_id"]
node_ids = options["node_ids"]
exclude_node_ids = options["exclude_node_ids"]
force_delete = options["force_delete"]
ignore_admin_flags = options["ignore_admin_flags"]

try:
channel = ChannelMetadata.objects.get(pk=channel_id)
@@ -136,10 +149,9 @@ def handle_async(self, *args, **options):
"Channel matching id {id} does not exist".format(id=channel_id)
)

(
total_resource_number,
delete_all_metadata,
) = delete_metadata(channel, node_ids, exclude_node_ids, force_delete)
(total_resource_number, delete_all_metadata,) = delete_metadata(
channel, node_ids, exclude_node_ids, force_delete, ignore_admin_flags
)
unused_files = LocalFile.objects.get_unused_files()
# Get the number of files that are being deleted
unused_files_count = unused_files.count()
4 changes: 2 additions & 2 deletions kolibri/core/content/management/commands/generate_schema.py
Original file line number Diff line number Diff line change
@@ -19,7 +19,7 @@
from kolibri.core.content.apps import KolibriContentConfig
from kolibri.core.content.constants.schema_versions import CONTENT_SCHEMA_VERSION
from kolibri.core.content.constants.schema_versions import CURRENT_SCHEMA_VERSION
from kolibri.core.content.utils.channel_import import models_to_exclude
from kolibri.core.content.utils.channel_import import no_schema_models
from kolibri.core.content.utils.sqlalchemybridge import __SQLALCHEMY_CLASSES_MODULE_NAME
from kolibri.core.content.utils.sqlalchemybridge import __SQLALCHEMY_CLASSES_PATH
from kolibri.core.content.utils.sqlalchemybridge import (
@@ -100,7 +100,7 @@ def handle(self, *args, **options):
table_names = [
model._meta.db_table
for name, model in app_config.models.items()
if name != "channelmetadatacache" and model not in models_to_exclude
if name != "channelmetadatacache" and model not in no_schema_models
]
metadata.reflect(bind=engine, only=table_names)
Base = prepare_base(metadata, name=version)
33 changes: 33 additions & 0 deletions kolibri/core/content/management/commands/importchannel.py
Original file line number Diff line number Diff line change
@@ -206,6 +206,13 @@ def progress_callback(bytes):
# if upgrading, import the channel
if not no_upgrade:
try:
# In each case we need to evaluate the queryset now,
# in order to get node ids as they currently are before
# the import. If we did not coerce each of these querysets
# to a list now, they would be lazily evaluated after the
# import, and would reflect the state of the database
# after the import.

# evaluate list so we have the current node ids
node_ids = list(
ContentNode.objects.filter(
@@ -214,13 +221,39 @@ def progress_callback(bytes):
.exclude(kind=content_kinds.TOPIC)
.values_list("id", flat=True)
)
# evaluate list so we have the current node ids
admin_imported_ids = list(
ContentNode.objects.filter(
channel_id=channel_id, available=True, admin_imported=True
)
.exclude(kind=content_kinds.TOPIC)
.values_list("id", flat=True)
)
# evaluate list so we have the current node ids
not_admin_imported_ids = list(
ContentNode.objects.filter(
channel_id=channel_id, available=True, admin_imported=False
)
.exclude(kind=content_kinds.TOPIC)
.values_list("id", flat=True)
)
import_ran = import_channel_by_id(
channel_id, self.is_cancelled, contentfolder
)
if import_ran:
if node_ids:
# annotate default channel db based on previously annotated leaf nodes
update_content_metadata(channel_id, node_ids=node_ids)
if admin_imported_ids:
# Reset admin_imported flag for nodes that were imported by admin
ContentNode.objects.filter_by_uuids(
admin_imported_ids
).update(admin_imported=True)
if not_admin_imported_ids:
# Reset admin_imported flag for nodes that were not imported by admin
ContentNode.objects.filter_by_uuids(
not_admin_imported_ids
).update(admin_imported=False)
else:
# ensure the channel is available to the frontend
ContentCacheKey.update_cache_key()
Loading