diff options
author | Sam Wilkins <35748010+samwilkins333@users.noreply.github.com> | 2019-10-09 16:59:11 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-09 16:59:11 -0400 |
commit | 062a938dae7e78b59aaf9a706d2b656cc4474ac6 (patch) | |
tree | dbbbfe1238a4babd3638132ea48f7e2332e7c540 /src/server/index.ts | |
parent | 0890639c166df6558c3a5c0fd3d427157b3549de (diff) | |
parent | ae9584b6a0b588e0b854a7c5b56723e1a71d47d3 (diff) |
Merge pull request #293 from browngraphicslab/exif
Exif
Diffstat (limited to 'src/server/index.ts')
-rw-r--r-- | src/server/index.ts | 92 |
1 files changed, 88 insertions, 4 deletions
diff --git a/src/server/index.ts b/src/server/index.ts index dd44a0ce8..62938b9c7 100644 --- a/src/server/index.ts +++ b/src/server/index.ts @@ -53,6 +53,8 @@ import { DashUploadUtils } from './DashUploadUtils'; import { BatchedArray, TimeUnit } from 'array-batcher'; import { ParsedPDF } from "./PdfTypes"; import { reject } from 'bluebird'; +import { ExifData } from 'exif'; +import { Result } from '../client/northstar/model/idea/idea'; const download = (url: string, dest: fs.PathLike) => request.get(url).pipe(fs.createWriteStream(dest)); let youtubeApiKey: string; @@ -319,6 +321,76 @@ app.get("/serializeDoc/:docId", async (req, res) => { res.send({ docs, files: Array.from(files) }); }); +export type Hierarchy = { [id: string]: string | Hierarchy }; +export type ZipMutator = (file: Archiver.Archiver) => void | Promise<void>; + +app.get(`${RouteStore.imageHierarchyExport}/:docId`, async (req, res) => { + const id = req.params.docId; + const hierarchy: Hierarchy = {}; + await targetedVisitorRecursive(id, hierarchy); + BuildAndDispatchZip(res, async zip => { + await hierarchyTraverserRecursive(zip, hierarchy); + }); +}); + +const BuildAndDispatchZip = async (res: Response, mutator: ZipMutator): Promise<void> => { + const zip = Archiver('zip'); + zip.pipe(res); + await mutator(zip); + return zip.finalize(); +}; + +const targetedVisitorRecursive = async (seedId: string, hierarchy: Hierarchy): Promise<void> => { + const local: Hierarchy = {}; + const { title, data } = await getData(seedId); + const label = `${title} (${seedId})`; + if (Array.isArray(data)) { + hierarchy[label] = local; + await Promise.all(data.map(proxy => targetedVisitorRecursive(proxy.fieldId, local))); + } else { + hierarchy[label + path.extname(data)] = data; + } +}; + +const getData = async (seedId: string): Promise<{ data: string | any[], title: string }> => { + return new Promise<{ data: string | any[], title: string }>((resolve, reject) => { + Database.Instance.getDocument(seedId, async (result: any) => { + const { data, proto, title } = result.fields; + if (data) { + if (data.url) { + resolve({ data: data.url, title }); + } else if (data.fields) { + resolve({ data: data.fields, title }); + } else { + reject(); + } + } + if (proto) { + getData(proto.fieldId).then(resolve, reject); + } + }); + }); +}; + +const hierarchyTraverserRecursive = async (file: Archiver.Archiver, hierarchy: Hierarchy, prefix = "Dash Export"): Promise<void> => { + for (const key of Object.keys(hierarchy)) { + const result = hierarchy[key]; + if (typeof result === "string") { + let path: string; + let matches: RegExpExecArray | null; + if ((matches = /\:1050\/files\/(upload\_[\da-z]{32}.*)/g.exec(result)) !== null) { + path = `${__dirname}/public/files/${matches[1]}`; + } else { + const information = await DashUploadUtils.UploadImage(result); + path = information.mediaPaths[0]; + } + file.file(path, { name: key, prefix }); + } else { + await hierarchyTraverserRecursive(file, result, `${prefix}/${key}`); + } + } +}; + app.get("/downloadId/:docId", async (req, res) => { res.set('Content-disposition', `attachment;`); res.set('Content-Type', "application/zip"); @@ -590,10 +662,11 @@ const uploadDirectory = __dirname + "/public/files/"; const pdfDirectory = uploadDirectory + "text"; DashUploadUtils.createIfNotExists(pdfDirectory); -interface FileResponse { +interface ImageFileResponse { name: string; path: string; type: string; + exif: Opt<DashUploadUtils.EnrichedExifData>; } // SETTERS @@ -604,10 +677,11 @@ app.post( form.uploadDir = uploadDirectory; form.keepExtensions = true; form.parse(req, async (_err, _fields, files) => { - let results: FileResponse[] = []; + let results: ImageFileResponse[] = []; for (const key in files) { const { type, path: location, name } = files[key]; const filename = path.basename(location); + let uploadInformation: Opt<DashUploadUtils.UploadInformation>; if (filename.endsWith(".pdf")) { let dataBuffer = fs.readFileSync(uploadDirectory + filename); const result: ParsedPDF = await pdf(dataBuffer); @@ -622,9 +696,10 @@ app.post( }); }); } else { - await DashUploadUtils.UploadImage(uploadDirectory + filename, filename).catch(() => console.log(`Unable to process ${filename}`)); + uploadInformation = await DashUploadUtils.UploadImage(uploadDirectory + filename, filename); } - results.push({ name, type, path: `/files/${filename}` }); + const exif = uploadInformation ? uploadInformation.exifData : undefined; + results.push({ name, type, path: `/files/${filename}`, exif }); } _success(res, results); @@ -632,6 +707,15 @@ app.post( } ); +app.post(RouteStore.inspectImage, async (req, res) => { + const { source } = req.body; + if (typeof source === "string") { + const uploadInformation = await DashUploadUtils.UploadImage(source); + return res.send(await DashUploadUtils.InspectImage(uploadInformation.mediaPaths[0])); + } + res.send({}); +}); + addSecureRoute( Method.POST, (user, res, req) => { |