1.0.14
This commit is contained in:
@@ -14,56 +14,14 @@ export async function JobsListMedia(req: Request, res: Response) {
|
||||
const jobid: string = (req.body.jobid || "").trim();
|
||||
await fs.ensureDir(PathToRoFolder(jobid));
|
||||
logger.debug("Listing media for job: " + PathToRoFolder(jobid));
|
||||
let ret: MediaFile[];
|
||||
|
||||
try {
|
||||
let ret: MediaFile[];
|
||||
|
||||
if (req.files) {
|
||||
//We just uploaded files, we're going to send only those back.
|
||||
ret = await Promise.all(
|
||||
(req.files as Express.Multer.File[]).map(async (file) => {
|
||||
const relativeFilePath: string = JobRelativeFilePath(jobid, file.filename);
|
||||
|
||||
const relativeThumbPath: string = await GenerateThumbnail(relativeFilePath);
|
||||
|
||||
const type: FileTypeResult | undefined = await fileTypeFromFile(relativeFilePath);
|
||||
|
||||
return {
|
||||
type,
|
||||
size: file.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file.filename]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, relativeThumbPath]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file.filename,
|
||||
relativeFilePath
|
||||
};
|
||||
})
|
||||
);
|
||||
ret = await processUploadedFiles(req.files as Express.Multer.File[], jobid);
|
||||
} else {
|
||||
const filesList: fs.Dirent[] = (
|
||||
await fs.readdir(PathToRoFolder(jobid), {
|
||||
withFileTypes: true
|
||||
})
|
||||
).filter((f) => f.isFile() && ListableChecker(f));
|
||||
|
||||
ret = await Promise.all(
|
||||
filesList.map(async (file) => {
|
||||
const relativeFilePath: string = JobRelativeFilePath(jobid, file.name);
|
||||
|
||||
const relativeThumbPath: string = await GenerateThumbnail(relativeFilePath);
|
||||
const type: FileTypeResult | undefined = await fileTypeFromFile(relativeFilePath);
|
||||
const fileSize = await fs.stat(relativeFilePath);
|
||||
return {
|
||||
type,
|
||||
size: fileSize.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file.name]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, relativeThumbPath]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file.name,
|
||||
relativeFilePath
|
||||
};
|
||||
})
|
||||
);
|
||||
ret = await processExistingFiles(jobid);
|
||||
}
|
||||
|
||||
if (!res.headersSent) res.json(ret);
|
||||
@@ -72,3 +30,114 @@ export async function JobsListMedia(req: Request, res: Response) {
|
||||
if (!res.headersSent) res.status(500).json(error);
|
||||
}
|
||||
}
|
||||
|
||||
async function processUploadedFiles(files: Express.Multer.File[], jobid: string): Promise<MediaFile[]> {
|
||||
const processFile = async (file: Express.Multer.File): Promise<MediaFile> => {
|
||||
const relativeFilePath: string = JobRelativeFilePath(jobid, file.filename);
|
||||
|
||||
try {
|
||||
const relativeThumbPath: string = await GenerateThumbnail(relativeFilePath);
|
||||
|
||||
const type: FileTypeResult | undefined = await Promise.race([
|
||||
fileTypeFromFile(relativeFilePath),
|
||||
new Promise<undefined>((resolve) => setTimeout(() => resolve(undefined), 5000))
|
||||
]);
|
||||
|
||||
return {
|
||||
type,
|
||||
size: file.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file.filename]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, relativeThumbPath]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file.filename,
|
||||
name: file.filename,
|
||||
path: relativeFilePath,
|
||||
thumbnailPath: relativeThumbPath
|
||||
};
|
||||
} catch (error) {
|
||||
logger.error(`Error processing uploaded file ${file.filename}:`, error);
|
||||
return {
|
||||
type: undefined,
|
||||
size: file.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file.filename]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, "assets", "file.svg"]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file.filename,
|
||||
name: file.filename,
|
||||
path: relativeFilePath,
|
||||
thumbnailPath: ""
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
return (await Promise.all(files.map(processFile))).filter((r): r is MediaFile => r !== null);
|
||||
}
|
||||
|
||||
async function processExistingFiles(jobid: string): Promise<MediaFile[]> {
|
||||
const dirPath = PathToRoFolder(jobid);
|
||||
const mediaFiles: MediaFile[] = [];
|
||||
const dir = await fs.opendir(dirPath);
|
||||
|
||||
for await (const dirent of dir) {
|
||||
if (!dirent.isFile() || !ListableChecker(dirent)) continue;
|
||||
|
||||
const file = dirent.name;
|
||||
const relativeFilePath: string = JobRelativeFilePath(jobid, file);
|
||||
|
||||
try {
|
||||
if (!(await fs.pathExists(relativeFilePath))) {
|
||||
logger.warn(`File no longer exists: ${relativeFilePath}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const fileStats = await Promise.race([
|
||||
fs.stat(relativeFilePath),
|
||||
new Promise<never>((_, reject) => setTimeout(() => reject(new Error("File stat timeout")), 5000))
|
||||
]);
|
||||
|
||||
const relativeThumbPath: string = await GenerateThumbnail(relativeFilePath);
|
||||
|
||||
const type: FileTypeResult | undefined = await Promise.race([
|
||||
fileTypeFromFile(relativeFilePath),
|
||||
new Promise<undefined>((resolve) => setTimeout(() => resolve(undefined), 5000))
|
||||
]);
|
||||
|
||||
mediaFiles.push({
|
||||
type,
|
||||
size: fileStats.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, relativeThumbPath]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file,
|
||||
name: file,
|
||||
path: relativeFilePath,
|
||||
thumbnailPath: relativeThumbPath
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error(`Error processing existing file ${file}:`, error);
|
||||
|
||||
try {
|
||||
const fileStats = await fs.stat(relativeFilePath);
|
||||
mediaFiles.push({
|
||||
type: undefined,
|
||||
size: fileStats.size,
|
||||
src: GenerateUrl([FolderPaths.StaticPath, FolderPaths.JobsFolder, jobid, file]),
|
||||
thumbnail: GenerateUrl([FolderPaths.StaticPath, "assets", "file.svg"]),
|
||||
thumbnailHeight: 250,
|
||||
thumbnailWidth: 250,
|
||||
filename: file,
|
||||
name: file,
|
||||
path: relativeFilePath,
|
||||
thumbnailPath: ""
|
||||
});
|
||||
} catch (statError) {
|
||||
logger.error(`Could not get stats for ${file}:`, statError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return mediaFiles;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user