@learnpack/learnpack 5.0.267 → 5.0.268
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commands/serve.js +70 -19
- package/lib/creatorDist/assets/{index-DmpsXknz.css → index-B4khtb0r.css} +3 -0
- package/lib/creatorDist/assets/{index-BXp9oelr.js → index-CqjbIn8n.js} +2391 -2383
- package/lib/creatorDist/index.html +2 -2
- package/lib/models/creator.d.ts +1 -0
- package/package.json +1 -1
- package/src/commands/serve.ts +105 -27
- package/src/creator/src/App.tsx +12 -6
- package/src/creator/src/components/syllabus/ContentIndex.tsx +5 -0
- package/src/creator/src/locales/en.json +2 -1
- package/src/creator/src/locales/es.json +2 -1
- package/src/creator/src/utils/rigo.ts +2 -3
- package/src/creatorDist/assets/{index-DmpsXknz.css → index-B4khtb0r.css} +3 -0
- package/src/creatorDist/assets/{index-BXp9oelr.js → index-CqjbIn8n.js} +2391 -2383
- package/src/creatorDist/index.html +2 -2
- package/src/models/creator.ts +1 -0
package/lib/commands/serve.js
CHANGED
@@ -403,6 +403,41 @@ class ServeCommand extends SessionCommand_1.default {
|
|
403
403
|
res.status(500).json({ error: error.message });
|
404
404
|
}
|
405
405
|
});
|
406
|
+
app.post("/actions/continue-generating/:courseSlug/:position", async (req, res) => {
|
407
|
+
const { courseSlug, position } = req.params;
|
408
|
+
const { feedback } = req.body;
|
409
|
+
const rigoToken = req.header("x-rigo-token");
|
410
|
+
if (!rigoToken) {
|
411
|
+
return res.status(400).json({
|
412
|
+
error: "Rigo token is required. x-rigo-token header is missing",
|
413
|
+
});
|
414
|
+
}
|
415
|
+
const syllabus = await bucket.file(`courses/${courseSlug}/.learn/initialSyllabus.json`);
|
416
|
+
const [content] = await syllabus.download();
|
417
|
+
const syllabusJson = JSON.parse(content.toString());
|
418
|
+
const exercise = syllabusJson.lessons[parseInt(position)];
|
419
|
+
// previous exercise
|
420
|
+
let previousReadme = "---";
|
421
|
+
const previousExercise = syllabusJson.lessons[parseInt(position) - 1];
|
422
|
+
if (previousExercise) {
|
423
|
+
// Get the readme of the previous exercise
|
424
|
+
const exSlug = (0, creatorUtilities_2.slugify)(previousExercise.id + "-" + previousExercise.title);
|
425
|
+
// llist the files un
|
426
|
+
const [files] = await bucket.getFiles({
|
427
|
+
prefix: `courses/${courseSlug}/exercises/${exSlug}/README`,
|
428
|
+
});
|
429
|
+
// select any README
|
430
|
+
const readmeFiles = files.map(f => f.name);
|
431
|
+
const readmeFile = readmeFiles.find(f => f.includes("README"));
|
432
|
+
if (readmeFile) {
|
433
|
+
const [content] = await bucket.file(readmeFile).download();
|
434
|
+
previousReadme = content.toString();
|
435
|
+
}
|
436
|
+
}
|
437
|
+
await startExerciseGeneration(bucket, rigoToken, syllabusJson.lessons, syllabusJson.courseInfo, exercise, `courses/${courseSlug}`, courseSlug, syllabusJson.courseInfo.purpose, previousReadme +
|
438
|
+
"\n\nThe user provided the following feedback related to the content of the course so far: \n\n" +
|
439
|
+
feedback);
|
440
|
+
});
|
406
441
|
app.post("/webhooks/:courseSlug/exercise-processor/:lessonID/:rigoToken", async (req, res) => {
|
407
442
|
// console.log("Receiving a webhook to exercise processor")
|
408
443
|
const { courseSlug, lessonID, rigoToken } = req.params;
|
@@ -410,17 +445,26 @@ class ServeCommand extends SessionCommand_1.default {
|
|
410
445
|
const syllabus = await bucket.file(`courses/${courseSlug}/.learn/initialSyllabus.json`);
|
411
446
|
const [content] = await syllabus.download();
|
412
447
|
const syllabusJson = JSON.parse(content.toString());
|
448
|
+
if (readme.status === "ERROR") {
|
449
|
+
(0, creatorSocket_1.emitToCourse)(courseSlug, "course-creation", {
|
450
|
+
lesson: lessonID,
|
451
|
+
status: "error",
|
452
|
+
log: `❌ Error generating the lesson ${lessonID}`,
|
453
|
+
});
|
454
|
+
}
|
413
455
|
const exerciseIndex = syllabusJson.lessons.findIndex(lesson => lesson.id === lessonID);
|
414
456
|
if (exerciseIndex === -1) {
|
415
457
|
console.log("Exercise not found receiving webhook, this should not happen", lessonID);
|
416
458
|
return res.json({ status: "ERROR", error: "Exercise not found" });
|
417
459
|
}
|
418
460
|
const exercise = syllabusJson.lessons[exerciseIndex];
|
419
|
-
const nextExercise = syllabusJson.lessons[exerciseIndex + 1] || null;
|
420
461
|
if (!exercise) {
|
421
|
-
|
422
|
-
|
462
|
+
return res.json({
|
463
|
+
status: "ERROR",
|
464
|
+
error: "Exercise not found or is invalid",
|
465
|
+
});
|
423
466
|
}
|
467
|
+
const nextExercise = syllabusJson.lessons[exerciseIndex + 1] || null;
|
424
468
|
const exSlug = (0, creatorUtilities_2.slugify)(exercise.id + "-" + exercise.title);
|
425
469
|
const readability = (0, creatorUtilities_2.checkReadability)(readme.parsed.content, PARAMS.max_words, 3);
|
426
470
|
(0, creatorSocket_1.emitToCourse)(courseSlug, "course-creation", {
|
@@ -430,9 +474,7 @@ class ServeCommand extends SessionCommand_1.default {
|
|
430
474
|
});
|
431
475
|
const exercisesDir = `courses/${courseSlug}/exercises`;
|
432
476
|
const targetDir = `${exercisesDir}/${exSlug}`;
|
433
|
-
const readmeFilename = `README
|
434
|
-
`${readme.parsed.language_code}.` :
|
435
|
-
""}md`;
|
477
|
+
const readmeFilename = `README${(0, creatorUtilities_1.getReadmeExtension)(readme.parsed.language_code)}`;
|
436
478
|
await uploadFileToBucket(bucket, readability.newMarkdown, `${targetDir}/${readmeFilename}`);
|
437
479
|
if (exercise.type.toLowerCase() === "code" &&
|
438
480
|
readme.parsed.codefile_content) {
|
@@ -444,12 +486,18 @@ class ServeCommand extends SessionCommand_1.default {
|
|
444
486
|
await uploadFileToBucket(bucket, readme.parsed.codefile_content, `${targetDir}/${readme.parsed.codefile_name.toLowerCase().trim()}`);
|
445
487
|
(0, creatorSocket_1.emitToCourse)(courseSlug, "course-creation", {
|
446
488
|
lesson: exSlug,
|
447
|
-
status: "
|
489
|
+
status: "generating",
|
448
490
|
log: `✅ Code file created for ${exercise.title}`,
|
449
491
|
});
|
450
492
|
}
|
451
|
-
|
493
|
+
let nextStarted = false;
|
494
|
+
if (nextExercise &&
|
495
|
+
(exerciseIndex === 0 || !(exerciseIndex % 3 === 0))) {
|
452
496
|
startExerciseGeneration(bucket, rigoToken, syllabusJson.lessons, syllabusJson.courseInfo, nextExercise, `courses/${courseSlug}`, courseSlug, syllabusJson.courseInfo.purpose, readme.parsed.content);
|
497
|
+
nextStarted = true;
|
498
|
+
}
|
499
|
+
else {
|
500
|
+
console.log("Stopping generation process at", exerciseIndex, exercise.title, "because it's a multiple of 3");
|
453
501
|
}
|
454
502
|
const imagesArray = (0, creatorUtilities_1.extractImagesFromMarkdown)(readability.newMarkdown);
|
455
503
|
if (imagesArray.length > 0) {
|
@@ -463,18 +511,21 @@ class ServeCommand extends SessionCommand_1.default {
|
|
463
511
|
await (0, exports.processImage)(image.url, image.alt, rigoToken, courseSlug);
|
464
512
|
}
|
465
513
|
}
|
466
|
-
(0, creatorSocket_1.emitToCourse)(courseSlug, "course-creation", {
|
467
|
-
lesson: exSlug,
|
468
|
-
status: "done",
|
469
|
-
log: `✅ The lesson ${exercise.id} - ${exercise.title} has been generated successfully!`,
|
470
|
-
});
|
471
514
|
const newSyllabus = Object.assign(Object.assign({}, syllabusJson), { lessons: syllabusJson.lessons.map(lesson => {
|
472
515
|
if (lesson.id === exercise.id) {
|
473
|
-
return Object.assign(Object.assign({}, lesson), { generated: true });
|
516
|
+
return Object.assign(Object.assign({}, lesson), { generated: true, status: "DONE" });
|
474
517
|
}
|
475
|
-
|
518
|
+
if (nextExercise && nextExercise.id === lesson.id && !nextStarted) {
|
519
|
+
return Object.assign(Object.assign({}, lesson), { generated: false, status: "GENERATING" });
|
520
|
+
}
|
521
|
+
return Object.assign({}, lesson);
|
476
522
|
}) });
|
477
523
|
await uploadFileToBucket(bucket, JSON.stringify(newSyllabus), `courses/${courseSlug}/.learn/initialSyllabus.json`);
|
524
|
+
(0, creatorSocket_1.emitToCourse)(courseSlug, "course-creation", {
|
525
|
+
lesson: exSlug,
|
526
|
+
status: "done",
|
527
|
+
log: `✅ The lesson ${exercise.id} - ${exercise.title} has been generated successfully!`,
|
528
|
+
});
|
478
529
|
res.json({ status: "SUCCESS" });
|
479
530
|
});
|
480
531
|
// The following endpoint is used to store an incoming translation where it supposed to be
|
@@ -865,18 +916,18 @@ class ServeCommand extends SessionCommand_1.default {
|
|
865
916
|
const sidebar = await createInitialSidebar(syllabus.lessons.map(lesson => (0, creatorUtilities_2.slugify)(lesson.id + "-" + lesson.title)), syllabus.courseInfo.language);
|
866
917
|
const initialSyllabus = Object.assign(Object.assign({}, syllabus), { lessons: syllabus.lessons.map((lesson, index) => {
|
867
918
|
if (index < 1) {
|
868
|
-
return Object.assign(Object.assign({}, lesson), { generated:
|
919
|
+
return Object.assign(Object.assign({}, lesson), { generated: false, status: "GENERATING" });
|
869
920
|
}
|
870
|
-
return Object.assign(Object.assign({}, lesson), { generated: false });
|
921
|
+
return Object.assign(Object.assign({}, lesson), { generated: false, status: "PENDING" });
|
871
922
|
}) });
|
872
923
|
await uploadFileToBucket(bucket, JSON.stringify(initialSyllabus), `${tutorialDir}/.learn/initialSyllabus.json`);
|
873
924
|
await uploadFileToBucket(bucket, JSON.stringify(sidebar), `${tutorialDir}/.learn/sidebar.json`);
|
874
925
|
const firstLesson = syllabus.lessons[0];
|
875
|
-
const lastResult = "
|
926
|
+
const lastResult = "---";
|
876
927
|
await startExerciseGeneration(bucket, rigoToken, syllabus.lessons, syllabus.courseInfo, firstLesson, tutorialDir, courseSlug, syllabus.courseInfo.purpose, lastResult);
|
877
928
|
await createInitialReadme(JSON.stringify(syllabus.courseInfo), courseSlug, rigoToken);
|
878
929
|
return res.json({
|
879
|
-
message: "Course
|
930
|
+
message: "Course generation started",
|
880
931
|
slug: syllabus.courseInfo.slug,
|
881
932
|
});
|
882
933
|
});
|