I wrote some code using some promise, in my case this is a convertion script which will upload files and attachements when they are converted. The convertion part is working fine, I see the expected results in the xwiki portal.
What I want is to loop though the files of a directory, do some convertions and find and collect all the image names in the file. After this is done I need to upload the page first because thats required on the xwiki side and after that I want to upload the attachements. At this moment its uploading the wrong attachements, instead of the one sof the file its uploading them from another file. The filename in both uploadImage and uploapPage is the page its uploading to.
function importDirToXWiki (filePath: string, imagePath: string){
fs.readdir(filePath, (err, files) => {
if (err){
console.log(err);
}
files.forEach(file => {
convertFile(space, filePath, imagePath, file);
});
});
};
function convertFile(directory: string, path: string, imagePath: string, filename: string){
fs.readFile(path "/" filename, async function(err: any, data: { toString: () => string; }) {
if(err) throw err;
attachments = []
//Split the lines
let lines = data.toString().replace(/\r\n/g,'\n').split('\n');
//Convert md to xwiki format
lines = convertHeaders(lines);
lines = convertLists(lines);
lines.map(function (line, i) {
let filename = extractUsingRegex(line, /([a-zA-Z0-9\s_\\.\-\(\):]) (.png|.jpg)/gm)
if(filename.length > 0) attachments.push(filename);
lines[i] = convertImageTags(line);
});
//Adding HTML support & keep XWiki format active
lines.unshift('{{html wiki="true"}}');
lines.push("{{/html}}");
await postNewPage(lines.join("\n"), directory, formatFileName(filename))
Promise.all(attachments.map(async attachment => {
await uploadImage(directory, formatFileName(filename), imagePath, attachment)
}))
});
};
async function uploadImage(space: string, page: string, imagePath: string, filename: string){
if(fs.existsSync(imagePath "/" filename)){
let file = fs.readFileSync(imagePath "/" filename);
await postNewAttachment(file, space, page, filename );
}
};
CodePudding user response:
You can use Node's fs/promises
API to make things simpler.
I also cleaned up some non-idiomatic uses of .forEach
vs .map
. You were also inadvertently making attachments
a global (no const
or var
); consider a linter such as ESLint to warn you about things like that.
const fsp = require("fs/promises");
async function importDirToXWiki(filePath: string, imagePath: string) {
const files = await fsp.readdir(filePath);
const conversionPromises = files.map((file) => convertFile(space, filePath, imagePath, file));
return Promise.all(conversionPromises);
}
async function convertFile(directory: string, path: string, imagePath: string, filename: string) {
const data = await fsp.readFile(path filename, "utf8");
const attachments = [];
//Split the lines
let lines = data.toString().replace(/\r\n/g, "\n").split("\n");
//Convert md to xwiki format
lines = convertHeaders(lines);
lines = convertLists(lines);
lines = lines.map(function (line) {
let filename = extractUsingRegex(line, /([a-zA-Z0-9\s_\\.\-\(\):]) (.png|.jpg)/gm);
if (filename.length > 0) attachments.push(filename);
return convertImageTags(line);
});
//Adding HTML support & keep XWiki format active
lines.unshift('{{html wiki="true"}}');
lines.push("{{/html}}");
await postNewPage(lines.join("\n"), directory, formatFileName(filename));
const uploadPromises = attachments.map((attachment) =>
uploadImage(directory, formatFileName(filename), imagePath, attachment),
);
return Promise.all(uploadPromises);
}
async function uploadImage(space: string, page: string, imagePath: string, filename: string) {
let data;
try {
const data = await fsp.readFile(imagePath filename);
return await postNewAttachment(data, space, page, filename);
} catch (err) {
if (err.code === "ENOENT") {
return; // "Not found", that's likely benign
}
throw err;
}
}