Skip to content

Commit

Permalink
fix: fixed pre-commit errors
Browse files Browse the repository at this point in the history
  • Loading branch information
Anas12091101 committed Mar 15, 2024
1 parent d0b552e commit 7cd4e47
Show file tree
Hide file tree
Showing 26 changed files with 475 additions and 306 deletions.
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ repos:
rev: v1.4.0
hooks:
- id: detect-secrets
args:
- --exclude-files '(poetry.lock|pants)'
exclude: "poetry.lock|pants|src/rapid_response_xblock/test_data/example_event.json$"
- repo: https://github.com/psf/black
rev: 24.1.1
hooks:
Expand All @@ -55,3 +54,4 @@ repos:
- types-pytz
- types-requests
- types-pkg_resources
- types-python-dateutil
Binary file removed src/rapid_response_xblock/.coverage
Binary file not shown.
3 changes: 2 additions & 1 deletion src/rapid_response_xblock/apps.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""AppConfig for rapid response"""

from django.apps import AppConfig
from edx_django_utils.plugins import PluginSettings, PluginURLs
from openedx.core.djangoapps.plugins.constants import ProjectType, SettingsType
Expand All @@ -22,7 +23,7 @@ class RapidResponseAppConfig(AppConfig):
SettingsType.COMMON: {
PluginSettings.RELATIVE_PATH: "settings.cms_settings"
},
}
},
},
PluginURLs.CONFIG: {
ProjectType.CMS: {
Expand Down
89 changes: 48 additions & 41 deletions src/rapid_response_xblock/block.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Rapid-response functionality"""

import logging
from datetime import datetime
from functools import wraps
Expand Down Expand Up @@ -51,14 +52,13 @@ def staff_only(handler_method):
"""
Wrapper that ensures a handler method is enabled for staff users only
""" # noqa: D401

@wraps(handler_method)
def wrapper(aside_instance, *args, **kwargs):
if not aside_instance.is_staff():
return Response(
status=403,
json_body="Unauthorized (staff only)"
)
return Response(status=403, json_body="Unauthorized (staff only)")
return handler_method(aside_instance, *args, **kwargs)

return wrapper


Expand All @@ -75,24 +75,19 @@ class RapidResponseAside(XBlockAside):
display_name=_("Rapid response enabled status"),
default=False,
scope=Scope.settings,
help=_("Indicates whether or not a problem is enabled for rapid response")
help=_("Indicates whether or not a problem is enabled for rapid response"),
)

@XBlockAside.aside_for("student_view")
def student_view_aside(self, block, context=None): # pylint: disable=unused-argument # noqa: ARG002
def student_view_aside(self, block, context=None): # noqa: ARG002
"""
Renders the aside contents for the student view
""" # noqa: D401
fragment = Fragment("")
if not self.is_staff() or not self.enabled:
return fragment
fragment.add_content(
render_template(
"static/html/rapid.html",
{
"is_open": self.has_open_run
}
)
render_template("static/html/rapid.html", {"is_open": self.has_open_run})
)
fragment.add_css(get_resource_bytes("static/css/rapid.css"))
fragment.add_javascript(get_resource_bytes("static/js/rapid.js"))
Expand All @@ -101,7 +96,7 @@ def student_view_aside(self, block, context=None): # pylint: disable=unused-arg
return fragment

@XBlockAside.aside_for("author_view")
def author_view_aside(self, block, context=None): # pylint: disable=unused-argument # noqa: ARG002
def author_view_aside(self, block, context=None): # noqa: ARG002
"""
Renders the aside contents for the author view
""" # noqa: D401
Expand All @@ -110,15 +105,15 @@ def author_view_aside(self, block, context=None): # pylint: disable=unused-argu
return Fragment("")

@XBlockAside.aside_for("studio_view")
def studio_view_aside(self, block, context=None): # pylint: disable=unused-argument # noqa: ARG002
def studio_view_aside(self, block, context=None): # noqa: ARG002
"""
Renders the aside contents for the studio view
""" # noqa: D401
return self.get_studio_fragment()

@XBlock.handler
@staff_only
def toggle_block_open_status(self, request=None, suffix=None): # pylint: disable=unused-argument # noqa: ARG002
def toggle_block_open_status(self, request=None, suffix=None): # noqa: ARG002
"""
Toggles the open/closed status for the rapid-response-enabled block
"""
Expand All @@ -144,7 +139,7 @@ def toggle_block_open_status(self, request=None, suffix=None): # pylint: disabl
)

@XBlock.handler
def toggle_block_enabled(self, request=None, suffix=None): # pylint: disable=unused-argument # noqa: ARG002
def toggle_block_enabled(self, request=None, suffix=None): # noqa: ARG002
"""
Toggles the enabled status for the rapid-response-enabled block
"""
Expand All @@ -153,7 +148,7 @@ def toggle_block_enabled(self, request=None, suffix=None): # pylint: disable=un

@XBlock.handler
@staff_only
def responses(self, request=None, suffix=None): # pylint: disable=unused-argument # noqa: ARG002
def responses(self, request=None, suffix=None): # noqa: ARG002
"""
Returns student responses for rapid-response-enabled block
""" # noqa: D401
Expand All @@ -173,19 +168,20 @@ def responses(self, request=None, suffix=None): # pylint: disable=unused-argume
)

total_counts = {
run["id"]: sum(
counts[choice["answer_id"]][run["id"]] for choice in choices
) for run in runs
run["id"]: sum(counts[choice["answer_id"]][run["id"]] for choice in choices)
for run in runs
}

return Response(json_body={
"is_open": is_open,
"runs": runs,
"choices": choices,
"counts": counts,
"total_counts": total_counts,
"server_now": datetime.now(tz=pytz.utc).isoformat(),
})
return Response(
json_body={
"is_open": is_open,
"runs": runs,
"choices": choices,
"counts": counts,
"total_counts": total_counts,
"server_now": datetime.now(tz=pytz.utc).isoformat(),
}
)

@classmethod
def should_apply_to_block(cls, block):
Expand Down Expand Up @@ -219,8 +215,7 @@ def get_studio_fragment(self):
fragment = Fragment("")
fragment.add_content(
render_template(
"static/html/rapid_studio.html",
{"is_enabled": self.enabled}
"static/html/rapid_studio.html", {"is_enabled": self.enabled}
)
)
fragment.add_css(get_resource_bytes("static/css/rapid.css"))
Expand All @@ -247,10 +242,14 @@ def has_open_run(self):
"""
Check if there is an open run for this problem
"""
run = RapidResponseRun.objects.filter(
problem_usage_key=self.wrapped_block_usage_key,
course_key=self.course_key,
).order_by("-created").first()
run = (
RapidResponseRun.objects.filter(
problem_usage_key=self.wrapped_block_usage_key,
course_key=self.course_key,
)
.order_by("-created")
.first()
)
return run and run.open

@property
Expand All @@ -268,7 +267,9 @@ def choices(self):
return [
{
"answer_id": choice.get("name"),
"answer_text": next(iter(choice.itertext())) if list(choice.itertext()) else "" # noqa: E501
"answer_text": (
next(iter(choice.itertext())) if list(choice.itertext()) else ""
),
}
for choice in choice_elements
]
Expand All @@ -289,7 +290,8 @@ def serialize_runs(runs):
"id": run.id,
"created": run.created.isoformat(),
"open": run.open,
} for run in runs
}
for run in runs
]

@staticmethod
Expand All @@ -305,15 +307,20 @@ def get_counts_for_problem(run_ids, choices):
dict:
A mapping of answer id => run id => count for that run
"""
response_data = RapidResponseSubmission.objects.filter(
run__id__in=run_ids
).values("answer_id", "run").annotate(count=Count("answer_id"))
response_data = (
RapidResponseSubmission.objects.filter(run__id__in=run_ids)
.values("answer_id", "run")
.annotate(count=Count("answer_id"))
)
# Make sure every answer has a count and convert to JSON serializable format
response_counts = {(item["answer_id"], item["run"]): item["count"] for item in response_data} # noqa: E501
response_counts = {
(item["answer_id"], item["run"]): item["count"] for item in response_data
}

return {
choice["answer_id"]: {
run_id: response_counts.get((choice["answer_id"], run_id), 0)
for run_id in run_ids
} for choice in choices
}
for choice in choices
}
33 changes: 18 additions & 15 deletions src/rapid_response_xblock/logger.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Capture events
"""

import logging
from typing import NamedTuple

Expand All @@ -15,10 +16,13 @@
)

log = logging.getLogger(__name__)
SubmissionEvent = NamedTuple(
"SubmissionEvent",
["raw_data", "user_id", "problem_usage_key", "course_key", "answer_text", "answer_id"] # noqa: E501
)
class SubmissionEvent(NamedTuple):
raw_data:dict
user_id:str
problem_usage_key:str
course_key:str
answer_text:str
answer_id:str


class SubmissionRecorder(BaseBackend):
Expand Down Expand Up @@ -68,14 +72,10 @@ def parse_submission_event(event):
return SubmissionEvent(
raw_data=event,
user_id=event["context"]["user_id"],
problem_usage_key=UsageKey.from_string(
event_data["problem_id"]
),
course_key=CourseLocator.from_string(
event["context"]["course_id"]
),
problem_usage_key=UsageKey.from_string(event_data["problem_id"]),
course_key=CourseLocator.from_string(event["context"]["course_id"]),
answer_text=submission["answer"],
answer_id=event_data["answers"][submission_key]
answer_id=event_data["answers"][submission_key],
)
except: # pylint: disable=bare-except # noqa: E722
log.exception("Unable to parse event data as a submission: %s", event)
Expand All @@ -86,10 +86,13 @@ def send(self, event):
if sub is None:
return

open_run = RapidResponseRun.objects.filter(
problem_usage_key=sub.problem_usage_key,
course_key=sub.course_key
).order_by("-created").first()
open_run = (
RapidResponseRun.objects.filter(
problem_usage_key=sub.problem_usage_key, course_key=sub.course_key
)
.order_by("-created")
.first()
)
if not open_run or not open_run.open:
# Problem is not open
return
Expand Down
Loading

0 comments on commit 7cd4e47

Please sign in to comment.