@learnpack/learnpack 5.0.262 → 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/managers/server/routes.js +1 -2
- 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/managers/server/routes.ts +9 -7
- package/src/ui/_app/app.js +101 -101
- 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
|
}));
|
@@ -305,8 +305,7 @@ async function default_1(app, configObject, configManager) {
|
|
305
305
|
const response = await (0, rigoActions_1.translateExercise)(rigoToken, {
|
306
306
|
text_to_translate: readme.body,
|
307
307
|
output_language: language,
|
308
|
-
|
309
|
-
});
|
308
|
+
}, `${process.env.HOST}/webhooks/translate-exercise`);
|
310
309
|
await (0, creatorUtilities_1.saveTranslatedReadme)(slug, response.parsed.output_language_code, response.parsed.translation);
|
311
310
|
(0, sidebarGenerator_1.addExerciseToSidebar)(slug, response.parsed.output_language_code, response.parsed.translated_slug, configDirPath || "");
|
312
311
|
console_1.default.success(`Translated ${slug} to ${language} successfully`);
|
@@ -19,9 +19,8 @@ export declare function downloadImage(imageUrl: string, savePath: string): Promi
|
|
19
19
|
type TTranslateInputs = {
|
20
20
|
text_to_translate: string;
|
21
21
|
output_language: string;
|
22
|
-
exercise_slug: string;
|
23
22
|
};
|
24
|
-
export declare const translateExercise: (token: string, inputs: TTranslateInputs) => Promise<any>;
|
23
|
+
export declare const translateExercise: (token: string, inputs: TTranslateInputs, webhookUrl: string) => Promise<any>;
|
25
24
|
type TGenerateCourseIntroductionInputs = {
|
26
25
|
course_title: string;
|
27
26
|
lessons_context: string;
|
@@ -63,7 +62,7 @@ export declare const createStructuredPreviewReadme: (token: string, inputs: TCre
|
|
63
62
|
export declare const translateCourseMetadata: (token: string, inputs: {
|
64
63
|
title: string;
|
65
64
|
description: string;
|
66
|
-
|
65
|
+
new_languages: string;
|
67
66
|
}) => Promise<any>;
|
68
67
|
export declare function createPreviewReadme(tutorialDir: string, packageInfo: PackageInfo, rigoToken: string, readmeContents: string[]): Promise<void>;
|
69
68
|
type TReduceReadmeInputs = {
|
@@ -88,4 +87,8 @@ export declare const isPackageAuthor: (token: string, packageSlug: string) => Pr
|
|
88
87
|
isAuthor: boolean;
|
89
88
|
status: number;
|
90
89
|
}>;
|
90
|
+
type TGetLanguageCodesInputs = {
|
91
|
+
raw_languages: string;
|
92
|
+
};
|
93
|
+
export declare const getLanguageCodes: (token: string, inputs: TGetLanguageCodesInputs) => Promise<any>;
|
91
94
|
export {};
|
package/lib/utils/rigoActions.js
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.isPackageAuthor = exports.fillSidebarJSON = exports.generateCourseShortName = exports.isValidRigoToken = exports.translateCourseMetadata = exports.createStructuredPreviewReadme = exports.readmeCreator = exports.createCodingReadme = exports.createCodeFile = exports.interactiveCreation = exports.generateCourseIntroduction = exports.translateExercise = exports.generateImage = exports.hasCreatorPermission = exports.createReadme = void 0;
|
3
|
+
exports.getLanguageCodes = exports.isPackageAuthor = exports.fillSidebarJSON = exports.generateCourseShortName = exports.isValidRigoToken = exports.translateCourseMetadata = exports.createStructuredPreviewReadme = exports.readmeCreator = exports.createCodingReadme = exports.createCodeFile = exports.interactiveCreation = exports.generateCourseIntroduction = exports.translateExercise = exports.generateImage = exports.hasCreatorPermission = exports.createReadme = void 0;
|
4
4
|
exports.downloadImage = downloadImage;
|
5
5
|
exports.createPreviewReadme = createPreviewReadme;
|
6
6
|
exports.makeReadmeReadable = makeReadmeReadable;
|
@@ -79,11 +79,12 @@ async function downloadImage(imageUrl, savePath) {
|
|
79
79
|
const buffer = Buffer.from(response.data, "binary");
|
80
80
|
await (0, promises_1.writeFile)(savePath, buffer);
|
81
81
|
}
|
82
|
-
const translateExercise = async (token, inputs) => {
|
83
|
-
const response = await axios_1.default.post(`${api_1.RIGOBOT_HOST}/v1/prompting/completion/
|
82
|
+
const translateExercise = async (token, inputs, webhookUrl) => {
|
83
|
+
const response = await axios_1.default.post(`${api_1.RIGOBOT_HOST}/v1/prompting/completion/translate-asset-markdown/`, {
|
84
84
|
inputs: inputs,
|
85
85
|
include_purpose_objective: false,
|
86
|
-
execute_async:
|
86
|
+
execute_async: true,
|
87
|
+
webhook_url: webhookUrl,
|
87
88
|
}, {
|
88
89
|
headers: {
|
89
90
|
"Content-Type": "application/json",
|
@@ -272,3 +273,13 @@ const isPackageAuthor = async (token, packageSlug) => {
|
|
272
273
|
}
|
273
274
|
};
|
274
275
|
exports.isPackageAuthor = isPackageAuthor;
|
276
|
+
const getLanguageCodes = async (token, inputs) => {
|
277
|
+
const response = await axios_1.default.post(`${api_1.RIGOBOT_HOST}/v1/prompting/completion/get-language-codes/`, { inputs, include_purpose_objective: false, execute_async: false }, {
|
278
|
+
headers: {
|
279
|
+
"Content-Type": "application/json",
|
280
|
+
Authorization: "Token " + token,
|
281
|
+
},
|
282
|
+
});
|
283
|
+
return response.data;
|
284
|
+
};
|
285
|
+
exports.getLanguageCodes = getLanguageCodes;
|
package/package.json
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
{
|
2
2
|
"name": "@learnpack/learnpack",
|
3
3
|
"description": "Seamlessly build, sell and/or take interactive & auto-graded tutorials, start learning now or build a new tutorial to your audience.",
|
4
|
-
"version": "5.0.
|
4
|
+
"version": "5.0.265",
|
5
5
|
"author": "Alejandro Sanchez @alesanchezr",
|
6
6
|
"contributors": [
|
7
7
|
{
|
package/src/commands/serve.ts
CHANGED
@@ -31,6 +31,7 @@ import {
|
|
31
31
|
isPackageAuthor,
|
32
32
|
createStructuredPreviewReadme,
|
33
33
|
translateCourseMetadata,
|
34
|
+
getLanguageCodes,
|
34
35
|
} from "../utils/rigoActions"
|
35
36
|
import * as dotenv from "dotenv"
|
36
37
|
import {
|
@@ -519,11 +520,25 @@ export default class ServeCommand extends SessionCommand {
|
|
519
520
|
const { courseSlug } = req.params
|
520
521
|
const body = req.body
|
521
522
|
|
522
|
-
|
523
|
+
console.log("RECEIVING INITIAL README WEBHOOK", body)
|
524
|
+
|
525
|
+
const langCode =
|
526
|
+
body.parsed.language_code || body.parsed.output_language_code || ""
|
527
|
+
|
528
|
+
const content = body.parsed.content || body.parsed.translation || ""
|
529
|
+
|
530
|
+
if (!content || !langCode) {
|
531
|
+
console.log("No content or language code to save", body)
|
532
|
+
return res.status(400).json({
|
533
|
+
status: "ERROR",
|
534
|
+
message: "No content to save",
|
535
|
+
})
|
536
|
+
}
|
537
|
+
|
523
538
|
const filePath = `courses/${courseSlug}/README${getReadmeExtension(
|
524
|
-
|
539
|
+
langCode
|
525
540
|
)}`
|
526
|
-
await uploadFileToBucket(bucket,
|
541
|
+
await uploadFileToBucket(bucket, content, filePath)
|
527
542
|
|
528
543
|
res.json({ status: "SUCCESS" })
|
529
544
|
}
|
@@ -707,6 +722,25 @@ export default class ServeCommand extends SessionCommand {
|
|
707
722
|
}
|
708
723
|
)
|
709
724
|
|
725
|
+
// The following endpoint is used to store an incoming translation where it supposed to be
|
726
|
+
app.post(
|
727
|
+
"/webhooks/:courseSlug/:exSlug/save-translation",
|
728
|
+
async (req, res) => {
|
729
|
+
const { courseSlug, exSlug } = req.params
|
730
|
+
const body = req.body
|
731
|
+
|
732
|
+
console.log("RECEIVING TRANSLATION WEBHOOK", body)
|
733
|
+
|
734
|
+
const readmePath = `courses/${courseSlug}/exercises/${exSlug}/README${getReadmeExtension(
|
735
|
+
body.parsed.output_language_code
|
736
|
+
)}`
|
737
|
+
|
738
|
+
await uploadFileToBucket(bucket, body.parsed.translation, readmePath)
|
739
|
+
|
740
|
+
res.json({ status: "SUCCESS" })
|
741
|
+
}
|
742
|
+
)
|
743
|
+
|
710
744
|
app.get("/check-preview-image/:slug", async (req, res) => {
|
711
745
|
const { slug } = req.params
|
712
746
|
const file = bucket.file(`courses/${slug}/preview.png`)
|
@@ -948,13 +982,10 @@ export default class ServeCommand extends SessionCommand {
|
|
948
982
|
}
|
949
983
|
|
950
984
|
const languagesToTranslate: string[] = languages.split(",")
|
951
|
-
|
952
|
-
|
953
|
-
|
954
|
-
|
955
|
-
|
956
|
-
const courseJson = JSON.parse(course.toString())
|
957
|
-
const languageCodes = new Set()
|
985
|
+
const languageCodesRes = await getLanguageCodes(rigoToken, {
|
986
|
+
raw_languages: languagesToTranslate.join(","),
|
987
|
+
})
|
988
|
+
const languageCodes = languageCodesRes.parsed.language_codes
|
958
989
|
|
959
990
|
try {
|
960
991
|
await Promise.all(
|
@@ -962,59 +993,68 @@ export default class ServeCommand extends SessionCommand {
|
|
962
993
|
const readmePath = `courses/${courseSlug}/exercises/${slug}/README${getReadmeExtension(
|
963
994
|
currentLanguage
|
964
995
|
)}`
|
965
|
-
|
966
996
|
const readme = await bucket.file(readmePath).download()
|
967
997
|
|
968
998
|
await Promise.all(
|
969
|
-
|
970
|
-
|
971
|
-
|
972
|
-
|
973
|
-
|
974
|
-
|
975
|
-
|
976
|
-
|
977
|
-
|
978
|
-
|
979
|
-
)
|
999
|
+
languageCodes.map(async (language: string) => {
|
1000
|
+
// verify if the translation already exists
|
1001
|
+
const translationPath = `courses/${courseSlug}/exercises/${slug}/README${getReadmeExtension(
|
1002
|
+
language
|
1003
|
+
)}`
|
1004
|
+
|
1005
|
+
const [exists] = await bucket.file(translationPath).exists()
|
1006
|
+
if (exists) {
|
1007
|
+
console.log(
|
1008
|
+
`Translation in ${language} already exists for exercise ${slug}`
|
1009
|
+
)
|
1010
|
+
return
|
1011
|
+
}
|
1012
|
+
|
1013
|
+
await translateExercise(
|
1014
|
+
rigoToken,
|
1015
|
+
{
|
1016
|
+
text_to_translate: readme.toString(),
|
1017
|
+
output_language: language,
|
1018
|
+
},
|
1019
|
+
`${process.env.HOST}/webhooks/${courseSlug}/${slug}/save-translation`
|
980
1020
|
)
|
981
|
-
await translatedReadme.save(response.parsed.translation)
|
982
|
-
|
983
|
-
languageCodes.add(response.parsed.output_language_code)
|
984
1021
|
})
|
985
1022
|
)
|
986
1023
|
})
|
987
1024
|
)
|
988
1025
|
|
989
|
-
const
|
990
|
-
|
991
|
-
|
992
|
-
|
1026
|
+
const course = await bucket
|
1027
|
+
.file(`courses/${courseSlug}/learn.json`)
|
1028
|
+
.download()
|
1029
|
+
|
1030
|
+
const courseJson = JSON.parse(course.toString())
|
1031
|
+
|
1032
|
+
const neededLanguages = new Set<string>()
|
1033
|
+
|
1034
|
+
let currentLanguages = Object.keys(courseJson.title)
|
1035
|
+
|
1036
|
+
for (const languageCode of languageCodes) {
|
1037
|
+
if (!currentLanguages.includes(languageCode)) {
|
1038
|
+
neededLanguages.add(languageCode)
|
993
1039
|
}
|
994
1040
|
}
|
995
1041
|
|
996
|
-
|
997
|
-
|
998
|
-
|
999
|
-
const result = await translateCourseMetadata(rigoToken, {
|
1000
|
-
title: courseJson.title[currentLanguage],
|
1001
|
-
description: courseJson.description[currentLanguage],
|
1002
|
-
destination_lang_code: languageCode as string,
|
1003
|
-
})
|
1042
|
+
const neededLanguagesList: string[] = [...neededLanguages]
|
1043
|
+
.map((lang: string) => lang.toLowerCase())
|
1044
|
+
.sort()
|
1004
1045
|
|
1005
|
-
|
1006
|
-
|
1007
|
-
|
1008
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
)
|
1046
|
+
if (neededLanguagesList.length > 0) {
|
1047
|
+
const result = await translateCourseMetadata(rigoToken, {
|
1048
|
+
title: JSON.stringify(courseJson.title),
|
1049
|
+
description: JSON.stringify(courseJson.description),
|
1050
|
+
new_languages: neededLanguagesList.join(","),
|
1051
|
+
})
|
1012
1052
|
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1053
|
+
const translateTitle = JSON.parse(result.parsed.title)
|
1054
|
+
const translateDescription = JSON.parse(result.parsed.description)
|
1055
|
+
|
1056
|
+
courseJson.title = translateTitle
|
1057
|
+
courseJson.description = translateDescription
|
1018
1058
|
|
1019
1059
|
await uploadFileToBucket(
|
1020
1060
|
bucket,
|
@@ -1022,34 +1062,45 @@ export default class ServeCommand extends SessionCommand {
|
|
1022
1062
|
`courses/${courseSlug}/learn.json`
|
1023
1063
|
)
|
1024
1064
|
|
1065
|
+
currentLanguages = Object.keys(courseJson.title)
|
1066
|
+
}
|
1067
|
+
|
1068
|
+
// Check that all the READMEs exists
|
1069
|
+
|
1070
|
+
const missingReadmeTranslations = []
|
1071
|
+
let firstAvailable = ""
|
1072
|
+
for (const languageCode of currentLanguages) {
|
1073
|
+
// eslint-disable-next-line no-await-in-loop
|
1025
1074
|
const previewReadme = await bucket.file(
|
1026
|
-
`courses/${courseSlug}/README${getReadmeExtension(
|
1075
|
+
`courses/${courseSlug}/README${getReadmeExtension(languageCode)}`
|
1027
1076
|
)
|
1028
|
-
const [previewReadmeContent] = await previewReadme.download()
|
1029
|
-
const previewReadmeContentString = previewReadmeContent.toString()
|
1030
|
-
|
1031
|
-
await Promise.all(
|
1032
|
-
[...languageCodes].map(async languageCode => {
|
1033
|
-
const translatedPreviewReadme = await translateExercise(
|
1034
|
-
rigoToken,
|
1035
|
-
{
|
1036
|
-
text_to_translate: previewReadmeContentString,
|
1037
|
-
output_language: languageCode as string,
|
1038
|
-
exercise_slug: "preview-readme",
|
1039
|
-
}
|
1040
|
-
)
|
1041
1077
|
|
1042
|
-
|
1043
|
-
|
1044
|
-
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1078
|
+
// eslint-disable-next-line no-await-in-loop
|
1079
|
+
const [exists] = await previewReadme.exists()
|
1080
|
+
if (!exists) {
|
1081
|
+
missingReadmeTranslations.push(languageCode)
|
1082
|
+
} else {
|
1083
|
+
// eslint-disable-next-line no-await-in-loop
|
1084
|
+
const [previewReadmeContent] = await previewReadme.download()
|
1085
|
+
const previewReadmeContentString = previewReadmeContent.toString()
|
1086
|
+
firstAvailable = previewReadmeContentString
|
1087
|
+
}
|
1051
1088
|
}
|
1052
1089
|
|
1090
|
+
await Promise.all(
|
1091
|
+
missingReadmeTranslations.map(async languageCode => {
|
1092
|
+
|
1093
|
+
await translateExercise(
|
1094
|
+
rigoToken,
|
1095
|
+
{
|
1096
|
+
text_to_translate: firstAvailable,
|
1097
|
+
output_language: languageCode as string,
|
1098
|
+
},
|
1099
|
+
`${process.env.HOST}/webhooks/${courseSlug}/initial-readme-processor`
|
1100
|
+
)
|
1101
|
+
})
|
1102
|
+
)
|
1103
|
+
|
1053
1104
|
return res.status(200).json({ message: "Translated exercises" })
|
1054
1105
|
} catch (error) {
|
1055
1106
|
console.log(error, "ERROR")
|
@@ -96,11 +96,14 @@ export default class BuildCommand extends SessionCommand {
|
|
96
96
|
.split(",")
|
97
97
|
.map(async (language: string) => {
|
98
98
|
const readme = await getReadmeForExercise(exercise)
|
99
|
-
const response = await translateExercise(
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
99
|
+
const response = await translateExercise(
|
100
|
+
rigoToken,
|
101
|
+
{
|
102
|
+
text_to_translate: readme,
|
103
|
+
output_language: language,
|
104
|
+
},
|
105
|
+
`${process.env.HOST}/webhooks/translate-exercise`
|
106
|
+
)
|
104
107
|
|
105
108
|
await saveTranslatedReadme(
|
106
109
|
exercise,
|
@@ -204,8 +204,7 @@ export default async function (
|
|
204
204
|
// symbolic link to maintain path compatiblity
|
205
205
|
const fetchStaticAsset = withHandler((req, res) => {
|
206
206
|
const filePath = `${config?.dirPath}/assets/${req.params.filePath}`
|
207
|
-
if (!fs.existsSync(filePath))
|
208
|
-
throw new Error("File not found: " + filePath)
|
207
|
+
if (!fs.existsSync(filePath)) throw new Error("File not found: " + filePath)
|
209
208
|
const content = fs.readFileSync(filePath)
|
210
209
|
res.write(content)
|
211
210
|
res.end()
|
@@ -436,11 +435,14 @@ throw new Error("File not found: " + filePath)
|
|
436
435
|
|
437
436
|
await Promise.all(
|
438
437
|
languagesToTranslate.map(async (language: string) => {
|
439
|
-
const response = await translateExercise(
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
438
|
+
const response = await translateExercise(
|
439
|
+
rigoToken,
|
440
|
+
{
|
441
|
+
text_to_translate: readme.body,
|
442
|
+
output_language: language,
|
443
|
+
},
|
444
|
+
`${process.env.HOST}/webhooks/translate-exercise`
|
445
|
+
)
|
444
446
|
|
445
447
|
await saveTranslatedReadme(
|
446
448
|
slug,
|