Skip to content

Commit

Permalink
Add Django 2.2 support (#262)
Browse files Browse the repository at this point in the history
Implement the changes to support Django 2.2 and remove Python 2 support fully.

Co-authored-by: Guruprasad Lakshmi Narayanan <[email protected]>
  • Loading branch information
kaizoku and Guruprasad Lakshmi Narayanan authored Apr 10, 2020
1 parent 695ab49 commit 69797ff
Show file tree
Hide file tree
Showing 50 changed files with 199 additions and 240 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ help: ## display this help message
@perl -nle'print $& if m{^[a-zA-Z_-]+:.*?## .*$$}' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m %-25s\033[0m %s\n", $$1, $$2}'

upgrade:
pip-compile --output-file test_requirements.txt test_requirements.in
pip-compile --upgrade --output-file test_requirements.txt test_requirements.in

extract_translations: ## extract strings to be translated, outputting .po files
cd $(WORKING_DIR) && i18n_tool extract
Expand Down
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ create its migrations:

```bash
(venv) ~/xblock_development/problem-builder $ cd ../venv/src/xblock-sdk
(venv) ~/xblock_development/venv/src/xblock-sdk $ make pip
(venv) ~/xblock_development/venv/src/xblock-sdk $ make install
(venv) ~/xblock_development/venv/src/xblock-sdk $ python manage.py makemigrations workbench
```

Expand Down Expand Up @@ -221,6 +221,9 @@ Problem Builder releases are tagged with a version number, e.g.
[`v2.6.5`](https://github.com/open-craft/problem-builder/tree/v2.6.5). We recommend installing the most recently tagged
version, with the exception of the following compatibility issues:

* `edx-platform` version `open-release/ironwood.2` and earlier must use
[v3.4.14](https://github.com/open-craft/problem-builder/tree/v3.4.14). See
[PR 262](https://github.com/open-craft/problem-builder/pull/262) for details.
* `edx-platform` version `open-release/eucalyptus.2` and earlier must use
[v2.6.0](https://github.com/open-craft/problem-builder/tree/v2.6.0). See
[PR 128](https://github.com/open-craft/problem-builder/pull/128) for details.
Expand Down
63 changes: 7 additions & 56 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,25 @@ jobs:
build:
docker:
- image: <<parameters.docker_image>>
- image: circleci/mysql:5.6
command: mysqld --character-set-server=latin1 --collation-server=latin1_swedish_ci
environment:
MYSQL_ROOT_PASSWORD: rootpw
parameters:
test_command:
type: string
docker_image:
type: string
environment:
MOZ_HEADLESS: 1
WORKBENCH_DATABASES: '{"default": {"ENGINE": "django.db.backends.mysql", "NAME": "db", "USER": "root", "PASSWORD": "rootpw", "HOST": "127.0.0.1", "OPTIONS": {"charset": "utf8mb4"}}}'
steps:
- checkout
- run:
name: Update system
command: |
sudo apt-get update
sudo apt-get install -y libgtk3.0-cil-dev libasound2 libasound2 libdbus-glib-1-2 libdbus-1-3 libgtk2.0-0
sudo apt-get install -y libgtk3.0-cil-dev libasound2 libasound2 libdbus-glib-1-2 libdbus-1-3 libgtk2.0-0 default-libmysqlclient-dev
- run:
name: Install geckodriver
command: |
Expand Down Expand Up @@ -68,7 +73,7 @@ jobs:
sudo apt-get update
virtualenv venv
source venv/bin/activate
pip install 'coverage<5'
pip install 'coverage==5.0.3'
- attach_workspace:
at: /tmp/workspace
- run:
Expand Down Expand Up @@ -125,60 +130,6 @@ workflows:
version: 2
build_and_deploy:
jobs:
- build:
name: py27-quality
test_command: make quality
docker_image: circleci/python:2.7-buster-browsers
filters:
tags:
only: /.*/
- build:
name: py27-unit
test_command: make test.unit
docker_image: circleci/python:2.7-buster-browsers
filters:
tags:
only: /.*/
- build:
name: py27-integration
test_command: make test.integration
docker_image: circleci/python:2.7-buster-browsers
filters:
tags:
only: /.*/
- coverage:
name: py27-coverage
docker_image: circleci/python:2.7-buster
filters:
tags:
only: /.*/
requires:
- py27-quality
- py27-unit
- py27-integration
- deploy:
name: py27-deploy-sdist
docker_image: circleci/python:2.7-buster
dist_type: sdist
requires:
- py27-coverage
filters:
tags:
only: /v[0-9]+(\.[0-9]+)*/
branches:
ignore: /.*/
- deploy:
name: py27-deploy-bdist_wheel
docker_image: circleci/python:2.7-buster
dist_type: bdist_wheel
requires:
- py27-coverage
filters:
tags:
only: /v[0-9]+(\.[0-9]+)*/
branches:
ignore: /.*/

- build:
name: py35-quality
test_command: make quality
Expand Down
4 changes: 2 additions & 2 deletions problem_builder/answer.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def mentoring_view(self, context=None):
context['answer_editable_id'] = uuid.uuid4().hex[:15]
context['self'] = self
context['hide_header'] = context.get('hide_header', False) or not self.show_title
html = loader.render_template('templates/html/answer_editable.html', context)
html = loader.render_django_template('templates/html/answer_editable.html', context)

fragment = Fragment(html)
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/answer.css'))
Expand Down Expand Up @@ -332,7 +332,7 @@ def mentoring_view(self, context=None):
context['student_input'] = None
else:
context['student_input'] = self.student_input
html = loader.render_template('templates/html/answer_read_only.html', context)
html = loader.render_django_template('templates/html/answer_read_only.html', context)

fragment = Fragment(html)
fragment.add_css_url(self.runtime.local_resource_url(self, self.css_path))
Expand Down
2 changes: 1 addition & 1 deletion problem_builder/completion.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ def mentoring_view(self, context):
context['title'] = self.display_name_with_default
context['hide_header'] = context.get('hide_header', False) or not self.show_title

html = loader.render_template('templates/html/completion.html', context)
html = loader.render_django_template('templates/html/completion.html', context)

fragment = Fragment(html)
fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/completion.js'))
Expand Down
8 changes: 4 additions & 4 deletions problem_builder/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def _(text):
# Classes ###########################################################


class ExportMixin(object):
class ExportMixin:
"""
Used by blocks which need to provide a downloadable export.
"""
Expand Down Expand Up @@ -92,7 +92,7 @@ def _get_course_name(self):
return ""


class ColorRule(object):
class ColorRule:
"""
A rule used to conditionally set colors
Expand Down Expand Up @@ -457,14 +457,14 @@ def student_view(self, context=None): # pylint: disable=unused-argument
blocks, rules_parsed, self.color_for_value, self.visual_title, self.visual_desc
)

report_template = loader.render_template('templates/html/dashboard_report.html', {
report_template = loader.render_django_template('templates/html/dashboard_report.html', {
'title': self.display_name,
'css': loader.load_unicode(self.css_path),
'student_name': self._get_user_full_name(),
'course_name': self._get_course_name(),
})

html = loader.render_template('templates/html/dashboard.html', {
html = loader.render_django_template('templates/html/dashboard.html', {
'blocks': blocks,
'display_name': self.display_name,
'visual_repr': visual_repr,
Expand Down
2 changes: 1 addition & 1 deletion problem_builder/dashboard_visual.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"""


class DashboardVisualData(object):
class DashboardVisualData:
"""
Data about the visual representation of a dashboard.
"""
Expand Down
2 changes: 1 addition & 1 deletion problem_builder/instructor_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def student_view(self, context=None):
_('Long Answer'): 'AnswerBlock',
}

html = loader.render_template('templates/html/instructor_tool.html', {
html = loader.render_django_template('templates/html/instructor_tool.html', {
'block_choices': block_choices,
'course_blocks_api': COURSE_BLOCKS_API,
'root_block_id': six.text_type(getattr(self.runtime, 'course_id', 'course_id')),
Expand Down
6 changes: 3 additions & 3 deletions problem_builder/mcq.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ def calculate_results(self, submission):
formatted_tips = None

if tips_html:
formatted_tips = loader.render_template('templates/html/tip_choice_group.html', {
formatted_tips = loader.render_django_template('templates/html/tip_choice_group.html', {
'tips_html': tips_html,
})

Expand Down Expand Up @@ -239,7 +239,7 @@ def get_author_edit_view_fragment(self, context):
show them in the author edit view, for clarity.
"""
fragment = Fragment()
fragment.add_content(loader.render_template('templates/html/ratingblock_edit_preview.html', {
fragment.add_content(loader.render_django_template('templates/html/ratingblock_edit_preview.html', {
'question': self.question,
'low': self.low,
'high': self.high,
Expand All @@ -265,7 +265,7 @@ def student_view(self, context):
if context: # Workbench does not provide context
rendering_for_studio = context.get('author_edit_view')
if rendering_for_studio:
fragment.add_content(loader.render_template('templates/html/rating_edit_footer.html', {
fragment.add_content(loader.render_django_template('templates/html/rating_edit_footer.html', {
"url_name": self.url_name
}))
return fragment
10 changes: 5 additions & 5 deletions problem_builder/mentoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def author_preview_view(self, context):
authors in Studio when not editing this block's children.
"""
fragment = self.student_view(context)
fragment.add_content(loader.render_template('templates/html/mentoring_url_name.html', {
fragment.add_content(loader.render_django_template('templates/html/mentoring_url_name.html', {
"url_name": self.url_name
}))
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/problem-builder-edit.css'))
Expand Down Expand Up @@ -609,7 +609,7 @@ def submit(self, submissions, suffix=''):
# server-side check that the user is allowed to submit:
if self.max_attempts_reached:
raise JsonHandlerError(403, "Maximum number of attempts already reached.")
elif self.has_missing_dependency:
if self.has_missing_dependency:
raise JsonHandlerError(
403,
"You need to complete all previous steps before being able to complete the current one."
Expand Down Expand Up @@ -742,7 +742,7 @@ def author_edit_view(self, context):
local_context = context.copy()
local_context['author_edit_view'] = True
fragment = super(MentoringBlock, self).author_edit_view(local_context)
fragment.add_content(loader.render_template('templates/html/mentoring_url_name.html', {
fragment.add_content(loader.render_django_template('templates/html/mentoring_url_name.html', {
'url_name': self.url_name
}))
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/problem-builder.css'))
Expand Down Expand Up @@ -851,7 +851,7 @@ def active_step_safe(self):
added/deleted.
"""
active_step = self.active_step
if active_step >= 0 and active_step < len(self.step_ids):
if 0 <= active_step < len(self.step_ids):
return active_step
if active_step == -1 and self.has_review_step:
return active_step # -1 indicates the review step
Expand Down Expand Up @@ -1107,7 +1107,7 @@ def author_edit_view(self, context):
Add some HTML to the author view that allows authors to add child blocks.
"""
fragment = super(MentoringWithExplicitStepsBlock, self).author_edit_view(context)
fragment.add_content(loader.render_template('templates/html/mentoring_url_name.html', {
fragment.add_content(loader.render_django_template('templates/html/mentoring_url_name.html', {
"url_name": self.url_name
}))
fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/problem-builder.css'))
Expand Down
4 changes: 2 additions & 2 deletions problem_builder/message.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ def parse_xml(cls, node, runtime, keys, id_generator):
return block


class CompletedMentoringMessageShim(object):
class CompletedMentoringMessageShim:
CATEGORY = 'pb-message'
STUDIO_LABEL = _("Message (Complete)")


class IncompleteMentoringMessageShim(object):
class IncompleteMentoringMessageShim:
CATEGORY = 'pb-message'
STUDIO_LABEL = _("Message (Incomplete)")

Expand Down
4 changes: 2 additions & 2 deletions problem_builder/migrations/0002_auto_20160121_1525.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ class Migration(migrations.Migration):
('submission_uid', models.CharField(max_length=32)),
('block_id', models.CharField(max_length=255, db_index=True)),
('notified', models.BooleanField(default=False, db_index=True)),
('shared_by', models.ForeignKey(related_name='problem_builder_shared_by', to=settings.AUTH_USER_MODEL)),
('shared_with', models.ForeignKey(related_name='problem_builder_shared_with', to=settings.AUTH_USER_MODEL)),
('shared_by', models.ForeignKey(related_name='problem_builder_shared_by', on_delete=models.CASCADE, to=settings.AUTH_USER_MODEL)),
('shared_with', models.ForeignKey(related_name='problem_builder_shared_with', on_delete=models.CASCADE, to=settings.AUTH_USER_MODEL)),
],
),
migrations.AlterUniqueTogether(
Expand Down
14 changes: 7 additions & 7 deletions problem_builder/mixins.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def _normalize_id(key):
return key


class XBlockWithTranslationServiceMixin(object):
class XBlockWithTranslationServiceMixin:
"""
Mixin providing access to i18n service
"""
Expand Down Expand Up @@ -80,7 +80,7 @@ def display_name_with_default(self):
return self._(self.CAPTION)


class StepParentMixin(object):
class StepParentMixin:
"""
An XBlock mixin for a parent block containing Step children
"""
Expand All @@ -100,7 +100,7 @@ def steps(self):
return [self.runtime.get_block(child_id) for child_id in self.step_ids]


class MessageParentMixin(object):
class MessageParentMixin:
"""
An XBlock mixin for a parent block containing MentoringMessageBlock children
"""
Expand Down Expand Up @@ -167,15 +167,15 @@ def author_preview_view(self, context):
return self.student_view(context)


class NoSettingsMixin(object):
class NoSettingsMixin:
""" Mixin for an XBlock that has no settings """

def studio_view(self, _context=None):
""" Studio View """
return Fragment(u'<p>{}</p>'.format(self._("This XBlock does not have any settings.")))


class StudentViewUserStateMixin(object):
class StudentViewUserStateMixin:
"""
Mixin to provide student_view_user_state view.
Expand Down Expand Up @@ -234,7 +234,7 @@ def student_view_user_state(self, context=None, suffix=''):
)


class StudentViewUserStateResultsTransformerMixin(object):
class StudentViewUserStateResultsTransformerMixin:
"""
A convenient way for MentoringBlock and MentoringStepBlock to share
student_results transform code.
Expand Down Expand Up @@ -267,7 +267,7 @@ def delete_key(self, dictionary, key):
return dictionary


class ExpandStaticURLMixin(object):
class ExpandStaticURLMixin:

def expand_static_url(self, text):
"""
Expand Down
6 changes: 3 additions & 3 deletions problem_builder/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,13 @@ class Share(models.Model):
to query for arbitrary anonymous user IDs. In order to make sharing work, we have
to store them here.
"""
shared_by = models.ForeignKey(User, related_name='problem_builder_shared_by')
shared_by = models.ForeignKey(User, on_delete=models.CASCADE, related_name='problem_builder_shared_by')
submission_uid = models.CharField(max_length=32)
block_id = models.CharField(max_length=255, db_index=True)
shared_with = models.ForeignKey(User, related_name='problem_builder_shared_with')
shared_with = models.ForeignKey(User, on_delete=models.CASCADE, related_name='problem_builder_shared_with')
notified = models.BooleanField(default=False, db_index=True)

class Meta(object):
class Meta:
# Since problem_builder isn't added to INSTALLED_APPS until it's imported,
# specify the app_label here.
app_label = 'problem_builder'
Expand Down
2 changes: 1 addition & 1 deletion problem_builder/mrq.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def calculate_results(self, submissions):

loader = ResourceLoader(__name__)
choice_result['completed'] = choice_completed
choice_result['tips'] = loader.render_template('templates/html/tip_choice_group.html', {
choice_result['tips'] = loader.render_django_template('templates/html/tip_choice_group.html', {
'tips_html': choice_tips_html,
})

Expand Down
Loading

0 comments on commit 69797ff

Please sign in to comment.