mirror of
https://github.com/gabehf/Tdarr_Plugins.git
synced 2026-03-09 15:38:19 -07:00
Merge pull request #542 from HaveAGitGat/parser_update
Use fileMoveOrCopy
This commit is contained in:
commit
66c3519ccd
13 changed files with 673 additions and 41 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
|
||||
import {
|
||||
getContainer, getFileName, getSubStem, moveFileAndValidate,
|
||||
getContainer, getFileName, getSubStem,
|
||||
} from '../../../../FlowHelpers/1.0.0/fileUtils';
|
||||
import {
|
||||
IpluginDetails,
|
||||
|
|
@ -113,11 +114,11 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
|
|||
|
||||
args.deps.fsextra.ensureDirSync(outputPath);
|
||||
|
||||
await moveFileAndValidate({
|
||||
inputPath: args.inputFileObj._id,
|
||||
outputPath: ouputFilePath,
|
||||
await fileMoveOrCopy({
|
||||
operation: 'move',
|
||||
sourcePath: args.inputFileObj._id,
|
||||
destinationPath: ouputFilePath,
|
||||
args,
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
|
||||
import {
|
||||
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate,
|
||||
getContainer, getFileAbosluteDir, getFileName,
|
||||
} from '../../../../FlowHelpers/1.0.0/fileUtils';
|
||||
import {
|
||||
IpluginDetails,
|
||||
|
|
@ -54,9 +55,10 @@ const plugin = async (args:IpluginInputArgs):Promise<IpluginOutputArgs> => {
|
|||
};
|
||||
}
|
||||
|
||||
await moveFileAndValidate({
|
||||
inputPath: args.inputFileObj._id,
|
||||
outputPath: ouputFilePath,
|
||||
await fileMoveOrCopy({
|
||||
operation: 'move',
|
||||
sourcePath: args.inputFileObj._id,
|
||||
destinationPath: ouputFilePath,
|
||||
args,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
|
||||
import {
|
||||
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate,
|
||||
getContainer, getFileAbosluteDir, getFileName,
|
||||
} from '../../../../FlowHelpers/1.0.0/fileUtils';
|
||||
import {
|
||||
IpluginDetails,
|
||||
|
|
@ -68,9 +69,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
|
|||
};
|
||||
}
|
||||
|
||||
await moveFileAndValidate({
|
||||
inputPath: args.inputFileObj._id,
|
||||
outputPath: newPath,
|
||||
await fileMoveOrCopy({
|
||||
operation: 'move',
|
||||
sourcePath: args.inputFileObj._id,
|
||||
destinationPath: newPath,
|
||||
args,
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import fileMoveOrCopy from '../../../../FlowHelpers/1.0.0/fileMoveOrCopy';
|
||||
import {
|
||||
getContainer, getFileAbosluteDir, getFileName, moveFileAndValidate,
|
||||
getContainer, getFileAbosluteDir, getFileName,
|
||||
} from '../../../../FlowHelpers/1.0.0/fileUtils';
|
||||
import {
|
||||
IpluginDetails,
|
||||
|
|
@ -66,9 +67,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
|
|||
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
|
||||
await moveFileAndValidate({
|
||||
inputPath: currentPath,
|
||||
outputPath: newPathTmp,
|
||||
await fileMoveOrCopy({
|
||||
operation: 'move',
|
||||
sourcePath: currentPath,
|
||||
destinationPath: newPathTmp,
|
||||
args,
|
||||
});
|
||||
|
||||
|
|
@ -83,9 +85,10 @@ const plugin = async (args: IpluginInputArgs): Promise<IpluginOutputArgs> => {
|
|||
|
||||
await new Promise((resolve) => setTimeout(resolve, 2000));
|
||||
|
||||
await moveFileAndValidate({
|
||||
inputPath: newPathTmp,
|
||||
outputPath: newPath,
|
||||
await fileMoveOrCopy({
|
||||
operation: 'move',
|
||||
sourcePath: newPathTmp,
|
||||
destinationPath: newPath,
|
||||
args,
|
||||
});
|
||||
|
||||
|
|
|
|||
275
FlowPluginsTs/FlowHelpers/1.0.0/fileMoveOrCopy.ts
Normal file
275
FlowPluginsTs/FlowHelpers/1.0.0/fileMoveOrCopy.ts
Normal file
|
|
@ -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('/');
|
||||
};
|
||||
|
||||
const getFileSize = async (file:string):Promise<number> => {
|
||||
export const getFileSize = async (file:string):Promise<number> => {
|
||||
const stats = await fs.stat(file);
|
||||
const { size } = stats;
|
||||
return size;
|
||||
|
|
|
|||
|
|
@ -132,7 +132,9 @@ export interface IpluginInputArgs {
|
|||
gracefulfs: any,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-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,
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
crudTransDBN: (collection: string, mode: string, docID: string, obj: any)=> any,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue