-
Notifications
You must be signed in to change notification settings - Fork 26
Expand file tree
/
Copy pathapi.py
More file actions
136 lines (117 loc) · 4.33 KB
/
api.py
File metadata and controls
136 lines (117 loc) · 4.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
"""Subsections API.
This module provides functions to manage subsections.
"""
from dataclasses import dataclass
from datetime import datetime
from typing import Iterable
from ..containers import api as containers_api
from ..containers.models import ContainerVersion
from ..publishing.models import LearningPackage
from ..units.models import Unit, UnitVersion
from .models import Subsection, SubsectionVersion
__all__ = [
"get_subsection",
"create_subsection_and_version",
"create_next_subsection_version",
"SubsectionListEntry",
"get_units_in_subsection",
]
def get_subsection(subsection_id: Subsection.ID, /):
"""Get a subsection"""
return Subsection.objects.select_related("container").get(pk=subsection_id)
def create_subsection_and_version(
learning_package_id: LearningPackage.ID,
container_code: str,
*,
title: str,
units: Iterable[Unit | UnitVersion] | None = None,
created: datetime,
created_by: int | None = None,
can_stand_alone: bool = True,
) -> tuple[Subsection, SubsectionVersion]:
"""
See documentation of `content_api.create_container_and_version()`
The only real purpose of this function is to rename `entities` to `units`, and to specify that the version
returned is a `SubsectionVersion`. In the future, if `SubsectionVersion` gets some fields that aren't on
`ContainerVersion`, this function would be more important.
"""
subsection, sv = containers_api.create_container_and_version(
learning_package_id,
container_code=container_code,
title=title,
entities=units,
created=created,
created_by=created_by,
can_stand_alone=can_stand_alone,
container_cls=Subsection,
)
assert isinstance(sv, SubsectionVersion)
return subsection, sv
def create_next_subsection_version(
subsection: Subsection | Subsection.ID,
*,
title: str | None = None,
units: Iterable[Unit | UnitVersion] | None = None,
created: datetime,
created_by: int | None,
) -> SubsectionVersion:
"""
See documentation of content_api.create_next_container_version()
The only real purpose of this function is to rename `entities` to `units`, and to specify that the version
returned is a `SubsectionVersion`. In the future, if `SubsectionVersion` gets some fields that aren't on
`ContainerVersion`, this function would be more important.
"""
if isinstance(subsection, int):
subsection = get_subsection(subsection)
assert isinstance(subsection, Subsection)
sv = containers_api.create_next_container_version(
subsection,
title=title,
entities=units,
created=created,
created_by=created_by,
# For now, `entities_action` and `force_version_num` are unsupported but we could add them in the future.
)
assert isinstance(sv, SubsectionVersion)
return sv
@dataclass(frozen=True)
class SubsectionListEntry:
"""
[ ❓TODO: STABLE or UNSTABLE? ]
Data about a single unit in a subsection.
"""
unit_version: UnitVersion
pinned: bool = False
@property
def unit(self):
return self.unit_version.unit
def get_units_in_subsection(
subsection: Subsection,
*,
published: bool,
) -> list[SubsectionListEntry]:
"""
[ ❓TODO: STABLE or UNSTABLE? ]
Get the list of entities and their versions in the draft or published
version of the given Subsection.
Args:
subsection: The Subsection, e.g. returned by `get_subsection()`
published: `True` if we want the published version of the subsection, or
`False` for the draft version.
"""
assert isinstance(subsection, Subsection)
units = []
try:
entries = containers_api.get_entities_in_container(
subsection,
published=published,
select_related_version="containerversion__unitversion",
)
except ContainerVersion.DoesNotExist as exc:
raise SubsectionVersion.DoesNotExist() from exc # Make the exception more specific
for entry in entries:
# Convert from generic PublishableEntityVersion to UnitVersion:
unit_version = entry.entity_version.containerversion.unitversion
assert isinstance(unit_version, UnitVersion)
units.append(SubsectionListEntry(unit_version=unit_version, pinned=entry.pinned))
return units