Merge pull request #542 from HaveAGitGat/parser_update

Use fileMoveOrCopy
make-only-subtitle-default
HaveAGitGat 2 years ago committed by GitHub
commit 66c3519ccd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -40,6 +40,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.plugin = exports.details = void 0; exports.plugin = exports.details = void 0;
var fileMoveOrCopy_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/fileMoveOrCopy"));
var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils"); var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
var normJoinPath_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/normJoinPath")); var normJoinPath_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/normJoinPath"));
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
@ -137,9 +138,10 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
}]; }];
} }
args.deps.fsextra.ensureDirSync(outputPath); args.deps.fsextra.ensureDirSync(outputPath);
return [4 /*yield*/, (0, fileUtils_1.moveFileAndValidate)({ return [4 /*yield*/, (0, fileMoveOrCopy_1.default)({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: ouputFilePath, sourcePath: args.inputFileObj._id,
destinationPath: ouputFilePath,
args: args, args: args,
})]; })];
case 1: case 1:

@ -35,8 +35,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
} }
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.plugin = exports.details = void 0; exports.plugin = exports.details = void 0;
var fileMoveOrCopy_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/fileMoveOrCopy"));
var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils"); var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({ var details = function () { return ({
@ -83,9 +87,10 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
variables: args.variables, variables: args.variables,
}]; }];
} }
return [4 /*yield*/, (0, fileUtils_1.moveFileAndValidate)({ return [4 /*yield*/, (0, fileMoveOrCopy_1.default)({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: ouputFilePath, sourcePath: args.inputFileObj._id,
destinationPath: ouputFilePath,
args: args, args: args,
})]; })];
case 1: case 1:

@ -35,8 +35,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
} }
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.plugin = exports.details = void 0; exports.plugin = exports.details = void 0;
var fileMoveOrCopy_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/fileMoveOrCopy"));
var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils"); var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({ var details = function () { return ({
@ -97,9 +101,10 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
variables: args.variables, variables: args.variables,
}]; }];
} }
return [4 /*yield*/, (0, fileUtils_1.moveFileAndValidate)({ return [4 /*yield*/, (0, fileMoveOrCopy_1.default)({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: newPath, sourcePath: args.inputFileObj._id,
destinationPath: newPath,
args: args, args: args,
})]; })];
case 1: case 1:

@ -35,8 +35,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
} }
}; };
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.plugin = exports.details = void 0; exports.plugin = exports.details = void 0;
var fileMoveOrCopy_1 = __importDefault(require("../../../../FlowHelpers/1.0.0/fileMoveOrCopy"));
var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils"); var fileUtils_1 = require("../../../../FlowHelpers/1.0.0/fileUtils");
/* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */ /* eslint no-plusplus: ["error", { "allowForLoopAfterthoughts": true }] */
var details = function () { return ({ var details = function () { return ({
@ -94,9 +98,10 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })];
case 1: case 1:
_a.sent(); _a.sent();
return [4 /*yield*/, (0, fileUtils_1.moveFileAndValidate)({ return [4 /*yield*/, (0, fileMoveOrCopy_1.default)({
inputPath: currentPath, operation: 'move',
outputPath: newPathTmp, sourcePath: currentPath,
destinationPath: newPathTmp,
args: args, args: args,
})]; })];
case 2: case 2:
@ -110,9 +115,10 @@ var plugin = function (args) { return __awaiter(void 0, void 0, void 0, function
return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })]; return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 2000); })];
case 3: case 3:
_a.sent(); _a.sent();
return [4 /*yield*/, (0, fileUtils_1.moveFileAndValidate)({ return [4 /*yield*/, (0, fileMoveOrCopy_1.default)({
inputPath: newPathTmp, operation: 'move',
outputPath: newPath, sourcePath: newPathTmp,
destinationPath: newPath,
args: args, args: args,
})]; })];
case 4: case 4:

@ -0,0 +1,328 @@
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (g && (g = 0, op[0] && (_ = 0)), _) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
Object.defineProperty(exports, "__esModule", { value: true });
var fs_1 = require("fs");
var fileUtils_1 = require("./fileUtils");
var getSizeBytes = function (fPath) { return __awaiter(void 0, void 0, void 0, function () {
var size, err_1;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
size = 0;
_a.label = 1;
case 1:
_a.trys.push([1, 3, , 4]);
return [4 /*yield*/, (0, fileUtils_1.getFileSize)(fPath)];
case 2:
size = _a.sent();
return [3 /*break*/, 4];
case 3:
err_1 = _a.sent();
return [3 /*break*/, 4];
case 4: return [2 /*return*/, size];
}
});
}); };
var compareOldNew = function (_a) {
var sourceFileSize = _a.sourceFileSize, destinationSize = _a.destinationSize, args = _a.args;
if (destinationSize !== sourceFileSize) {
args.jobLog("After move/copy, destination file of size ".concat(destinationSize, " does not match")
+ " cache file of size ".concat(sourceFileSize));
}
else {
args.jobLog("After move/copy, destination file of size ".concat(destinationSize, " does match")
+ " cache file of size ".concat(sourceFileSize));
}
};
var tryMove = function (_a) {
var sourcePath = _a.sourcePath, destinationPath = _a.destinationPath, sourceFileSize = _a.sourceFileSize, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () {
var error, err_2, destinationSize;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
args.jobLog("Attempting move from ".concat(sourcePath, " to ").concat(destinationPath, ", method 1"));
error = false;
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, fs_1.promises.rename(sourcePath, destinationPath)];
case 2:
_b.sent();
return [3 /*break*/, 4];
case 3:
err_2 = _b.sent();
error = true;
args.jobLog("File move error: ".concat(JSON.stringify(err_2)));
return [3 /*break*/, 4];
case 4: return [4 /*yield*/, getSizeBytes(destinationPath)];
case 5:
destinationSize = _b.sent();
compareOldNew({
sourceFileSize: sourceFileSize,
destinationSize: destinationSize,
args: args,
});
if (error || destinationSize !== sourceFileSize) {
return [2 /*return*/, false];
}
return [2 /*return*/, true];
}
});
});
};
var tryMvdir = function (_a) {
var sourcePath = _a.sourcePath, destinationPath = _a.destinationPath, sourceFileSize = _a.sourceFileSize, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () {
var error, destinationSize;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
args.jobLog("Attempting move from ".concat(sourcePath, " to ").concat(destinationPath, ", method 2"));
error = false;
return [4 /*yield*/, new Promise(function (resolve) {
// fs-extra and move-file don't work when destination is on windows root of drive
// mvdir will try to move else fall back to copy/unlink
// potential bug on unraid
args.deps.mvdir(sourcePath, destinationPath, { overwrite: true })
.then(function () {
resolve(true);
}).catch(function (err) {
error = true;
args.jobLog("File move error: ".concat(err));
resolve(err);
});
})];
case 1:
_b.sent();
return [4 /*yield*/, getSizeBytes(destinationPath)];
case 2:
destinationSize = _b.sent();
compareOldNew({
sourceFileSize: sourceFileSize,
destinationSize: destinationSize,
args: args,
});
if (error || destinationSize !== sourceFileSize) {
return [2 /*return*/, false];
}
return [2 /*return*/, true];
}
});
});
};
// Keep in e.g. https://github.com/HaveAGitGat/Tdarr/issues/858
var tyNcp = function (_a) {
var sourcePath = _a.sourcePath, destinationPath = _a.destinationPath, sourceFileSize = _a.sourceFileSize, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () {
var error_1, destinationSize;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
if (!args.deps.ncp) return [3 /*break*/, 3];
args.jobLog("Attempting copy from ".concat(sourcePath, " to ").concat(destinationPath, " , method 1"));
error_1 = false;
return [4 /*yield*/, new Promise(function (resolve) {
args.deps.ncp(sourcePath, destinationPath, function (err) {
if (err) {
error_1 = true;
args.jobLog("File copy error: ".concat(err));
resolve(err);
}
else {
resolve(true);
}
});
})];
case 1:
_b.sent();
return [4 /*yield*/, getSizeBytes(destinationPath)];
case 2:
destinationSize = _b.sent();
compareOldNew({
sourceFileSize: sourceFileSize,
destinationSize: destinationSize,
args: args,
});
if (error_1 || destinationSize !== sourceFileSize) {
return [2 /*return*/, false];
}
return [2 /*return*/, true];
case 3: return [2 /*return*/, false];
}
});
});
};
var tryNormalCopy = function (_a) {
var sourcePath = _a.sourcePath, destinationPath = _a.destinationPath, sourceFileSize = _a.sourceFileSize, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () {
var error, err_3, destinationSize;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
args.jobLog("Attempting copy from ".concat(sourcePath, " to ").concat(destinationPath, " , method 2"));
error = false;
_b.label = 1;
case 1:
_b.trys.push([1, 3, , 4]);
return [4 /*yield*/, fs_1.promises.copyFile(sourcePath, destinationPath)];
case 2:
_b.sent();
return [3 /*break*/, 4];
case 3:
err_3 = _b.sent();
error = true;
args.jobLog("File copy error: ".concat(JSON.stringify(err_3)));
return [3 /*break*/, 4];
case 4: return [4 /*yield*/, getSizeBytes(destinationPath)];
case 5:
destinationSize = _b.sent();
compareOldNew({
sourceFileSize: sourceFileSize,
destinationSize: destinationSize,
args: args,
});
if (error || destinationSize !== sourceFileSize) {
return [2 /*return*/, false];
}
return [2 /*return*/, true];
}
});
});
};
var cleanSourceFile = function (_a) {
var args = _a.args, sourcePath = _a.sourcePath;
return __awaiter(void 0, void 0, void 0, function () {
var err_4;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
args.jobLog("Deleting source file ".concat(sourcePath));
return [4 /*yield*/, fs_1.promises.unlink(sourcePath)];
case 1:
_b.sent();
return [3 /*break*/, 3];
case 2:
err_4 = _b.sent();
args.jobLog("Failed to delete source file ".concat(sourcePath, ": ").concat(JSON.stringify(err_4)));
return [3 /*break*/, 3];
case 3: return [2 /*return*/];
}
});
});
};
var fileMoveOrCopy = function (_a) {
var operation = _a.operation, sourcePath = _a.sourcePath, destinationPath = _a.destinationPath, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () {
var sourceFileSize, moved, mvdird, ncpd, copied;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
args.jobLog('Calculating cache file size in bytes');
return [4 /*yield*/, getSizeBytes(sourcePath)];
case 1:
sourceFileSize = _b.sent();
args.jobLog("".concat(sourceFileSize));
if (!(operation === 'move')) return [3 /*break*/, 4];
return [4 /*yield*/, tryMove({
sourcePath: sourcePath,
destinationPath: destinationPath,
args: args,
sourceFileSize: sourceFileSize,
})];
case 2:
moved = _b.sent();
if (moved) {
return [2 /*return*/, true];
}
return [4 /*yield*/, tryMvdir({
sourcePath: sourcePath,
destinationPath: destinationPath,
args: args,
sourceFileSize: sourceFileSize,
})];
case 3:
mvdird = _b.sent();
if (mvdird) {
return [2 /*return*/, true];
}
args.jobLog('Failed to move file, trying copy');
_b.label = 4;
case 4: return [4 /*yield*/, tyNcp({
sourcePath: sourcePath,
destinationPath: destinationPath,
args: args,
sourceFileSize: sourceFileSize,
})];
case 5:
ncpd = _b.sent();
if (!ncpd) return [3 /*break*/, 8];
if (!(operation === 'move')) return [3 /*break*/, 7];
return [4 /*yield*/, cleanSourceFile({
args: args,
sourcePath: sourcePath,
})];
case 6:
_b.sent();
_b.label = 7;
case 7: return [2 /*return*/, true];
case 8: return [4 /*yield*/, tryNormalCopy({
sourcePath: sourcePath,
destinationPath: destinationPath,
args: args,
sourceFileSize: sourceFileSize,
})];
case 9:
copied = _b.sent();
if (!copied) return [3 /*break*/, 12];
if (!(operation === 'move')) return [3 /*break*/, 11];
return [4 /*yield*/, cleanSourceFile({
args: args,
sourcePath: sourcePath,
})];
case 10:
_b.sent();
_b.label = 11;
case 11: return [2 /*return*/, true];
case 12: throw new Error("Failed to ".concat(operation, " file"));
}
});
});
};
exports.default = fileMoveOrCopy;

@ -36,7 +36,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
} }
}; };
Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "__esModule", { value: true });
exports.getScanTypes = exports.getPluginWorkDir = exports.moveFileAndValidate = exports.getSubStem = exports.getFfType = exports.getFileAbosluteDir = exports.getFileName = exports.getContainer = void 0; exports.getScanTypes = exports.getPluginWorkDir = exports.moveFileAndValidate = exports.getFileSize = exports.getSubStem = exports.getFfType = exports.getFileAbosluteDir = exports.getFileName = exports.getContainer = void 0;
var fs_1 = require("fs"); var fs_1 = require("fs");
var getContainer = function (filePath) { var getContainer = function (filePath) {
var parts = filePath.split('.'); var parts = filePath.split('.');
@ -79,13 +79,14 @@ var getFileSize = function (file) { return __awaiter(void 0, void 0, void 0, fun
} }
}); });
}); }; }); };
exports.getFileSize = getFileSize;
var moveFileAndValidate = function (_a) { var moveFileAndValidate = function (_a) {
var inputPath = _a.inputPath, outputPath = _a.outputPath, args = _a.args; var inputPath = _a.inputPath, outputPath = _a.outputPath, args = _a.args;
return __awaiter(void 0, void 0, void 0, function () { return __awaiter(void 0, void 0, void 0, function () {
var inputSize, res1, outputSize, err_1, res2, errMessage; var inputSize, res1, outputSize, err_1, res2, errMessage;
return __generator(this, function (_b) { return __generator(this, function (_b) {
switch (_b.label) { switch (_b.label) {
case 0: return [4 /*yield*/, getFileSize(inputPath)]; case 0: return [4 /*yield*/, (0, exports.getFileSize)(inputPath)];
case 1: case 1:
inputSize = _b.sent(); inputSize = _b.sent();
args.jobLog("Attempt 1: Moving file from ".concat(inputPath, " to ").concat(outputPath)); args.jobLog("Attempt 1: Moving file from ".concat(inputPath, " to ").concat(outputPath));
@ -107,7 +108,7 @@ var moveFileAndValidate = function (_a) {
_b.label = 3; _b.label = 3;
case 3: case 3:
_b.trys.push([3, 5, , 6]); _b.trys.push([3, 5, , 6]);
return [4 /*yield*/, getFileSize(outputPath)]; return [4 /*yield*/, (0, exports.getFileSize)(outputPath)];
case 4: case 4:
outputSize = _b.sent(); outputSize = _b.sent();
return [3 /*break*/, 6]; return [3 /*break*/, 6];
@ -135,7 +136,7 @@ var moveFileAndValidate = function (_a) {
})]; })];
case 7: case 7:
res2 = _b.sent(); res2 = _b.sent();
return [4 /*yield*/, getFileSize(outputPath)]; return [4 /*yield*/, (0, exports.getFileSize)(outputPath)];
case 8: case 8:
outputSize = _b.sent(); outputSize = _b.sent();
if (!res2 || inputSize !== outputSize) { if (!res2 || inputSize !== outputSize) {

@ -1,5 +1,6 @@
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
import { import {
getContainer, getFileName, getSubStem, moveFileAndValidate, getContainer, getFileName, getSubStem,
} from '../../../../FlowHelpers/1.0.0/fileUtils'; } from '../../../../FlowHelpers/1.0.0/fileUtils';
import { import {
IpluginDetails, IpluginDetails,
@ -113,11 +114,11 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
args.deps.fsextra.ensureDirSync(outputPath); args.deps.fsextra.ensureDirSync(outputPath);
await moveFileAndValidate({ await fileMoveOrCopy({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: ouputFilePath, sourcePath: args.inputFileObj._id,
destinationPath: ouputFilePath,
args, args,
}); });
return { return {

@ -1,5 +1,6 @@
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
import { import {
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate, getContainer, getFileAbosluteDir, getFileName,
} from '../../../../FlowHelpers/1.0.0/fileUtils'; } from '../../../../FlowHelpers/1.0.0/fileUtils';
import { import {
IpluginDetails, IpluginDetails,
@ -54,9 +55,10 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
}; };
} }
await moveFileAndValidate({ await fileMoveOrCopy({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: ouputFilePath, sourcePath: args.inputFileObj._id,
destinationPath: ouputFilePath,
args, args,
}); });

@ -1,5 +1,6 @@
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
import { import {
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate, getContainer, getFileAbosluteDir, getFileName,
} from '../../../../FlowHelpers/1.0.0/fileUtils'; } from '../../../../FlowHelpers/1.0.0/fileUtils';
import { import {
IpluginDetails, IpluginDetails,
@ -68,9 +69,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
}; };
} }
await moveFileAndValidate({ await fileMoveOrCopy({
inputPath: args.inputFileObj._id, operation: 'move',
outputPath: newPath, sourcePath: args.inputFileObj._id,
destinationPath: newPath,
args, args,
}); });

@ -1,5 +1,6 @@
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
import { import {
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate, getContainer, getFileAbosluteDir, getFileName,
} from '../../../../FlowHelpers/1.0.0/fileUtils'; } from '../../../../FlowHelpers/1.0.0/fileUtils';
import { import {
IpluginDetails, IpluginDetails,
@ -66,9 +67,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
await new Promise((resolve) => setTimeout(resolve, 2000)); await new Promise((resolve) => setTimeout(resolve, 2000));
await moveFileAndValidate({ await fileMoveOrCopy({
inputPath: currentPath, operation: 'move',
outputPath: newPathTmp, sourcePath: currentPath,
destinationPath: newPathTmp,
args, args,
}); });
@ -83,9 +85,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
await new Promise((resolve) => setTimeout(resolve, 2000)); await new Promise((resolve) => setTimeout(resolve, 2000));
await moveFileAndValidate({ await fileMoveOrCopy({
inputPath: newPathTmp, operation: 'move',
outputPath: newPath, sourcePath: newPathTmp,
destinationPath: newPath,
args, args,
}); });

@ -0,0 +1,275 @@
import { promises as fs } from 'fs';
import { getFileSize } from './fileUtils';
import { IpluginInputArgs } from './interfaces/interfaces';
interface Imove {
sourcePath:string,
destinationPath:string,
sourceFileSize:number,
args:IpluginInputArgs,
}
const getSizeBytes = async (fPath: string): Promise<number> => {
let size = 0;
try {
size = await getFileSize(fPath);
} catch (err) {
// err
}
return size;
};
const compareOldNew = ({
sourceFileSize,
destinationSize,
args,
}:{
sourceFileSize:number,
destinationSize:number,
args:IpluginInputArgs,
}):void => {
if (destinationSize !== sourceFileSize) {
args.jobLog(`After move/copy, destination file of size ${destinationSize} does not match`
+ ` cache file of size ${sourceFileSize}`);
} else {
args.jobLog(`After move/copy, destination file of size ${destinationSize} does match`
+ ` cache file of size ${sourceFileSize}`);
}
};
const tryMove = async ({
sourcePath,
destinationPath,
sourceFileSize,
args,
}:Imove):Promise<boolean> => {
args.jobLog(`Attempting move from ${sourcePath} to ${destinationPath}, method 1`);
let error = false;
try {
await fs.rename(sourcePath, destinationPath);
} catch (err) {
error = true;
args.jobLog(`File move error: ${JSON.stringify(err)}`);
}
const destinationSize = await getSizeBytes(destinationPath);
compareOldNew({
sourceFileSize,
destinationSize,
args,
});
if (error || destinationSize !== sourceFileSize) {
return false;
}
return true;
};
const tryMvdir = async ({
sourcePath,
destinationPath,
sourceFileSize,
args,
}:Imove):Promise<boolean> => {
args.jobLog(`Attempting move from ${sourcePath} to ${destinationPath}, method 2`);
let error = false;
await new Promise((resolve) => {
// fs-extra and move-file don't work when destination is on windows root of drive
// mvdir will try to move else fall back to copy/unlink
// potential bug on unraid
args.deps.mvdir(sourcePath, destinationPath, { overwrite: true })
.then(() => {
resolve(true);
}).catch((err: Error) => {
error = true;
args.jobLog(`File move error: ${err}`);
resolve(err);
});
});
const destinationSize = await getSizeBytes(destinationPath);
compareOldNew({
sourceFileSize,
destinationSize,
args,
});
if (error || destinationSize !== sourceFileSize) {
return false;
}
return true;
};
// Keep in e.g. https://github.com/HaveAGitGat/Tdarr/issues/858
const tyNcp = async ({
sourcePath,
destinationPath,
sourceFileSize,
args,
}:Imove):Promise<boolean> => {
// added in 2.14.01
if (args.deps.ncp) {
args.jobLog(`Attempting copy from ${sourcePath} to ${destinationPath} , method 1`);
let error = false;
await new Promise((resolve) => {
args.deps.ncp(sourcePath, destinationPath, (err: Error) => {
if (err) {
error = true;
args.jobLog(`File copy error: ${err}`);
resolve(err);
} else {
resolve(true);
}
});
});
const destinationSize = await getSizeBytes(destinationPath);
compareOldNew({
sourceFileSize,
destinationSize,
args,
});
if (error || destinationSize !== sourceFileSize) {
return false;
}
return true;
}
return false;
};
const tryNormalCopy = async ({
sourcePath,
destinationPath,
sourceFileSize,
args,
}:Imove):Promise<boolean> => {
args.jobLog(`Attempting copy from ${sourcePath} to ${destinationPath} , method 2`);
let error = false;
try {
await fs.copyFile(sourcePath, destinationPath);
} catch (err) {
error = true;
args.jobLog(`File copy error: ${JSON.stringify(err)}`);
}
const destinationSize = await getSizeBytes(destinationPath);
compareOldNew({
sourceFileSize,
destinationSize,
args,
});
if (error || destinationSize !== sourceFileSize) {
return false;
}
return true;
};
const cleanSourceFile = async ({
args,
sourcePath,
}:{
args:IpluginInputArgs,
sourcePath: string,
}) => {
try {
args.jobLog(`Deleting source file ${sourcePath}`);
await fs.unlink(sourcePath);
} catch (err) {
args.jobLog(`Failed to delete source file ${sourcePath}: ${JSON.stringify(err)}`);
}
};
const fileMoveOrCopy = async ({
operation,
sourcePath,
destinationPath,
args,
}: {
operation: 'move' | 'copy',
sourcePath: string,
destinationPath: string,
args: IpluginInputArgs,
}):Promise<boolean> => {
args.jobLog('Calculating cache file size in bytes');
const sourceFileSize = await getSizeBytes(sourcePath);
args.jobLog(`${sourceFileSize}`);
if (operation === 'move') {
const moved = await tryMove({
sourcePath,
destinationPath,
args,
sourceFileSize,
});
if (moved) {
return true;
}
const mvdird = await tryMvdir({
sourcePath,
destinationPath,
args,
sourceFileSize,
});
if (mvdird) {
return true;
}
args.jobLog('Failed to move file, trying copy');
}
const ncpd = await tyNcp({
sourcePath,
destinationPath,
args,
sourceFileSize,
});
if (ncpd) {
if (operation === 'move') {
await cleanSourceFile({
args,
sourcePath,
});
}
return true;
}
const copied = await tryNormalCopy({
sourcePath,
destinationPath,
args,
sourceFileSize,
});
if (copied) {
if (operation === 'move') {
await cleanSourceFile({
args,
sourcePath,
});
}
return true;
}
throw new Error(`Failed to ${operation} file`);
};
export default fileMoveOrCopy;

@ -36,7 +36,7 @@ export const getSubStem = ({
return parts.join('/'); return parts.join('/');
}; };
const getFileSize = async (file:string):Promise<number> => { export const getFileSize = async (file:string):Promise<number> => {
const stats = await fs.stat(file); const stats = await fs.stat(file);
const { size } = stats; const { size } = stats;
return size; return size;

@ -133,6 +133,8 @@ export interface IpluginInputArgs {
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
mvdir: any, mvdir: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
ncp: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
axios: any, axios: any,
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
crudTransDBN: (collection: string, mode: string, docID: string, obj: any)=> any, crudTransDBN: (collection: string, mode: string, docID: string, obj: any)=> any,

Loading…
Cancel
Save