Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions frontends/api/src/generated/v1/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,12 @@ export interface CourseResource {
* @memberof CourseResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof CourseResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -1020,6 +1026,12 @@ export interface CourseResourceRequest {
* @memberof CourseResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof CourseResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -1582,6 +1594,12 @@ export interface LearningPathResource {
* @memberof LearningPathResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof LearningPathResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -1680,6 +1698,12 @@ export interface LearningPathResourceRequest {
* @memberof LearningPathResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof LearningPathResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -2336,6 +2360,12 @@ export interface LearningResourceRun {
* @memberof LearningResourceRun
*/
availability?: AvailabilityEnum | null
/**
*
* @type {string}
* @memberof LearningResourceRun
*/
location?: string
}

/**
Expand Down Expand Up @@ -2491,6 +2521,12 @@ export interface LearningResourceRunRequest {
* @memberof LearningResourceRunRequest
*/
availability?: AvailabilityEnum | null
/**
*
* @type {string}
* @memberof LearningResourceRunRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -3517,6 +3553,12 @@ export interface PatchedLearningPathResourceRequest {
* @memberof PatchedLearningPathResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof PatchedLearningPathResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -4315,6 +4357,12 @@ export interface PodcastEpisodeResource {
* @memberof PodcastEpisodeResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof PodcastEpisodeResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -4413,6 +4461,12 @@ export interface PodcastEpisodeResourceRequest {
* @memberof PodcastEpisodeResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof PodcastEpisodeResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -4691,6 +4745,12 @@ export interface PodcastResource {
* @memberof PodcastResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof PodcastResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -4789,6 +4849,12 @@ export interface PodcastResourceRequest {
* @memberof PodcastResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof PodcastResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -5287,6 +5353,12 @@ export interface ProgramResource {
* @memberof ProgramResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof ProgramResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -5385,6 +5457,12 @@ export interface ProgramResourceRequest {
* @memberof ProgramResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof ProgramResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -6142,6 +6220,12 @@ export interface VideoPlaylistResource {
* @memberof VideoPlaylistResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof VideoPlaylistResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -6240,6 +6324,12 @@ export interface VideoPlaylistResourceRequest {
* @memberof VideoPlaylistResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof VideoPlaylistResourceRequest
*/
location?: string
}

/**
Expand Down Expand Up @@ -6506,6 +6596,12 @@ export interface VideoResource {
* @memberof VideoResource
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof VideoResource
*/
location?: string
}

/**
Expand Down Expand Up @@ -6604,6 +6700,12 @@ export interface VideoResourceRequest {
* @memberof VideoResourceRequest
*/
continuing_ed_credits?: string | null
/**
*
* @type {string}
* @memberof VideoResourceRequest
*/
location?: string
}

/**
Expand Down
1 change: 1 addition & 0 deletions learning_resources/etl/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,3 +116,4 @@ class ResourceNextRunConfig:
next_start_date: datetime = None
prices: list[Decimal] = field(default_factory=list)
availability: str = None
location: str = None
15 changes: 9 additions & 6 deletions learning_resources/etl/loaders.py
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,20 @@ def load_run_dependent_values(
next_upcoming_run
or resource.runs.filter(published=True).order_by("-start_date").first()
)
resource.availability = best_run.availability if best_run else resource.availability
resource.prices = (
best_run.prices
if resource.certification and best_run and best_run.prices
else []
)
if best_run:
resource.availability = best_run.availability
resource.prices = (
best_run.prices
if resource.certification and best_run and best_run.prices
else []
)
resource.location = best_run.location
resource.save()
return ResourceNextRunConfig(
next_start_date=resource.next_start_date,
prices=resource.prices,
availability=resource.availability,
location=resource.location,
)


Expand Down
3 changes: 3 additions & 0 deletions learning_resources/etl/loaders_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -1463,18 +1463,21 @@ def test_load_run_dependent_values(certification):
availability=Availability.dated.name,
prices=[Decimal("0.00"), Decimal("20.00")],
start_date=closest_date,
location="Portland, ME",
)
LearningResourceRunFactory.create(
learning_resource=course,
published=True,
availability=Availability.dated.name,
prices=[Decimal("0.00"), Decimal("50.00")],
start_date=furthest_date,
location="Portland, OR",
)
result = load_run_dependent_values(course)
assert result.next_start_date == course.next_start_date == closest_date
assert result.prices == course.prices == ([] if not certification else run.prices)
assert result.availability == course.availability == Availability.dated.name
assert result.location == course.location == run.location


@pytest.mark.parametrize(
Expand Down
16 changes: 16 additions & 0 deletions learning_resources/etl/sloan.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,21 @@ def parse_format(run_data: dict) -> str:
return default_format()


def parse_location(run_data: dict) -> str:
"""
Parse location from run data

Args:
run_data (list): the run data

Returns:
str: the location
"""
if not run_data or run_data["Delivery"] == "Online":
return ""
return run_data["Location"] or ""


def extract():
"""
Extract Sloan Executive Education data
Expand Down Expand Up @@ -232,6 +247,7 @@ def transform_run(run_data, course_data):
"instructors": [{"full_name": name.strip()} for name in faculty_names],
"pace": [parse_pace(run_data)],
"format": parse_format(run_data),
"location": parse_location(run_data),
}


Expand Down
21 changes: 21 additions & 0 deletions learning_resources/etl/sloan_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
parse_datetime,
parse_format,
parse_image,
parse_location,
parse_pace,
transform_course,
transform_delivery,
Expand Down Expand Up @@ -130,6 +131,7 @@ def test_transform_run(
"instructors": [{"full_name": name.strip()} for name in faculty_names],
"pace": [Pace.instructor_paced.name],
"format": [Format.synchronous.name],
"location": run_data["Location"],
}


Expand Down Expand Up @@ -280,3 +282,22 @@ def test_parse_format(delivery, run_format, expected_format):
}
assert parse_format(run_data) == expected_format
assert parse_format(None) == [Format.asynchronous.name]


@pytest.mark.parametrize(
("delivery", "location", "result"),
[
("Online", "Online", ""),
("In Person", "Cambridge, MA", "Cambridge, MA"),
("Blended", "Boston, MA", "Boston, MA"),
("Online", None, ""),
],
)
def test_parse_location(delivery, location, result):
"""Test that the location is parsed correctly"""
run_data = {
"Delivery": delivery,
"Location": location,
}
assert parse_location(run_data) == result
assert parse_location(None) == ""
22 changes: 22 additions & 0 deletions learning_resources/migrations/0070_learningresource_location.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Generated by Django 4.2.16 on 2024-09-24 15:28

from django.db import migrations, models


class Migration(migrations.Migration):
dependencies = [
("learning_resources", "0069_learningresource_ocw_topics"),
]

operations = [
migrations.AddField(
model_name="learningresource",
name="location",
field=models.CharField(blank=True, max_length=256),
),
migrations.AddField(
model_name="learningresourcerun",
name="location",
field=models.CharField(blank=True, max_length=256),
),
]
4 changes: 3 additions & 1 deletion learning_resources/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from django.contrib.auth.models import User
from django.contrib.postgres.fields import ArrayField
from django.db import models
from django.db.models import Count, JSONField, OuterRef, Prefetch, Q
from django.db.models import CharField, Count, JSONField, OuterRef, Prefetch, Q
from django.db.models.functions import Lower
from django.utils import timezone

Expand Down Expand Up @@ -455,6 +455,7 @@ class LearningResource(TimestampedModel):
),
default=default_format,
)
location = models.CharField(max_length=256, blank=True)

@property
def audience(self) -> str | None:
Expand Down Expand Up @@ -606,6 +607,7 @@ class LearningResourceRun(TimestampedModel):
),
default=default_format,
)
location = CharField(max_length=256, blank=True)

def __str__(self):
return f"LearningResourceRun platform={self.learning_resource.platform} run_id={self.run_id}" # noqa: E501
Expand Down
1 change: 1 addition & 0 deletions learning_resources/serializers_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def test_learning_resource_serializer( # noqa: PLR0913
"pace": [
{"code": lr_pace, "name": Pace[lr_pace].value} for lr_pace in resource.pace
],
"location": resource.location,
"next_start_date": resource.next_start_date,
"availability": resource.availability,
"completeness": 1.0,
Expand Down
Loading
Loading