UNPKG

twin-scanner-cli

Version:

Find duplicate files in multiple folders scanning .txt and .torrent files.

100 lines (90 loc) 2.75 kB
import path from 'node:path' import * as A from 'fp-ts/lib/Array' import { pipe } from 'fp-ts/lib/function' import * as TE from 'fp-ts/lib/TaskEither' import type { TExtensionsRemoveDuplicatesStrategies } from '../types' import type { TDuplicateFormatTorrent, TGetDuplicatesInFolderTorrent } from './types' import { readDirTE } from '@/files/system-operations' import { isIndirectDuplicateFilename } from '@/logic/helpers' import { getFilesInfo } from '@/logic/readers' import type { TFileInfo } from '@/logic/types' const getDuplicateAbsolutePaths = (folder: string, filesInfo: TFileInfo[]) => ( isConsideredDuplicate: (curFile: TFileInfo) => boolean ): { pathsForDuplicateFiles: string[] folder: string uniqueLength: number duplicateLength: number } => filesInfo.reduce( (acc, cur) => { const isDuplicate = isConsideredDuplicate(cur) return isDuplicate ? { ...acc, pathsForDuplicateFiles: [...acc.pathsForDuplicateFiles, cur.absolutePath], duplicateLength: acc.duplicateLength + 1, } : { ...acc, uniqueLength: acc.uniqueLength + 1, } }, { pathsForDuplicateFiles: [] as string[], folder, uniqueLength: 0, duplicateLength: 0, } satisfies { pathsForDuplicateFiles: string[] folder: string uniqueLength: number duplicateLength: number } ) const getDuplicateTorrentsFilesInFolder: TGetDuplicatesInFolderTorrent = strategy => folder => pipe( folder, readDirTE, TE.flatMap(filenames => pipe( filenames, A.filter(filename => path.extname(filename) === '.torrent'), getFilesInfo(folder), TE.map(filesInfo => pipe( filesInfo, A.map(v => v.filename), strategy.isDuplicate, getDuplicateAbsolutePaths(folder, filesInfo) ) ) ) ) ) /** * @description * Create duplicate maps for all .txt files in folders */ export const getDuplicateTorrentsFilesInFolders = ( folderList: string[], options: { strategy: TExtensionsRemoveDuplicatesStrategies['torrent'] } ): TE.TaskEither<Error, TDuplicateFormatTorrent> => pipe( folderList, A.traverse(TE.ApplicativePar)(getDuplicateTorrentsFilesInFolder(options.strategy)), TE.map(duplicates => pipe( duplicates, A.filter(v => v.uniqueLength > 0) ) ) ) export const isDuplicateTorrent = (filenames: string[]) => (curFile: TFileInfo): boolean => isIndirectDuplicateFilename(filenames, curFile.filename)