
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.

Overview
restore_channel rebuilds an exercise's questions only from its Perseus archive. An exercise published as a QTI package alone restores with no questions. A dual-published exercise restores with its QTI item identifiers as assessment_ids, and publishing the restored channel then fails on them.
Complexity: Medium
Target branch: unstable
Context
- Restore reads only
preset='exercise' files:
|
sql_command = ( |
|
"SELECT checksum, extension " |
|
"preset FROM {table} WHERE contentnode_id='{id}' AND preset='exercise';".format( |
|
table=FILE_TABLE, id=contentnode.node_id |
|
) |
|
) |
- Restored
assessment_ids are the ids exercise.json lists:
|
for index, assessment_id in enumerate(data["all_assessment_items"]): |
|
with open("{}.json".format(assessment_id), "rb") as fobj: |
|
assessment_item = generate_assessment_item( |
|
assessment_id, |
|
index, |
|
data["assessment_mapping"][assessment_id], |
|
json.load(fobj), |
|
download_url=download_url, |
|
) |
- Publishing decodes every legacy item's
assessment_id as hex:
|
def hex_to_qti_id(hex_string): |
|
""" |
|
Encode a 32 digit hex to a 22 character base64 encoded id and a K prefix. |
|
""" |
|
bytes_data = bytes.fromhex(hex_string) |
|
return f"K{base64.urlsafe_b64encode(bytes_data).decode('ascii').rstrip('=')}" |
- On
1beec6ecb, a dual-published node with one QTI editor choice question and one legacy input_question, restored from its Perseus archive, then published:
restored assessment_ids: item_1, <32-char hex>
ValueError: non-hexadecimal number found in fromhex() arg at position 0
The Change
- Restore should recreate the questions of every published exercise, whichever archives it was published with.
How to Get There
- Publish a channel holding an exercise with one QTI editor question and one legacy question.
- Run
manage.py restore_channel <channel_id> --download-url <studio url>.
- Publish the restored channel.
Acceptance Criteria
AI usage
Claude Code found this during an automated self-review of the #6205 branch, reproduced the publish failure with a scratch test, and drafted this issue.
❌ This issue is not open for contribution. Visit Contributing guidelines to learn about the contributing process and how to find suitable issues.
Overview
restore_channelrebuilds an exercise's questions only from its Perseus archive. An exercise published as a QTI package alone restores with no questions. A dual-published exercise restores with its QTI item identifiers asassessment_ids, and publishing the restored channel then fails on them.Complexity: Medium
Target branch: unstable
Context
preset='exercise'files:studio/contentcuration/contentcuration/utils/import_tools.py
Lines 456 to 461 in 1beec6e
assessment_ids are the idsexercise.jsonlists:studio/contentcuration/contentcuration/utils/import_tools.py
Lines 516 to 524 in 1beec6e
assessment_idas hex:studio/contentcuration/contentcuration/utils/assessment/qti/convert.py
Lines 65 to 70 in 1beec6e
1beec6ecb, a dual-published node with one QTI editor choice question and one legacyinput_question, restored from its Perseus archive, then published:The Change
How to Get There
manage.py restore_channel <channel_id> --download-url <studio url>.Acceptance Criteria
import_toolstests cover both cases.AI usage
Claude Code found this during an automated self-review of the #6205 branch, reproduced the publish failure with a scratch test, and drafted this issue.