Skip to content

Commit

Permalink
Store canvas terms info PoC
Browse files Browse the repository at this point in the history
  • Loading branch information
marcospri committed Jan 27, 2025
1 parent 18d1121 commit bc6edaa
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 22 deletions.
1 change: 1 addition & 0 deletions lms/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
LMSCourseMembership,
)
from lms.models.lms_segment import LMSSegment, LMSSegmentMembership
from lms.models.lms_term import LMSTerm
from lms.models.lms_user import LMSUser, LMSUserApplicationInstance
from lms.models.lti_params import CLAIM_PREFIX, LTIParams
from lms.models.lti_registration import LTIRegistration
Expand Down
7 changes: 6 additions & 1 deletion lms/models/lms_course.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from lms.models._mixins import CreatedUpdatedMixin

if TYPE_CHECKING:
from lms.models import LMSUser, LTIRole
from lms.models import LMSTerm, LMSUser, LTIRole


class LMSCourse(CreatedUpdatedMixin, Base):
Expand Down Expand Up @@ -58,6 +58,11 @@ class LMSCourse(CreatedUpdatedMixin, Base):
ends_at: Mapped[datetime | None] = mapped_column()
"""The end date of the course. Only for when we get this information directly from the LMS"""

lms_term_id: Mapped[int | None] = mapped_column(
sa.ForeignKey("lms_term.id", ondelete="cascade"), index=True
)
lms_term: Mapped["LMSTerm"] = relationship()


class LMSCourseApplicationInstance(CreatedUpdatedMixin, Base):
"""Record of on which installs (application instances) we have seen one course."""
Expand Down
9 changes: 9 additions & 0 deletions lms/models/lti_params.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import logging
from datetime import datetime

from dateutil import parser

CLAIM_PREFIX = "https://purl.imsglobal.org/spec/lti/claim"

Expand Down Expand Up @@ -26,6 +29,12 @@ def __init__(self, v11: dict, v13: dict | None = None):
def v11(self):
return self

def get_datetime(self, key: str) -> datetime | None:
try:
return parser.isoparse(self.get(key))
except (TypeError, ValueError):
return None

@classmethod
def from_request(cls, request):
"""Create an LTIParams from the request."""
Expand Down
4 changes: 4 additions & 0 deletions lms/services/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
LTILaunchVerificationError,
LTIOAuthError,
)
from lms.services.lms_term import LMSTermService
from lms.services.lti_grading import LTIGradingService
from lms.services.lti_names_roles import LTINamesRolesService
from lms.services.lti_registration import LTIRegistrationService
Expand Down Expand Up @@ -165,6 +166,9 @@ def includeme(config): # noqa: PLR0915
config.register_service_factory(
"lms.services.auto_grading.factory", iface=AutoGradingService
)
config.register_service_factory(
"lms.services.lms_term.factory", iface=LMSTermService
)

# Plugins are not the same as top level services but we want to register them as pyramid services too
# Importing them here to:
Expand Down
37 changes: 16 additions & 21 deletions lms/services/course.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
import json
from copy import deepcopy
from datetime import datetime
from typing import Mapping

from dateutil import parser
from sqlalchemy import Select, select, union

from lms.db import full_text_match
Expand All @@ -28,14 +25,22 @@
)
from lms.product.family import Family
from lms.services.grouping import GroupingService
from lms.services.lms_term import LMSTermService
from lms.services.upsert import bulk_upsert


class CourseService:
def __init__(self, db, application_instance, grouping_service: GroupingService):
def __init__(
self,
db,
application_instance,
grouping_service: GroupingService,
lms_term_service: LMSTermService,
):
self._db = db
self._application_instance = application_instance
self._grouping_service = grouping_service
self._lms_term_service = lms_term_service

def any_with_setting(self, group, key, value=True) -> bool:
"""
Expand Down Expand Up @@ -314,7 +319,10 @@ def _upsert_lms_course(self, course: Course, lti_params: LTIParams) -> LMSCourse
"https://purl.imsglobal.org/spec/lti-nrps/claim/namesroleservice", {}
).get("context_memberships_url")

course_starts_at, course_ends_at = self._get_course_dates(lti_params)
course_starts_at = lti_params.get_datetime("custom_curse_starts")
course_ends_at = lti_params.get_datetime("custom_course_ends")

lms_term = self._lms_term_service.get_term(lti_params)
lms_api_course_id = self._get_api_id_from_launch(lti_params)

lms_course = bulk_upsert(
Expand All @@ -330,6 +338,7 @@ def _upsert_lms_course(self, course: Course, lti_params: LTIParams) -> LMSCourse
"starts_at": course_starts_at,
"ends_at": course_ends_at,
"lms_api_course_id": lms_api_course_id,
"lms_term_id": lms_term.id if lms_term else None,
}
],
index_elements=["h_authority_provided_id"],
Expand All @@ -340,6 +349,7 @@ def _upsert_lms_course(self, course: Course, lti_params: LTIParams) -> LMSCourse
"starts_at",
"ends_at",
"lms_api_course_id",
"lms_term_id",
],
).one()
bulk_upsert(
Expand Down Expand Up @@ -431,22 +441,6 @@ def _get_copied_from_course(self, lti_params) -> Course | None:

return None

def _get_course_dates(
self, lti_params: Mapping
) -> tuple[datetime | None, datetime | None]:
"""Get the dates for the current curse, None if not available."""
try:
course_starts_at = parser.isoparse(lti_params.get("custom_course_starts"))
except (TypeError, ValueError):
course_starts_at = None

try:
course_ends_at = parser.isoparse(lti_params.get("custom_course_ends"))
except (TypeError, ValueError):
course_ends_at = None

return course_starts_at, course_ends_at

def _get_api_id_from_launch(self, lti_params: LTIParams) -> str | None:
"""Get the API ID from the launch params.
Expand All @@ -464,4 +458,5 @@ def course_service_factory(_context, request):
request.lti_user.application_instance if request.lti_user else None
),
grouping_service=request.find_service(name="grouping"),
lms_term_service=request.find_service(LMSTermService),
)

0 comments on commit bc6edaa

Please sign in to comment.