Работа над MegaStorage
This commit is contained in:
70
server/core/LibSharedStorage/MegaStorage.js
Normal file
70
server/core/LibSharedStorage/MegaStorage.js
Normal 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;
|
||||
59
server/core/ZipStreamer.js
Normal file
59
server/core/ZipStreamer.js
Normal 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;
|
||||
Reference in New Issue
Block a user