Skip to content

Commit

Permalink
Split index.js
Browse files Browse the repository at this point in the history
- Extract modules from `index.js` and move to `src`
- Specify `files` in package.json
  • Loading branch information
nikolay-borzov committed Aug 22, 2019
1 parent a95af6e commit e34a2dd
Show file tree
Hide file tree
Showing 6 changed files with 176 additions and 156 deletions.
154 changes: 0 additions & 154 deletions index.js

This file was deleted.

9 changes: 7 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"description": "Removes files that are not specified in selected torrent file",
"author": "Nikolay Borzov <[email protected]>",
"license": "MIT",
"main": "index.js",
"bin": "index.js",
"main": "src/index.js",
"bin": "src/index.js",
"preferGlobal": true,
"repository": "https://github.com/nikolay-borzov/torrent-clean.git",
"bugs": {
Expand All @@ -16,6 +16,11 @@
"start": "node torrent-clean.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"files": [
"src",
"README.md",
"LICENSE"
],
"dependencies": {
"chalk": "^2.4.2",
"delete-empty": "^3.0.0",
Expand Down
28 changes: 28 additions & 0 deletions src/delete-files.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
const fs = require('fs')
const util = require('util')
const unlink = util.promisify(fs.unlink)
const deleteEmpty = require('delete-empty')

const logColor = require('./log-color')

async function deleteFiles(filenames) {
try {
const deletePromises = filenames.map(filename => unlink(filename))
await Promise.all(deletePromises)
} catch (error) {
console.log(logColor.error('Cannot delete files'), error)
}
}

async function deleteEmptyFolders(dirPath) {
try {
await deleteEmpty(dirPath)
} catch (error) {
console.log(logColor.error('Cannot delete empty directories'), error)
}
}

module.exports = async function deleteFilesAndEmptyFolders(filenames, dirPath) {
await deleteFiles(filenames)
await deleteEmptyFolders(dirPath)
}
104 changes: 104 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/usr/bin/env node

const os = require('os')
const path = require('path')
const recursive = require('recursive-readdir')
const { Confirm } = require('enquirer')
const chalk = require('chalk')

const logColor = require('./log-color')
const parseTorrent = require('./parse-torrent')
const deleteFilesAndEmptyFolders = require('./delete-files')

const IGNORE_GLOBS = ['~uTorrentPartFile*']
const FILES_LIST_LIMIT = 20

function outputFilenames(filenames, verbose) {
if (verbose) {
filenames.forEach(filename => console.log(logColor.fileName(filename)))
} else {
const limit = Math.min(FILES_LIST_LIMIT, filenames.length)

for (let i = 0; i < limit; i++) {
console.log(logColor.fileName(filenames[i]))
}

if (limit < filenames.length) {
console.log(logColor.fileName(`...and ${filenames.length - limit} more`))
}
}

console.log()
}

const argv = require('minimist')(process.argv.slice(2), {
alias: { torrent: ['t'], dir: ['d'] },
boolean: ['verbose'],
default: { dir: process.cwd(), verbose: false }
})

console.log(logColor.info.bold('dir:'.padEnd(10)), argv.dir)
console.log(logColor.info.bold('torrent:'.padEnd(10)), argv.torrent, os.EOL)

if (!argv.torrent) {
console.log(logColor.error(`${chalk.bold('torrent')} argument is required`))
return
}

const torrentId = argv.torrent
const directoryPath = path.resolve(argv.dir)
const verbose = argv.verbose

console.log(logColor.info('Parsing torrent file...'))
Promise.all([
parseTorrent(torrentId),
recursive(directoryPath, IGNORE_GLOBS)
]).then(async ([parseResult, dirFiles]) => {
if (!parseResult) {
return
}

const { name, files } = parseResult

console.log(`Parsed ${chalk.bold(name)}.`, os.EOL)

const rootDir = `${name}${path.sep}`
const torrentFiles = files.map(file =>
path.join(directoryPath, file.replace(rootDir, ''))
)

const outdated = dirFiles.reduce((result, filename) => {
if (torrentFiles.indexOf(filename) === -1) {
result.push(filename)
}

return result
}, [])

if (outdated.length) {
console.log(`Found ${chalk.bold(outdated.length)} extra file(s).`)

const dirRoot = `${directoryPath}${path.sep}`
const filenames = outdated.map(filename => filename.replace(dirRoot, ''))
outputFilenames(filenames, verbose)

const deleteConfirm = new Confirm({
name: 'delete',
message: 'Delete extra files?',
initial: true
})

const deleteFilesAnswer = await deleteConfirm.run()

if (deleteFilesAnswer) {
console.log()
console.log(logColor.info('Deleting extra files...'))

await deleteFilesAndEmptyFolders(outdated, directoryPath)

console.log('Files deleted.')
}
} else {
console.log('No extra files found!')
}
})
5 changes: 5 additions & 0 deletions src/log-color.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const chalk = require('chalk')

exports.info = chalk.green
exports.error = chalk.bgRed
exports.fileName = chalk.grey
32 changes: 32 additions & 0 deletions src/parse-torrent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const WebTorrent = require('webtorrent')
const memoryChunkStore = require('memory-chunk-store')

const logColor = require('./log-color')

async function getTorrentMetadata(torrentId) {
return new Promise(resolve => {
parseTorrent(torrentId, resolve)
}).catch(error => {
console.log(logColor.error('Unable to parse torrent'), error)
})
}

function parseTorrent(torrentId, onDone) {
const client = new WebTorrent()

// Use memory-chunk-store to avoid creating directories inside tmp/webtorrent(https://github.com/webtorrent/webtorrent/issues/1562)
const torrent = client.add(torrentId, {
store: memoryChunkStore
})

torrent.on('metadata', () => {
onDone({
name: torrent.name,
files: torrent.files.map(file => file.path)
})

client.destroy()
})
}

module.exports = getTorrentMetadata

0 comments on commit e34a2dd

Please sign in to comment.