Skip to content

Commit 293f20f

Browse files
authored
feat: export LearningPackage data in lp_dump command (#338)
Updates the lp_dump management command to export real data from the LearningPackage model instead of using stub values.
1 parent a1dd9e5 commit 293f20f

File tree

3 files changed

+54
-14
lines changed

3 files changed

+54
-14
lines changed

openedx_learning/apps/authoring/backup_restore/api.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
"""
44
import zipfile
55

6+
from openedx_learning.apps.authoring.publishing.api import get_learning_package_by_key
7+
68
from .toml import TOMLLearningPackageFile
79

810
TOML_PACKAGE_NAME = "package.toml"
@@ -11,9 +13,12 @@
1113
def create_zip_file(lp_key: str, path: str) -> None:
1214
"""
1315
Creates a zip file with a toml file so far (WIP)
16+
17+
Can throw a NotFoundError at get_learning_package_by_key
1418
"""
15-
toml_file = TOMLLearningPackageFile()
16-
toml_file.create(lp_key)
19+
learning_package = get_learning_package_by_key(lp_key)
20+
toml_file = TOMLLearningPackageFile(learning_package)
21+
toml_file.create()
1722
toml_content: str = toml_file.get()
1823
with zipfile.ZipFile(path, "w", compression=zipfile.ZIP_DEFLATED) as zipf:
1924
# Add the TOML string as a file in the ZIP

openedx_learning/apps/authoring/backup_restore/management/commands/lp_dump.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@
33
"""
44
import logging
55

6+
from django.core.management import CommandError
67
from django.core.management.base import BaseCommand
78

89
from openedx_learning.apps.authoring.backup_restore.api import create_zip_file
10+
from openedx_learning.apps.authoring.publishing.api import LearningPackage
911

1012
logger = logging.getLogger(__name__)
1113

@@ -23,15 +25,21 @@ def add_arguments(self, parser):
2325
def handle(self, *args, **options):
2426
lp_key = options['lp_key']
2527
file_name = options['file_name']
28+
if not file_name.endswith(".zip"):
29+
raise CommandError("Output file name must end with .zip")
2630
try:
2731
create_zip_file(lp_key, file_name)
2832
message = f'{lp_key} written to {file_name}'
2933
self.stdout.write(self.style.SUCCESS(message))
30-
except Exception as e: # pylint: disable=broad-exception-caught
31-
message = f"Error creating zip file: error {e}"
32-
self.stderr.write(self.style.ERROR(message))
34+
except LearningPackage.DoesNotExist as exc:
35+
message = f"Learning package with key {lp_key} not found"
36+
logger.exception(message)
37+
raise CommandError(message) from exc
38+
except Exception as e:
39+
message = f"Failed to export learning package '{lp_key}': {e}"
3340
logger.exception(
3441
"Failed to create zip file %s (learning‑package key %s)",
3542
file_name,
3643
lp_key,
3744
)
45+
raise CommandError(message) from e

openedx_learning/apps/authoring/backup_restore/toml.py

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,38 +8,65 @@
88
from tomlkit import comment, document, dumps, nl, table
99
from tomlkit.items import Table
1010

11+
from openedx_learning.apps.authoring.publishing.models.learning_package import LearningPackage
12+
1113

1214
class TOMLLearningPackageFile():
1315
"""
14-
Class to create a .toml file of a learning package (WIP)
16+
Class to create a .toml representation of a LearningPackage instance.
17+
18+
This class builds a structured TOML document using `tomlkit` with metadata and fields
19+
extracted from a `LearningPackage` object. The output can later be saved to a file or used elsewhere.
1520
"""
1621

17-
def __init__(self):
22+
def __init__(self, learning_package: LearningPackage):
1823
self.doc = document()
24+
self.learning_package = learning_package
1925

2026
def _create_header(self) -> None:
27+
"""
28+
Adds a comment with the current datetime to indicate when the export occurred.
29+
This helps with traceability and file versioning.
30+
"""
2131
self.doc.add(comment(f"Datetime of the export: {datetime.now()}"))
2232
self.doc.add(nl())
2333

2434
def _create_table(self, params: Dict[str, Any]) -> Table:
35+
"""
36+
Builds a TOML table section from a dictionary of key-value pairs.
37+
38+
Args:
39+
params (Dict[str, Any]): A dictionary containing keys and values to include in the TOML table.
40+
41+
Returns:
42+
Table: A TOML table populated with the provided keys and values.
43+
"""
2544
section = table()
2645
for key, value in params.items():
2746
section.add(key, value)
2847
return section
2948

30-
def create(self, lp_key: str) -> None:
49+
def create(self) -> None:
3150
"""
32-
Process the toml file
51+
Populates the TOML document with a header and a table containing
52+
metadata from the LearningPackage instance.
53+
54+
This method must be called before calling `get()`, otherwise the document will be empty.
3355
"""
3456
self._create_header()
3557
section = self._create_table({
36-
"title": "",
37-
"key": lp_key,
38-
"description": "",
39-
"created": "",
40-
"updated": ""
58+
"title": self.learning_package.title,
59+
"key": self.learning_package.key,
60+
"description": self.learning_package.description,
61+
"created": self.learning_package.created,
62+
"updated": self.learning_package.updated
4163
})
4264
self.doc.add("learning_package", section)
4365

4466
def get(self) -> str:
67+
"""
68+
Returns:
69+
str: The string representation of the generated TOML document.
70+
Ensure `create()` has been called beforehand to get meaningful output.
71+
"""
4572
return dumps(self.doc)

0 commit comments

Comments
 (0)