@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.
@@ -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
- console.log("Exercise not found receiving webhook, this should not happen", lessonID);
422
- return res.json({ status: "SUCCESS" });
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.${readme.parsed.language_code && readme.parsed.language_code !== "en" ?
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: "done",
489
+ status: "generating",
448
490
  log: `✅ Code file created for ${exercise.title}`,
449
491
  });
450
492
  }
451
- if (nextExercise) {
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
- return lesson;
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: true });
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 = "Nothing";
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 created",
930
+ message: "Course generation started",
880
931
  slug: syllabus.courseInfo.slug,
881
932
  });
882
933
  });
@@ -1043,6 +1043,9 @@
1043
1043
  .text-blue-900 {
1044
1044
  color: var(--color-blue-900);
1045
1045
  }
1046
+ .text-gray-200 {
1047
+ color: var(--color-gray-200);
1048
+ }
1046
1049
  .text-gray-400 {
1047
1050
  color: var(--color-gray-400);
1048
1051
  }