Работа над MegaStorage

This commit is contained in:
Book Pauk
2019-10-27 19:18:37 +07:00
parent 25f309bcb0
commit 864f008679
2 changed files with 129 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
const fs = require('fs-extra');
const path = require('path');
const ZipStreamer = require('../ZipStreamer');
const utils = require('../utils');
class MegaStorage {
constructor() {
this.readingFiles = false;
this.stats = null;
}
async init(config) {
this.config = config;
this.megaStorageDir = config.megaStorageDir;
this.compressLevel = (config.compressLevel ? config.compressLevel : 4);
await fs.ensureDir(this.megaStorageDir);
}
async nameHash(filename) {
const hash = utils.toBase36(await utils.getFileHash(filename, 'sha1'));
const hashPath = `${hash.substr(0, 2)}/${hash.substr(2, 2)}/${hash}`;
const fullHashPath = `${this.megaStorageDir}/${hashPath}`;
return {
filename,
hash,
hashPath,
fullHashPath,
zipPath: `${fullHashPath}.zip`,
descPath: `${fullHashPath}.desc`,
};
}
async checkFileExists(nameHash) {
return await fs.pathExists(nameHash.zipPath);
}
async addFile(nameHash, desc = null, force = false) {
if (await this.checkFileExists(nameHash) && !force)
return false;
await fs.ensureDir(path.dirname(nameHash.zipPath));
const zip = new ZipStreamer();
let entry = {};
let resultFile = await zip.pack(nameHash.zipPath, [nameHash.filename], {zlib: {level: this.compressLevel}}, (ent) => {
entry = ent;
});
if (desc) {
desc = Object.assign({}, desc, {fileSize: entry.size, zipFileSize: resultFile.size});
this.updateDesc(nameHash, desc);
}
return desc;
}
async updateDesc(nameHash, desc) {
await fs.writeFile(nameHash.descPath, JSON.stringify(desc, null, 2));
}
async readFiles(callback) {
}
async stopReadFiles() {
}
async getStats(gather = false) {
}
}
module.exports = MegaStorage;

View File

@@ -0,0 +1,59 @@
const fs = require('fs-extra');
const path = require('path');
const zipStream = require('zip-stream');
const unzipStream = require('node-stream-zip');
class ZipStreamer {
constructor() {
}
//TODO: сделать рекурсивный обход директорий, пока только файлы
//files = ['filename', 'dirname/']
pack(zipFile, files, options, entryCallback) {
return new Promise((resolve, reject) => { (async() => {
entryCallback = (entryCallback ? entryCallback : () => {});
const zip = new zipStream(options);
const outputStream = fs.createWriteStream(zipFile);
outputStream.on('error', reject);
outputStream.on('finish', async() => {
let file = {path: zipFile};
try {
file.size = (await fs.stat(zipFile)).size;
} catch (e) {
reject(e);
}
resolve(file);
});
zip.on('error', reject);
zip.pipe(outputStream);
const zipAddEntry = (filename) => {
return new Promise((resolve, reject) => {
const basename = path.basename(filename);
const source = fs.createReadStream(filename);
zip.entry(source, {name: basename}, (err, entry) => {
if (err) reject(err);
resolve(entry);
});
});
};
for (const filename of files) {
const entry = await zipAddEntry(filename);
entryCallback({path: entry.name, size: entry.size, compressedSize: entry.csize});
}
zip.finish();
})().catch(reject); });
}
unpack(zipFile, entryCallback) {
}
}
module.exports = ZipStreamer;