dort
Version:
File sharing through web with wonderful alternation.
181 lines (138 loc) • 4.69 kB
JavaScript
/**
* 文件监控模块
*/
const chokidar = require('chokidar')
const fs = require('fs')
const mime = require('mime')
const socketIoClient = require('socket.io-client')
class Watch {
constructor (_config) {
this.config = _config
this.path = process.cwd() + _config.path
this.setExcludeRegex()
this.setSocket()
this.watch()
}
// 初始化socket
setSocket () {
this.socket = socketIoClient(`${this.config.domain}/watch`)
this.socket.on('connect', () => {
this.socket.emit('start_project', { name: this.config.name, path: this.path, exclude: this.config.exclude, excludeRegex: '' + this.excludeRegex })
if (this.config.debug) {
console.log('[watch]'.green.bold + ' - ' + 'socket connect'.cyan)
}
})
this.socket.on('disconnect', () => {
if (this.config.debug) {
console.log('[watch]'.green.bold + ' - ' + 'socket disconnect'.cyan)
}
})
}
setExcludeRegex () {
const regexs = []
const Minimatch = require('minimatch').Minimatch
Object.keys(this.config.exclude).forEach(key => {
const value = this.config.exclude[key]
const minimatch = new Minimatch(value, { dot: true })
let regex = '' + minimatch.makeRe()
regex = regex.replace('/^', '')
regex = regex.replace('$/', '')
regexs.push(regex)
})
this.excludeRegex = new RegExp(regexs.join('|'))
}
watch () {
this.watch = chokidar.watch(
this.path,
{
ignored: this.excludeRegex
}
)
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'start watching'.cyan + ' - ' + this.path.cyan)
}
// 添加文件事件响应函数
this.watch.on('add', (_path) => {
const relativePath = _path.replace(this.path, '.')
const mimeType = mime.getType(relativePath)
const file = {}
file.path = relativePath
file.canRead = true
// 媒体文件不可读
if (mimeType && mimeType.match(/^(audio)|(video)|(image)/)) {
file.canRead = false
}
fs.stat(_path, (err, stats) => {
if (err) throw err
// 判断文件大小
if (this.config.maxFileSize < stats.size) {
file.canRead = false
}
fs.readFile(_path, (err, data) => {
if (err) throw err
if (file.canRead) {
file.content = data.toString()
}
this.socket.emit('create_file', file)
})
})
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'add'.cyan + ' - ' + relativePath.cyan)
}
})
// 更新文件事件响应函数
this.watch.on('change', (_path) => {
const relativePath = _path.replace(this.path, '.')
const mimeType = mime.getType(relativePath)
const file = {}
file.path = relativePath
file.canRead = true
// 媒体文件不可读
if (mimeType && mimeType.match(/^(audio)|(video)|(image)/)) {
file.canRead = false
}
fs.stat(_path, (err, stats) => {
if (err) throw err
// 判断文件大小
if (this.config.maxFileSize < stats.size) {
file.canRead = false
}
fs.readFile(_path, (err, data) => {
if (err) throw err
if (file.canRead) {
file.content = data.toString()
}
this.socket.emit('update_file', file)
})
})
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'change'.cyan + ' - ' + relativePath.cyan)
}
})
// 删除文件事件响应函数
this.watch.on('unlink', (_path) => {
const relativePath = _path.replace(this.path, '.')
this.socket.emit('delete_file', { path: relativePath })
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'unlink'.cyan + ' - ' + relativePath.cyan)
}
})
// 添加文件夹事件响应函数
this.watch.on('addDir', (_path) => {
const relativePath = _path.replace(this.path, '.')
this.socket.emit('create_folder', { path: relativePath })
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'addDir'.cyan + ' - ' + relativePath.cyan)
}
})
// 删除文件夹事件响应函数
this.watch.on('unlinkDir', (_path) => {
const relativePath = _path.replace(this.path, '.')
this.socket.emit('delete_folder', { path: relativePath })
if (this.config.debug >= 1) {
console.log('[watch]'.green.bold + ' - ' + 'unlinkDir'.cyan + ' - ' + relativePath.cyan)
}
})
}
}
module.exports = Watch