250 lines
4.9 KiB
JavaScript
250 lines
4.9 KiB
JavaScript
'use strict'
|
|
|
|
// Depedencies
|
|
let chokidar = require( 'chokidar' ),
|
|
path = require( 'path' ),
|
|
colors = require( 'colors' ),
|
|
ip = require( 'ip' ),
|
|
socket_io_client = require( 'socket.io-client' ),
|
|
fs = require( 'fs' ),
|
|
mime = require( 'mime' ),
|
|
minimatch = require( 'minimatch' )
|
|
|
|
/**
|
|
* Watcher class
|
|
*/
|
|
class Watcher
|
|
{
|
|
/**
|
|
* Constructor
|
|
*/
|
|
constructor( _options )
|
|
{
|
|
this.set_options( _options )
|
|
this.set_watcher()
|
|
this.set_socket()
|
|
}
|
|
|
|
/**
|
|
* Set options
|
|
*/
|
|
set_options( _options )
|
|
{
|
|
// No option
|
|
if( typeof _options !== 'object' )
|
|
_options = {}
|
|
|
|
// Defaults
|
|
if( typeof _options.debug === 'undefined' )
|
|
_options.debug = false
|
|
|
|
if( typeof _options.port === 'undefined' )
|
|
_options.port = 1571
|
|
|
|
if( typeof _options.domain === 'undefined' )
|
|
_options.domain = `http://${ip.address()}:${_options.port}`
|
|
|
|
if( typeof _options.max_file_size === 'undefined' )
|
|
_options.max_file_size = 2000
|
|
|
|
// Save
|
|
this.options = _options
|
|
}
|
|
|
|
/**
|
|
* Set socket
|
|
* Connect to site
|
|
*/
|
|
set_socket()
|
|
{
|
|
// Set up
|
|
this.socket = socket_io_client( `${this.options.domain}/app` )
|
|
|
|
// Connect event
|
|
this.socket.on( 'connect', () =>
|
|
{
|
|
this.socket.emit( 'start_project', { name: this.options.name } )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'connected'.green.bold )
|
|
}
|
|
} )
|
|
}
|
|
|
|
/**
|
|
* Set watcher
|
|
* Listen to modifications on file and folders
|
|
*/
|
|
set_watcher()
|
|
{
|
|
// Set up
|
|
this.watcher = chokidar.watch(
|
|
process.cwd(),
|
|
{
|
|
// ignored : /[\/\\]\./,
|
|
ignoreInitial: true
|
|
}
|
|
)
|
|
|
|
// Add event
|
|
this.watcher.on( 'add', ( _path ) =>
|
|
{
|
|
// Set up
|
|
let relative_path = _path.replace( process.cwd(), '.' ),
|
|
mime_type = mime.lookup( relative_path ),
|
|
file = {}
|
|
|
|
file.path = relative_path
|
|
file.can_read = true
|
|
|
|
// Test mime type
|
|
if( mime_type.match(/^(audio)|(video)|(image)/) )
|
|
{
|
|
file.can_read = false
|
|
}
|
|
|
|
// Test exclusion
|
|
for( let _exclude_key in this.options.exclude )
|
|
{
|
|
// Set up
|
|
let _exclude = this.options.exclude[ _exclude_key ],
|
|
relative_path = _path.replace( process.cwd() + '/', '' )
|
|
|
|
// Match excluded path
|
|
if( minimatch( relative_path, _exclude ) )
|
|
return
|
|
}
|
|
|
|
// Retrieve stats
|
|
fs.stat( _path, ( error, stats ) =>
|
|
{
|
|
// Max file size
|
|
if( stats.size > this.options.max_file_size )
|
|
file.can_read = false
|
|
|
|
// Read
|
|
fs.readFile( _path, ( error, data ) =>
|
|
{
|
|
if( file.can_read )
|
|
file.content = data.toString()
|
|
|
|
// Send
|
|
this.socket.emit( 'create_file', file )
|
|
} )
|
|
} )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'add:'.green.bold, relative_path )
|
|
}
|
|
} )
|
|
|
|
// Change event
|
|
this.watcher.on( 'change', ( _path ) =>
|
|
{
|
|
// Set up
|
|
let relative_path = _path.replace( process.cwd(), '.' ),
|
|
mime_type = mime.lookup( relative_path ),
|
|
file = {}
|
|
|
|
file.path = relative_path
|
|
file.can_read = true
|
|
|
|
// Test mime type
|
|
if( mime_type.match(/^(audio)|(video)|(image)/) )
|
|
{
|
|
file.can_read = false
|
|
}
|
|
|
|
// Test exclusion
|
|
for( let _exclude_key in this.options.exclude )
|
|
{
|
|
// Set up
|
|
let _exclude = this.options.exclude[ _exclude_key ],
|
|
relative_path = _path.replace( process.cwd() + '/', '' )
|
|
|
|
// Match excluded path
|
|
if( minimatch( relative_path, _exclude ) )
|
|
return
|
|
}
|
|
|
|
// Retrieve stats
|
|
fs.stat( _path, ( error, stats ) =>
|
|
{
|
|
// Test max file size
|
|
if( stats.size > this.options.max_file_size )
|
|
file.can_read = false
|
|
|
|
// Read
|
|
fs.readFile( _path, ( error, data ) =>
|
|
{
|
|
if( file.can_read )
|
|
file.content = data.toString()
|
|
|
|
// Send
|
|
this.socket.emit( 'update_file', file )
|
|
} )
|
|
} )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'change:'.green.bold, relative_path )
|
|
}
|
|
} )
|
|
|
|
// Unlink event
|
|
this.watcher.on( 'unlink', ( _path ) =>
|
|
{
|
|
// Set up
|
|
let relative_path = _path.replace( process.cwd(), '.' )
|
|
|
|
// Send
|
|
this.socket.emit( 'delete_file', { path: relative_path } )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'unlink:'.green.bold, relative_path )
|
|
}
|
|
} )
|
|
|
|
// AddDir event
|
|
this.watcher.on( 'addDir', ( _path ) =>
|
|
{
|
|
// Set up
|
|
let relative_path = _path.replace( process.cwd(), '.' )
|
|
|
|
// Send
|
|
this.socket.emit( 'create_folder', { path: relative_path } )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'addDir:'.green.bold, relative_path )
|
|
}
|
|
} )
|
|
|
|
// UnlinkDir event
|
|
this.watcher.on( 'unlinkDir', ( _path ) =>
|
|
{
|
|
// Set up
|
|
let relative_path = _path.replace( process.cwd(), '.' )
|
|
|
|
// Send
|
|
this.socket.emit( 'delete_folder', { path: relative_path } )
|
|
|
|
// Debug
|
|
if( this.options.debug )
|
|
{
|
|
console.log( 'unlinkDir:'.green.bold, relative_path )
|
|
}
|
|
} )
|
|
}
|
|
}
|
|
|
|
module.exports = Watcher
|