@learnpack/learnpack 5.0.261 → 5.0.265
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 +82 -50
- package/lib/commands/translate.js +1 -2
- package/lib/creatorDist/assets/{index-BvHkfJm4.js → index-6e9E-1qG.js} +1996 -1947
- package/lib/creatorDist/index.html +1 -1
- package/lib/managers/server/routes.js +1 -2
- package/lib/models/creator.d.ts +2 -0
- package/lib/utils/rigoActions.d.ts +6 -3
- package/lib/utils/rigoActions.js +15 -4
- package/package.json +1 -1
- package/src/commands/serve.ts +123 -72
- package/src/commands/translate.ts +8 -5
- package/src/creator/src/App.tsx +29 -6
- package/src/creator/src/components/PurposeSelector.tsx +6 -6
- package/src/creator/src/components/TurnstileModal.tsx +34 -19
- package/src/creator/src/locales/en.json +4 -0
- package/src/creator/src/locales/es.json +4 -0
- package/src/creator/src/utils/store.ts +5 -0
- package/src/creatorDist/assets/{index-BvHkfJm4.js → index-6e9E-1qG.js} +1996 -1947
- package/src/creatorDist/index.html +1 -1
- package/src/managers/server/routes.ts +9 -7
- package/src/models/creator.ts +4 -0
- package/src/ui/_app/app.css +1 -1
- package/src/ui/_app/app.js +356 -348
- package/src/ui/_app/index.html +19 -2
- package/src/ui/app.tar.gz +0 -0
- package/src/utils/rigoActions.ts +27 -5
package/lib/commands/serve.js
CHANGED
@@ -330,9 +330,18 @@ class ServeCommand extends SessionCommand_1.default {
|
|
330
330
|
app.post("/webhooks/:courseSlug/initial-readme-processor", async (req, res) => {
|
331
331
|
const { courseSlug } = req.params;
|
332
332
|
const body = req.body;
|
333
|
-
|
334
|
-
const
|
335
|
-
|
333
|
+
console.log("RECEIVING INITIAL README WEBHOOK", body);
|
334
|
+
const langCode = body.parsed.language_code || body.parsed.output_language_code || "";
|
335
|
+
const content = body.parsed.content || body.parsed.translation || "";
|
336
|
+
if (!content || !langCode) {
|
337
|
+
console.log("No content or language code to save", body);
|
338
|
+
return res.status(400).json({
|
339
|
+
status: "ERROR",
|
340
|
+
message: "No content to save",
|
341
|
+
});
|
342
|
+
}
|
343
|
+
const filePath = `courses/${courseSlug}/README${(0, creatorUtilities_1.getReadmeExtension)(langCode)}`;
|
344
|
+
await uploadFileToBucket(bucket, content, filePath);
|
336
345
|
res.json({ status: "SUCCESS" });
|
337
346
|
});
|
338
347
|
app.post("/webhooks/:courseSlug/images/:imageId", async (req, res) => {
|
@@ -438,6 +447,15 @@ class ServeCommand extends SessionCommand_1.default {
|
|
438
447
|
await uploadFileToBucket(bucket, JSON.stringify(newSyllabus), `courses/${courseSlug}/.learn/initialSyllabus.json`);
|
439
448
|
res.json({ status: "SUCCESS" });
|
440
449
|
});
|
450
|
+
// The following endpoint is used to store an incoming translation where it supposed to be
|
451
|
+
app.post("/webhooks/:courseSlug/:exSlug/save-translation", async (req, res) => {
|
452
|
+
const { courseSlug, exSlug } = req.params;
|
453
|
+
const body = req.body;
|
454
|
+
console.log("RECEIVING TRANSLATION WEBHOOK", body);
|
455
|
+
const readmePath = `courses/${courseSlug}/exercises/${exSlug}/README${(0, creatorUtilities_1.getReadmeExtension)(body.parsed.output_language_code)}`;
|
456
|
+
await uploadFileToBucket(bucket, body.parsed.translation, readmePath);
|
457
|
+
res.json({ status: "SUCCESS" });
|
458
|
+
});
|
441
459
|
app.get("/check-preview-image/:slug", async (req, res) => {
|
442
460
|
const { slug } = req.params;
|
443
461
|
const file = bucket.file(`courses/${slug}/preview.png`);
|
@@ -623,65 +641,79 @@ class ServeCommand extends SessionCommand_1.default {
|
|
623
641
|
return res.status(400).json({ error: "RigoToken not found" });
|
624
642
|
}
|
625
643
|
const languagesToTranslate = languages.split(",");
|
626
|
-
const
|
627
|
-
.
|
628
|
-
|
629
|
-
const
|
630
|
-
const languageCodes = new Set();
|
644
|
+
const languageCodesRes = await (0, rigoActions_1.getLanguageCodes)(rigoToken, {
|
645
|
+
raw_languages: languagesToTranslate.join(","),
|
646
|
+
});
|
647
|
+
const languageCodes = languageCodesRes.parsed.language_codes;
|
631
648
|
try {
|
632
649
|
await Promise.all(exerciseSlugs.map(async (slug) => {
|
633
650
|
const readmePath = `courses/${courseSlug}/exercises/${slug}/README${(0, creatorUtilities_1.getReadmeExtension)(currentLanguage)}`;
|
634
651
|
const readme = await bucket.file(readmePath).download();
|
635
|
-
await Promise.all(
|
636
|
-
|
652
|
+
await Promise.all(languageCodes.map(async (language) => {
|
653
|
+
// verify if the translation already exists
|
654
|
+
const translationPath = `courses/${courseSlug}/exercises/${slug}/README${(0, creatorUtilities_1.getReadmeExtension)(language)}`;
|
655
|
+
const [exists] = await bucket.file(translationPath).exists();
|
656
|
+
if (exists) {
|
657
|
+
console.log(`Translation in ${language} already exists for exercise ${slug}`);
|
658
|
+
return;
|
659
|
+
}
|
660
|
+
await (0, rigoActions_1.translateExercise)(rigoToken, {
|
637
661
|
text_to_translate: readme.toString(),
|
638
662
|
output_language: language,
|
639
|
-
|
640
|
-
});
|
641
|
-
const translatedReadme = await bucket.file(`courses/${courseSlug}/exercises/${slug}/README${(0, creatorUtilities_1.getReadmeExtension)(response.parsed.output_language_code)}`);
|
642
|
-
await translatedReadme.save(response.parsed.translation);
|
643
|
-
languageCodes.add(response.parsed.output_language_code);
|
663
|
+
}, `${process.env.HOST}/webhooks/${courseSlug}/${slug}/save-translation`);
|
644
664
|
}));
|
645
665
|
}));
|
646
|
-
const
|
647
|
-
|
648
|
-
|
649
|
-
|
666
|
+
const course = await bucket
|
667
|
+
.file(`courses/${courseSlug}/learn.json`)
|
668
|
+
.download();
|
669
|
+
const courseJson = JSON.parse(course.toString());
|
670
|
+
const neededLanguages = new Set();
|
671
|
+
let currentLanguages = Object.keys(courseJson.title);
|
672
|
+
for (const languageCode of languageCodes) {
|
673
|
+
if (!currentLanguages.includes(languageCode)) {
|
674
|
+
neededLanguages.add(languageCode);
|
650
675
|
}
|
651
676
|
}
|
652
|
-
|
653
|
-
|
654
|
-
|
655
|
-
|
656
|
-
|
657
|
-
|
658
|
-
|
659
|
-
|
660
|
-
|
661
|
-
|
662
|
-
|
663
|
-
|
664
|
-
|
665
|
-
for (const metadata of translatedCourseMetadata) {
|
666
|
-
courseJson.title[metadata.languageCode] = metadata.title;
|
667
|
-
courseJson.description[metadata.languageCode] =
|
668
|
-
metadata.description;
|
669
|
-
}
|
677
|
+
const neededLanguagesList = [...neededLanguages]
|
678
|
+
.map((lang) => lang.toLowerCase())
|
679
|
+
.sort();
|
680
|
+
if (neededLanguagesList.length > 0) {
|
681
|
+
const result = await (0, rigoActions_1.translateCourseMetadata)(rigoToken, {
|
682
|
+
title: JSON.stringify(courseJson.title),
|
683
|
+
description: JSON.stringify(courseJson.description),
|
684
|
+
new_languages: neededLanguagesList.join(","),
|
685
|
+
});
|
686
|
+
const translateTitle = JSON.parse(result.parsed.title);
|
687
|
+
const translateDescription = JSON.parse(result.parsed.description);
|
688
|
+
courseJson.title = translateTitle;
|
689
|
+
courseJson.description = translateDescription;
|
670
690
|
await uploadFileToBucket(bucket, JSON.stringify(courseJson), `courses/${courseSlug}/learn.json`);
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
}
|
691
|
+
currentLanguages = Object.keys(courseJson.title);
|
692
|
+
}
|
693
|
+
// Check that all the READMEs exists
|
694
|
+
const missingReadmeTranslations = [];
|
695
|
+
let firstAvailable = "";
|
696
|
+
for (const languageCode of currentLanguages) {
|
697
|
+
// eslint-disable-next-line no-await-in-loop
|
698
|
+
const previewReadme = await bucket.file(`courses/${courseSlug}/README${(0, creatorUtilities_1.getReadmeExtension)(languageCode)}`);
|
699
|
+
// eslint-disable-next-line no-await-in-loop
|
700
|
+
const [exists] = await previewReadme.exists();
|
701
|
+
if (!exists) {
|
702
|
+
missingReadmeTranslations.push(languageCode);
|
703
|
+
}
|
704
|
+
else {
|
705
|
+
// eslint-disable-next-line no-await-in-loop
|
706
|
+
const [previewReadmeContent] = await previewReadme.download();
|
707
|
+
const previewReadmeContentString = previewReadmeContent.toString();
|
708
|
+
firstAvailable = previewReadmeContentString;
|
709
|
+
}
|
684
710
|
}
|
711
|
+
await Promise.all(missingReadmeTranslations.map(async (languageCode) => {
|
712
|
+
await (0, rigoActions_1.translateExercise)(rigoToken, {
|
713
|
+
text_to_translate: firstAvailable,
|
714
|
+
output_language: languageCode,
|
715
|
+
}, `${process.env.HOST}/webhooks/${courseSlug}/initial-readme-processor`);
|
716
|
+
}));
|
685
717
|
return res.status(200).json({ message: "Translated exercises" });
|
686
718
|
}
|
687
719
|
catch (error) {
|
@@ -78,8 +78,7 @@ class BuildCommand extends SessionCommand_1.default {
|
|
78
78
|
const response = await (0, rigoActions_1.translateExercise)(rigoToken, {
|
79
79
|
text_to_translate: readme,
|
80
80
|
output_language: language,
|
81
|
-
|
82
|
-
});
|
81
|
+
}, `${process.env.HOST}/webhooks/translate-exercise`);
|
83
82
|
await (0, creatorUtilities_1.saveTranslatedReadme)(exercise, response.parsed.output_language_code, response.parsed.translation);
|
84
83
|
console_1.default.success(`Translated ${exercise} to ${language} successfully`);
|
85
84
|
}));
|