diff --git a/contentcuration/automation/utils/appnexus/base.py b/contentcuration/automation/utils/appnexus/base.py index ab9e6d5096..02f3308b14 100644 --- a/contentcuration/automation/utils/appnexus/base.py +++ b/contentcuration/automation/utils/appnexus/base.py @@ -1,6 +1,5 @@ from abc import ABC from abc import abstractmethod -from builtins import NotImplementedError class BackendRequest(object): diff --git a/contentcuration/contentcuration/__init__.py b/contentcuration/contentcuration/__init__.py index d13e951393..b6fc8176d9 100644 --- a/contentcuration/contentcuration/__init__.py +++ b/contentcuration/contentcuration/__init__.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - # This will make sure the app is always imported when # Django starts so that shared_task will use this app. from .celery import app as celery_app # noqa diff --git a/contentcuration/contentcuration/debug_panel_settings.py b/contentcuration/contentcuration/debug_panel_settings.py deleted file mode 100644 index c097acbbc6..0000000000 --- a/contentcuration/contentcuration/debug_panel_settings.py +++ /dev/null @@ -1,29 +0,0 @@ -from .dev_settings import * # noqa - -# These endpoints will throw an error on the django debug panel. -EXCLUDED_DEBUG_URLS = [ - "/content/storage", - - # Disabling sync API because as soon as the sync API gets polled - # the current request data gets overwritten. - # Can be removed after websockets deployment. - "/api/sync", -] - -DEBUG_PANEL_ACTIVE = True - - -def custom_show_toolbar(request): - return not any( - request.path.startswith(url) for url in EXCLUDED_DEBUG_URLS - ) # noqa F405 - - -# if debug_panel exists, add it to our INSTALLED_APPS. -INSTALLED_APPS += ("debug_panel", "debug_toolbar", "pympler") # noqa F405 -MIDDLEWARE += ( # noqa F405 - "debug_toolbar.middleware.DebugToolbarMiddleware", -) -DEBUG_TOOLBAR_CONFIG = { - "SHOW_TOOLBAR_CALLBACK": custom_show_toolbar, -} diff --git a/contentcuration/contentcuration/dev_urls.py b/contentcuration/contentcuration/dev_urls.py index afbb7a83f8..70ef17dc9c 100644 --- a/contentcuration/contentcuration/dev_urls.py +++ b/contentcuration/contentcuration/dev_urls.py @@ -75,9 +75,3 @@ def file_server(request, storage_path=None): re_path(r"^api-auth/", include("rest_framework.urls", namespace="rest_framework")), re_path(r"^content/(?P.+)$", file_server), ] - -if getattr(settings, "DEBUG_PANEL_ACTIVE", False): - - import debug_toolbar - - urlpatterns = [re_path(r"^__debug__/", include(debug_toolbar.urls))] + urlpatterns diff --git a/contentcuration/contentcuration/management/commands/loadconstants.py b/contentcuration/contentcuration/management/commands/loadconstants.py index 8451359db6..3c54ac2025 100644 --- a/contentcuration/contentcuration/management/commands/loadconstants.py +++ b/contentcuration/contentcuration/management/commands/loadconstants.py @@ -1,6 +1,4 @@ import logging as logmodule -from builtins import object -from builtins import str from django.conf import settings from django.contrib.sites.models import Site diff --git a/contentcuration/contentcuration/migrations/0001_squashed_0094_auto_20180910_2342.py b/contentcuration/contentcuration/migrations/0001_squashed_0094_auto_20180910_2342.py index f09d96d66c..72bab632d6 100644 --- a/contentcuration/contentcuration/migrations/0001_squashed_0094_auto_20180910_2342.py +++ b/contentcuration/contentcuration/migrations/0001_squashed_0094_auto_20180910_2342.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.13 on 2018-10-02 17:57 -from __future__ import unicode_literals - import uuid import django.contrib.postgres.fields.jsonb diff --git a/contentcuration/contentcuration/migrations/0002_auto_20181220_1734.py b/contentcuration/contentcuration/migrations/0002_auto_20181220_1734.py index 919b892d9f..3c972e3eb1 100644 --- a/contentcuration/contentcuration/migrations/0002_auto_20181220_1734.py +++ b/contentcuration/contentcuration/migrations/0002_auto_20181220_1734.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-12-20 17:34 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0003_copy_data.py b/contentcuration/contentcuration/migrations/0003_copy_data.py index 402b993dd8..9a934b95a3 100644 --- a/contentcuration/contentcuration/migrations/0003_copy_data.py +++ b/contentcuration/contentcuration/migrations/0003_copy_data.py @@ -1,12 +1,10 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-12-20 17:34 -from __future__ import unicode_literals - -from django.db import migrations - import ast import json +from django.db import migrations + def forwards(apps, schema_editor): Channel = apps.get_model('contentcuration', 'channel') diff --git a/contentcuration/contentcuration/migrations/0004_remove_rename_json_field.py b/contentcuration/contentcuration/migrations/0004_remove_rename_json_field.py index 1504437609..a79cd7c18a 100644 --- a/contentcuration/contentcuration/migrations/0004_remove_rename_json_field.py +++ b/contentcuration/contentcuration/migrations/0004_remove_rename_json_field.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-12-20 17:34 -from __future__ import unicode_literals - from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0097_task.py b/contentcuration/contentcuration/migrations/0097_task.py index 5e411b2076..e8936964e8 100644 --- a/contentcuration/contentcuration/migrations/0097_task.py +++ b/contentcuration/contentcuration/migrations/0097_task.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2019-02-28 20:19 -from __future__ import unicode_literals - import uuid import django.contrib.postgres.fields.jsonb diff --git a/contentcuration/contentcuration/migrations/0098_auto_20190424_1709.py b/contentcuration/contentcuration/migrations/0098_auto_20190424_1709.py index 8ad3980ffc..26d1b1ca74 100644 --- a/contentcuration/contentcuration/migrations/0098_auto_20190424_1709.py +++ b/contentcuration/contentcuration/migrations/0098_auto_20190424_1709.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-04-24 17:09 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb import django.db.models.deletion from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0099_auto_20190715_2201.py b/contentcuration/contentcuration/migrations/0099_auto_20190715_2201.py index 95a18ed834..4d38de0da7 100644 --- a/contentcuration/contentcuration/migrations/0099_auto_20190715_2201.py +++ b/contentcuration/contentcuration/migrations/0099_auto_20190715_2201.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-07-15 22:01 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0100_calculate_included_languages.py b/contentcuration/contentcuration/migrations/0100_calculate_included_languages.py index 62d7c6095b..619b6e6f83 100644 --- a/contentcuration/contentcuration/migrations/0100_calculate_included_languages.py +++ b/contentcuration/contentcuration/migrations/0100_calculate_included_languages.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-06-12 00:00 -from __future__ import unicode_literals - from datetime import datetime from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0101_extra_fields_json_field.py b/contentcuration/contentcuration/migrations/0101_extra_fields_json_field.py index 23ba8a20a2..5ffe791275 100644 --- a/contentcuration/contentcuration/migrations/0101_extra_fields_json_field.py +++ b/contentcuration/contentcuration/migrations/0101_extra_fields_json_field.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Semi-automatically generated by Micah 1.11.20 on 2019-04-24 23:05 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import connection from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0102_auto_20190904_1627.py b/contentcuration/contentcuration/migrations/0102_auto_20190904_1627.py index e22681cc85..29f829baa7 100644 --- a/contentcuration/contentcuration/migrations/0102_auto_20190904_1627.py +++ b/contentcuration/contentcuration/migrations/0102_auto_20190904_1627.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-09-04 16:27 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0103_auto_20190905_0408.py b/contentcuration/contentcuration/migrations/0103_auto_20190905_0408.py index 3adf2ba00b..da1a79ea2a 100644 --- a/contentcuration/contentcuration/migrations/0103_auto_20190905_0408.py +++ b/contentcuration/contentcuration/migrations/0103_auto_20190905_0408.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-09-05 04:08 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0104_auto_20191028_2325.py b/contentcuration/contentcuration/migrations/0104_auto_20191028_2325.py index bb7a1bf983..64e3428099 100644 --- a/contentcuration/contentcuration/migrations/0104_auto_20191028_2325.py +++ b/contentcuration/contentcuration/migrations/0104_auto_20191028_2325.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-10-28 23:25 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0105_channel_published_data.py b/contentcuration/contentcuration/migrations/0105_channel_published_data.py index 8ac4104871..63d9cfd257 100644 --- a/contentcuration/contentcuration/migrations/0105_channel_published_data.py +++ b/contentcuration/contentcuration/migrations/0105_channel_published_data.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-11-13 02:17 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0106_auto_20191113_0217.py b/contentcuration/contentcuration/migrations/0106_auto_20191113_0217.py index 00358a6dde..55f546524c 100644 --- a/contentcuration/contentcuration/migrations/0106_auto_20191113_0217.py +++ b/contentcuration/contentcuration/migrations/0106_auto_20191113_0217.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-11-13 02:17 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0107_auto_20191115_2344.py b/contentcuration/contentcuration/migrations/0107_auto_20191115_2344.py index cbcfa6ec92..93cace4d02 100644 --- a/contentcuration/contentcuration/migrations/0107_auto_20191115_2344.py +++ b/contentcuration/contentcuration/migrations/0107_auto_20191115_2344.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-11-15 23:44 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0108_mptt_tree_id_migration.py b/contentcuration/contentcuration/migrations/0108_mptt_tree_id_migration.py index 05bdd0024c..e9349c4e24 100644 --- a/contentcuration/contentcuration/migrations/0108_mptt_tree_id_migration.py +++ b/contentcuration/contentcuration/migrations/0108_mptt_tree_id_migration.py @@ -1,6 +1,4 @@ # -*- coding: utf-8 -*- -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0109_auto_20191202_1759.py b/contentcuration/contentcuration/migrations/0109_auto_20191202_1759.py index c925e8a638..db4fd7fcb8 100644 --- a/contentcuration/contentcuration/migrations/0109_auto_20191202_1759.py +++ b/contentcuration/contentcuration/migrations/0109_auto_20191202_1759.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-12-02 17:59 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0110_auto_20200511_2245.py b/contentcuration/contentcuration/migrations/0110_auto_20200511_2245.py index 1ed1bdf269..51a0c8581d 100644 --- a/contentcuration/contentcuration/migrations/0110_auto_20200511_2245.py +++ b/contentcuration/contentcuration/migrations/0110_auto_20200511_2245.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.28 on 2020-05-11 22:45 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0111_auto_20200513_2252.py b/contentcuration/contentcuration/migrations/0111_auto_20200513_2252.py index 8a539c6319..c60d7a6268 100644 --- a/contentcuration/contentcuration/migrations/0111_auto_20200513_2252.py +++ b/contentcuration/contentcuration/migrations/0111_auto_20200513_2252.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-05-13 22:52 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0112_auto_20200613_0050.py b/contentcuration/contentcuration/migrations/0112_auto_20200613_0050.py index 9d352e0e84..f236c416ed 100644 --- a/contentcuration/contentcuration/migrations/0112_auto_20200613_0050.py +++ b/contentcuration/contentcuration/migrations/0112_auto_20200613_0050.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-06-13 00:50 -from __future__ import unicode_literals - -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/contentcuration/contentcuration/migrations/0113_channel_tagline.py b/contentcuration/contentcuration/migrations/0113_channel_tagline.py index bd2bde0014..4687dc774f 100644 --- a/contentcuration/contentcuration/migrations/0113_channel_tagline.py +++ b/contentcuration/contentcuration/migrations/0113_channel_tagline.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-06-13 01:02 -from __future__ import unicode_literals - -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/contentcuration/contentcuration/migrations/0114_assessment_item_unique_keypair.py b/contentcuration/contentcuration/migrations/0114_assessment_item_unique_keypair.py index 1500d7531f..1d50578bc8 100644 --- a/contentcuration/contentcuration/migrations/0114_assessment_item_unique_keypair.py +++ b/contentcuration/contentcuration/migrations/0114_assessment_item_unique_keypair.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2021-01-11 20:55 -from __future__ import unicode_literals - from django.db import migrations import contentcuration.models diff --git a/contentcuration/contentcuration/migrations/0115_index_contentnode_node_id_field.py b/contentcuration/contentcuration/migrations/0115_index_contentnode_node_id_field.py index 04dc54c739..246b80972a 100644 --- a/contentcuration/contentcuration/migrations/0115_index_contentnode_node_id_field.py +++ b/contentcuration/contentcuration/migrations/0115_index_contentnode_node_id_field.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-08-06 20:20 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0116_index_channel_contentnode_file.py b/contentcuration/contentcuration/migrations/0116_index_channel_contentnode_file.py index 695ee570e5..32828c0416 100644 --- a/contentcuration/contentcuration/migrations/0116_index_channel_contentnode_file.py +++ b/contentcuration/contentcuration/migrations/0116_index_channel_contentnode_file.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-09-15 18:39 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0117_assessment_id_index.py b/contentcuration/contentcuration/migrations/0117_assessment_id_index.py index aee4e57372..31f2abc73d 100644 --- a/contentcuration/contentcuration/migrations/0117_assessment_id_index.py +++ b/contentcuration/contentcuration/migrations/0117_assessment_id_index.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2020-09-14 21:59 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0118_relaunch_migrations.py b/contentcuration/contentcuration/migrations/0118_relaunch_migrations.py index 8d8c32ac1d..1e4562f24a 100644 --- a/contentcuration/contentcuration/migrations/0118_relaunch_migrations.py +++ b/contentcuration/contentcuration/migrations/0118_relaunch_migrations.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-01-14 15:50 -from __future__ import unicode_literals - import django.db.models.deletion import django.utils.timezone from django.conf import settings diff --git a/contentcuration/contentcuration/migrations/0119_task_channel_id.py b/contentcuration/contentcuration/migrations/0119_task_channel_id.py index bed2d82b4e..a4d69fc81f 100644 --- a/contentcuration/contentcuration/migrations/0119_task_channel_id.py +++ b/contentcuration/contentcuration/migrations/0119_task_channel_id.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-01-14 23:12 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0120_auto_20210128_1646.py b/contentcuration/contentcuration/migrations/0120_auto_20210128_1646.py index 6ce83097b8..96544fa29e 100644 --- a/contentcuration/contentcuration/migrations/0120_auto_20210128_1646.py +++ b/contentcuration/contentcuration/migrations/0120_auto_20210128_1646.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-01-28 16:46 -from __future__ import unicode_literals +import django.db.models.functions.text +from django.db import migrations +from django.db import models import contentcuration.models -from django.db import migrations, models -import django.db.models.functions.text class Migration(migrations.Migration): diff --git a/contentcuration/contentcuration/migrations/0121_auto_20210305_2028.py b/contentcuration/contentcuration/migrations/0121_auto_20210305_2028.py index dc68fea6ee..4628a43bd2 100644 --- a/contentcuration/contentcuration/migrations/0121_auto_20210305_2028.py +++ b/contentcuration/contentcuration/migrations/0121_auto_20210305_2028.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-03-05 20:28 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0122_file_modified_index.py b/contentcuration/contentcuration/migrations/0122_file_modified_index.py index b83b432a4d..45702de28e 100644 --- a/contentcuration/contentcuration/migrations/0122_file_modified_index.py +++ b/contentcuration/contentcuration/migrations/0122_file_modified_index.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-03-05 20:28 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0123_auto_20210407_0057.py b/contentcuration/contentcuration/migrations/0123_auto_20210407_0057.py index e25ade1e36..e181f57ac0 100644 --- a/contentcuration/contentcuration/migrations/0123_auto_20210407_0057.py +++ b/contentcuration/contentcuration/migrations/0123_auto_20210407_0057.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-04-07 00:57 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0124_user_feature_flags.py b/contentcuration/contentcuration/migrations/0124_user_feature_flags.py index deb0a29783..5f4e393c27 100644 --- a/contentcuration/contentcuration/migrations/0124_user_feature_flags.py +++ b/contentcuration/contentcuration/migrations/0124_user_feature_flags.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-04-27 20:39 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0125_user_feature_flags_default.py b/contentcuration/contentcuration/migrations/0125_user_feature_flags_default.py index 59d2266dcf..1f1e32c082 100644 --- a/contentcuration/contentcuration/migrations/0125_user_feature_flags_default.py +++ b/contentcuration/contentcuration/migrations/0125_user_feature_flags_default.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-04-27 20:39 -from __future__ import unicode_literals - import django.contrib.postgres.fields.jsonb from django.db import migrations diff --git a/contentcuration/contentcuration/migrations/0126_auto_20210219_2314.py b/contentcuration/contentcuration/migrations/0126_auto_20210219_2314.py index 82ee59c7c3..2f66e54cff 100644 --- a/contentcuration/contentcuration/migrations/0126_auto_20210219_2314.py +++ b/contentcuration/contentcuration/migrations/0126_auto_20210219_2314.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-02-19 23:14 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0127_auto_20210504_1744.py b/contentcuration/contentcuration/migrations/0127_auto_20210504_1744.py index ffd63ab8b0..9c426ac588 100644 --- a/contentcuration/contentcuration/migrations/0127_auto_20210504_1744.py +++ b/contentcuration/contentcuration/migrations/0127_auto_20210504_1744.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-05-04 17:44 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/migrations/0128_auto_20210511_1605.py b/contentcuration/contentcuration/migrations/0128_auto_20210511_1605.py index 97ec962be5..7bfa3e3d67 100644 --- a/contentcuration/contentcuration/migrations/0128_auto_20210511_1605.py +++ b/contentcuration/contentcuration/migrations/0128_auto_20210511_1605.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-05-11 16:05 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/contentcuration/production_settings.py b/contentcuration/contentcuration/production_settings.py index da6a199125..5fbaa5ee86 100644 --- a/contentcuration/contentcuration/production_settings.py +++ b/contentcuration/contentcuration/production_settings.py @@ -1,7 +1,5 @@ # flake8: noqa # ignore the entire file in general, since we do a lot of overrides here which break pep8 compat -from __future__ import absolute_import - from . import settings as base_settings from .settings import * # noqa from contentcuration.utils.secretmanagement import get_secret diff --git a/contentcuration/contentcuration/profile_settings.py b/contentcuration/contentcuration/profile_settings.py deleted file mode 100644 index 7b0e35b389..0000000000 --- a/contentcuration/contentcuration/profile_settings.py +++ /dev/null @@ -1,3 +0,0 @@ -from .not_production_settings import * # noqa - -MIDDLEWARE = ("whitenoise.middleware.WhiteNoiseMiddleware",) + MIDDLEWARE # noqa diff --git a/contentcuration/contentcuration/ricecooker_versions.py b/contentcuration/contentcuration/ricecooker_versions.py index 97716a65b9..ed82ffeb3e 100644 --- a/contentcuration/contentcuration/ricecooker_versions.py +++ b/contentcuration/contentcuration/ricecooker_versions.py @@ -1,8 +1,3 @@ -from future import standard_library - -standard_library.install_aliases() - - """ Latest ricecooker version Any version >= VERSION_OK will get a message that diff --git a/contentcuration/contentcuration/settings.py b/contentcuration/contentcuration/settings.py index 62825373b3..6145a35b79 100644 --- a/contentcuration/contentcuration/settings.py +++ b/contentcuration/contentcuration/settings.py @@ -15,7 +15,6 @@ import re import sys from datetime import timedelta -from tempfile import gettempdir from django.utils.timezone import now @@ -84,7 +83,6 @@ 'django_s3_storage', 'webpack_loader', 'django_filters', - 'mathfilters', 'django.contrib.postgres', 'django_celery_results', 'kolibri_public', @@ -137,22 +135,6 @@ # 'django.middleware.cache.FetchFromCacheMiddleware', ) -if os.getenv("PROFILE_STUDIO_FULL"): - MIDDLEWARE = MIDDLEWARE + ("pyinstrument.middleware.ProfilerMiddleware",) - PYINSTRUMENT_PROFILE_DIR = os.getenv("PROFILE_DIR") or "{}/profile".format( - gettempdir() - ) -elif os.getenv("PROFILE_STUDIO_FILTER"): - MIDDLEWARE = MIDDLEWARE + ("customizable_django_profiler.cProfileMiddleware",) - PROFILER = { - "activate": True, - "output": ["dump", "console"], - "count": "10", - "file_location": os.getenv("PROFILE_DIR") - or "{}/profile/studio".format(gettempdir()), - "trigger": "query_param:{}".format(os.getenv("PROFILE_STUDIO_FILTER")), - } - if os.getenv("GCLOUD_ERROR_REPORTING"): MIDDLEWARE = ( "contentcuration.middleware.error_reporting.ErrorReportingMiddleware", diff --git a/contentcuration/contentcuration/tasks.py b/contentcuration/contentcuration/tasks.py index 39f89805ce..5ebb81c08e 100644 --- a/contentcuration/contentcuration/tasks.py +++ b/contentcuration/contentcuration/tasks.py @@ -3,9 +3,6 @@ `contentcuration.utils.celery.tasks.CeleryTask`. See the methods of that class for enqueuing and fetching results of the tasks. """ -from __future__ import absolute_import -from __future__ import unicode_literals - import logging import time diff --git a/contentcuration/contentcuration/tests/base.py b/contentcuration/contentcuration/tests/base.py index ad110c7302..f09fee7d9a 100644 --- a/contentcuration/contentcuration/tests/base.py +++ b/contentcuration/contentcuration/tests/base.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import - -from builtins import str - from django.conf import settings from django.core.files.uploadedfile import SimpleUploadedFile from django.core.management import call_command diff --git a/contentcuration/contentcuration/tests/helpers.py b/contentcuration/contentcuration/tests/helpers.py index 73371135be..b0eeecb4a3 100644 --- a/contentcuration/contentcuration/tests/helpers.py +++ b/contentcuration/contentcuration/tests/helpers.py @@ -1,4 +1,3 @@ -from builtins import str from importlib import import_module import mock diff --git a/contentcuration/contentcuration/tests/test_asynctask.py b/contentcuration/contentcuration/tests/test_asynctask.py index 4496680f9c..9521fc6adf 100644 --- a/contentcuration/contentcuration/tests/test_asynctask.py +++ b/contentcuration/contentcuration/tests/test_asynctask.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import threading import time import uuid diff --git a/contentcuration/contentcuration/tests/test_authentication.py b/contentcuration/contentcuration/tests/test_authentication.py index 5a8979d6ae..bae5a743c4 100644 --- a/contentcuration/contentcuration/tests/test_authentication.py +++ b/contentcuration/contentcuration/tests/test_authentication.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import urllib.parse from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/test_channel_model.py b/contentcuration/contentcuration/tests/test_channel_model.py index 0014aeb41c..1ea51a2bd6 100755 --- a/contentcuration/contentcuration/tests/test_channel_model.py +++ b/contentcuration/contentcuration/tests/test_channel_model.py @@ -1,11 +1,8 @@ #!/usr/bin/env python -from __future__ import division - import json from datetime import datetime from django.urls import reverse_lazy -from past.utils import old_div from .base import BaseAPITestCase from .base import StudioTestCase @@ -234,7 +231,7 @@ def test_save_channels_to_token(self): def test_public_endpoint(self): """ Make sure public endpoint returns all the channels under the token """ - published_channel_count = int(old_div(len(self.channels), 2)) + published_channel_count = int(len(self.channels) // 2) for c in self.channels[:published_channel_count]: c.main_tree.published = True c.main_tree.save() diff --git a/contentcuration/contentcuration/tests/test_channel_views.py b/contentcuration/contentcuration/tests/test_channel_views.py index 5ca54b28a3..439d7c8d95 100644 --- a/contentcuration/contentcuration/tests/test_channel_views.py +++ b/contentcuration/contentcuration/tests/test_channel_views.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.conf import settings from django.core.cache import cache from django.db import connection diff --git a/contentcuration/contentcuration/tests/test_chef_pipeline.py b/contentcuration/contentcuration/tests/test_chef_pipeline.py index 3a0e0ea0c9..51ee683209 100644 --- a/contentcuration/contentcuration/tests/test_chef_pipeline.py +++ b/contentcuration/contentcuration/tests/test_chef_pipeline.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import json from django.core.files.uploadedfile import SimpleUploadedFile diff --git a/contentcuration/contentcuration/tests/test_contentnodes.py b/contentcuration/contentcuration/tests/test_contentnodes.py index d9b0ae235d..383861a2c3 100644 --- a/contentcuration/contentcuration/tests/test_contentnodes.py +++ b/contentcuration/contentcuration/tests/test_contentnodes.py @@ -1,13 +1,7 @@ -from __future__ import absolute_import -from __future__ import division - import random import string import time import uuid -from builtins import range -from builtins import str -from builtins import zip import pytest from django.db import IntegrityError @@ -18,7 +12,6 @@ from le_utils.constants import format_presets from mixer.backend.django import mixer from mock import patch -from past.utils import old_div from . import testdata from .base import StudioTestCase @@ -44,7 +37,7 @@ def _create_nodes(num_nodes, title, parent=None, levels=2): for i in range(num_nodes): new_node = ContentNode.objects.create(title=title, parent=parent, kind=topic) # create a couple levels for testing purposes - if i > 0 and levels > 1 and i % (old_div(num_nodes, levels)) == 0: + if i > 0 and levels > 1 and i % (num_nodes // levels) == 0: parent = new_node diff --git a/contentcuration/contentcuration/tests/test_createchannel.py b/contentcuration/contentcuration/tests/test_createchannel.py index 01405e2622..06d7f3c393 100644 --- a/contentcuration/contentcuration/tests/test_createchannel.py +++ b/contentcuration/contentcuration/tests/test_createchannel.py @@ -1,8 +1,4 @@ -from __future__ import absolute_import - import json -from builtins import range -from builtins import str import requests from django.urls import reverse_lazy diff --git a/contentcuration/contentcuration/tests/test_exportchannel.py b/contentcuration/contentcuration/tests/test_exportchannel.py index 71b09bda94..a235fafe86 100644 --- a/contentcuration/contentcuration/tests/test_exportchannel.py +++ b/contentcuration/contentcuration/tests/test_exportchannel.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import json import os import random diff --git a/contentcuration/contentcuration/tests/test_files.py b/contentcuration/contentcuration/tests/test_files.py index 215743e93d..eabca028e0 100755 --- a/contentcuration/contentcuration/tests/test_files.py +++ b/contentcuration/contentcuration/tests/test_files.py @@ -1,23 +1,15 @@ # -*- coding: utf-8 -*- -from __future__ import absolute_import - import json -from builtins import str import pytest from django.core.files.storage import default_storage -from django.core.files.uploadedfile import SimpleUploadedFile -from django.urls import reverse_lazy from le_utils.constants import content_kinds -from le_utils.constants import format_presets from mock import patch -from past.builtins import basestring from .base import BaseAPITestCase from .base import StudioTestCase from .testdata import base64encoding from .testdata import generated_base64encoding -from .testdata import srt_subtitle from contentcuration.api import write_raw_content_to_storage from contentcuration.models import ContentNode from contentcuration.models import delete_empty_file_reference @@ -69,7 +61,7 @@ def test_internal_thumbnail(self): } ] map_files_to_node(self.user, node, file_data) - self.assertTrue(isinstance(node.thumbnail_encoding, basestring)) + self.assertTrue(isinstance(node.thumbnail_encoding, str)) thumbnail_data = json.loads(node.thumbnail_encoding) self.assertEqual(thumbnail_data["base64"], generated_base64encoding()) diff --git a/contentcuration/contentcuration/tests/test_format_preset_model.py b/contentcuration/contentcuration/tests/test_format_preset_model.py index 93287a9d2c..555b43937d 100644 --- a/contentcuration/contentcuration/tests/test_format_preset_model.py +++ b/contentcuration/contentcuration/tests/test_format_preset_model.py @@ -1,7 +1,3 @@ -from __future__ import absolute_import - -import types - from .base import StudioTestCase from contentcuration.models import FormatPreset diff --git a/contentcuration/contentcuration/tests/test_gcs_storage.py b/contentcuration/contentcuration/tests/test_gcs_storage.py index 8af75f4f8e..0add165805 100755 --- a/contentcuration/contentcuration/tests/test_gcs_storage.py +++ b/contentcuration/contentcuration/tests/test_gcs_storage.py @@ -1,6 +1,4 @@ #!/usr/bin/env python -from future import standard_library -standard_library.install_aliases() from io import BytesIO import pytest diff --git a/contentcuration/contentcuration/tests/test_rest_framework.py b/contentcuration/contentcuration/tests/test_rest_framework.py index 6cb0acfd6a..7baf24ee0a 100644 --- a/contentcuration/contentcuration/tests/test_rest_framework.py +++ b/contentcuration/contentcuration/tests/test_rest_framework.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import json import pytest @@ -39,7 +37,7 @@ def test_unauthorized_get(self): def test_readonly_fields(self): original_version = self.channel.version url = reverse_lazy("channel-list") + "/" + self.channel.pk - response = self.put( + self.put( url, { "version": original_version + 1, diff --git a/contentcuration/contentcuration/tests/test_serializers.py b/contentcuration/contentcuration/tests/test_serializers.py index 9ea2e2529c..3d1a9e4f02 100644 --- a/contentcuration/contentcuration/tests/test_serializers.py +++ b/contentcuration/contentcuration/tests/test_serializers.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.db.models.query import QuerySet from le_utils.constants import content_kinds from mock import Mock diff --git a/contentcuration/contentcuration/tests/test_sushibar_endpoints.py b/contentcuration/contentcuration/tests/test_sushibar_endpoints.py index 6c88fbc29d..861cea196d 100644 --- a/contentcuration/contentcuration/tests/test_sushibar_endpoints.py +++ b/contentcuration/contentcuration/tests/test_sushibar_endpoints.py @@ -1,11 +1,6 @@ -from __future__ import absolute_import -from __future__ import print_function - import functools import json import os -from builtins import str -from builtins import zip from django.urls import reverse_lazy diff --git a/contentcuration/contentcuration/tests/test_sync.py b/contentcuration/contentcuration/tests/test_sync.py index 3a2ba590c5..c411d3a3e6 100644 --- a/contentcuration/contentcuration/tests/test_sync.py +++ b/contentcuration/contentcuration/tests/test_sync.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/test_urlendpoints.py b/contentcuration/contentcuration/tests/test_urlendpoints.py index 46750925e0..3771aebee4 100644 --- a/contentcuration/contentcuration/tests/test_urlendpoints.py +++ b/contentcuration/contentcuration/tests/test_urlendpoints.py @@ -1,7 +1,4 @@ -from __future__ import absolute_import - import importlib -from builtins import str from django.conf import settings from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/test_user.py b/contentcuration/contentcuration/tests/test_user.py index 9fda1ceefe..0be1b140bb 100644 --- a/contentcuration/contentcuration/tests/test_user.py +++ b/contentcuration/contentcuration/tests/test_user.py @@ -7,7 +7,6 @@ import json import sys import tempfile -from builtins import range from django.core.management import call_command from django.test import TransactionTestCase diff --git a/contentcuration/contentcuration/tests/test_utils.py b/contentcuration/contentcuration/tests/test_utils.py index 6012d56431..82bec7738b 100644 --- a/contentcuration/contentcuration/tests/test_utils.py +++ b/contentcuration/contentcuration/tests/test_utils.py @@ -1,8 +1,3 @@ -from __future__ import absolute_import - -from future import standard_library -standard_library.install_aliases() -from builtins import str from io import BytesIO from django.conf import settings diff --git a/contentcuration/contentcuration/tests/test_zipcontentview.py b/contentcuration/contentcuration/tests/test_zipcontentview.py index 270a131001..7d6056d945 100644 --- a/contentcuration/contentcuration/tests/test_zipcontentview.py +++ b/contentcuration/contentcuration/tests/test_zipcontentview.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import os import tempfile import zipfile diff --git a/contentcuration/contentcuration/tests/testdata.py b/contentcuration/contentcuration/tests/testdata.py index bbae770ef1..ed05189f0d 100644 --- a/contentcuration/contentcuration/tests/testdata.py +++ b/contentcuration/contentcuration/tests/testdata.py @@ -1,7 +1,4 @@ # -*- coding: utf-8 -*- -from future import standard_library -standard_library.install_aliases() - import hashlib import json import logging diff --git a/contentcuration/contentcuration/tests/viewsets/test_assessmentitem.py b/contentcuration/contentcuration/tests/viewsets/test_assessmentitem.py index aff73eeb38..ebc04ac7c2 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_assessmentitem.py +++ b/contentcuration/contentcuration/tests/viewsets/test_assessmentitem.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import json import uuid diff --git a/contentcuration/contentcuration/tests/viewsets/test_bookmark.py b/contentcuration/contentcuration/tests/viewsets/test_bookmark.py index 04d53cd756..f2ccdc550c 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_bookmark.py +++ b/contentcuration/contentcuration/tests/viewsets/test_bookmark.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.urls import reverse from contentcuration import models diff --git a/contentcuration/contentcuration/tests/viewsets/test_channel.py b/contentcuration/contentcuration/tests/viewsets/test_channel.py index 17549ab128..76c5ac1ed3 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_channel.py +++ b/contentcuration/contentcuration/tests/viewsets/test_channel.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid import mock diff --git a/contentcuration/contentcuration/tests/viewsets/test_channelset.py b/contentcuration/contentcuration/tests/viewsets/test_channelset.py index 19ec846f11..2fb108a3a2 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_channelset.py +++ b/contentcuration/contentcuration/tests/viewsets/test_channelset.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/viewsets/test_clipboard.py b/contentcuration/contentcuration/tests/viewsets/test_clipboard.py index 59113c0532..50f65f7624 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_clipboard.py +++ b/contentcuration/contentcuration/tests/viewsets/test_clipboard.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid from django.core.management import call_command diff --git a/contentcuration/contentcuration/tests/viewsets/test_contentnode.py b/contentcuration/contentcuration/tests/viewsets/test_contentnode.py index cf2a6fe3d5..28519c2762 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_contentnode.py +++ b/contentcuration/contentcuration/tests/viewsets/test_contentnode.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid import mock diff --git a/contentcuration/contentcuration/tests/viewsets/test_file.py b/contentcuration/contentcuration/tests/viewsets/test_file.py index 2a4e4e2376..e5c8680412 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_file.py +++ b/contentcuration/contentcuration/tests/viewsets/test_file.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/viewsets/test_invitation.py b/contentcuration/contentcuration/tests/viewsets/test_invitation.py index fad9b52be4..22e6499a64 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_invitation.py +++ b/contentcuration/contentcuration/tests/viewsets/test_invitation.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - import uuid from django.urls import reverse diff --git a/contentcuration/contentcuration/tests/viewsets/test_user.py b/contentcuration/contentcuration/tests/viewsets/test_user.py index 54c3f98ea5..64f052ed9e 100644 --- a/contentcuration/contentcuration/tests/viewsets/test_user.py +++ b/contentcuration/contentcuration/tests/viewsets/test_user.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.urls import reverse from contentcuration.tests import testdata diff --git a/contentcuration/contentcuration/utils/csv_writer.py b/contentcuration/contentcuration/utils/csv_writer.py index 413843ae3a..a5fecd4ba7 100644 --- a/contentcuration/contentcuration/utils/csv_writer.py +++ b/contentcuration/contentcuration/utils/csv_writer.py @@ -3,7 +3,6 @@ import os import re import sys -from builtins import next from django.conf import settings from django.contrib.sites.models import Site diff --git a/contentcuration/contentcuration/utils/files.py b/contentcuration/contentcuration/utils/files.py index 1d1125293a..a5d8361e8c 100644 --- a/contentcuration/contentcuration/utils/files.py +++ b/contentcuration/contentcuration/utils/files.py @@ -1,11 +1,9 @@ -from future import standard_library -standard_library.install_aliases() import base64 import copy -from io import BytesIO import os import re import tempfile +from io import BytesIO from multiprocessing.dummy import Pool import requests diff --git a/contentcuration/contentcuration/utils/import_tools.py b/contentcuration/contentcuration/utils/import_tools.py index 532adc4a52..e662b75fc4 100644 --- a/contentcuration/contentcuration/utils/import_tools.py +++ b/contentcuration/contentcuration/utils/import_tools.py @@ -1,8 +1,4 @@ # -*- coding: utf-8 -*- -from future import standard_library -standard_library.install_aliases() -from builtins import str -from past.builtins import basestring import datetime import json import logging @@ -167,7 +163,7 @@ def write_to_thumbnail_file(raw_thumbnail): raw_thumbnail (str): base64 encoded thumbnail Returns: thumbnail filename """ - if raw_thumbnail and isinstance(raw_thumbnail, basestring) and raw_thumbnail != "" and 'static' not in raw_thumbnail: + if raw_thumbnail and isinstance(raw_thumbnail, str) and raw_thumbnail != "" and 'static' not in raw_thumbnail: with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tempf: try: tempf.close() @@ -210,7 +206,7 @@ def create_nodes(cursor, target_id, parent, indent=1, download_url=None): assessment_query = "SELECT mastery_model, randomize FROM {table} WHERE contentnode_id='{node}'".format(table=ASSESSMENTMETADATA_TABLE, node=id) result = cursor.execute(assessment_query).fetchone() extra_fields = result[0] if result else {} - if isinstance(extra_fields, basestring): + if isinstance(extra_fields, str): extra_fields = json.loads(extra_fields) if result: extra_fields.update({"randomize": result[1]}) diff --git a/contentcuration/contentcuration/utils/nodes.py b/contentcuration/contentcuration/utils/nodes.py index c84467a5cc..78e9cdc80f 100644 --- a/contentcuration/contentcuration/utils/nodes.py +++ b/contentcuration/contentcuration/utils/nodes.py @@ -1,11 +1,7 @@ -from __future__ import division - import json import logging import os import time -from builtins import next -from builtins import str from io import BytesIO from django.conf import settings diff --git a/contentcuration/contentcuration/utils/parser.py b/contentcuration/contentcuration/utils/parser.py index 9fb48bc832..aeadcad33a 100644 --- a/contentcuration/contentcuration/utils/parser.py +++ b/contentcuration/contentcuration/utils/parser.py @@ -17,13 +17,10 @@ EXPONENT: [DECIMAL | INTEGER]e+{0,1}[INTEGER] """ -from __future__ import division - import json import re from django.utils.translation import get_language -from past.utils import old_div LANGUAGE = get_language() or "" @@ -52,7 +49,7 @@ fraction=FRACTION.pattern, integer=INTEGER.pattern)) PERCENTAGE = re.compile("({num})%".format(num=VALID_NUMBER.pattern)) -EXPONENT = re.compile("((?:{decimal}|{integer})e\+?{integer})".format(decimal=DECIMAL.pattern, integer=INTEGER.pattern)) +EXPONENT = re.compile("((?:{decimal}|{integer})e\\+?{integer})".format(decimal=DECIMAL.pattern, integer=INTEGER.pattern)) def extract_value(text): @@ -78,20 +75,20 @@ def parse_decimal(text): def parse_fraction(text): match = FRACTION.search(text) - return match and old_div(parse_integer(match.group(2)), parse_integer(match.group(3))) + return match and float(parse_integer(match.group(2))) / float(parse_integer(match.group(3))) def parse_mixed_number(text): match = MIXED_NUMBER.search(text) - if(match): + if match: number = parse_integer(match.group(1)) - return (abs(number) + parse_fraction(match.group(3))) * (old_div(number, abs(number))) + return (abs(number) + parse_fraction(match.group(3))) * (float(number) / float(abs(number))) return None def parse_percentage(text): match = PERCENTAGE.search(text) - return match and old_div(extract_value(match.group(1)), 100) + return match and extract_value(match.group(1)) / float(100) def parse_exponent(text): diff --git a/contentcuration/contentcuration/utils/publish.py b/contentcuration/contentcuration/utils/publish.py index dfe8249c4a..210eaf5efb 100644 --- a/contentcuration/contentcuration/utils/publish.py +++ b/contentcuration/contentcuration/utils/publish.py @@ -1,5 +1,3 @@ -from __future__ import division - import itertools import json import logging as logmodule @@ -10,7 +8,6 @@ import traceback import uuid import zipfile -from builtins import str from copy import deepcopy from itertools import chain @@ -42,8 +39,6 @@ from le_utils.constants import file_formats from le_utils.constants import format_presets from le_utils.constants import roles -from past.builtins import basestring -from past.utils import old_div from search.models import ChannelFullTextSearch from search.models import ContentNodeFullTextSearch from search.utils import get_fts_annotated_channel_qs @@ -208,7 +203,7 @@ def __init__( self.root_node = root_node task_percent_total = 80.0 total_nodes = root_node.get_descendant_count() + 1 # make sure we include root_node - self.percent_per_node = old_div(task_percent_total, total_nodes) + self.percent_per_node = task_percent_total / float(total_nodes) self.progress_tracker = progress_tracker self.default_language = default_language self.channel_id = channel_id @@ -511,7 +506,7 @@ def create_perseus_exercise(ccnode, kolibrinode, exercise_data, user_id=None): def parse_assessment_metadata(ccnode): extra_fields = ccnode.extra_fields - if isinstance(extra_fields, basestring): + if isinstance(extra_fields, str): extra_fields = json.loads(extra_fields) extra_fields = migrate_extra_fields(extra_fields) or {} randomize = extra_fields.get('randomize') if extra_fields.get('randomize') is not None else True diff --git a/contentcuration/contentcuration/utils/sync.py b/contentcuration/contentcuration/utils/sync.py index 5b3664002a..03a33d9249 100644 --- a/contentcuration/contentcuration/utils/sync.py +++ b/contentcuration/contentcuration/utils/sync.py @@ -1,5 +1,3 @@ -from __future__ import division - import copy import logging diff --git a/contentcuration/contentcuration/views/internal.py b/contentcuration/contentcuration/views/internal.py index f2f268ca1a..184506b21a 100644 --- a/contentcuration/contentcuration/views/internal.py +++ b/contentcuration/contentcuration/views/internal.py @@ -1,6 +1,5 @@ import json import logging -from builtins import str from collections import namedtuple from distutils.version import LooseVersion @@ -22,7 +21,6 @@ from le_utils.constants.labels.needs import NEEDSLIST from le_utils.constants.labels.resource_type import RESOURCETYPELIST from le_utils.constants.labels.subjects import SUBJECTSLIST -from past.builtins import basestring from rest_framework import status from rest_framework.authentication import SessionAuthentication from rest_framework.authentication import TokenAuthentication @@ -481,7 +479,7 @@ def create_channel(channel_data, user): raise SuspiciousOperation("User is not authorized to edit this channel") extra_fields = channel_data.get('extra_fields') or {} - if isinstance(extra_fields, basestring): + if isinstance(extra_fields, str): extra_fields = json.loads(extra_fields) extra_fields.update({'ricecooker_version': channel.ricecooker_version}) @@ -726,7 +724,7 @@ def create_node(node_data, parent_node, sort_order): # noqa: C901 raise ObjectDoesNotExist("Invalid license found") extra_fields = node_data["extra_fields"] or {} - if isinstance(extra_fields, basestring): + if isinstance(extra_fields, str): extra_fields = json.loads(extra_fields) # validate completion criteria diff --git a/contentcuration/kolibri_content/apps.py b/contentcuration/kolibri_content/apps.py index 633df0795a..f7a8e2adf0 100644 --- a/contentcuration/kolibri_content/apps.py +++ b/contentcuration/kolibri_content/apps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/contentcuration/kolibri_content/base_models.py b/contentcuration/kolibri_content/base_models.py index 0fbe59c710..786a927740 100644 --- a/contentcuration/kolibri_content/base_models.py +++ b/contentcuration/kolibri_content/base_models.py @@ -6,8 +6,6 @@ In addition, any foreign key fields have on_delete definitions added for Django 3 compatibility. https://github.com/learningequality/kolibri/blob/0f6bb6781a4453cd9fdc836d52b65dd69e395b20/kolibri/core/content/base_models.py#L68 """ -from __future__ import print_function - from django.db import models from kolibri_content.fields import DateTimeTzField from kolibri_content.fields import JSONField diff --git a/contentcuration/kolibri_content/migrations/0001_initial.py b/contentcuration/kolibri_content/migrations/0001_initial.py index f3a39aa5af..6cc24249c8 100644 --- a/contentcuration/kolibri_content/migrations/0001_initial.py +++ b/contentcuration/kolibri_content/migrations/0001_initial.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.13 on 2018-02-14 22:37 -from __future__ import unicode_literals - import django.db.models.deletion import django.db.models.manager import jsonfield.fields diff --git a/contentcuration/kolibri_content/migrations/0002_auto_20180327_1414.py b/contentcuration/kolibri_content/migrations/0002_auto_20180327_1414.py index d5264f98e8..7075639eda 100644 --- a/contentcuration/kolibri_content/migrations/0002_auto_20180327_1414.py +++ b/contentcuration/kolibri_content/migrations/0002_auto_20180327_1414.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.13 on 2018-03-27 21:14 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0003_contentnode_coach_content.py b/contentcuration/kolibri_content/migrations/0003_contentnode_coach_content.py index d887392a3c..da83434af1 100644 --- a/contentcuration/kolibri_content/migrations/0003_contentnode_coach_content.py +++ b/contentcuration/kolibri_content/migrations/0003_contentnode_coach_content.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.9.13 on 2018-03-28 00:14 -from __future__ import unicode_literals - -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/contentcuration/kolibri_content/migrations/0004_auto_20180910_2342.py b/contentcuration/kolibri_content/migrations/0004_auto_20180910_2342.py index 0974bc2189..deca7ee32b 100644 --- a/contentcuration/kolibri_content/migrations/0004_auto_20180910_2342.py +++ b/contentcuration/kolibri_content/migrations/0004_auto_20180910_2342.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.15 on 2018-09-10 23:42 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0005_auto_20190424_1709.py b/contentcuration/kolibri_content/migrations/0005_auto_20190424_1709.py index ffa09d5cb6..06777a740c 100644 --- a/contentcuration/kolibri_content/migrations/0005_auto_20190424_1709.py +++ b/contentcuration/kolibri_content/migrations/0005_auto_20190424_1709.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-04-24 17:09 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0006_auto_20191028_2325.py b/contentcuration/kolibri_content/migrations/0006_auto_20191028_2325.py index 34876e4266..7082842671 100644 --- a/contentcuration/kolibri_content/migrations/0006_auto_20191028_2325.py +++ b/contentcuration/kolibri_content/migrations/0006_auto_20191028_2325.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2019-10-28 23:25 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0007_auto_20200613_0050.py b/contentcuration/kolibri_content/migrations/0007_auto_20200613_0050.py index e902d18c54..4789ff682f 100644 --- a/contentcuration/kolibri_content/migrations/0007_auto_20200613_0050.py +++ b/contentcuration/kolibri_content/migrations/0007_auto_20200613_0050.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-06-13 00:50 -from __future__ import unicode_literals - -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/contentcuration/kolibri_content/migrations/0008_channelmetadata_tagline.py b/contentcuration/kolibri_content/migrations/0008_channelmetadata_tagline.py index cf3f6bf34d..fd39f84c8c 100644 --- a/contentcuration/kolibri_content/migrations/0008_channelmetadata_tagline.py +++ b/contentcuration/kolibri_content/migrations/0008_channelmetadata_tagline.py @@ -1,8 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-06-13 01:02 -from __future__ import unicode_literals - -from django.db import migrations, models +from django.db import migrations +from django.db import models class Migration(migrations.Migration): diff --git a/contentcuration/kolibri_content/migrations/0009_contentnode_options.py b/contentcuration/kolibri_content/migrations/0009_contentnode_options.py index 5644d7a44e..369f56f92c 100644 --- a/contentcuration/kolibri_content/migrations/0009_contentnode_options.py +++ b/contentcuration/kolibri_content/migrations/0009_contentnode_options.py @@ -1,9 +1,7 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-04-11 19:07 -from __future__ import unicode_literals - -from django.db import migrations import jsonfield.fields +from django.db import migrations class Migration(migrations.Migration): diff --git a/contentcuration/kolibri_content/migrations/0010_auto_20210202_0604.py b/contentcuration/kolibri_content/migrations/0010_auto_20210202_0604.py index 7800d2c5e9..4572673628 100644 --- a/contentcuration/kolibri_content/migrations/0010_auto_20210202_0604.py +++ b/contentcuration/kolibri_content/migrations/0010_auto_20210202_0604.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-02-02 06:04 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0011_auto_20210504_1744.py b/contentcuration/kolibri_content/migrations/0011_auto_20210504_1744.py index feddf0b1e4..72a8620702 100644 --- a/contentcuration/kolibri_content/migrations/0011_auto_20210504_1744.py +++ b/contentcuration/kolibri_content/migrations/0011_auto_20210504_1744.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-05-04 17:44 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/migrations/0012_auto_20210511_1605.py b/contentcuration/kolibri_content/migrations/0012_auto_20210511_1605.py index 757419a2cf..bb08a8f64a 100644 --- a/contentcuration/kolibri_content/migrations/0012_auto_20210511_1605.py +++ b/contentcuration/kolibri_content/migrations/0012_auto_20210511_1605.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.29 on 2021-05-11 16:05 -from __future__ import unicode_literals - from django.db import migrations from django.db import models diff --git a/contentcuration/kolibri_content/models.py b/contentcuration/kolibri_content/models.py index 1ceab27b64..5a6476d2d1 100644 --- a/contentcuration/kolibri_content/models.py +++ b/contentcuration/kolibri_content/models.py @@ -3,8 +3,6 @@ and then manually adding the fields and models from legacy_models in order to create a completely backwards compatible export database. """ -from __future__ import unicode_literals - from django.db import models from kolibri_content import base_models from kolibri_content.fields import UUIDField diff --git a/contentcuration/kolibri_content/router.py b/contentcuration/kolibri_content/router.py index 9a991a9df1..35e3fe72ba 100644 --- a/contentcuration/kolibri_content/router.py +++ b/contentcuration/kolibri_content/router.py @@ -11,7 +11,6 @@ """ import os import threading -from builtins import object from functools import wraps from django.apps import apps diff --git a/contentcuration/kolibri_public/tests/test_public_v1_api.py b/contentcuration/kolibri_public/tests/test_public_v1_api.py index ecaac9c177..442830471a 100644 --- a/contentcuration/kolibri_public/tests/test_public_v1_api.py +++ b/contentcuration/kolibri_public/tests/test_public_v1_api.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.conf import settings from django.core.cache import cache from django.urls import reverse diff --git a/contentcuration/search/apps.py b/contentcuration/search/apps.py index 5c529b4df0..5726231f79 100644 --- a/contentcuration/search/apps.py +++ b/contentcuration/search/apps.py @@ -1,5 +1,3 @@ -from __future__ import unicode_literals - from django.apps import AppConfig diff --git a/contentcuration/search/migrations/0001_initial.py b/contentcuration/search/migrations/0001_initial.py index a8ec0fac70..9df128ff11 100644 --- a/contentcuration/search/migrations/0001_initial.py +++ b/contentcuration/search/migrations/0001_initial.py @@ -1,7 +1,5 @@ # -*- coding: utf-8 -*- # Generated by Django 1.11.20 on 2020-07-21 16:58 -from __future__ import unicode_literals - import uuid import django.contrib.postgres.fields.jsonb diff --git a/contentcuration/search/tests/test_search.py b/contentcuration/search/tests/test_search.py index aef996296d..95d643f504 100644 --- a/contentcuration/search/tests/test_search.py +++ b/contentcuration/search/tests/test_search.py @@ -1,5 +1,3 @@ -from __future__ import absolute_import - from django.urls import reverse from contentcuration.models import Channel diff --git a/docs/dev_tools.md b/docs/dev_tools.md index 7d23039f25..6b47885ca4 100644 --- a/docs/dev_tools.md +++ b/docs/dev_tools.md @@ -28,59 +28,3 @@ yarn run lint-frontend:format ``` Make sure you've set up pre-commit hooks as described above. This will ensure that linting is automatically run on staged changes before every commit. - -## Profiling and local production testing - -If you want to test the performance of your changes, you can start up a local server with settings closer to a production environment like so: - -```bash -# build frontend dependencies -yarn run build -# run the server (no webpack) -yarn run runserver -# or for profiling production more closely -yarn run runserver:prod-profiling -``` - -Once the local production server is running, you can also use Locust to test your changes under scenarios of high demand like so: - -```bash -cd deploy/chaos/loadtest -make timed_run -make stop_slaves # mac: killall python -``` - -### Profiling - -In case you need to profile the application to know which part of the code are more time consuming, there are two different profilers available to work in two different modes. Both will store the profiling output in a directory that's determined by the `PROFILE_DIR` env variable. If this variable is not set, the output files will be store in a folder called profiler inside the OS temp folder (`/tmp/profile` usually) -Note that both profiling modes are incompatible: you can either use one or the other, but not both at the same time. In case the env variables are set for both modes, _All request profiling mode_ will be used. - -#### All requests profiling mode - -This mode will create interactive html files with all the profiling information for every request the Studio server receives. The name of the files will contain the total execution time, the endpoint name and a timestamp. - -To activate it an env variable called `PROFILE_STUDIO_FULL` must be set. - -Example of use: - -`PROFILE_STUDIO_FULL=y yarn runserver` - -Afterwards no further treatment of the generated files is needed. You can open directly the html files in your browser. - -#### Endpoint profiling mode - -When using the _all requests mode_ it's usual that the profile folder is soon full of information for requests that are not interesting for the developer, obscuring the files for specific endpoints. - -If an env variable called `PROFILE_STUDIO_FILTER` is used, the profiler will be executed only on the http requests containing the text stated by the variable. - -Example of use: - -`PROFILE_STUDIO_FILTER=edit yarn localprodserver` - -For this case, only html requests having the text _edit_ in their request path will be profiled. The profile folder will not have html files, but binary dump files (with the timestamp as filename) of the profiler information that can be later seen by different profiling tools (`snakeviz` that can be installed using pip is recommended). Also while the server is running, the ten most time consuming lines of code of the filtered request will be shown in the console where Studio has been launched. - -Example of snakeviz use: - -`snakeviz /tmp/profile/studio\:20200909161405011678.prof` - -will open the browser with an interactive diagram with all the profiling information diff --git a/package.json b/package.json index 68c73b2aef..96747557be 100644 --- a/package.json +++ b/package.json @@ -25,8 +25,6 @@ "test-jest:debug": "node --inspect node_modules/.bin/jest --runInBand --watch", "minio": "MINIO_API_CORS_ALLOW_ORIGIN='http://localhost:8080,http://127.0.0.1:8080' MINIO_ACCESS_KEY=development MINIO_SECRET_KEY=development minio server ~/.minio_data/ || true", "runserver": "cd contentcuration && python manage.py runserver --settings=contentcuration.dev_settings 0.0.0.0:8080", - "runserver:debug-panel": "cd contentcuration && python manage.py runserver --settings=contentcuration.debug_panel_settings 0.0.0.0:8080", - "runserver:prod-profiling": "cd contentcuration && DJANGO_SETTINGS_MODULE=contentcuration.profile_settings gunicorn -b 0.0.0.0:8080 --workers=3 --threads=2 contentcuration.wsgi", "devserver": "npm-run-all --parallel build:dev runserver", "devserver:hot": "npm-run-all --parallel build:dev:hot runserver", "devserver-hot": "yarn run devserver:hot", diff --git a/performance/README.md b/performance/README.md deleted file mode 100644 index b9225b2a26..0000000000 --- a/performance/README.md +++ /dev/null @@ -1,45 +0,0 @@ -# Kolibri Studio load testing experiment - -# Expected behaviour - -- None of the requests will return a 500, 502 or 503 error -- None of the requests will take longer than 20 seconds to return a response - -# Steps to run - -To run against your local studio instance, simply run: - -``` bash -$ make run -``` - -This pings your localhost:8080 server with 100 clients and a 20 users/sec hatch -rate. You can set each of these parameters for a run. - -You can also specify the duration to run the tests for, along with the results -file(s), using the following parameters: - -```bash -make run TIME_ARG="-t5m" RESULTS_FILE="--csv=profile_results" -``` - -To run this script against the Studio staging server, change the `URL` -parameter: - -``` bash -$ make run URL=https://develop.studio.learningequality.org -USERNAME= PASSWORD= -``` - -To customize the number of clients and the hatch rate, set the `NUM_CLIENTS` and -the `HATCH_RATE` respectively: - -``` bash -$ make run NUM_CLIENTS=5 HATCH_RATE=1 -``` - -After stopping it, Locust slaves must be stopped: - -```bash -$ make stop_slaves -``` diff --git a/performance/locustfile.py b/performance/locustfile.py deleted file mode 100755 index a1dfe6c367..0000000000 --- a/performance/locustfile.py +++ /dev/null @@ -1,256 +0,0 @@ -#!/usr/bin/env python -import json -import os -import time -from random import choice - -from locust import HttpUser -from locust import task -from locust import TaskSet -try: - import urllib.request as urlrequest -except ImportError: - import urllib as urlrequest - -USERNAME = os.getenv("LOCUST_USERNAME") or "a@a.com" -PASSWORD = os.getenv("LOCUST_PASSWORD") or "a" - - -class BaseTaskSet(TaskSet): - max_wait = 60000 - - def _login(self): - """ - Helper function to log in the user to the current session. - """ - resp = self.client.get("/accounts/") - csrf = resp.cookies["csrftoken"] - formdata = { - "username": USERNAME, - "password": PASSWORD, - } - self.client.post( - "/accounts/login/", - data=json.dumps(formdata), - headers={ - "content-type": "application/x-www-form-urlencoded", - "referer": "{}/accounts/".format(self.client.base_url), - "X-CSRFToken": csrf - } - ) - - def _run_async_task(self, url, channel_id, data): - copy_resp = self.client.post(url, - data=json.dumps(data), - headers={ - "content-type": "application/json", - 'X-CSRFToken': self.client.cookies.get('csrftoken'), - 'Referer': self.client.base_url - }) - copy_resp_data = copy_resp.json() - task_id = copy_resp_data["id"] - finished = False - time_elapsed = 0 - status = 'QUEUED' - while not finished: - time.sleep(1) - time_elapsed += 1 - task_resp = self.client.get("/api/task/{}?channel_id={}".format(task_id, channel_id)) - task_data = task_resp.json() - if task_data["status"] in ["SUCCESS", "FAILED"] or time_elapsed > 120: - finished = True - status = task_data["status"] - - return status - - -class ChannelListPage(BaseTaskSet): - """ - Task to explore different channels lists - """ - def on_start(self): - self._login() - - @task - def channel_list(self): - """ - Load the channel page and the important endpoints. - """ - self.client.get("/channels/") - - -class ChannelPage(BaseTaskSet): - """ - Task to open and view a channel, including its topics and nodes - """ - def on_start(self): - self._login() - - def get_first_public_channel_id(self): - """ - Returns the id of the first available public channel - :returns: id of the first available public channel or None if there are not public channels - """ - resp = self.client.get("/api/channels?public=true").json() - try: - channel_id = resp[0]['id'] - except IndexError: - channel_id = None - return channel_id - - def get_first_edit_channel_id(self): - """ - Returns the id of the first available public channel - :returns: id of the first available public channel or None if there are not public channels - """ - resp = self.client.get("/api/channels?edit=true").json() - try: - channel_id = resp[0]['id'] - except IndexError: - channel_id = None - return channel_id - - def get_topic_id(self, channel_id, random=False): - """ - Returns the id of a randomly selected topic for the provided channel_id - :param: channel_id: id of the channel where the topic must be found - :returns: id of the selected topic - """ - channel_resp = self.client.get('/api/channel/{}'.format(channel_id)).json() - children = channel_resp['main_tree']['children'] - topic_id = children[0] - if random: - topic_id = choice(children) - return topic_id - - def get_resource_id(self, topic_id, random=False): - """ - Returns the id of a randoly selected resource for the provided topic_id - :param: topic_id: id of the topic where the resource must be found - :returns: id of the selected resource - """ - nodes_resp = self.client.get('/api/contentnodes?parent={}'.format(topic_id)).json() - try: - while nodes_resp[0]['kind'] == 'topic': - nodes = nodes_resp[0]['children'] - nodes_resp = self.client.get('/api/contentnodes?ids={}'.format(','.join(nodes))).json() - node_id = nodes_resp[0]['id'] - if random: - node_id = choice(nodes_resp)['id'] - return node_id - except IndexError: - return None - - @task - def open_channel(self, channel_id=None): - """ - Open to edit a channel, if channel_id is None it opens the first public channel - """ - if not channel_id: - channel_id = self.get_first_public_channel_id() - if channel_id: - self.client.get('/channels/{}'.format(channel_id)) - - # This is the most frequently hit scenario outside of ricecooker usage, so give it more weight. - @task(3) - def open_subtopic(self, channel_id=None, topic_id=None): - """ - Open a topic, if channel_id is None it opens the first public channel - """ - if not channel_id: - channel_id = self.get_first_public_channel_id() - if channel_id and not topic_id: - topic_id = self.get_topic_id(channel_id) - if topic_id: - self.get_resource_id(topic_id) - - @task - def preview_content_item(self, content_id=None, random=False): - """ - Do request on all the files for a content item. - If content_id is not provided it will fetch a random content - """ - if not content_id: - channel_id = self.get_first_public_channel_id() - topic_id = self.get_topic_id(channel_id, random=random) - content_id = self.get_resource_id(topic_id, random=random) - if content_id: - resp = self.client.get('/api/contentnode/{}'.format(content_id)).json() - if 'files' in resp[0]: - for resource in resp[0]['files']: - storage_url = resource['storage_url'] - print("Requesting resource {}".format(storage_url)) - urlrequest.urlopen(storage_url).read() - - -class ChannelEdit(BaseTaskSet): - # This flag was recommended to ensure on_stop is always called, but it seems not to be enough - # on its own to ensure this behavior. Leaving as it's possible this is needed, but along with - # something else. - always_run_on_stop = True - - def on_start(self): - self._login() - self.created_channels = [] - - def on_stop(self): - # FIXME: This is not being called when the run completes, need to find out why. - # Note that until this is fixed, any channel with the name "Locust Test Channel" - # in the database needs to be manually deleted. - for channel in self.created_channels: - self.client.delete( - "/api/channel/{}/".format(channel), - headers={ - "content-type": "application/json", - 'X-CSRFToken': self.client.cookies.get('csrftoken'), - } - ) - - # TODO: check for deletion issues and report so that manual cleanup can be performed if needed. - - @task(6) - def create_channel(self): - """ - Load the channel page and the important endpoints. - """ - formdata = { - "name": "Locust Test Channel", - "description": "Description of locust test channel", - "thumbnail_url": '/static/img/kolibri_placeholder.png', - "count": 0, - "size": 0, - "published": False, - "view_only": False, - "viewers": [], - "content_defaults": {}, - "pending_editors": [] - } - self.client.post( - "/api/channel", - data=json.dumps(formdata), - headers={ - "content-type": "application/json", - 'X-CSRFToken': self.client.cookies.get('csrftoken'), - 'Referer': self.client.base_url - } - ) - - -class LoginPage(BaseTaskSet): - tasks = [ChannelListPage, ChannelPage, ChannelEdit] - - # This is by far our most hit endpoint, over 50% of all calls, so - # weight it accordingly. - @task(10) - def loginpage(self): - """ - Visit the login page and the i18n endpoints without logging in. - """ - self.client.get("/accounts/") - - -class StudioDesktopBrowserUser(HttpUser): - tasks = [LoginPage, ChannelListPage] - min_wait = 5000 - max_wait = 20000 - host = os.getenv("LOCUST_URL") or "http://localhost:8080" diff --git a/performance/prep.py b/performance/prep.py deleted file mode 100644 index f97e1a72e6..0000000000 --- a/performance/prep.py +++ /dev/null @@ -1,69 +0,0 @@ -""" -THIS WILL CLEAR YOUR DATABASE AND FILL IT WITH TEST DATA! - -Prepare the local database for load testing. - -It does the following: -- Creates an admin user. -- Creates 1000 channels. Create 3 users for each channel, and assign 1 as the editor and the other two as viewers. -""" -import logging -import os -import subprocess -import sys -import warnings - -# output any info logs -logging.basicConfig(level="INFO") - -# set sys.path to include the contentcuration dir -root_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) -cc_dir = os.path.join(root_dir, "contentcuration") -sys.path.append(cc_dir) - -# set the settings module -os.putenv("DJANGO_SETTINGS_MODULE", "contentcuration.test_settings") - -from django.core.management import call_command - -from contentcuration.models import Channel, User - -# CONSTANTS -NUM_CHANNELS = 1000 -NUM_NODES_PER_CHANNEL = 500 - -from contentcuration.tests.utils import mixer - -mixer.register( - User, - information="{}", - content_defaults="{}", - policies="{}" -) - - -if __name__ == "__main__": - warnings.warn("THIS WILL CLEAR YOUR DATABASE AND FILL IT WITH TEST DATA!") - logging.info("Clearing the DB") - call_command("flush", "--noinput") - - # set up our DB from scratch and create our user - logging.info("Setting up the database") - call_command("setup") - - # create NUM_CHANNELS channels using mixer - - logging.info("Creating {} channels".format(NUM_CHANNELS)) - - for _ in range(NUM_CHANNELS): - editor = mixer.blend(User) - c = mixer.blend(Channel) - c.editors.add(editor) - viewers = mixer.cycle(2).blend(User) - for v in viewers: - v.view_only_channels.add(c) - v.save() - c.save() - - # start the server in prod mode - subprocess.call(["yarn", "run", "devserver"]) diff --git a/performance/run_perftests.py b/performance/run_perftests.py deleted file mode 100644 index 52fe538e57..0000000000 --- a/performance/run_perftests.py +++ /dev/null @@ -1,38 +0,0 @@ -import sys - -import gevent -from locust.env import Environment -from locust.event import EventHook -from locust.log import setup_logging -from locust.stats import stats_printer -from locustfile import StudioDesktopBrowserUser -setup_logging("DEBUG", None) - -def error_output(*args, **kwargs): - print("Error: {}, {}".format(args, kwargs)) - -failure_hook = EventHook() -failure_hook.add_listener(error_output) - -# setup Environment and Runner -env = Environment(user_classes=[StudioDesktopBrowserUser]) -env.events.request_failure = failure_hook -env.create_local_runner() - -# start a WebUI instance -env.create_web_ui("127.0.0.1", 8089) - -# start a greenlet that periodically outputs the current stats -gevent.spawn(stats_printer(env.stats)) - -# start the test -env.runner.start(10, hatch_rate=10) - -# in 60 seconds stop the runner -gevent.spawn_later(60, lambda: env.runner.quit()) - -# wait for the greenlets -env.runner.greenlet.join() - -# stop the web server for good measures -env.web_ui.stop() diff --git a/requirements-dev.in b/requirements-dev.in index d4c263ba34..20245d9ba2 100644 --- a/requirements-dev.in +++ b/requirements-dev.in @@ -1,24 +1,11 @@ -c requirements.txt django-concurrent-test-helper==0.7.0 -django-debug-panel==0.8.3 -django-debug-toolbar==3.5.0 -flake8==3.4.1 -whitenoise -Pympler mock mixer==6.1.3 pytest pytest-django -pytest-logging pytest-timeout -pytest-watch pre-commit==1.15.1 nodeenv pip-tools==7.4.1 -locust drf-yasg==1.21.5 -pyinstrument -pypandoc -git+https://github.com/someshchaturvedi/customizable-django-profiler.git#customizable-django-profiler -tabulate==0.9.0 -fonttools diff --git a/requirements-dev.txt b/requirements-dev.txt index 7cfbabd670..0df97d27c2 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -10,14 +10,11 @@ asgiref==3.3.4 # django aspy-yaml==1.3.0 # via pre-commit -brotli==1.0.9 - # via geventhttpclient build==1.2.1 # via pip-tools certifi==2020.12.5 # via # -c requirements.txt - # geventhttpclient # requests cfgv==3.3.1 # via pre-commit @@ -28,42 +25,26 @@ charset-normalizer==3.3.2 click==8.1.3 # via # -c requirements.txt - # flask # pip-tools -colorama==0.4.4 - # via pytest-watch -configargparse==1.5.3 - # via locust coreapi==2.3.3 # via drf-yasg coreschema==0.0.4 # via # coreapi # drf-yasg -customizable-django-profiler @ git+https://github.com/someshchaturvedi/customizable-django-profiler.git - # via -r requirements-dev.in distlib==0.3.9 # via virtualenv django==3.2.24 # via # -c requirements.txt - # django-debug-toolbar # djangorestframework # drf-yasg django-concurrent-test-helper==0.7.0 # via -r requirements-dev.in -django-debug-panel==0.8.3 - # via -r requirements-dev.in -django-debug-toolbar==3.5.0 - # via - # -r requirements-dev.in - # django-debug-panel djangorestframework==3.15.1 # via # -c requirements.txt # drf-yasg -docopt==0.6.2 - # via pytest-watch drf-yasg==1.21.5 # via -r requirements-dev.in exceptiongroup==1.2.2 @@ -72,27 +53,6 @@ faker==0.9.1 # via mixer filelock==3.16.1 # via virtualenv -flake8==3.4.1 - # via -r requirements-dev.in -flask==2.0.3 - # via - # flask-basicauth - # flask-cors - # locust -flask-basicauth==0.2.0 - # via locust -flask-cors==5.0.0 - # via locust -fonttools==4.43.0 - # via -r requirements-dev.in -gevent==23.9.1 - # via - # geventhttpclient - # locust -geventhttpclient==2.0.9 - # via locust -greenlet==2.0.2 - # via gevent identify==2.4.4 # via pre-commit idna==2.10 @@ -105,30 +65,18 @@ inflection==0.5.1 # via drf-yasg iniconfig==1.1.1 # via pytest -itsdangerous==2.0.1 - # via flask itypes==1.2.0 # via coreapi jinja2==3.1.5 - # via - # coreschema - # flask -locust==2.15.1 - # via -r requirements-dev.in + # via coreschema markupsafe==2.1.2 - # via - # jinja2 - # werkzeug -mccabe==0.6.1 - # via flake8 + # via jinja2 mixer==6.1.3 # via -r requirements-dev.in mock==4.0.3 # via # -r requirements-dev.in # django-concurrent-test-helper -msgpack==1.0.4 - # via locust nodeenv==1.8.0 # via # -r requirements-dev.in @@ -147,20 +95,6 @@ pluggy==0.13.1 # via pytest pre-commit==1.15.1 # via -r requirements-dev.in -psutil==5.8.0 - # via locust -pycodestyle==2.3.1 - # via flake8 -pyflakes==1.5.0 - # via flake8 -pyinstrument==3.4.2 - # via -r requirements-dev.in -pyinstrument-cext==0.2.4 - # via pyinstrument -pympler==1.0.1 - # via -r requirements-dev.in -pypandoc==1.8.1 - # via -r requirements-dev.in pyproject-hooks==1.1.0 # via # build @@ -169,17 +103,11 @@ pytest==7.4.4 # via # -r requirements-dev.in # pytest-django - # pytest-logging # pytest-timeout - # pytest-watch pytest-django==4.9.0 # via -r requirements-dev.in -pytest-logging==2015.11.4 - # via -r requirements-dev.in pytest-timeout==1.4.2 # via -r requirements-dev.in -pytest-watch==4.2.0 - # via -r requirements-dev.in python-dateutil==2.8.2 # via # -c requirements.txt @@ -193,15 +121,10 @@ pyyaml==6.0 # via # aspy-yaml # pre-commit -pyzmq==23.1.0 - # via locust requests==2.32.3 # via # -c requirements.txt # coreapi - # locust -roundrobin==0.0.2 - # via locust ruamel-yaml==0.17.21 # via drf-yasg ruamel-yaml-clib==0.2.6 @@ -211,16 +134,12 @@ six==1.16.0 # -c requirements.txt # django-concurrent-test-helper # faker - # geventhttpclient # pre-commit # python-dateutil sqlparse==0.4.1 # via # -c requirements.txt # django - # django-debug-toolbar -tabulate==0.9.0 - # via -r requirements-dev.in tblib==1.7.0 # via django-concurrent-test-helper text-unidecode==1.2 @@ -232,8 +151,6 @@ tomli==1.2.3 # build # pip-tools # pytest -typing-extensions==4.5.0 - # via locust uritemplate==3.0.1 # via # coreapi @@ -244,22 +161,10 @@ urllib3==1.26.18 # requests virtualenv==20.26.6 # via pre-commit -watchdog==2.1.8 - # via pytest-watch -werkzeug==3.0.6 - # via - # flask - # locust wheel==0.38.1 # via pip-tools -whitenoise==5.2.0 - # via -r requirements-dev.in zipp==3.19.1 # via importlib-metadata -zope-event==4.5.0 - # via gevent -zope-interface==5.4.0 - # via gevent # The following packages are considered to be unsafe in a requirements file: # pip diff --git a/requirements.in b/requirements.in index 71b1ce3cf6..78c1cf92d1 100644 --- a/requirements.in +++ b/requirements.in @@ -20,14 +20,12 @@ django-s3-storage==0.15.0 requests>=2.20.0 google-cloud-core django-db-readonly==0.7.0 -django-mathfilters google-cloud-kms==2.10.0 google-crc32c==1.1.2 backoff django-model-utils==4.5.1 django-redis django-prometheus -future sentry-sdk html5lib==1.1 pillow==10.3.0 diff --git a/requirements.txt b/requirements.txt index d16dcbd9ed..e15ff859d1 100644 --- a/requirements.txt +++ b/requirements.txt @@ -74,8 +74,6 @@ django-js-asset==1.2.2 # via django-mptt django-js-reverse==0.9.1 # via -r requirements.in -django-mathfilters==1.0.0 - # via -r requirements.in django-model-utils==4.5.1 # via -r requirements.in django-mptt==0.14.0 @@ -94,8 +92,6 @@ django-webpack-loader==0.7.0 # via -r requirements.in djangorestframework==3.15.1 # via -r requirements.in -future==0.18.3 - # via -r requirements.in google-api-core[grpc]==1.27.0 # via # google-cloud-core