feat(transfer): download everything to tmp dir to prevent unfinish transfers
This commit is contained in:
15
src/background/deleteFolderRecursive.js
Normal file
15
src/background/deleteFolderRecursive.js
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
module.exports = function deleteFolderRecursive(path) {
|
||||||
|
if (fs.existsSync(path)) {
|
||||||
|
fs.readdirSync(path).forEach(function(file, index){
|
||||||
|
var curPath = path + "/" + file;
|
||||||
|
if (fs.lstatSync(curPath).isDirectory()) { // recurse
|
||||||
|
deleteFolderRecursive(curPath);
|
||||||
|
} else { // delete file
|
||||||
|
fs.unlinkSync(curPath);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fs.rmdirSync(path);
|
||||||
|
}
|
||||||
|
};
|
@ -12,6 +12,7 @@ const ph = require('path')
|
|||||||
const directoryFilesRecursive = require('./directoryFilesRecursive')
|
const directoryFilesRecursive = require('./directoryFilesRecursive')
|
||||||
const {promisify} = require('util');
|
const {promisify} = require('util');
|
||||||
const mkdirp = promisify(require('mkdirp'))
|
const mkdirp = promisify(require('mkdirp'))
|
||||||
|
const deleteFolderRecursive = require('./deleteFolderRecursive')
|
||||||
|
|
||||||
class p2p {
|
class p2p {
|
||||||
constructor(send = () => {})
|
constructor(send = () => {})
|
||||||
@ -413,7 +414,7 @@ class p2p {
|
|||||||
return () => callbacks.forEach(callback => callback())
|
return () => callbacks.forEach(callback => callback())
|
||||||
}
|
}
|
||||||
|
|
||||||
file(path, targetPath, remotePeer)
|
file(path, targetPath, remotePeer, parent)
|
||||||
{
|
{
|
||||||
if(!this.dataDirectory)
|
if(!this.dataDirectory)
|
||||||
{
|
{
|
||||||
@ -430,16 +431,19 @@ class p2p {
|
|||||||
logT('transfer', 'get file request', path)
|
logT('transfer', 'get file request', path)
|
||||||
const promise = new Promise(async (resolve) =>
|
const promise = new Promise(async (resolve) =>
|
||||||
{
|
{
|
||||||
const filePath = this.dataDirectory + '/' + (targetPath || path)
|
const realPath = (targetPath || path).replace(/\\/g, '/')
|
||||||
// recreate directory to file if not exist
|
const filePath = this.dataDirectory + '/' + realPath
|
||||||
await mkdirp(ph.dirname(filePath))
|
const tmpPath = this.dataDirectory + '/' + realPath.split('/').map(p => p + '.tmp').join('/')
|
||||||
|
|
||||||
|
// create temporary directory and file for downloading
|
||||||
|
await mkdirp(ph.dirname(tmpPath))
|
||||||
let fileStream
|
let fileStream
|
||||||
if(!fs.existsSync(filePath) || !fs.lstatSync(filePath).isDirectory())
|
if(!fs.existsSync(tmpPath) || !fs.lstatSync(tmpPath).isDirectory())
|
||||||
fileStream = fs.createWriteStream(filePath)
|
fileStream = fs.createWriteStream(tmpPath)
|
||||||
|
|
||||||
let peer = null
|
let peer = null
|
||||||
let firstTransfer = false
|
let firstTransfer = false
|
||||||
let deleteCallback = (remotePeer || this).emit('file', {path}, (chunk, nil, addr) => {
|
let deleteCallback = (remotePeer || this).emit('file', {path}, async (chunk, nil, addr) => {
|
||||||
if(peer && addr !== peer)
|
if(peer && addr !== peer)
|
||||||
{
|
{
|
||||||
logT('transfer', 'ignore other peers responce', addr.peerId)
|
logT('transfer', 'ignore other peers responce', addr.peerId)
|
||||||
@ -454,8 +458,20 @@ class p2p {
|
|||||||
fileStream.end()
|
fileStream.end()
|
||||||
if(firstTransfer) // данные передало до этого, значит файл целый
|
if(firstTransfer) // данные передало до этого, значит файл целый
|
||||||
{
|
{
|
||||||
|
const renameCallback = async () => {
|
||||||
|
await mkdirp(ph.dirname(filePath))
|
||||||
|
fs.renameSync(tmpPath, filePath)
|
||||||
|
}
|
||||||
|
if(parent)
|
||||||
|
{
|
||||||
|
resolve(renameCallback)
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await renameCallback()
|
||||||
resolve(true)
|
resolve(true)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,14 +482,18 @@ class p2p {
|
|||||||
logT('transfer', 'get folder content', filesList)
|
logT('transfer', 'get folder content', filesList)
|
||||||
deleteCallback()
|
deleteCallback()
|
||||||
const transferFiles = () => {
|
const transferFiles = () => {
|
||||||
Promise.all(filesList.map(file => this.file(file, null, addr))).then(() => {
|
Promise.all(filesList.map(file => this.file(file, null, addr, true))).then(async (files) => {
|
||||||
|
// files transfers, now move it from tmp dir
|
||||||
|
Promise.all(files.map((renameCallback) => renameCallback())).then(() => {
|
||||||
|
deleteFolderRecursive(tmpPath)
|
||||||
logT('transfer', 'finish transfer all files from folder')
|
logT('transfer', 'finish transfer all files from folder')
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
|
})
|
||||||
}
|
}
|
||||||
if(fileStream)
|
if(fileStream)
|
||||||
fileStream.end(null, null, () => {
|
fileStream.end(null, null, () => {
|
||||||
fs.unlinkSync(filePath)
|
fs.unlinkSync(tmpPath)
|
||||||
transferFiles()
|
transferFiles()
|
||||||
})
|
})
|
||||||
else
|
else
|
||||||
|
Reference in New Issue
Block a user