Skip to content

Commit ad711db

Browse files
authored
Merge pull request #39 from lambda-feedback/b359-generate-tex-file
B359 generate tex file
2 parents d19e12b + f502eb1 commit ad711db

2 files changed

Lines changed: 116 additions & 1783 deletions

File tree

index.ts

Lines changed: 116 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,16 @@ import { PdcTs } from "pdc-ts";
55
import { deleteFile, errorRefiner } from "./src/utils";
66
import { z } from "zod";
77

8-
export const schema = z.object({
9-
userId: z.string(),
10-
markdown: z.string(),
11-
setNumber: z.number(),
12-
moduleSlug: z.string(),
13-
});
8+
const TypeOfFileSchema = z.enum(["PDF", "TEX"]);
9+
10+
export const schema = z.array(
11+
z.object({
12+
userId: z.string(),
13+
fileName: z.string(),
14+
typeOfFile: TypeOfFileSchema,
15+
markdown: z.string(),
16+
})
17+
);
1418

1519
export const handler = async function (
1620
event: APIGatewayEvent
@@ -34,88 +38,124 @@ export const handler = async function (
3438
}
3539

3640
const requestData = parsed.data;
37-
const humanSetNumber = requestData.setNumber + 1;
38-
const timestamp = new Date()
39-
.toISOString()
40-
.replace(/[-:T.]/g, "")
41-
.slice(0, 14);
42-
const filename = `${requestData.moduleSlug}_S${humanSetNumber}_${timestamp}.pdf`;
4341

44-
const localPath = `/tmp/${filename}`;
45-
const s3Path = `${requestData.userId}/${filename}`;
46-
let url: string | undefined;
42+
const region = "eu-west-2";
43+
const s3Client = new S3Client({ region });
44+
const s3Bucket = process.env.PUBLIC_S3_BUCKET;
4745

4846
const pdcTs = new PdcTs();
4947

50-
const markdown = requestData.markdown;
51-
try {
52-
await pdcTs.Execute({
53-
from: "markdown-implicit_figures", // pandoc source format (disabling the implicit_figures extension to remove all image captions)
54-
to: "latex", // pandoc output format
55-
pandocArgs: ["--pdf-engine=pdflatex", `--template=./template.latex`],
56-
spawnOpts: { argv0: "+RTS -M512M -RTS" },
57-
outputToFile: true, // Controls whether the output will be returned as a string or written to a file
58-
sourceText: markdown, // Use this if your input is a string. If you set this, the file input will be ignored
59-
destFilePath: localPath,
60-
});
61-
} catch (e: unknown) {
62-
if (e instanceof Error) {
63-
console.error(e.message);
64-
} else {
65-
console.error(e);
66-
}
67-
68-
const TeXoutput = await pdcTs.Execute({
69-
from: "markdown-implicit_figures", // pandoc source format (disabling the implicit_figures extension to remove all image captions)
70-
to: "latex", // pandoc output format
71-
pandocArgs: ["--pdf-engine=pdflatex", `--template=./template.latex`],
72-
outputToFile: false, // Controls whether the output will be returned as a string or written to a file
73-
sourceText: markdown, // Use this if your input is a string. If you set this, the file input will be ignored
74-
destFilePath: localPath,
75-
});
76-
77-
// Find the offending text from the error message:
78-
e = errorRefiner(String(e), TeXoutput, false);
79-
80-
return {
81-
statusCode: 500,
82-
body: JSON.stringify({ e }),
83-
};
84-
}
48+
// Generate file
49+
const generateFile = async (
50+
pandocArgs: string[],
51+
destFilePath: string,
52+
markdown: string
53+
) => {
54+
try {
55+
await pdcTs.Execute({
56+
from: "markdown-implicit_figures", // pandoc source format (disabling the implicit_figures extension to remove all image captions)
57+
to: "latex", // pandoc output format
58+
pandocArgs,
59+
spawnOpts: { argv0: "+RTS -M512M -RTS" },
60+
outputToFile: true, // Controls whether the output will be returned as a string or written to a file
61+
sourceText: markdown, // Use this if your input is a string. If you set this, the file input will be ignored
62+
destFilePath,
63+
});
64+
} catch (e: unknown) {
65+
if (e instanceof Error) {
66+
console.error(e.message);
67+
} else {
68+
console.error(e);
69+
}
8570

86-
try {
87-
const region = "eu-west-2";
88-
const fileStream = fs.createReadStream(localPath);
89-
const s3Client = new S3Client({ region });
90-
const s3Bucket = process.env.PUBLIC_S3_BUCKET;
91-
const params = {
92-
Bucket: s3Bucket,
93-
Key: s3Path,
94-
Body: fileStream,
95-
};
71+
const TeXoutput = await pdcTs.Execute({
72+
from: "markdown-implicit_figures", // pandoc source format (disabling the implicit_figures extension to remove all image captions)
73+
to: "latex", // pandoc output format
74+
pandocArgs,
75+
outputToFile: false, // Controls whether the output will be returned as a string or written to a file
76+
sourceText: markdown, // Use this if your input is a string. If you set this, the file input will be ignored
77+
destFilePath,
78+
});
9679

97-
const command = new PutObjectCommand(params);
98-
await s3Client.send(command);
80+
// Find the offending text from the error message:
81+
e = errorRefiner(String(e), TeXoutput, false);
9982

100-
url = `https://${s3Bucket}.s3.${region}.amazonaws.com/${s3Path}`;
101-
} catch (e: unknown) {
102-
console.error("S3 upload failed");
103-
if (e instanceof Error) {
104-
console.error(e.message);
10583
return {
10684
statusCode: 500,
107-
body: e.message,
85+
body: JSON.stringify({ e }),
10886
};
109-
} else {
110-
console.error(e);
111-
return {
112-
statusCode: 500,
113-
body: "S3 Upload failed",
87+
}
88+
};
89+
90+
const saveFileToS3 = async (localPathPDF: string, s3Path: string) => {
91+
// Save PDF file to S3 bucket
92+
try {
93+
const fileStream = fs.createReadStream(localPathPDF);
94+
const params = {
95+
Bucket: s3Bucket,
96+
Key: s3Path,
97+
Body: fileStream,
11498
};
99+
100+
const command = new PutObjectCommand(params);
101+
await s3Client.send(command);
102+
} catch (e: unknown) {
103+
console.error("S3 upload failed");
104+
if (e instanceof Error) {
105+
console.error(e.message);
106+
return {
107+
statusCode: 500,
108+
body: e.message,
109+
};
110+
} else {
111+
console.error(e);
112+
return {
113+
statusCode: 500,
114+
body: "S3 Upload failed",
115+
};
116+
}
117+
} finally {
118+
// cleanup
119+
deleteFile(localPathPDF);
120+
}
121+
};
122+
123+
let url = "";
124+
for (let eachRequestData of requestData) {
125+
const markdown = eachRequestData.markdown;
126+
127+
switch (eachRequestData.typeOfFile) {
128+
case "PDF":
129+
const filenamePDF = `${eachRequestData.fileName}.pdf`;
130+
const localPathPDF = `/tmp/${filenamePDF}`;
131+
const generatePDFResult = await generateFile(
132+
["--pdf-engine=pdflatex", `--template=./template.latex`],
133+
localPathPDF,
134+
markdown
135+
);
136+
137+
if (generatePDFResult?.statusCode) {
138+
return generatePDFResult;
139+
}
140+
const s3PathPDF = `${eachRequestData.userId}/${filenamePDF}`;
141+
await saveFileToS3(localPathPDF, s3PathPDF);
142+
url = `https://${s3Bucket}.s3.${region}.amazonaws.com/${s3PathPDF}`;
143+
break;
144+
case "TEX":
145+
const filenameTEX = `${eachRequestData.fileName}.tex`;
146+
const localPathTEX = `/tmp/${filenameTEX}`;
147+
148+
await generateFile(
149+
[`--template=./template.latex`],
150+
localPathTEX,
151+
markdown
152+
);
153+
154+
const s3PathTEX = `${eachRequestData.userId}/${filenameTEX}`;
155+
156+
await saveFileToS3(localPathTEX, s3PathTEX);
157+
break;
115158
}
116-
} finally {
117-
// cleanup
118-
deleteFile(localPath);
119159
}
120160

121161
return {

0 commit comments

Comments
 (0)