|
| 1 | +import * as fs from "fs"; |
| 2 | +import * as path from "path"; |
| 3 | +import * as archiver from "archiver"; |
| 4 | +import * as uuid from "uuid"; |
| 5 | +import {ServiceOptions} from "../options/serviceOptions"; |
| 6 | +import {CcfVersion, ExportFormat, ExportCacheBase, IExportResponse} from "./exportCacheBase"; |
| 7 | +import moment = require("moment"); |
| 8 | + |
| 9 | +const debug = require("debug")("mnb:export-api:swc"); |
| 10 | + |
| 11 | +export class SwcExportCache extends ExportCacheBase { |
| 12 | + public constructor(ccfVersion: CcfVersion) { |
| 13 | + super(ccfVersion, ExportFormat.Swc); |
| 14 | + } |
| 15 | + |
| 16 | + public loadContents(): ExportCacheBase { |
| 17 | + const dataLocation = path.join(ServiceOptions.dataPath, this.CcfVersion === CcfVersion.Janelia25 ? "swc25" : "swc30"); |
| 18 | + |
| 19 | + if (!fs.existsSync(dataLocation)) { |
| 20 | + debug("swc data path does not exist"); |
| 21 | + return; |
| 22 | + } |
| 23 | + |
| 24 | + debug("initiating swc cache load"); |
| 25 | + |
| 26 | + fs.readdirSync(dataLocation).forEach(file => { |
| 27 | + if (file.slice(-4) === ".swc") { |
| 28 | + const swcName = file.slice(0, -4); |
| 29 | + |
| 30 | + const data = fs.readFileSync(path.join(dataLocation, file), {encoding: "utf8"}); |
| 31 | + |
| 32 | + this._cache.set(swcName, data); |
| 33 | + } |
| 34 | + }); |
| 35 | + |
| 36 | + debug(`loaded ${this._cache.size} neurons (swc)`) |
| 37 | + |
| 38 | + return this; |
| 39 | + } |
| 40 | + |
| 41 | + public async findContents(ids: string[], hostname: string): Promise<IExportResponse> { |
| 42 | + if (!ids || ids.length === 0) { |
| 43 | + debug(`null swc id request`); |
| 44 | + return null; |
| 45 | + } |
| 46 | + |
| 47 | + const t1 = process.hrtime(); |
| 48 | + |
| 49 | + debug(`handling json request for ids: ${ids.join(", ")}`); |
| 50 | + |
| 51 | + let response: IExportResponse; |
| 52 | + |
| 53 | + if (ids.length === 1) { |
| 54 | + let encoded = null; |
| 55 | + |
| 56 | + const data = this._cache.get(ids[0]); |
| 57 | + |
| 58 | + if (data) { |
| 59 | + encoded = Buffer.from(`# Downloaded ${moment().format("YYYY/MM/DD")}. \n` + data).toString("base64"); |
| 60 | + } |
| 61 | + |
| 62 | + response = { |
| 63 | + contents: encoded, |
| 64 | + filename: ids[0] + ".swc" |
| 65 | + }; |
| 66 | + } else { |
| 67 | + const tempFile = uuid.v4(); |
| 68 | + |
| 69 | + response = await new Promise(async (resolve) => { |
| 70 | + const output = fs.createWriteStream(tempFile); |
| 71 | + |
| 72 | + output.on("finish", () => { |
| 73 | + const readData = fs.readFileSync(tempFile); |
| 74 | + |
| 75 | + const encoded = readData.toString("base64"); |
| 76 | + |
| 77 | + fs.unlinkSync(tempFile); |
| 78 | + |
| 79 | + resolve({ |
| 80 | + contents: encoded, |
| 81 | + filename: "mlnb-export-data.zip" |
| 82 | + }); |
| 83 | + }); |
| 84 | + |
| 85 | + const archive = archiver("zip", {zlib: {level: 9}}); |
| 86 | + |
| 87 | + archive.pipe(output); |
| 88 | + |
| 89 | + ids.forEach(id => { |
| 90 | + const data = this._cache.get(id); |
| 91 | + |
| 92 | + if (data) { |
| 93 | + archive.append(`# Generated ${moment().format("YYYY/MM/DD")}. \n` + data, {name: id + ".swc"}); |
| 94 | + } |
| 95 | + }); |
| 96 | + |
| 97 | + await archive.finalize(); |
| 98 | + }); |
| 99 | + } |
| 100 | + |
| 101 | + await this.logMetrics(ids, hostname, process.hrtime(t1)); |
| 102 | + |
| 103 | + return response; |
| 104 | + } |
| 105 | +} |
0 commit comments